%bcond_with wayland
-%{!?profile:%define profile tv}
-
%define _manifestdir %{TZ_SYS_RW_PACKAGES}
%define _desktop_icondir %{TZ_SYS_SHARE}/icons/default/small
Summary: Tizen Web APIs implemented
Source0: %{name}-%{version}.tar.gz
-%ifarch %{arm} aarch64
-# ARM
-%define tizen_is_emulator 0
-%else
-# I586
-%define tizen_is_emulator 1
-%endif
-
-%if "%{_repository}" == "arm64-wayland"
-# 64bit
-%define tizen_is_arm64 1
-%else
-# 32bit
-%define tizen_is_arm64 0
-%endif
-
####################################################################
# Common Profile : artik #
####################################################################
-%if "%{?profile}" == "common"
-
-%define tizen_privilege_engine CYNARA
-
-%define tizen_feature_account_support 0
-%define tizen_feature_alarm_support 1
-%define tizen_feature_app_control_settings_support 1
-%define tizen_feature_application_support 1
-%define tizen_feature_archive_support 0
-%define tizen_feature_badge_support 0
-%define tizen_feature_bluetooth_support 1
-%define tizen_feature_bookmark_support 0
-%define tizen_feature_calendar_support 0
-%define tizen_feature_contact_support 0
-%define tizen_feature_content_support 1
-%define tizen_feature_datacontrol_support 0
-%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
-%define tizen_feature_iotcon_support 0
-%define tizen_feature_location_batch 0
-%define tizen_feature_key_manager_support 0
-%define tizen_feature_media_controller_support 0
-%define tizen_feature_media_key_support 0
-%define tizen_feature_message_port_support 1
-%define tizen_feature_messaging_support 0
-%define tizen_feature_nfc_emulation_support 0
-%define tizen_feature_nfc_support 0
-%define tizen_feature_notification_support 0
-%define tizen_feature_package_support 1
-%define tizen_feature_player_util_support 0
-%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
-%define tizen_feature_sound_support 1
-%define tizen_feature_system_info_support 1
-%define tizen_feature_system_setting_support 0
-%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 0
-%define tizen_feature_callhistory_support 0
-%define tizen_feature_nbs_support 0
-%define tizen_feature_tvinputdevice_support 0
-
-%endif # tizen_profile_common
+
+%define tizen_common_privilege_engine CYNARA
+
+%define tizen_common_feature_account_support 0
+%define tizen_common_feature_alarm_support 1
+%define tizen_common_feature_app_control_settings_support 1
+%define tizen_common_feature_application_support 1
+%define tizen_common_feature_archive_support 0
+%define tizen_common_feature_badge_support 0
+%define tizen_common_feature_bluetooth_support 1
+%define tizen_common_feature_bookmark_support 0
+%define tizen_common_feature_calendar_support 0
+%define tizen_common_feature_contact_support 0
+%define tizen_common_feature_content_support 1
+%define tizen_common_feature_datacontrol_support 0
+%define tizen_common_feature_datasync_support 0
+%define tizen_common_feature_download_support 1
+%define tizen_common_feature_exif_support 1
+%define tizen_common_feature_feedback_support 0
+%define tizen_common_feature_filesystem_support 1
+%define tizen_common_feature_fm_radio_support 0
+%define tizen_common_feature_ham_support 0
+%define tizen_common_feature_iotcon_support 0
+%define tizen_common_feature_location_batch 0
+%define tizen_common_feature_key_manager_support 0
+%define tizen_common_feature_media_controller_support 0
+%define tizen_common_feature_media_key_support 0
+%define tizen_common_feature_message_port_support 1
+%define tizen_common_feature_messaging_support 0
+%define tizen_common_feature_nfc_emulation_support 0
+%define tizen_common_feature_nfc_support 0
+%define tizen_common_feature_notification_support 0
+%define tizen_common_feature_package_support 1
+%define tizen_common_feature_player_util_support 0
+%define tizen_common_feature_power_support 0
+%define tizen_common_feature_preference_support 0
+%define tizen_common_feature_push_support 0
+%define tizen_common_feature_se_support 0
+%define tizen_common_feature_sensor_support 0
+%define tizen_common_feature_sound_support 1
+%define tizen_common_feature_system_info_support 1
+%define tizen_common_feature_system_setting_support 0
+%define tizen_common_feature_telephony_support 0
+%define tizen_common_feature_time_support 1
+%define tizen_common_feature_web_setting_support 0
+%define tizen_common_feature_widget_service_support 0
+%define tizen_common_feature_wi_fi_support 1
+%define tizen_common_feature_inputdevice_support 0
+%define tizen_common_feature_callhistory_support 0
+%define tizen_common_feature_nbs_support 0
+%define tizen_common_feature_tvinputdevice_support 0
+
####################################################################
# Mobile Profile : TM1(32bit), Redwood(SM-Z910F), KIRAN(Z130H) #
# TM2(64bit)
####################################################################
-%if "%{?profile}" == "mobile"
-
-%define tizen_privilege_engine CYNARA
-
-%define tizen_feature_account_support 1
-%define tizen_feature_alarm_support 1
-%define tizen_feature_app_control_settings_support 1
-%define tizen_feature_application_support 1
-%define tizen_feature_archive_support 1
-%define tizen_feature_badge_support 1
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_bluetooth_support 0
-%else
-%define tizen_feature_bluetooth_support 1
-%endif
-%define tizen_feature_bookmark_support 1
-%define tizen_feature_calendar_support 1
-%define tizen_feature_contact_support 1
-%define tizen_feature_content_support 1
-%define tizen_feature_datacontrol_support 1
-%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
-# FM radio feature
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_fm_radio_support 1
-%else
-%if 0%{?tizen_is_arm64}
-%define tizen_feature_fm_radio_support 0
+%define tizen_mobile_privilege_engine CYNARA
+
+%define tizen_mobile_feature_account_support 1
+%define tizen_mobile_feature_alarm_support 1
+%define tizen_mobile_feature_app_control_settings_support 1
+%define tizen_mobile_feature_application_support 1
+%define tizen_mobile_feature_archive_support 1
+%define tizen_mobile_feature_badge_support 1
+%define tizen_mobile_feature_bluetooth_support 1
+%define tizen_mobile_feature_bookmark_support 1
+%define tizen_mobile_feature_calendar_support 1
+%define tizen_mobile_feature_contact_support 1
+%define tizen_mobile_feature_content_support 1
+%define tizen_mobile_feature_datacontrol_support 1
+%define tizen_mobile_feature_datasync_support 0
+%define tizen_mobile_feature_download_support 1
+%define tizen_mobile_feature_exif_support 1
+%define tizen_mobile_feature_feedback_support 1
+%define tizen_mobile_feature_filesystem_support 1
+
+%ifarch aarch64
+%define tizen_mobile_feature_fm_radio_support 0
%else
-%define tizen_feature_fm_radio_support 1
-%endif
+%define tizen_mobile_feature_fm_radio_support 1
%endif
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_ham_support 1
-%else
-%define tizen_feature_ham_support 0
-%endif
-%define tizen_feature_iotcon_support 1
-%define tizen_feature_location_batch 0
-%define tizen_feature_key_manager_support 1
-%define tizen_feature_media_controller_support 1
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_media_key_support 0
-%else
-%define tizen_feature_media_key_support 1
-%endif
-%define tizen_feature_message_port_support 1
-%define tizen_feature_messaging_support 1
+%define tizen_mobile_feature_ham_support 0
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_nfc_emulation_support 0
-%define tizen_feature_nfc_support 1
-%else
-%define tizen_feature_nfc_emulation_support 0
-%define tizen_feature_nfc_support 0
-%endif
-%define tizen_feature_notification_support 1
-%define tizen_feature_package_support 1
-%define tizen_feature_player_util_support 1
-%define tizen_feature_power_support 1
-%define tizen_feature_preference_support 1
-%define tizen_feature_push_support 1
+%define tizen_mobile_feature_iotcon_support 1
+%define tizen_mobile_feature_location_batch 0
+%define tizen_mobile_feature_key_manager_support 1
+%define tizen_mobile_feature_media_controller_support 1
+
+%define tizen_mobile_feature_media_key_support 1
+
+%define tizen_mobile_feature_message_port_support 1
+%define tizen_mobile_feature_messaging_support 1
+
+%define tizen_mobile_feature_nfc_emulation_support 0
+%define tizen_mobile_feature_nfc_support 0
+
+%define tizen_mobile_feature_notification_support 1
+%define tizen_mobile_feature_package_support 1
+%define tizen_mobile_feature_player_util_support 1
+%define tizen_mobile_feature_power_support 1
+%define tizen_mobile_feature_preference_support 1
+%define tizen_mobile_feature_push_support 1
# secure element feature
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_se_support 0
-%else
-%if 0%{?tizen_is_arm64}
-%define tizen_feature_se_support 0
+%ifarch aarch64
+%define tizen_mobile_feature_se_support 0
%else
-%define tizen_feature_se_support 1
-%endif
+%define tizen_mobile_feature_se_support 1
%endif
-%define tizen_feature_sensor_support 1
-%define tizen_feature_sound_support 1
-%define tizen_feature_system_info_support 1
-%define tizen_feature_system_setting_support 1
+%define tizen_mobile_feature_sensor_support 1
+%define tizen_mobile_feature_sound_support 1
+%define tizen_mobile_feature_system_info_support 1
+%define tizen_mobile_feature_system_setting_support 1
# telephony feature
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_telephony_support 1
+%ifarch aarch64
+%define tizen_mobile_feature_telephony_support 0
+%define tizen_mobile_feature_callhistory_support 0
+%define tizen_mobile_feature_nbs_support 0
%else
-%if 0%{?tizen_is_arm64}
-%define tizen_feature_telephony_support 0
-%else
-%define tizen_feature_telephony_support 1
-%endif
+%define tizen_mobile_feature_telephony_support 1
+%define tizen_mobile_feature_callhistory_support 1
+%define tizen_mobile_feature_nbs_support 1
%endif
-%define tizen_feature_time_support 1
-%define tizen_feature_web_setting_support 1
-%define tizen_feature_widget_service_support 1
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_wi_fi_support 0
-%else
-%define tizen_feature_wi_fi_support 1
-%endif
-%define tizen_feature_inputdevice_support 1
+%define tizen_mobile_feature_time_support 1
+%define tizen_mobile_feature_web_setting_support 1
+%define tizen_mobile_feature_widget_service_support 1
-%if 0%{?tizen_feature_telephony_support}
-%define tizen_feature_callhistory_support 1
-%define tizen_feature_nbs_support 1
-%else
-%define tizen_feature_callhistory_support 0
-%define tizen_feature_nbs_support 0
-%endif
+%define tizen_mobile_feature_wi_fi_support 1
-%define tizen_feature_tvinputdevice_support 0
+%define tizen_mobile_feature_inputdevice_support 1
+
+%define tizen_mobile_feature_tvinputdevice_support 0
-%endif # tizen_profile_mobile
####################################################################
-# Wearable Profile : B2 / TW1 #
+# Wearable Profile : B2 / TW2 #
####################################################################
-%if "%{?profile}" == "wearable"
-%define tizen_privilege_engine CYNARA
+%define tizen_wearable_privilege_engine CYNARA
# Account API is optional in Tizen Wearable Profile.
-%define tizen_feature_account_support 0
+%define tizen_wearable_feature_account_support 1
-%define tizen_feature_alarm_support 1
-%define tizen_feature_app_control_settings_support 1
-%define tizen_feature_application_support 1
+%define tizen_wearable_feature_alarm_support 1
+%define tizen_wearable_feature_app_control_settings_support 1
+%define tizen_wearable_feature_application_support 1
# Archive API is optional in Tizen Wearable Profile.
-%define tizen_feature_archive_support 1
+%define tizen_wearable_feature_archive_support 1
# Badge API is mandatory in Tizen Wearable Profile.
-%define tizen_feature_badge_support 1
+%define tizen_wearable_feature_badge_support 1
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_bluetooth_support 0
-%else
-%define tizen_feature_bluetooth_support 1
-%endif
+%define tizen_wearable_feature_bluetooth_support 1
# Bookmark API is optional in Tizen Wearable Profile.
-%define tizen_feature_bookmark_support 0
+%define tizen_wearable_feature_bookmark_support 0
# Calendar API is mandatory in Tizen Wearable Profile.
-%define tizen_feature_calendar_support 0
-%define tizen_feature_contact_support 0
-%define tizen_feature_content_support 1
-%define tizen_feature_datacontrol_support 1
-%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 0
-%define tizen_feature_ham_support 1
-%define tizen_feature_iotcon_support 1
-%define tizen_feature_location_batch 0
-%define tizen_feature_media_controller_support 1
+%define tizen_wearable_feature_calendar_support 1
+%define tizen_wearable_feature_contact_support 1
+%define tizen_wearable_feature_content_support 1
+%define tizen_wearable_feature_datacontrol_support 1
+%define tizen_wearable_feature_datasync_support 0
+%define tizen_wearable_feature_download_support 1
+%define tizen_wearable_feature_exif_support 1
+%define tizen_wearable_feature_feedback_support 1
+%define tizen_wearable_feature_filesystem_support 1
+%define tizen_wearable_feature_fm_radio_support 0
+%define tizen_wearable_feature_ham_support 1
+%define tizen_wearable_feature_iotcon_support 1
+%define tizen_wearable_feature_location_batch 0
+%define tizen_wearable_feature_media_controller_support 1
# MediayKey API is optional in Tizen Wearable Profile.
# tizen.org/feature/network.bluetooth.audio.media is required for MediayKey API
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_media_key_support 0
-%else
-%define tizen_feature_media_key_support 1
-%endif
-%define tizen_feature_key_manager_support 1
-%define tizen_feature_message_port_support 1
-%define tizen_feature_messaging_support 0
-%define tizen_feature_nfc_emulation_support 0
-%define tizen_feature_nfc_support 1
-%define tizen_feature_notification_support 1
-%define tizen_feature_package_support 1
-%define tizen_feature_player_util_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
-%else
-%define tizen_feature_se_support 1
-%endif
-%define tizen_feature_sensor_support 1
-%define tizen_feature_sound_support 1
-%define tizen_feature_system_info_support 1
-%define tizen_feature_system_setting_support 1
-%if 0%{?tizen_is_emulator}
-%define tizen_feature_telephony_support 1
-%else
-%define tizen_feature_telephony_support 0
-%endif
-%define tizen_feature_time_support 1
-%define tizen_feature_web_setting_support 0
-%define tizen_feature_widget_service_support 1
-%define tizen_feature_wi_fi_support 1
-%define tizen_feature_inputdevice_support 1
-%define tizen_feature_tvinputdevice_support 0
+%define tizen_wearable_feature_media_key_support 1
+%define tizen_wearable_feature_key_manager_support 1
+%define tizen_wearable_feature_message_port_support 1
+%define tizen_wearable_feature_messaging_support 0
+%define tizen_wearable_feature_nfc_emulation_support 0
+%define tizen_wearable_feature_nfc_support 1
+%define tizen_wearable_feature_notification_support 1
+%define tizen_wearable_feature_package_support 1
+%define tizen_wearable_feature_player_util_support 1
+%define tizen_wearable_feature_power_support 1
+%define tizen_wearable_feature_preference_support 1
+%define tizen_wearable_feature_push_support 1
+%define tizen_wearable_feature_se_support 1
+# sensor module is not supported in TW2 devices
+%define tizen_wearable_feature_sensor_support 0
+%define tizen_wearable_feature_sound_support 1
+%define tizen_wearable_feature_system_info_support 1
+%define tizen_wearable_feature_system_setting_support 1
#- telephony related APIs
# CallHistory API is optional in Tizen Wearable Profile.
# NetworkBearerSelection API is optional in Tizen Wearable Profile.
-%if 0%{?tizen_feature_telephony_support}
-%define tizen_feature_callhistory_support 1
-%define tizen_feature_nbs_support 1
-%else
-%define tizen_feature_callhistory_support 0
-%define tizen_feature_nbs_support 0
-%endif
+%define tizen_wearable_feature_telephony_support 0
+%define tizen_wearable_feature_callhistory_support 0
+%define tizen_wearable_feature_nbs_support 0
+
+%define tizen_wearable_feature_time_support 1
+%define tizen_wearable_feature_web_setting_support 0
+%define tizen_wearable_feature_widget_service_support 1
+%define tizen_wearable_feature_wi_fi_support 1
+%define tizen_wearable_feature_inputdevice_support 1
+%define tizen_wearable_feature_tvinputdevice_support 0
-%endif # tizen_profile_wearable
####################################################################
# TV Profile #
####################################################################
-%if "%{?profile}" == "tv"
-
-%define tizen_privilege_engine CYNARA
-
-%define tizen_feature_account_support 0
-%define tizen_feature_alarm_support 1
-%define tizen_feature_app_control_settings_support 0
-%define tizen_feature_application_support 1
-%define tizen_feature_archive_support 1
-%define tizen_feature_badge_support 0
-%define tizen_feature_bluetooth_support 0
-%define tizen_feature_bookmark_support 0
-%define tizen_feature_calendar_support 0
-%define tizen_feature_callhistory_support 0
-%define tizen_feature_contact_support 0
-%define tizen_feature_content_support 1
-%define tizen_feature_datacontrol_support 1
-%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
-%define tizen_feature_iotcon_support 1
-%define tizen_feature_key_manager_support 1
-%define tizen_feature_media_controller_support 0
-%define tizen_feature_media_key_support 1
-%define tizen_feature_message_port_support 1
-%define tizen_feature_messaging_support 0
-%define tizen_feature_nbs_support 0
-%define tizen_feature_nfc_emulation_support 0
-%define tizen_feature_nfc_support 0
-%define tizen_feature_notification_support 0
-%define tizen_feature_package_support 1
-%define tizen_feature_player_util_support 0
-%define tizen_feature_power_support 0
-%define tizen_feature_preference_support 0
-%define tizen_feature_push_support 1
-%define tizen_feature_se_support 0
-%define tizen_feature_sensor_support 0
-%define tizen_feature_sound_support 0
-%define tizen_feature_system_info_support 1
-%define tizen_feature_system_setting_support 0
-%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
+
+%define tizen_tv_privilege_engine CYNARA
+
+%define tizen_tv_feature_account_support 0
+%define tizen_tv_feature_alarm_support 1
+%define tizen_tv_feature_app_control_settings_support 0
+%define tizen_tv_feature_application_support 1
+%define tizen_tv_feature_archive_support 1
+%define tizen_tv_feature_badge_support 0
+%define tizen_tv_feature_bluetooth_support 0
+%define tizen_tv_feature_bookmark_support 0
+%define tizen_tv_feature_calendar_support 0
+%define tizen_tv_feature_callhistory_support 0
+%define tizen_tv_feature_contact_support 0
+%define tizen_tv_feature_content_support 1
+%define tizen_tv_feature_datacontrol_support 1
+%define tizen_tv_feature_datasync_support 0
+%define tizen_tv_feature_download_support 1
+%define tizen_tv_feature_exif_support 1
+%define tizen_tv_feature_feedback_support 0
+%define tizen_tv_feature_filesystem_support 1
+%define tizen_tv_feature_fm_radio_support 0
+%define tizen_tv_feature_ham_support 0
+%define tizen_tv_feature_iotcon_support 1
+%define tizen_tv_feature_key_manager_support 1
+%define tizen_tv_feature_media_controller_support 0
+%define tizen_tv_feature_media_key_support 0
+%define tizen_tv_feature_message_port_support 1
+%define tizen_tv_feature_messaging_support 0
+%define tizen_tv_feature_nbs_support 0
+%define tizen_tv_feature_nfc_emulation_support 0
+%define tizen_tv_feature_nfc_support 0
+%define tizen_tv_feature_notification_support 0
+%define tizen_tv_feature_package_support 1
+%define tizen_tv_feature_player_util_support 0
+%define tizen_tv_feature_power_support 0
+%define tizen_tv_feature_preference_support 0
+%define tizen_tv_feature_push_support 1
+%define tizen_tv_feature_se_support 0
+%define tizen_tv_feature_sensor_support 0
+%define tizen_tv_feature_sound_support 0
+%define tizen_tv_feature_system_info_support 1
+%define tizen_tv_feature_system_setting_support 0
+%define tizen_tv_feature_telephony_support 0
+%define tizen_tv_feature_time_support 1
+%define tizen_tv_feature_web_setting_support 1
+%define tizen_tv_feature_widget_service_support 0
+%define tizen_tv_feature_wi_fi_support 1
+%define tizen_tv_feature_inputdevice_support 0
+%define tizen_tv_feature_tvinputdevice_support 1
+
+# common, or "unified (undefined)"
+%define unified_build 1
+# GBM Product Build Optimization. Not for 4.0 Public Unified Build.
+%if "%{?profile}" == "tv" || "%{?profile}" == "mobile" || "%{?profile}" == "wearable" || "%{?profile}" == "ivi"
+%define unified_build 0
+%endif
+
+# GBM Product Build Optimization. Not for 4.0 Public Unified Build.
+%if "%{?profile}" == "tv" || "%{?profile}" == "mobile" || "%{?profile}" == "wearable" || "%{?profile}" == "common"
+%define tizen_privilege_engine %{expand:%tizen_%{?profile}_privilege_engine}
+
+%define tizen_feature_account_support %{expand:%tizen_%{?profile}_feature_account_support}
+%define tizen_feature_alarm_support %{expand:%tizen_%{?profile}_feature_alarm_support}
+%define tizen_feature_app_control_settings_support %{expand:%tizen_%{?profile}_feature_app_control_settings_support}
+%define tizen_feature_application_support %{expand:%tizen_%{?profile}_feature_application_support}
+%define tizen_feature_archive_support %{expand:%tizen_%{?profile}_feature_archive_support}
+%define tizen_feature_badge_support %{expand:%tizen_%{?profile}_feature_badge_support}
+%define tizen_feature_bluetooth_support %{expand:%tizen_%{?profile}_feature_bluetooth_support}
+%define tizen_feature_bookmark_support %{expand:%tizen_%{?profile}_feature_bookmark_support}
+%define tizen_feature_calendar_support %{expand:%tizen_%{?profile}_feature_calendar_support}
+%define tizen_feature_contact_support %{expand:%tizen_%{?profile}_feature_contact_support}
+%define tizen_feature_content_support %{expand:%tizen_%{?profile}_feature_content_support}
+%define tizen_feature_datacontrol_support %{expand:%tizen_%{?profile}_feature_datacontrol_support}
+%define tizen_feature_datasync_support %{expand:%tizen_%{?profile}_feature_datasync_support}
+%define tizen_feature_download_support %{expand:%tizen_%{?profile}_feature_download_support}
+%define tizen_feature_exif_support %{expand:%tizen_%{?profile}_feature_exif_support}
+%define tizen_feature_feedback_support %{expand:%tizen_%{?profile}_feature_feedback_support}
+%define tizen_feature_filesystem_support %{expand:%tizen_%{?profile}_feature_filesystem_support}
+%define tizen_feature_fm_radio_support %{expand:%tizen_%{?profile}_feature_fm_radio_support}
+%define tizen_feature_ham_support %{expand:%tizen_%{?profile}_feature_ham_support}
+%define tizen_feature_iotcon_support %{expand:%tizen_%{?profile}_feature_iotcon_support}
+%define tizen_feature_location_batch %{expand:%tizen_%{?profile}_feature_location_batch}
+%define tizen_feature_key_manager_support %{expand:%tizen_%{?profile}_feature_key_manager_support}
+%define tizen_feature_media_controller_support %{expand:%tizen_%{?profile}_feature_media_controller_support}
+%define tizen_feature_media_key_support %{expand:%tizen_%{?profile}_feature_media_key_support}
+%define tizen_feature_message_port_support %{expand:%tizen_%{?profile}_feature_message_port_support}
+%define tizen_feature_messaging_support %{expand:%tizen_%{?profile}_feature_messaging_support}
+%define tizen_feature_nfc_emulation_support %{expand:%tizen_%{?profile}_feature_nfc_emulation_support}
+%define tizen_feature_nfc_support %{expand:%tizen_%{?profile}_feature_nfc_support}
+%define tizen_feature_notification_support %{expand:%tizen_%{?profile}_feature_notification_support}
+%define tizen_feature_package_support %{expand:%tizen_%{?profile}_feature_package_support}
+%define tizen_feature_player_util_support %{expand:%tizen_%{?profile}_feature_player_util_support}
+%define tizen_feature_power_support %{expand:%tizen_%{?profile}_feature_power_support}
+%define tizen_feature_preference_support %{expand:%tizen_%{?profile}_feature_preference_support}
+%define tizen_feature_push_support %{expand:%tizen_%{?profile}_feature_push_support}
+%define tizen_feature_se_support %{expand:%tizen_%{?profile}_feature_se_support}
+%define tizen_feature_sensor_support %{expand:%tizen_%{?profile}_feature_sensor_support}
+%define tizen_feature_sound_support %{expand:%tizen_%{?profile}_feature_sound_support}
+%define tizen_feature_system_info_support %{expand:%tizen_%{?profile}_feature_system_info_support}
+%define tizen_feature_system_setting_support %{expand:%tizen_%{?profile}_feature_system_setting_support}
+%define tizen_feature_telephony_support %{expand:%tizen_%{?profile}_feature_telephony_support}
+%define tizen_feature_time_support %{expand:%tizen_%{?profile}_feature_time_support}
+%define tizen_feature_web_setting_support %{expand:%tizen_%{?profile}_feature_web_setting_support}
+%define tizen_feature_widget_service_support %{expand:%tizen_%{?profile}_feature_widget_service_support}
+%define tizen_feature_wi_fi_support %{expand:%tizen_%{?profile}_feature_wi_fi_support}
+%define tizen_feature_inputdevice_support %{expand:%tizen_%{?profile}_feature_inputdevice_support}
+%define tizen_feature_callhistory_support %{expand:%tizen_%{?profile}_feature_callhistory_support}
+%define tizen_feature_nbs_support %{expand:%tizen_%{?profile}_feature_nbs_support}
+%define tizen_feature_tvinputdevice_support %{expand:%tizen_%{?profile}_feature_tvinputdevice_support}
+%endif
BuildRequires: pkgconfig(security-privilege-manager)
BuildRequires: ninja
BuildRequires: pkgconfig(capi-network-wifi-manager)
BuildRequires: pkgconfig(tapi)
BuildRequires: pkgconfig(libpcrecpp)
-BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(capi-appfw-app-common)
BuildRequires: pkgconfig(capi-appfw-app-manager)
BuildRequires: pkgconfig(capi-appfw-package-manager)
BuildRequires: pkgconfig(capi-content-media-content)
BuildRequires: pkgconfig(security-privilege-checker)
%endif
-%if "%{?tizen_privilege_engine}" == "CYNARA"
+%if "%{?tizen_privilege_engine}" == "CYNARA" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(cynara-client)
BuildRequires: pkgconfig(libsmack)
%endif
-%if 0%{?tizen_feature_account_support}
+%if "%{?tizen_feature_account_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(accounts-svc)
%endif
-%if 0%{?tizen_feature_alarm_support}
+%if "%{?tizen_feature_alarm_support}" == "1" || "%{?unified_build}" == "1"
+BuildRequires: pkgconfig(capi-appfw-app-control)
+BuildRequires: pkgconfig(capi-appfw-application)
BuildRequires: pkgconfig(capi-appfw-alarm)
BuildRequires: pkgconfig(alarm-service)
%endif
-%if 0%{?tizen_feature_bookmark_support}
+%if "%{?tizen_feature_application_support}" == "1" || "%{?unified_build}" == "1"
+BuildRequires: pkgconfig(capi-appfw-app-control)
+BuildRequires: pkgconfig(capi-appfw-event)
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "mobile"
+BuildRequires: pkgconfig(capi-context)
+%endif
+
+%endif
+
+%if "%{?tizen_feature_bluetooth_support}" == "1" || "%{?unified_build}" == "1"
+BuildRequires: pkgconfig(capi-appfw-app-control)
+%endif
+
+%if "%{?tizen_feature_bookmark_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-web-bookmark)
BuildRequires: pkgconfig(bookmark-adaptor)
%endif
-%if 0%{?tizen_feature_datacontrol_support}
+%if "%{?tizen_feature_datacontrol_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-data-control)
%endif
-%if 0%{?tizen_feature_download_support}
+%if "%{?tizen_feature_download_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-web-url-download)
%endif
-%if 0%{?tizen_feature_ham_support}
+%if "%{?tizen_feature_ham_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(motion)
BuildRequires: pkgconfig(capi-system-sensor)
BuildRequires: pkgconfig(capi-location-manager)
BuildRequires: pkgconfig(sensor)
%endif
-%if 0%{?tizen_feature_iotcon_support}
+%if "%{?tizen_feature_iotcon_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(iotcon)
%endif
-%if 0%{?tizen_feature_player_util_support}
+%if "%{?tizen_feature_player_util_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(chromium-efl)
%endif
-%if 0%{?tizen_feature_power_support}
-BuildRequires: pkgconfig(deviced)
-%endif
-
-%if 0%{?tizen_feature_power_support}
+%if "%{?tizen_feature_power_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-appfw-application)
%endif
-%if 0%{?tizen_feature_push_support}
+%if "%{?tizen_feature_push_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(push)
+BuildRequires: pkgconfig(capi-appfw-app-control)
%endif
-%if 0%{?tizen_feature_key_manager_support}
+%if "%{?tizen_feature_key_manager_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(key-manager)
%endif
-%if 0%{?tizen_feature_media_controller_support}
+%if "%{?tizen_feature_media_controller_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-media-controller)
%endif
-%if 0%{?tizen_feature_messaging_support}
+%if "%{?tizen_feature_messaging_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(ecore-file)
BuildRequires: pkgconfig(email-service)
BuildRequires: pkgconfig(msg-service)
BuildRequires: pkgconfig(db-util)
%endif
-%if 0%{?tizen_feature_badge_support}
+%if "%{?tizen_feature_badge_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(badge)
%endif
-%if 0%{?tizen_feature_calendar_support}
+%if "%{?tizen_feature_calendar_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(calendar-service2)
%endif
-%if 0%{?tizen_feature_contact_support}
+%if "%{?tizen_feature_contact_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(contacts-service2)
%endif
-%if 0%{?tizen_feature_callhistory_support}
+%if "%{?tizen_feature_callhistory_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(contacts-service2)
%endif
-%if 0%{?tizen_feature_exif_support}
+%if "%{?tizen_feature_exif_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(libexif)
%endif
-%if 0%{?tizen_feature_nfc_support}
+%if "%{?tizen_feature_nfc_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-network-nfc)
+BuildRequires: pkgconfig(capi-appfw-app-control)
%endif
-%if 0%{?tizen_feature_fm_radio_support}
+%if "%{?tizen_feature_fm_radio_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-media-radio)
%endif
-%if 0%{?tizen_feature_feedback_support}
+%if "%{?tizen_feature_feedback_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(feedback)
%endif
-%if 0%{?tizen_feature_se_support}
+%if "%{?tizen_feature_se_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-network-smartcard)
%endif
-%if 0%{?tizen_feature_message_port_support}
+%if "%{?tizen_feature_message_port_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-message-port)
%endif
-%if 0%{?tizen_feature_notification_support}
+%if "%{?tizen_feature_notification_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(capi-appfw-app-control)
+%endif
+
+%if "%{?tizen_feature_preference_support}" == "1" || "%{?unified_build}" == "1"
+BuildRequires: pkgconfig(capi-appfw-preference)
%endif
-%if 0%{?tizen_feature_sound_support}
+%if "%{?tizen_feature_sound_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-media-sound-manager)
%endif
-%if 0%{?tizen_feature_sensor_support}
+%if "%{?tizen_feature_sensor_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-system-sensor)
%endif
-%if 0%{?tizen_feature_media_key_support}
+%if "%{?tizen_feature_media_key_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(capi-system-media-key)
%endif
-%if 0%{?tizen_feature_widget_service_support}
+%if "%{?tizen_feature_widget_service_support}" == "1" || "%{?unified_build}" == "1"
BuildRequires: pkgconfig(widget_service)
%endif
+Requires: %{name}-compat = %{version}-%{release}
+%if "%{?unified_build}" == "1"
+Recommends: %{name}-profile_common = %{version}-%{release}
+%endif
+
%description
Tizen Web APIs implemented.
+%package profile_common
+Summary: webapi-plugin binaries for common profile
+Provides: %{name}-compat = %{version}-%{release}
+Conflicts: %{name}-profile_mobile
+Conflicts: %{name}-profile_wearable
+Conflicts: %{name}-profile_tv
+Conflicts: %{name}-profile_ivi
+%description profile_common
+Tizen Web API implementation binaries for Tizen common profile.
+
+%package profile_mobile
+Summary: webapi-plugin binaries for mobile profile
+Provides: %{name}-compat = %{version}-%{release}
+Conflicts: %{name}-profile_common
+Conflicts: %{name}-profile_wearable
+Conflicts: %{name}-profile_tv
+Conflicts: %{name}-profile_ivi
+%description profile_mobile
+Tizen Web API implementation binaries for Tizen mobile profile.
+
+%ifarch %{ix86} x86_64
+%package mobile-extension-emulator
+Summary: webapi-plugin binaries for mobile emulator
+Requires: %{name}-profile_mobile = %{version}-%{release}
+%description mobile-extension-emulator
+Tizen Web API implementation binaries for Tizen mobile emulator.
+%endif
+
+%package profile_wearable
+Summary: webapi-plugin binaries for wearable profile
+Provides: %{name}-compat = %{version}-%{release}
+Conflicts: %{name}-profile_mobile
+Conflicts: %{name}-profile_common
+Conflicts: %{name}-profile_tv
+Conflicts: %{name}-profile_ivi
+%description profile_wearable
+Tizen Web API implementation binaries for Tizen wearable profile.
+
+%ifarch %{ix86} x86_64
+%package wearable-extension-emulator
+Summary: webapi-plugin binaries for wearable emulator
+Requires: %{name}-profile_wearable = %{version}-%{release}
+%description wearable-extension-emulator
+Tizen Web API implementation binaries for Tizen wearable emulator.
+%endif
+
+%package profile_tv
+Summary: webapi-plugin binaries for tv profile
+Provides: %{name}-compat = %{version}-%{release}
+Conflicts: %{name}-profile_mobile
+Conflicts: %{name}-profile_wearable
+Conflicts: %{name}-profile_common
+Conflicts: %{name}-profile_ivi
+%description profile_tv
+Tizen Web API implementation binaries for Tizen tv profile.
+
+%package profile_ivi
+Summary: webapi-plugin binaries for ivi profile
+Provides: %{name}-compat = %{version}-%{release}
+Conflicts: %{name}-profile_mobile
+Conflicts: %{name}-profile_wearable
+Conflicts: %{name}-profile_tv
+Conflicts: %{name}-profile_common
+%description profile_ivi
+Tizen Web API implementation binaries for Tizen ivi profile.
+
%package devel
Summary: webapi-plugins development headers
Group: Development/Libraries
%build
export GYP_GENERATORS='ninja'
+
+%if "%{?unified_build}" == "1"
+# Build All Profiles
+
+# Mobile
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=mobile -Dprivilege_engine=%{tizen_mobile_privilege_engine}"
+GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
+GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
+
+# feature flags
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_mobile_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_mobile_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_mobile_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_mobile_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_mobile_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_mobile_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_mobile_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_mobile_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_mobile_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_mobile_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_mobile_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_mobile_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_mobile_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_mobile_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_mobile_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_mobile_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_mobile_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_mobile_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_mobile_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_mobile_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_mobile_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_mobile_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_mobile_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_mobile_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_mobile_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_mobile_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_mobile_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_mobile_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_mobile_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_mobile_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_mobile_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_mobile_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_mobile_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_mobile_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_mobile_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_mobile_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_mobile_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_mobile_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_mobile_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_mobile_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_mobile_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_mobile_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_mobile_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_mobile_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_mobile_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_mobile_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_mobile_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_mobile_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_mobile_feature_tvinputdevice_support}"
+
+./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_mobile
+popd
+
+# mobile-extension-emulator
+%ifarch %{ix86} x86_64
+
+%define tizen_mobile_feature_bluetooth_support 0
+
+# FM radio feature
+%define tizen_mobile_feature_fm_radio_support 1
+
+%define tizen_mobile_feature_ham_support 1
+%define tizen_mobile_feature_media_key_support 0
+%define tizen_mobile_feature_nfc_emulation_support 0
+%define tizen_mobile_feature_nfc_support 1
+
+# secure element feature
+%define tizen_mobile_feature_se_support 0
+
+# telephony feature
+%define tizen_mobile_feature_telephony_support 1
+%define tizen_mobile_feature_callhistory_support 1
+%define tizen_mobile_feature_nbs_support 1
+
+%define tizen_mobile_feature_wi_fi_support 0
+
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=mobile -Dprivilege_engine=%{tizen_mobile_privilege_engine}"
+GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
+GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
+
+# feature flags
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_mobile_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_mobile_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_mobile_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_mobile_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_mobile_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_mobile_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_mobile_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_mobile_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_mobile_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_mobile_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_mobile_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_mobile_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_mobile_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_mobile_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_mobile_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_mobile_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_mobile_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_mobile_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_mobile_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_mobile_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_mobile_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_mobile_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_mobile_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_mobile_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_mobile_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_mobile_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_mobile_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_mobile_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_mobile_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_mobile_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_mobile_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_mobile_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_mobile_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_mobile_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_mobile_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_mobile_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_mobile_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_mobile_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_mobile_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_mobile_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_mobile_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_mobile_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_mobile_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_mobile_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_mobile_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_mobile_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_mobile_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_mobile_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_mobile_feature_tvinputdevice_support}"
+
+./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_mobile_emulator
+popd
+%endif
+
+# WEARABLE
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=wearable -Dprivilege_engine=%{tizen_wearable_privilege_engine}"
+GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
+GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
+
+# feature flags
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_wearable_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_wearable_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_wearable_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_wearable_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_wearable_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_wearable_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_wearable_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_wearable_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_wearable_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_wearable_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_wearable_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_wearable_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_wearable_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_wearable_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_wearable_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_wearable_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_wearable_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_wearable_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_wearable_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_wearable_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_wearable_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_wearable_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_wearable_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_wearable_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_wearable_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_wearable_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_wearable_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_wearable_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_wearable_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_wearable_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_wearable_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_wearable_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_wearable_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_wearable_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_wearable_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_wearable_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_wearable_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_wearable_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_wearable_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_wearable_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_wearable_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_wearable_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_wearable_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_wearable_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_wearable_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_wearable_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_wearable_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_wearable_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_wearable_feature_tvinputdevice_support}"
+
+./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_wearable
+popd
+
+# wearable-extension-emulator
+%ifarch %{ix86} x86_64
+
+%define tizen_wearable_feature_bluetooth_support 0
+
+# MediayKey API is optional in Tizen Wearable Profile.
+# tizen.org/feature/network.bluetooth.audio.media is required for MediayKey API
+%define tizen_wearable_feature_media_key_support 0
+
+#- telephony related APIs
+# CallHistory API is optional in Tizen Wearable Profile.
+# NetworkBearerSelection API is optional in Tizen Wearable Profile.
+%define tizen_wearable_feature_se_support 0
+%define tizen_wearable_feature_telephony_support 1
+%define tizen_wearable_feature_callhistory_support 1
+%define tizen_wearable_feature_nbs_support 1
+%define tizen_wearable_feature_sensor_support 1
+
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=wearable -Dprivilege_engine=%{tizen_wearable_privilege_engine}"
+GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
+GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
+
+# feature flags
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_wearable_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_wearable_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_wearable_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_wearable_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_wearable_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_wearable_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_wearable_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_wearable_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_wearable_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_wearable_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_wearable_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_wearable_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_wearable_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_wearable_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_wearable_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_wearable_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_wearable_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_wearable_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_wearable_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_wearable_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_wearable_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_wearable_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_wearable_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_wearable_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_wearable_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_wearable_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_wearable_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_wearable_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_wearable_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_wearable_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_wearable_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_wearable_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_wearable_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_wearable_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_wearable_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_wearable_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_wearable_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_wearable_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_wearable_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_wearable_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_wearable_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_wearable_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_wearable_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_wearable_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_wearable_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_wearable_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_wearable_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_wearable_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_wearable_feature_tvinputdevice_support}"
+
+./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_wearable_emulator
+popd
+%endif
+
+# TV
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=tv -Dprivilege_engine=%{tizen_tv_privilege_engine}"
+GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
+GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
+
+# feature flags
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_tv_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_tv_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_tv_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_tv_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_tv_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_tv_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_tv_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_tv_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_tv_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_tv_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_tv_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_tv_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_tv_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_tv_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_tv_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_tv_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_tv_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_tv_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_tv_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_tv_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_tv_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_tv_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_tv_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_tv_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_tv_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_tv_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_tv_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_tv_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_tv_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_tv_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_tv_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_tv_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_tv_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_tv_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_tv_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_tv_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_tv_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_tv_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_tv_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_tv_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_tv_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_tv_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_tv_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_tv_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_tv_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_tv_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_tv_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_tv_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_tv_feature_tvinputdevice_support}"
+
+./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_tv
+popd
+
+%endif
+
+# Unified: common/ Others: its own profile
+%if "%{?profile}" != "mobile" && "%{?profile}" != "tv" && "%{?profile}" != "wearable" && "%{?profile}" != "ivi"
+GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=common -Dprivilege_engine=%{tizen_privilege_engine}"
+%else
GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_os=%{profile} -Dprivilege_engine=%{tizen_privilege_engine}"
+%endif
GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}"
GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}"
# feature flags
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_is_emulator=%{?tizen_is_emulator}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_feature_account_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_feature_alarm_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_feature_app_control_settings_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_feature_application_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_feature_archive_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_feature_badge_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_feature_bluetooth_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_feature_bookmark_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_feature_calendar_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_feature_callhistory_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_feature_contact_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_feature_content_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_feature_datacontrol_support}"
-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}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_feature_iotcon_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_feature_location_batch}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_feature_key_manager_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_feature_media_controller_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_feature_media_key_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_feature_message_port_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_feature_messaging_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_feature_nbs_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_feature_nfc_emulation_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_feature_nfc_support}"
-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_player_util_support=%{?tizen_feature_player_util_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}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_feature_se_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_feature_sound_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_feature_system_info_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_feature_system_setting_support}"
-GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_feature_telephony_support}"
-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}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_common_feature_account_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_common_feature_alarm_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_app_control_settings_support=%{?tizen_common_feature_app_control_settings_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_application_support=%{?tizen_common_feature_application_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_archive_support=%{?tizen_common_feature_archive_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_badge_support=%{?tizen_common_feature_badge_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bluetooth_support=%{?tizen_common_feature_bluetooth_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_bookmark_support=%{?tizen_common_feature_bookmark_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_calendar_support=%{?tizen_common_feature_calendar_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_callhistory_support=%{?tizen_common_feature_callhistory_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_contact_support=%{?tizen_common_feature_contact_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_content_support=%{?tizen_common_feature_content_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_common_feature_datacontrol_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_common_feature_datasync_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_common_feature_download_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_common_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_common_feature_feedback_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_common_feature_filesystem_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_common_feature_fm_radio_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_common_feature_ham_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_iotcon_support=%{?tizen_common_feature_iotcon_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_location_batch=%{?tizen_common_feature_location_batch}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_key_manager_support=%{?tizen_common_feature_key_manager_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_controller_support=%{?tizen_common_feature_media_controller_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_media_key_support=%{?tizen_common_feature_media_key_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_message_port_support=%{?tizen_common_feature_message_port_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_messaging_support=%{?tizen_common_feature_messaging_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nbs_support=%{?tizen_common_feature_nbs_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_emulation_support=%{?tizen_common_feature_nfc_emulation_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_common_feature_nfc_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_common_feature_notification_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_common_feature_package_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_player_util_support=%{?tizen_common_feature_player_util_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_common_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_common_feature_preference_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_common_feature_push_support}"
+#GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_common_feature_sap_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_common_feature_sensor_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_se_support=%{?tizen_common_feature_se_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sound_support=%{?tizen_common_feature_sound_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_info_support=%{?tizen_common_feature_system_info_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_system_setting_support=%{?tizen_common_feature_system_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_common_feature_telephony_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_common_feature_time_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_common_feature_inputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_common_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_common_feature_widget_service_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_common_feature_wi_fi_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_common_feature_tvinputdevice_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
+%if "%{?profile}" != "mobile" && "%{?profile}" != "tv" && "%{?profile}" != "wearable" && "%{?profile}" != "ivi"
ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_common
+ln -sf bin_common Default
+
+# IVI does not have independent configurations, yet.
+# Copying the whole result in order to support ivi subpacakge
+cp -R bin_common bin_ivi
+
+popd
+%else
+ninja -C out/Default %{?_smp_mflags}
+pushd out
+mv Default bin_%{?profile}
+ln -sf bin_%{?profile} Default
+popd
+%endif
%install
-mkdir -p %{buildroot}/usr/share/license
-cp LICENSE %{buildroot}/usr/share/license/%{name}
-cat LICENSE.BSD-3-Clause >> %{buildroot}/usr/share/license/%{name}
-cat LICENSE.MIT >> %{buildroot}/usr/share/license/%{name}
# Extensions.
mkdir -p %{buildroot}%{crosswalk_extensions_path}
-install -p -m 644 out/Default/libtizen*.so %{buildroot}%{crosswalk_extensions_path}
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "common"
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/common
+install -p -m 644 out/bin_common/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/common
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/common out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/common \
+ %{buildroot}%{crosswalk_extensions_path}/common > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/common/plugins.json
+%endif
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "mobile"
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/mobile
+install -p -m 644 out/bin_mobile/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/mobile
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/mobile out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/mobile \
+ %{buildroot}%{crosswalk_extensions_path}/mobile > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/mobile/plugins.json
+
+# mobile-extension-emulator
+%ifarch %{ix86} x86_64
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/mobile_emulator
+install -p -m 644 out/bin_mobile_emulator/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/mobile_emulator
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/mobile_emulator out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/mobile_emulator \
+ %{buildroot}%{crosswalk_extensions_path}/mobile_emulator > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/mobile_emulator/plugins.json
+%endif // mobile-extension-emulator
+
+%endif // mobile
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "wearable"
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/wearable
+install -p -m 644 out/bin_wearable/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/wearable
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/wearable out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/wearable \
+ %{buildroot}%{crosswalk_extensions_path}/wearable > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/wearable/plugins.json
+
+# wearable-extension-emulator
+%ifarch %{ix86} x86_64
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/wearable_emulator
+install -p -m 644 out/bin_wearable_emulator/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/wearable_emulator
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/mobile_emulator out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/wearable_emulator \
+ %{buildroot}%{crosswalk_extensions_path}/wearable_emulator > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/wearable_emulator/plugins.json
+%endif // wearable-extension-emulator
+
+%endif // wearable
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "tv"
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/tv
+install -p -m 644 out/bin_tv/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/tv
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/tv out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/tv \
+ %{buildroot}%{crosswalk_extensions_path}/tv > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/tv/plugins.json
+%endif
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "ivi"
+mkdir -p %{buildroot}%{crosswalk_extensions_path}/ivi
+install -p -m 644 out/bin_ivi/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/ivi
+# execute desc_gentool
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/ivi out/Default/desc_gentool \
+ %{crosswalk_extensions_path}/ivi \
+ %{buildroot}%{crosswalk_extensions_path}/ivi > plugins.json
+
+# temporary plugins description for lazy loading
+install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/ivi/plugins.json
+%endif
# devel files
mkdir -p %{buildroot}%{_libdir}/pkgconfig
cp -a tools/slimit %{buildroot}%{_includedir}/%{name}/tools/slimit
cp -a out/Default/desc_gentool %{buildroot}%{_includedir}/%{name}/tools/desc_gentool
-# execute desc_gentool
-LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path} out/Default/desc_gentool \
- %{crosswalk_extensions_path} \
- %{buildroot}%{crosswalk_extensions_path} > plugins.json
+%files
+%manifest webapi-plugins.manifest
+%license LICENSE
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "common"
+%post profile_common
+ln -sf %{crosswalk_extensions_path}/common/* %{crosswalk_extensions_path}
+%preun profile_common
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files profile_common
+%dir %{crosswalk_extensions_path}/common/
+%{crosswalk_extensions_path}/common/libtizen*.so
+%{crosswalk_extensions_path}/common/plugins.json
+%manifest webapi-plugins.manifest
+%endif
-# temporary plugins description for lazy loading
-install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/plugins.json
+%if "%{?unified_build}" == "1" || "%{?profile}" == "mobile"
+%post profile_mobile
+ln -sf %{crosswalk_extensions_path}/mobile/* %{crosswalk_extensions_path}
+%preun profile_mobile
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files profile_mobile
+%dir %{crosswalk_extensions_path}/mobile/
+%{crosswalk_extensions_path}/mobile/libtizen*.so
+%{crosswalk_extensions_path}/mobile/plugins.json
+%manifest webapi-plugins.manifest
+# mobile-extension-emulator
+%ifarch %{ix86} x86_64
+%post mobile-extension-emulator
+ln -sf %{crosswalk_extensions_path}/mobile_emulator/* %{crosswalk_extensions_path}
+%preun mobile-extension-emulator
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files mobile-extension-emulator
+%dir %{crosswalk_extensions_path}/mobile_emulator/
+%{crosswalk_extensions_path}/mobile_emulator/libtizen*.so
+%{crosswalk_extensions_path}/mobile_emulator/plugins.json
+%manifest webapi-plugins.manifest
+%endif // mobile-extension-emulator
+%endif // mobile
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "wearable"
+%post profile_wearable
+ln -sf %{crosswalk_extensions_path}/wearable/* %{crosswalk_extensions_path}
+%preun profile_wearable
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files profile_wearable
+%dir %{crosswalk_extensions_path}/wearable/
+%{crosswalk_extensions_path}/wearable/libtizen*.so
+%{crosswalk_extensions_path}/wearable/plugins.json
+%manifest webapi-plugins.manifest
-%files
-%{crosswalk_extensions_path}/libtizen*.so
-%{crosswalk_extensions_path}/plugins.json
-%{_datadir}/license/%{name}
+# wearable-extension-emulator
+%ifarch %{ix86} x86_64
+%post wearable-extension-emulator
+ln -sf %{crosswalk_extensions_path}/wearable_emulator/* %{crosswalk_extensions_path}
+%preun wearable-extension-emulator
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files wearable-extension-emulator
+%dir %{crosswalk_extensions_path}/wearable_emulator/
+%{crosswalk_extensions_path}/wearable_emulator/libtizen*.so
+%{crosswalk_extensions_path}/wearable_emulator/plugins.json
%manifest webapi-plugins.manifest
+%endif // wearable-extension-emulator
+%endif // wearable
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "tv"
+%post profile_tv
+ln -sf %{crosswalk_extensions_path}/tv/* %{crosswalk_extensions_path}
+%preun profile_tv
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files profile_tv
+%dir %{crosswalk_extensions_path}/tv/
+%{crosswalk_extensions_path}/tv/libtizen*.so
+%{crosswalk_extensions_path}/tv/plugins.json
+%manifest webapi-plugins.manifest
+%endif
+
+%if "%{?unified_build}" == "1" || "%{?profile}" == "ivi"
+%post profile_ivi
+ln -sf %{crosswalk_extensions_path}/ivi/* %{crosswalk_extensions_path}
+%preun profile_ivi
+# This is an un-installation.
+if [ "$1" == "0" ]; then
+ rm %{crosswalk_extensions_path}/libtizen*.so
+ rm %{crosswalk_extensions_path}/plugins.json
+fi
+%files profile_ivi
+%dir %{crosswalk_extensions_path}/ivi/
+%{crosswalk_extensions_path}/ivi/libtizen*.so
+%{crosswalk_extensions_path}/ivi/plugins.json
+%manifest webapi-plugins.manifest
+%endif
%files devel
%{_includedir}/*
'type': 'loadable_module',
'dependencies': [
'../common/common.gyp:tizen_common',
+ '../notification/notification.gyp:tizen_notification',
],
'sources': [
'alarm_api.js',
'variables': {
'packages': [
'capi-appfw-alarm',
+ 'capi-appfw-app-control',
+ 'capi-appfw-application',
]
},
}],
}
}
+var LogManager = function() {
+ this.enableLog = true;
+};
+
+LogManager.prototype.allow = function() {
+ this.enableLog = true;
+};
+
+LogManager.prototype.disallow = function() {
+ this.enableLog = false;
+};
+
+var _warningLogs = new LogManager();
+
//class AlarmManager ////////////////////////////////////////////////////
AlarmManager.prototype.add = function () {
var args = AV.validateMethod(arguments, [
}
};
+AlarmManager.prototype.addAlarmNotification = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name: 'alarm',
+ type: AV.Types.PLATFORM_OBJECT,
+ values: [tizen.AlarmRelative, tizen.AlarmAbsolute]
+ }, {
+ name: 'notification',
+ type: AV.Types.PLATFORM_OBJECT,
+ values: [tizen.StatusNotification, tizen.UserNotification]
+ }]);
+
+ var type = null, milliseconds = 0;
+ if (args.alarm instanceof tizen.AlarmRelative) {
+ type = 'AlarmRelative';
+ } else if (args.alarm instanceof tizen.AlarmAbsolute) {
+ type = 'AlarmAbsolute';
+ milliseconds = args.alarm.date.getTime();
+ }
+
+ var callArgs = {};
+ callArgs.alarm = args.alarm;
+ callArgs.type = type;
+ callArgs.notification = args.notification;
+ callArgs.milliseconds = Converter.toString(milliseconds);
+ callArgs.isPeriodSet = !T.isNullOrUndefined(args.alarm.period);
+
+ //add marker for UserNotification implementation
+ callArgs.newImpl = (callArgs.notification instanceof tizen.UserNotification);
+
+ var result = native.callSync('AlarmManager_addAlarmNotification', callArgs);
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
+ else {
+ _edit.allow();
+ UpdateInternalData_(args.alarm, native.getResultObject(result));
+ _edit.disallow();
+ }
+};
+
AlarmManager.prototype.remove = function () {
var args = AV.validateMethod(arguments, [
{
throw native.getErrorObject(result);
} else {
result = native.getResultObject(result);
+
+ var alarm;
+ _warningLogs.disallow();
if ('AlarmRelative' === result.type) {
- return new tizen.AlarmRelative(result.delay, result.period, InternalData_(result));
+ alarm = new tizen.AlarmRelative(result.delay, result.period, InternalData_(result));
} else {
var date = new Date(result.year, result.month, result.day,
result.hour, result.min, result.sec);
- return new tizen.AlarmAbsolute(date, result.second, InternalData_(result));
+ alarm = new tizen.AlarmAbsolute(date, result.second, InternalData_(result));
+ }
+ _warningLogs.allow();
+ return alarm;
+ }
+};
+
+function _prepareAppControl(noti) {
+ if (!noti || !noti.actions || !noti.actions.appControl) {
+ privUtils_.log("Do nothing - appControl is NOT present");
+ return;
+ }
+ if (!T.isNullOrUndefined(noti.actions.appControl.operation)) {
+ noti.actions.appControl = new tizen.ApplicationControl(
+ noti.actions.appControl.operation,
+ noti.actions.appControl.uri,
+ noti.actions.appControl.mime,
+ noti.actions.appControl.category,
+ noti.actions.appControl.data,
+ noti.actions.appControl.launchMode);
+ }
+}
+
+function _prepareDetailInfo(noti) {
+ if (!noti || !noti.textContents || !noti.textContents.detailInfo) {
+ console.log("Do nothing - detailInfo is NOT present");
+ return;
+ }
+ var detailInfo = noti.textContents.detailInfo;
+ if (T.isArray(detailInfo)) {
+ var _d = [];
+ for (var i = 0; i < detailInfo.length; ++i) {
+ _d.push(new tizen.NotificationDetailInfo(detailInfo[i].mainText,
+ detailInfo[i].subText || null));
+ }
+ noti.textContents.detailInfo = _d;
+ }
+}
+
+AlarmManager.prototype.getAlarmNotification = function () {
+ var args = AV.validateMethod(arguments, [
+ {
+ name : 'id',
+ type : AV.Types.STRING,
}
+ ]);
+
+ var result = native.callSync('AlarmManager_getAlarmNotification', {id: Number(args.id)});
+
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ } else {
+ var noti = native.getResultObject(result);
+ _prepareAppControl(noti);
+ _prepareDetailInfo(noti);
+ return new tizen.UserNotification(noti.userType, noti.title, noti);
}
};
} else {
var data = native.getResultObject(result);
var md = [];
+ _warningLogs.disallow();
data.forEach(function (i) {
if ('AlarmRelative'=== i.type) {
md.push(new tizen.AlarmRelative(i.delay, i.period, InternalData_(i)));
md.push(new tizen.AlarmAbsolute(date, i.second, InternalData_(i)));
}
});
+ _warningLogs.allow();
return md;
}
};
} else {
if(!T.isNullOrUndefined(second)){
m_period = Converter.toLong(second);
+ if(_warningLogs.enableLog){
+ privUtils_.warn("This Constructor is deprecated since Tizen 4.0." +
+ " Please consider using other constructors or other type of an alarm.");
+ }
}
}
}
using namespace std::placeholders;
RegisterSyncHandler("AlarmManager_add", std::bind(&AlarmManager::Add, &manager_, _1, _2));
+ RegisterSyncHandler("AlarmManager_addAlarmNotification",
+ std::bind(&AlarmManager::AddAlarmNotification, &manager_, _1, _2));
RegisterSyncHandler("AlarmManager_remove", std::bind(&AlarmManager::Remove, &manager_, _1, _2));
RegisterSyncHandler("AlarmManager_removeAll",
std::bind(&AlarmManager::RemoveAll, &manager_, _1, _2));
RegisterSyncHandler("AlarmManager_get", std::bind(&AlarmManager::Get, &manager_, _1, _2));
+ RegisterSyncHandler("AlarmManager_getAlarmNotification",
+ std::bind(&AlarmManager::GetAlarmNotification, &manager_, _1, _2));
RegisterSyncHandler("AlarmManager_getAll", std::bind(&AlarmManager::GetAll, &manager_, _1, _2));
// AlarmRelative
RegisterSyncHandler("AlarmRelative_getRemainingSeconds",
#include <app.h>
#include <app_alarm.h>
#include <app_control_internal.h>
+#include <notification_internal.h>
#include "common/converter.h"
#include "common/logger.h"
#include "alarm_instance.h"
#include "alarm_utils.h"
+#include "notification/common_notification.h"
+#include "notification/status_notification.h"
+#include "notification/user_notification.h"
+
using namespace common;
using namespace common::tools;
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";
+const std::string kPrivilegeNotification = "http://tizen.org/privilege/notification";
const std::string kAlarmRelative = "AlarmRelative";
const std::string kAlarmAbsolute = "AlarmAbsolute";
const char* kAlarmTypeValueRelative = "RELATIVE";
const char* kAlarmRelativeDelayKey = "RELATIVE_DELAY";
-
-const char* kSundayShort = "SU";
-const char* kMondayShort = "MO";
-const char* kTuesdayShort = "TU";
-const char* kWednesdayShort = "WE";
-const char* kThuesdayShort = "TH";
-const char* kFridayShort = "FR";
-const char* kSaturdayShort = "SA";
}
AlarmManager::AlarmManager() {
!(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
kAlarmAbsoluteReccurrenceTypeByDayValue);
- picojson::array days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
+ const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
int repeat_value = 0;
- for (auto iter = days_of_the_week.begin(); iter != days_of_the_week.end(); ++iter) {
- auto day = (*iter).get<std::string>();
- if (kSundayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_SUNDAY;
- } else if (kMondayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_MONDAY;
- } else if (kTuesdayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_TUESDAY;
- } else if (kWednesdayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_WEDNESDAY;
- } else if (kThuesdayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_THURSDAY;
- } else if (kFridayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_FRIDAY;
- } else if (kSaturdayShort == day) {
- repeat_value |= ALARM_WEEK_FLAG_SATURDAY;
- } else {
- LogAndReportError(
- PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid days of the week value."),
- &out);
- return;
- }
+ PlatformResult result = util::ArrayDaysToMask(days_of_the_week, &repeat_value);
+ if (!result) {
+ LogAndReportError(PlatformResult(result.error_code(), result.message()), &out);
+ return;
}
ret = alarm_schedule_with_recurrence_week_flag(app_control, &start_date, repeat_value,
&alarm_id);
ReportSuccess(result, out);
}
+void AlarmManager::AddAlarmNotification(const picojson::value& args, picojson::object& out) {
+ using namespace extension::notification;
+ LoggerD("Entered");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
+
+ if (!args.contains("alarm") || !args.contains("notification")) {
+ LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
+ &out);
+ return;
+ }
+
+ const picojson::object& alarm = args.get("alarm").get<picojson::object>();
+
+ std::string alarm_type;
+ if (args.contains("type")) {
+ alarm_type = args.get("type").get<std::string>();
+ }
+
+ notification_h notification_handle = nullptr;
+ app_control_h app_control = nullptr;
+
+ SCOPE_EXIT {
+ notification_free(notification_handle);
+ app_control_destroy(app_control);
+ };
+
+ using namespace std::placeholders;
+ GetHandleFromJsonFun impl{};
+ if (args.contains("newImpl") && args.get("newImpl").is<bool>() &&
+ args.get("newImpl").get<bool>()) {
+ LoggerD("New implementation");
+ impl = std::bind(&UserNotification::GetNotiHandleFromJson, _1, _2, _3);
+ } else {
+ LoggerW("Deprecated object used");
+ impl = std::bind(&StatusNotification::GetNotiHandleFromJson, _1, _2, _3);
+ }
+
+ PlatformResult platform_result = impl(args.get("notification"), false, ¬ification_handle);
+ if (!platform_result) {
+ LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, platform_result.message().c_str()),
+ &out);
+ }
+ platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
+
+ if (!platform_result) {
+ LogAndReportError(
+ PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
+ }
+
+ int alarm_id = 0;
+ int ret = 0;
+
+ if (kAlarmRelative == alarm_type) {
+ ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
+ if (ret != APP_CONTROL_ERROR_NONE) {
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
+ ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ const auto it_period = alarm.find("period");
+ const auto it_delay = alarm.find("delay");
+
+ if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
+ LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
+ &out);
+ return;
+ }
+
+ int delay = static_cast<int>(it_delay->second.get<double>());
+
+ std::string delay_str = std::to_string(delay);
+ ret = app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
+ ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
+
+ if (!platform_result) {
+ LogAndReportError(
+ PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
+ }
+
+ int period = 0;
+ if (it_period->second.is<double>()) {
+ period = static_cast<int>(it_period->second.get<double>());
+ }
+
+ bool isPeriodSet = false;
+ if (args.contains("isPeriodSet")) {
+ isPeriodSet = args.get("isPeriodSet").get<bool>();
+ }
+
+ if (!isPeriodSet) {
+ ret = alarm_schedule_noti_once_after_delay(notification_handle, delay, &alarm_id);
+ } else {
+ ret = alarm_schedule_noti_after_delay(notification_handle, delay, period, &alarm_id);
+ }
+ } else {
+ if (alarm.find("period")->second.is<double>()) {
+ LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+ "AlarmAbsolute constructed by deprecated constructor."),
+ &out);
+ return;
+ }
+
+ ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
+ ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
+ long long int milliseconds = 0;
+
+ if (args.contains("milliseconds")) {
+ milliseconds = strtoll(args.get("milliseconds").get<std::string>().c_str(), nullptr, 10);
+ }
+
+ time_t second = milliseconds / 1000;
+ struct tm start_date = {0};
+
+ tzset();
+ if (nullptr == localtime_r(&second, &start_date)) {
+ LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Invalid date."), &out);
+ return;
+ }
+
+ mktime(&start_date);
+
+ char str_date[kDateSize];
+
+ snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
+ start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
+ start_date.tm_sec, start_date.tm_isdst);
+
+ ret = app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
+ ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
+ !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
+ app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
+ kAlarmAbsoluteReccurrenceTypeByDayValue);
+
+ const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
+ int repeat_value = 0;
+ util::ArrayDaysToMask(days_of_the_week, &repeat_value);
+
+ platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
+ if (!platform_result) {
+ LogAndReportError(
+ PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
+ }
+
+ ret = alarm_schedule_noti_with_recurrence_week_flag(notification_handle, &start_date,
+ repeat_value, &alarm_id);
+ } else {
+ ret = app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
+ kAlarmAbsoluteRecurrenceTypeNone);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
+ ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
+ if (!platform_result) {
+ LogAndReportError(
+ PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
+ }
+
+ ret = alarm_schedule_noti_once_at_date(notification_handle, &start_date, &alarm_id);
+ }
+ }
+
+ if (ALARM_ERROR_NONE != ret) {
+ if (ALARM_ERROR_INVALID_TIME == ret || ALARM_ERROR_INVALID_DATE == ret ||
+ ALARM_ERROR_INVALID_PARAMETER == ret) {
+ platform_result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid data.");
+ } else {
+ platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Error while adding alarm to server.");
+ }
+
+ LogAndReportError(platform_result, &out,
+ ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+
+ if (alarm_type == kAlarmRelative) {
+ int period = 0;
+ ret = alarm_get_scheduled_period(alarm_id, &period);
+ if (ALARM_ERROR_NONE != ret) {
+ LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
+ ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
+ return;
+ }
+ if (0 != period) {
+ result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
+ }
+ }
+
+ result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
+ ReportSuccess(result, out);
+}
+
void AlarmManager::Remove(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
char* alarm_type = nullptr;
char* date_string = nullptr;
char* delay_string = nullptr;
+ notification_h notification_handle = nullptr;
SCOPE_EXIT {
app_control_destroy(app_control);
free(alarm_type);
free(date_string);
free(delay_string);
+ notification_free(notification_handle);
};
- ret = alarm_get_app_control(id, &app_control);
- if (ALARM_ERROR_NONE != ret) {
- return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found.",
- ("Alarm not found: %d (%s)", ret, get_error_message(ret)));
+ if (ALARM_ERROR_NONE != alarm_get_app_control(id, &app_control)) {
+ if (ALARM_ERROR_NONE != alarm_get_notification(id, ¬ification_handle)) {
+ return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found.",
+ ("Alarm not found: %d (%s)", ret, get_error_message(ret)));
+ } else {
+ PlatformResult platform_result = extension::notification::CommonNotification::GetAppControl(
+ notification_handle, &app_control);
+ if (!platform_result) {
+ return LogAndCreateResult(
+ platform_result.error_code(), platform_result.message().c_str(),
+ ("Failed to get AppControl: %d (%s)", platform_result.error_code(),
+ platform_result.message().c_str()));
+ }
+ }
}
ret = app_control_get_extra_data(app_control, kAlarmKeyType, &alarm_type);
obj.insert(std::make_pair("second", picojson::value(picojson::array())))
.first->second.get<picojson::array>();
+ using namespace util;
if (byDayValue & ALARM_WEEK_FLAG_SUNDAY) array.push_back(picojson::value(kSundayShort));
if (byDayValue & ALARM_WEEK_FLAG_MONDAY) array.push_back(picojson::value(kMondayShort));
if (byDayValue & ALARM_WEEK_FLAG_TUESDAY) array.push_back(picojson::value(kTuesdayShort));
}
}
+void AlarmManager::GetAlarmNotification(const picojson::value& args, picojson::object& out) {
+ using namespace extension::notification;
+ LoggerD("Entered");
+
+ int alarm_id = 0;
+ int ret = ALARM_ERROR_NONE;
+ notification_h notification_handle = nullptr;
+ PlatformResult platform_result = PlatformResult(ErrorCode::NO_ERROR);
+
+ SCOPE_EXIT {
+ notification_free(notification_handle);
+ };
+
+ if (args.contains("id") && args.get("id").is<double>()) {
+ alarm_id = static_cast<int>(args.get("id").get<double>());
+ }
+
+ ret = alarm_get_notification(alarm_id, ¬ification_handle);
+
+ if (ALARM_ERROR_NONE != ret) {
+ if (ALARM_ERROR_INVALID_PARAMETER == ret) {
+ platform_result =
+ PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm with given ID was not found.");
+ } else {
+ platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Failed to get notification.");
+ }
+ LogAndReportError(platform_result, &out);
+ }
+
+ app_control_h app_control = nullptr;
+ platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
+
+ if (!platform_result) {
+ LogAndReportError(platform_result, &out);
+ }
+
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+
+ platform_result = UserNotification::ToJson(-1, notification_handle, app_control, &result_obj);
+
+ if (ALARM_ERROR_NONE != ret) {
+ LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Failed ToJson()."), &out);
+ }
+
+ ReportSuccess(result, out);
+}
+
static bool AlarmIterateCB(int alarm_id, void* user_data) {
LoggerD("Enter");
virtual ~AlarmManager();
void Add(const picojson::value& args, picojson::object& out);
+ void AddAlarmNotification(const picojson::value& args, picojson::object& out);
void Remove(const picojson::value& args, picojson::object& out);
void RemoveAll(const picojson::value& args, picojson::object& out);
void Get(const picojson::value& args, picojson::object& out);
+ void GetAlarmNotification(const picojson::value& args, picojson::object& out);
void GetAll(const picojson::value& args, picojson::object& out);
// AlarmRelative
namespace alarm {
namespace util {
+const char* kSundayShort = "SU";
+const char* kMondayShort = "MO";
+const char* kTuesdayShort = "TU";
+const char* kWednesdayShort = "WE";
+const char* kThuesdayShort = "TH";
+const char* kFridayShort = "FR";
+const char* kSaturdayShort = "SA";
+
using namespace common;
PlatformResult AppControlToService(const picojson::object& obj, app_control_h* app_control) {
return PlatformResult(ErrorCode::NO_ERROR);
}
+PlatformResult ArrayDaysToMask(const picojson::array& days_of_the_week, int* repeat_value) {
+ LoggerD("Entered");
+ for (auto iter = days_of_the_week.begin(); iter != days_of_the_week.end(); ++iter) {
+ auto day = (*iter).get<std::string>();
+ if (kSundayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_SUNDAY;
+ } else if (kMondayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_MONDAY;
+ } else if (kTuesdayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_TUESDAY;
+ } else if (kWednesdayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_WEDNESDAY;
+ } else if (kThuesdayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_THURSDAY;
+ } else if (kFridayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_FRIDAY;
+ } else if (kSaturdayShort == day) {
+ *repeat_value |= ALARM_WEEK_FLAG_SATURDAY;
+ } else {
+ return LogAndCreateResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid days of the week value.");
+ }
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // util
} // alarm
} // extension
#ifndef ALARM_ALARM_UTILS_H_
#define ALARM_ALARM_UTILS_H_
+#include <app_alarm.h>
#include <app_control.h>
#include "common/picojson.h"
namespace alarm {
namespace util {
+extern const char* kSundayShort;
+extern const char* kMondayShort;
+extern const char* kTuesdayShort;
+extern const char* kWednesdayShort;
+extern const char* kThuesdayShort;
+extern const char* kFridayShort;
+extern const char* kSaturdayShort;
+
common::PlatformResult AppControlToService(const picojson::object& obj, app_control_h* app_control);
common::PlatformResult AppControlToServiceExtraData(const picojson::object& app_obj,
app_control_h* app_control);
+common::PlatformResult ArrayDaysToMask(const picojson::array& days_of_the_week, int* repeat_value);
} // util
} // alarm
} // extension
'packages': [
'aul',
'capi-appfw-app-manager',
- 'capi-appfw-application',
+ 'capi-appfw-app-control',
+ 'capi-appfw-event',
'capi-appfw-package-manager',
'pkgmgr',
'pkgmgr-info',
]
},
}],
+ ['extension_host_os == "mobile"', {
+ 'variables': {
+ 'packages': [
+ 'capi-context',
+ ]
+ }
+ }],
],
},
],
GROUP: 'GROUP'
};
+var ApplicationUsageMode = {
+ RECENTLY: 'RECENTLY',
+ FREQUENTLY: 'FREQUENTLY'
+};
+
// TODO: Please uncomment below lines when system events is ready
//var SystemEvent = {
// BATTERY_CHARGER_STATUS: 'BATTERY_CHARGER_STATUS',
}
};
+ApplicationManager.prototype.getBatteryUsageInfo = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name: 'successCallback',
+ type: AV.Types.FUNCTION
+ },
+ {
+ name: 'errorCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'days',
+ type: AV.Types.LONG,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'limit',
+ type: AV.Types.LONG,
+ optional: true,
+ nullable: true
+ }]);
+
+ var callArgs = {};
+
+ if (!T.isNullOrUndefined(args.days)) {
+ callArgs.days = args.days;
+ }
+
+ if (!T.isNullOrUndefined(args.limit)) {
+ callArgs.limit = args.limit;
+ }
+
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+ } else {
+ var data = native.getResultObject(result);
+ var resultArray = [];
+ data.forEach(function (i) {
+ resultArray.push(new ApplicationBatteryUsage(i));
+ });
+ args.successCallback(resultArray);
+ }
+ };
+
+ var result = native.call('ApplicationManager_getBatteryUsageInfo', callArgs, callback);
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
+};
+
+ApplicationManager.prototype.getAppsUsageInfo = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name: 'successCallback',
+ type: AV.Types.FUNCTION
+ },
+ {
+ name: 'errorCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'mode',
+ type: AV.Types.ENUM,
+ values: T.getValues(ApplicationUsageMode),
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'filter',
+ type: AV.Types.DICTIONARY,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'limit',
+ type: AV.Types.LONG,
+ optional: true,
+ nullable: true
+ }]);
+
+ var callArgs = {};
+
+ if (!T.isNullOrUndefined(args.mode)) {
+ callArgs.mode = args.mode;
+ }
+
+ if (!T.isNullOrUndefined(args.filter) && typeof args.filter !== 'object') {
+ setTimeout(function() {
+ native.callIfPossible(args.errorCallback,
+ new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+ 'filter must be an object.'));
+ }, 0);
+ return;
+ }
+
+ callArgs.filter = {};
+ if (!T.isNullOrUndefined(args.filter)) {
+ var filter = args.filter;
+ if (!T.isNullOrUndefined(filter.timeSpan)) {
+ callArgs.filter.timeSpan = Converter.toLong(filter.timeSpan);
+ } else {
+ if (!T.isNullOrUndefined(filter.startTime)) {
+ if (filter.startTime instanceof Date) {
+ callArgs.filter.startTime = filter.startTime.getTime() / 1000;
+ } else {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR,
+ 'startTime given with invalid type.');
+ }
+ }
+
+ if (!T.isNullOrUndefined(filter.endTime)) {
+ if (filter.endTime instanceof Date) {
+ callArgs.filter.endTime = filter.endTime.getTime() / 1000;
+ } else {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR,
+ 'endTime given with invalid type.');
+ }
+ }
+ }
+ }
+
+ if (!T.isNullOrUndefined(args.limit)) {
+ callArgs.limit = args.limit;
+ }
+
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+ } else {
+ var data = native.getResultObject(result);
+ var resultArray = [];
+ data.forEach(function(i) {
+ resultArray.push(new ApplicationUsage(i));
+ });
+ args.successCallback(resultArray);
+ }
+ };
+
+ var result = native.call('ApplicationManager_getAppsUsageInfo', callArgs, callback);
+ if (native.isFailure(result)) {
+ throw native.getErrorObject(result);
+ }
+};
+
function ListenerManager(native, listenerName) {
this.listeners = {};
this.nextId = 1;
applicationEventListener.removeListener(args.watchId);
};
+function StatusListenerManager(native, listenerName) {
+ this.listeners = {};
+ this.listenersCount = 0;
+ this.nextId = 1;
+ this.nativeSet = false;
+ this.native = native;
+ this.listenerName = listenerName;
+};
+
+StatusListenerManager.prototype.onListenerCalled = function(msg) {
+ var statusType = msg.statusType;
+ var app_id = msg.appId;
+
+ for (var watchId in this.listeners) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ var listener = this.listeners[watchId];
+ if (!listener.appId || listener.appId === app_id) {
+ listener.callback(app_id, statusType);
+ }
+ }
+ }
+};
+
+StatusListenerManager.prototype.addListener = function(callback, appId) {
+ if (!this.nativeSet) {
+ var result = this.native.callSync('ApplicationManager_addAppStatusChangeListener');
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+
+ this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
+ this.nativeSet = true;
+ }
+
+ var listener = {
+ 'callback' : callback,
+ 'appId' : appId
+ };
+
+ var id = this.nextId++;
+ this.listeners[id] = listener;
+ this.listenersCount++;
+
+ return id;
+};
+
+StatusListenerManager.prototype.removeListener = function(watchId) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ if (this.listenersCount > 1) {
+ delete this.listeners[watchId];
+ this.listenersCount--;
+ return;
+ }
+
+ if (this.nativeSet) {
+ var result = this.native.callSync('ApplicationManager_removeStatusChangeListener');
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+
+ delete this.listeners[watchId];
+ this.listenersCount--;
+
+ this.native.removeListener(this.listenerName);
+ this.nativeSet = false;
+ }
+ }
+};
+
+var APP_STATUS_CHANGE_LISTENER = 'AppStatusChangeListener';
+var appStatusChangeListener = new StatusListenerManager(native, APP_STATUS_CHANGE_LISTENER);
+
+ApplicationManager.prototype.addAppStatusChangeListener = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name : 'statusChangeListener',
+ type : AV.Types.FUNCTION,
+ },
+ {
+ name : 'appId',
+ type : AV.Types.STRING,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ if (args.appId !== undefined && args.appId !== null && !args.appId.length) {
+ throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Application id is empty');
+ }
+
+ return appStatusChangeListener.addListener(args.statusChangeListener, args.appId);
+};
+
+ApplicationManager.prototype.removeAppStatusChangeListener = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name : 'watchId',
+ type : AV.Types.LONG
+ }
+ ]);
+
+ appStatusChangeListener.removeListener(args.watchId);
+};
+
// class Application ////////////////////////////////////////////////////
function Application(data) {
});
}
-// class ApplicationMetaData ////////////////////////////////////////////////////
+// class ApplicationMetaData ///////////////////////////////////////////////////////
function ApplicationMetaData(data) {
Object.defineProperties(this, {
key : {
});
}
+//class ApplicationBatteryUsage ////////////////////////////////////////////////////
+function ApplicationBatteryUsage(data) {
+ Object.defineProperties(this, {
+ appId : {
+ value : data.appId,
+ writable : false,
+ enumerable : true
+ },
+ batteryUsage : {
+ value : data.batteryUsage,
+ writable : false,
+ enumerable : true
+ }
+ });
+}
+
+//class ApplicationUsage ////////////////////////////////////////////////////////
+function ApplicationUsage(data) {
+ Object.defineProperties(this, {
+ appId : {
+ value : data.appId,
+ writable : false,
+ enumerable : true
+ },
+ totalCount : {
+ value : data.totalCount,
+ writable : false,
+ enumerable : true
+ },
+ totalDuration : {
+ value : data.totalDuration,
+ writable : false,
+ enumerable : true
+ },
+ lastTime : {
+ value : new Date(data.lastTime * 1000),
+ writable : false,
+ enumerable : true
+ }
+ });
+}
+
// exports ////////////////////////////////////////////////////
exports = new ApplicationManager();
const std::string kPrivilegeAppManagerKill = "http://tizen.org/privilege/appmanager.kill";
const std::string kPrivilegeApplicationInfo = "http://tizen.org/privilege/application.info";
const std::string kPrivilegeApplicationLaunch = "http://tizen.org/privilege/application.launch";
+const std::string kPrivilegeAppHistoryRead = "http://tizen.org/privilege/apphistory.read";
} // namespace
using namespace common;
REGISTER_SYNC("ApplicationManager_getAppMetaData", GetAppMetaData);
REGISTER_SYNC("ApplicationManager_addAppInfoEventListener", AddAppInfoEventListener);
REGISTER_SYNC("ApplicationManager_removeAppInfoEventListener", RemoveAppInfoEventListener);
+ REGISTER_SYNC("ApplicationManager_addAppStatusChangeListener", AddStatusListener);
+ REGISTER_SYNC("ApplicationManager_removeStatusChangeListener", RemoveStatusListener);
// Application
REGISTER_SYNC("Application_getRequestedAppControl", GetRequestedAppControl);
REGISTER_ASYNC("ApplicationManager_findAppControl", FindAppControl);
REGISTER_ASYNC("ApplicationManager_getAppsContext", GetAppsContext);
REGISTER_ASYNC("ApplicationManager_getAppsInfo", GetAppsInfo);
+ REGISTER_ASYNC("ApplicationManager_getAppsUsageInfo", GetAppsUsageInfo);
+ REGISTER_ASYNC("ApplicationManager_getBatteryUsageInfo", GetBatteryUsageInfo);
#undef REGISTER_ASYNC
}
manager_.GetAppMetaData(app_id, &out);
}
+void ApplicationInstance::GetBatteryUsageInfo(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeAppHistoryRead, &out);
+
+ manager_.GetBatteryUsageInfo(args, &out);
+}
+
+void ApplicationInstance::GetAppsUsageInfo(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeAppHistoryRead, &out);
+
+ manager_.GetAppsUsageInfo(args, &out);
+}
+
void ApplicationInstance::AddAppInfoEventListener(const picojson::value& args,
picojson::object& out) {
LoggerD("Entered");
manager_.StopEventListener(event_name);
}
+void ApplicationInstance::AddStatusListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+
+ JsonCallback cb = [this](picojson::value* event) -> void {
+ Instance::PostMessage(this, event->serialize().c_str());
+ };
+
+ PlatformResult result = manager_.StartStatusListener(cb);
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void ApplicationInstance::RemoveStatusListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+
+ PlatformResult result = manager_.StopStatusChangeListener();
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
} // namespace application
} // namespace extension
void GetAppCerts(const picojson::value& args, picojson::object& out);
void GetAppSharedURI(const picojson::value& args, picojson::object& out);
void GetAppMetaData(const picojson::value& args, picojson::object& out);
+ void GetBatteryUsageInfo(const picojson::value& args, picojson::object& out);
+ void GetAppsUsageInfo(const picojson::value& args, picojson::object& out);
void AddAppInfoEventListener(const picojson::value& args, picojson::object& out);
void RemoveAppInfoEventListener(const picojson::value& args, picojson::object& out);
void GetRequestedAppControl(const picojson::value& args, picojson::object& out);
void BroadcastTrustedEvent(const picojson::value& args, picojson::object& out);
void AddEventListener(const picojson::value& args, picojson::object& out);
void RemoveEventListener(const picojson::value& args, picojson::object& out);
+ void AddStatusListener(const picojson::value& args, picojson::object& out);
+ void RemoveStatusListener(const picojson::value& args, picojson::object& out);
ApplicationManager manager_;
Application current_application_;
#include <app_control_internal.h>
#include <app_info.h>
-#include <app_manager.h>
#include <app_manager_extension.h>
#include <appsvc.h>
#include <aul.h>
const std::string kOnUpdated = "onupdated";
const std::string kOnUninstalled = "onuninstalled";
const std::string kData = "data";
+const std::string kStatusType = "statusType";
+const std::string kAppId = "appId";
+const std::string kListenerId = "listenerId";
+const std::string kAppStatusChangeListener = "AppStatusChangeListener";
+const std::string kAppUsageModeFrequently = "FREQUENTLY";
+const std::string kAppUsageModeRecently = "RECENTLY";
const std::map<std::string, std::string> event_map_ = {
{SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
{SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
{SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
{SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
+
+#ifdef TIZEN_MOBILE
+const int kMaximumBatteryRetrievedObjects = 30;
+const int kMaximumAppsRetrievedObjects = 10;
+const int kDefaultPeriodOfTime = 30;
+#endif
}
ApplicationManager::ApplicationManager(ApplicationInstance& instance)
: pkgmgr_client_handle_(nullptr),
pkgmgr_client_uninstall_handle_(nullptr),
- instance_(instance) {
+ instance_(instance),
+ app_status_handle_(nullptr) {
LoggerD("Enter");
}
ApplicationManager::~ApplicationManager() {
LoggerD("Enter");
StopAppInfoEventListener();
+ StopStatusChangeListener();
+
+ if (app_status_handle_) {
+ int ret = app_manager_event_destroy(app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ LoggerE("app_manager_event_destroy failed, error: %d", ret);
+ }
+ }
}
void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
ReportSuccess(result, *out);
}
+#ifdef TIZEN_MOBILE
+PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
+ const context_history_filter_h filter,
+ context_history_data_e* data_type_out) {
+ LoggerD("Entered");
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ int limit = kMaximumBatteryRetrievedObjects;
+ if (args.contains("limit")) {
+ limit = static_cast<int>(args.get("limit").get<double>());
+ }
+
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
+
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
+ ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
+
+ if (args.contains("days")) {
+ const int days = static_cast<int>(args.get("days").get<double>());
+ data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
+
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
+ ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+
+ *data_type_out = data_type_in;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record,
+ picojson::object* object) {
+ LoggerD("Entered");
+
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ double amount = 0.0;
+ char* app_id = nullptr;
+ SCOPE_EXIT {
+ free(app_id);
+ };
+
+ ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
+ ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
+ ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ object->insert(std::make_pair("appId", picojson::value(app_id)));
+ object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
+ const context_history_filter_h filter,
+ context_history_data_e* data_type_out) {
+ LoggerD("Entered");
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ int limit = kMaximumAppsRetrievedObjects;
+ if (args.contains("limit")) {
+ limit = static_cast<int>(args.get("limit").get<double>());
+ }
+
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
+ ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
+ if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
+ data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
+ }
+
+ int time_span = kDefaultPeriodOfTime;
+ const picojson::object& JS_filter = args.get("filter").get<picojson::object>();
+ auto time_span_iter = JS_filter.find("timeSpan");
+ if (JS_filter.end() != time_span_iter || (JS_filter.end() == JS_filter.find("startTime") &&
+ JS_filter.end() == JS_filter.find("endTime"))) {
+ // In the second case, we treat the filter object just like an empty object.
+ // The default value of filter will be used instead.
+ if (JS_filter.end() != time_span_iter) {
+ time_span = static_cast<int>(time_span_iter->second.get<double>());
+ }
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
+ // context_history_filter_set_int may return only success or
+ // CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
+ // Although this should never happen, it's better to check ret's value
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR,
+ "Error while setting the default TIME_SPAN value.",
+ ("Error while setting the default TIME_SPAN value: %d (%s)", ret,
+ get_error_message(ret)));
+ }
+ } else {
+ auto start_time_iter = JS_filter.find("startTime");
+ auto end_time_iter = JS_filter.find("endTime");
+ if (start_time_iter != JS_filter.end()) {
+ int start_time = static_cast<int>(start_time_iter->second.get<double>());
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
+ ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+ if (end_time_iter != JS_filter.end()) {
+ int end_time = static_cast<int>(end_time_iter->second.get<double>());
+ ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
+ ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+ }
+
+ *data_type_out = data_type_in;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
+ picojson::object* object) {
+ LoggerD("Entered");
+
+ int ret = CONTEXT_HISTORY_ERROR_NONE;
+ int total_count = 0;
+ int total_duration = 0;
+ int last_time = 0;
+ char* app_id = nullptr;
+ SCOPE_EXIT {
+ free(app_id);
+ };
+
+ ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
+ ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
+ ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Failed to get total duration.",
+ ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
+ ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ object->insert(std::make_pair("appId", picojson::value(app_id)));
+ object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
+ object->insert(
+ std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
+ object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+#endif
+
+void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
+ LoggerD("Entered");
+
+#ifdef TIZEN_MOBILE
+ int callback_id = -1;
+ const auto& callback = args.get(kCallbackId);
+ if (callback.is<double>()) {
+ callback_id = static_cast<int>(callback.get<double>());
+ }
+
+ auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
+ LoggerD("Entered");
+ PlatformResult result = ApplicationManager::GetContextHistory(
+ args, &response.get()->get<picojson::object>(), &ApplicationManager::BatteryUsageFilter,
+ &ApplicationManager::BatteryUsageAttributes);
+ if (!result) {
+ LogAndReportError(result, &response.get()->get<picojson::object>());
+ }
+ };
+
+ auto get_battery_usage_response =
+ [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
+ LoggerD("Entered");
+ picojson::object& obj = response->get<picojson::object>();
+ obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+ Instance::PostMessage(&this->instance_, response->serialize().c_str());
+ };
+
+ auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
+ TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
+ data);
+#else
+ // 20170510 Context API is supported only for mobile profile, other ones would result with
+ // NotSupportedError
+ LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
+ "This feature is not supported on this profile."),
+ out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
+#endif
+}
+
+void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
+ LoggerD("Entered");
+
+#ifdef TIZEN_MOBILE
+ int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
+
+ auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
+ LoggerD("Entered");
+ PlatformResult result = ApplicationManager::GetContextHistory(
+ args, &response.get()->get<picojson::object>(), &ApplicationManager::AppsUsageFilter,
+ &ApplicationManager::AppsUsageAttributes);
+ if (!result) {
+ LogAndReportError(result, &response.get()->get<picojson::object>());
+ }
+ };
+
+ auto get_apps_usage_response =
+ [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
+ LoggerD("Entered");
+ picojson::object& obj = response->get<picojson::object>();
+ obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+ Instance::PostMessage(&this->instance_, response->serialize().c_str());
+ };
+
+ auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
+ TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
+#else
+ // Context API is supported only for mobile profile, other ones would result with
+ // NotSupportedError
+ LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
+ "This feature is not supported on this profile."),
+ out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
+#endif
+}
+
void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
LoggerD("Entered");
}
}
+void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
+ app_manager_event_type_e event_type,
+ app_manager_event_state_e event_state,
+ app_manager_event_h handle, void* user_data) {
+ LoggerD("Entered");
+
+ if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
+ LoggerD("State different from completed");
+ return;
+ }
+
+ ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
+
+ if (!manager || !manager->status_callback_) {
+ LoggerD("No event listener registered, skipping.");
+ return;
+ }
+
+ bool status_type;
+ switch (event_type) {
+ case APP_MANAGER_EVENT_ENABLE_APP:
+ status_type = true;
+ break;
+ case APP_MANAGER_EVENT_DISABLE_APP:
+ status_type = false;
+ break;
+ default:
+ LoggerD("Uknown status type skipping.");
+ return;
+ }
+
+ picojson::value event = picojson::value(picojson::object());
+ picojson::object& event_o = event.get<picojson::object>();
+
+ event_o[kStatusType] = picojson::value(status_type);
+ event_o[kAppId] = picojson::value(app_id);
+ event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
+
+ manager->status_callback_(&event);
+}
+
+#ifdef TIZEN_MOBILE
+PlatformResult ApplicationManager::GetContextHistory(
+ const picojson::value& args, picojson::object* out,
+ common::PlatformResult (*modify_filter_cb)(const picojson::value&,
+ const context_history_filter_h,
+ context_history_data_e* data_type),
+ common::PlatformResult (*add_attributes_to_object)(const context_history_record_h,
+ picojson::object*)) {
+ LoggerD("Entered");
+ context_history_list_h list = nullptr;
+ context_history_h handle = nullptr;
+ context_history_filter_h filter = nullptr;
+
+ SCOPE_EXIT {
+ context_history_list_destroy(list);
+ context_history_destroy(handle);
+ context_history_filter_destroy(filter);
+ };
+
+ int ret = context_history_create(&handle);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Failed to create context handle.",
+ ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = context_history_filter_create(&filter);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Failed to create filter handle.",
+ ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ context_history_data_e data_type;
+
+ PlatformResult result = modify_filter_cb(args, filter, &data_type);
+ if (!result) {
+ return result;
+ }
+
+ picojson::value result_array = picojson::value(picojson::array());
+ picojson::array& array_obj = result_array.get<picojson::array>();
+
+ ret = context_history_get_list(handle, data_type, filter, &list);
+ if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
+ ReportSuccess(result_array, *out);
+ return PlatformResult(ErrorCode::NO_ERROR);
+ } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
+ ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ int size = 0;
+ ret = context_history_list_get_count(list, &size);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
+ ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ array_obj.resize(size, picojson::value(picojson::object()));
+
+ for (int i = 0; i < size; ++i) {
+ context_history_record_h record = nullptr;
+ SCOPE_EXIT {
+ context_history_record_destroy(record);
+ };
+
+ ret = context_history_list_get_current(list, &record);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::ABORT_ERR, "Failed to get current record.",
+ ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
+ if (!result) {
+ return result;
+ }
+
+ ret = context_history_list_move_next(list);
+ if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
+ ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
+ }
+ }
+
+ ReportSuccess(result_array, *out);
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+#endif
+
+PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
+ LoggerD("Entered");
+
+ int ret = APP_MANAGER_ERROR_NONE;
+
+ if (!app_status_handle_) {
+ ret = app_manager_event_create(&app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
+ ("app_manager_event_create failed, error: %d", ret));
+ }
+
+ ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
+ ("app_manager_event_set_status failed, error: %d", ret));
+ }
+ }
+
+ status_callback_ = callback;
+ ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
+ ("app_manager_set_event_cb failed, error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::StopStatusChangeListener() {
+ LoggerD("Entered");
+
+ if (app_status_handle_) {
+ int ret = app_manager_unset_event_cb(app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
+ ("app_manager_unset_event_cb failed, error: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace application
} // namespace extension
#define SRC_APPLICATION_APPLICATION_MANAGER_H__
#include <app_event.h>
+#include <app_manager.h>
#include <bundle.h>
#include <package-manager.h>
#include <pkgmgr-info.h>
#include <functional>
+#include <functional>
#include <memory>
#include <string>
+#ifdef TIZEN_MOBILE
+#include <context-service/context_history.h>
+#endif
#include "common/picojson.h"
#include "common/platform_result.h"
void GetAppCerts(const std::string& app_id, picojson::object* out);
void GetAppSharedUri(const std::string& app_id, picojson::object* out);
void GetAppMetaData(const std::string& app_id, picojson::object* out);
+ void GetBatteryUsageInfo(const picojson::value& args, picojson::object* out);
+ void GetAppsUsageInfo(const picojson::value& args, picojson::object* out);
void StartAppInfoEventListener(picojson::object* out);
void StopAppInfoEventListener();
void GetApplicationInformationSize(const picojson::value& args, picojson::object* out);
common::PlatformResult StartEventListener(const std::string& event_name,
const JsonCallback& callback);
void StopEventListener(const std::string& event_name);
+ common::PlatformResult StartStatusListener(const JsonCallback& callback);
+ common::PlatformResult StopStatusChangeListener();
private:
char* GetPackageId(const std::string& app_id);
pkgmgr_client* pkgmgr_client_handle_;
pkgmgr_client* pkgmgr_client_uninstall_handle_;
ApplicationInstance& instance_;
+ app_manager_event_h app_status_handle_;
JsonCallback event_callback_;
+ JsonCallback status_callback_;
std::map<std::string, event_handler_h> event_handler_map_;
static void OnEvent(const char* event_name, bundle* event_data, void* user_data);
+ static void OnStatusEvent(const char* type, const char* app_id,
+ app_manager_event_type_e event_type,
+ app_manager_event_state_e event_state, app_manager_event_h handle,
+ void* user_data);
+
+#ifdef TIZEN_MOBILE
+ static common::PlatformResult GetContextHistory(
+ const picojson::value& args, picojson::object* out,
+ common::PlatformResult (*)(const picojson::value&, const context_history_filter_h,
+ context_history_data_e* data_type),
+ common::PlatformResult (*)(const context_history_record_h, picojson::object*));
+
+ static common::PlatformResult BatteryUsageFilter(const picojson::value&,
+ const context_history_filter_h,
+ context_history_data_e* data_type);
+ static common::PlatformResult BatteryUsageAttributes(const context_history_record_h,
+ picojson::object*);
+
+ static common::PlatformResult AppsUsageFilter(const picojson::value&,
+ const context_history_filter_h,
+ context_history_data_e* data_type);
+ static common::PlatformResult AppsUsageAttributes(const context_history_record_h,
+ picojson::object*);
+#endif
};
} // namespace application
return LogAndCreateResult(ErrorCode::IO_ERR, "Node has been deleted from platform.");
}
- int err = 0;
- struct dirent entry = {0};
- struct dirent* result = nullptr;
+ errno = 0;
+ struct dirent* entry = nullptr;
NameList name_list;
- while ((0 == (err = readdir_r(dir, &entry, &result))) && result) {
- if (!strcmp(entry.d_name, ".") || !strncmp(entry.d_name, "..", 2)) {
+ while (nullptr != (entry = readdir(dir))) {
+ if (!strcmp(entry->d_name, ".") || !strncmp(entry->d_name, "..", 2)) {
continue;
}
- name_list.push_back(entry.d_name);
+ name_list.push_back(entry->d_name);
}
if (closedir(dir) != 0) {
return LogAndCreateResult(ErrorCode::IO_ERR, "Could not close platform node.");
}
- if (0 != err) {
+ if (0 != errno) {
return LogAndCreateResult(ErrorCode::IO_ERR, "Error while reading directory.");
}
return LogAndCreateResult(ErrorCode::IO_ERR, "Node has been deleted from platform.");
}
- int err = 0;
- struct dirent entry = {0};
- struct dirent* result = nullptr;
+ errno = 0;
+ struct dirent* entry = nullptr;
NodeList node_list;
- while ((0 == (err = readdir_r(dir, &entry, &result))) && result) {
- if (!strcmp(entry.d_name, ".") || !strncmp(entry.d_name, "..", 2)) {
+ while (nullptr != (entry = readdir(dir))) {
+ if (!strcmp(entry->d_name, ".") || !strncmp(entry->d_name, "..", 2)) {
continue;
}
NodePtr node;
- Node::resolve(*m_path + entry.d_name, &node);
+ Node::resolve(*m_path + entry->d_name, &node);
node->setPermissions(getPermissions()); // inherit access rights
node_list.push_back(node);
}
return LogAndCreateResult(ErrorCode::IO_ERR, "Could not close platform node.");
}
- if (0 != err) {
+ if (0 != errno) {
SLoggerE("Path %s Perm %d", m_path->getFullPath().c_str(), m_perms);
return LogAndCreateResult(ErrorCode::IO_ERR, "Error while reading directory.");
}
SLoggerE("File %s", path->getFullPath().c_str());
return LogAndCreateResult(ErrorCode::IO_ERR, "Node does not exist or access denied.");
}
- struct dirent entry = {0};
- struct dirent* result = nullptr;
+ struct dirent* entry = nullptr;
PlatformResult platform_result(ErrorCode::NO_ERROR);
- while ((0 == (readdir_r(dir, &entry, &result))) && result) {
- if (!strcmp(entry.d_name, ".") || !strncmp(entry.d_name, "..", 2)) {
+ while (nullptr != (entry = readdir(dir))) {
+ if (!strcmp(entry->d_name, ".") || !strncmp(entry->d_name, "..", 2)) {
continue;
}
- PathPtr subPath = *path + entry.d_name;
+ PathPtr subPath = *path + entry->d_name;
struct stat info;
memset(&info, 0, sizeof(struct stat));
if (lstat(subPath->getFullPath().c_str(), &info) == 0) {
'variables': {
'packages': [
'capi-network-bluetooth',
+ 'capi-appfw-app-control',
'capi-system-info',
'libpcrecpp',
]
* Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
*/
gboolean
-_auto_gen_org_tizen_system_deviced_display_call_lockstate_sync (
+_auto_gen_org_tizen_system_deviced_display_call_lockstate_nopt_sync (
_auto_genOrgTizenSystemDevicedDisplay *proxy,
const gchar *arg_state,
const gchar *arg_option1,
{
GVariant *_ret;
_ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
- "lockstate",
+ "lockstate_nopt", //Since Tizen 4.0 we call "lockstate_nopt" method
+ //because "lockstate" requires additional privilege
g_variant_new ("(sssi)",
arg_state,
arg_option1,
_auto_genOrgTizenSystemDevicedDisplay *proxy, gint *out_result, GAsyncResult *res,
GError **error);
-gboolean _auto_gen_org_tizen_system_deviced_display_call_lockstate_sync(
+gboolean _auto_gen_org_tizen_system_deviced_display_call_lockstate_nopt_sync(
_auto_genOrgTizenSystemDevicedDisplay *proxy, const gchar *arg_state, const gchar *arg_option1,
const gchar *arg_option2, gint arg_timeout, gint *out_result, GCancellable *cancellable,
GError **error);
const gint _timeout = static_cast<gint>(timeout);
gint out_result;
- gboolean ret = _auto_gen_org_tizen_system_deviced_display_call_lockstate_sync(
+ gboolean ret = _auto_gen_org_tizen_system_deviced_display_call_lockstate_nopt_sync(
proxy_, arg_state, arg_option1, arg_option2, _timeout, &out_result, NULL, &error);
if (!ret) {
err_->ReportError(error);
'variables': {
'packages': [
'capi-appfw-app-manager',
- 'capi-appfw-application',
+ 'capi-appfw-app-common',
'capi-appfw-package-manager',
'storage',
'security-privilege-manager',
var JSON_ = xwalk.JSON;
var validator_ = xwalk.utils.validator;
+var converter_ = xwalk.utils.converter;
var types_ = validator_.Types;
+var type_ = xwalk.utils.type;
+var native_ = new xwalk.utils.NativeManager(extension);
var callbackId = 0;
var callbacks = {};
+var listeners_ = {};
+var DATA_CONTROL_MANAGER_LISTENER_ID = 'DataControlManagerChangeCallback';
+
+var DataType = {
+ 'MAP': 'MAP',
+ 'SQL': 'SQL'
+};
+
+var EventType = {
+ 'SQL_UPDATE': 'SQL_UPDATE',
+ 'SQL_INSERT': 'SQL_INSERT',
+ 'SQL_DELETE': 'SQL_DELETE',
+ 'MAP_SET': 'MAP_SET',
+ 'MAP_ADD': 'MAP_ADD',
+ 'MAP_REMOVE': 'MAP_REMOVE'
+};
+
+
+var DataControlListenersManager = (function() {
+
+ function changeEvent(event) {
+ var successCallback;
+
+ if (DataType.SQL === event.eventType) {
+ if (type_.isEmptyObject(this._SQLDataControlCallbackMap)) {
+ return;
+ }
+ for (var listenerId in this._SQLDataControlCallbackMap) {
+ if (this._SQLDataControlCallbackMap.hasOwnProperty(listenerId)) {
+ if (this._SQLDataControlCallbackMap[listenerId].providerId === event.providerId &&
+ this._SQLDataControlCallbackMap[listenerId].dataId === event.dataId) {
+ successCallback = this._SQLDataControlCallbackMap[listenerId].changeCallback;
+ if (type_.isFunction(successCallback)) {
+ successCallback(event.type, {columns: event.columns, values: event.values});
+ }
+ }
+ }
+ }
+ } else {
+ if (type_.isEmptyObject(this._MAPDataControlCallbackMap)) {
+ return;
+ }
+ for (var listenerId in this._MAPDataControlCallbackMap) {
+ if (this._MAPDataControlCallbackMap.hasOwnProperty(listenerId)) {
+ if (this._MAPDataControlCallbackMap[listenerId].providerId === event.providerId &&
+ this._MAPDataControlCallbackMap[listenerId].dataId === event.dataId) {
+ successCallback = this._MAPDataControlCallbackMap[listenerId].changeCallback;
+ if (type_.isFunction(successCallback)) {
+ successCallback(event.type, {columns: event.columns, values: event.values});
+ }
+ }
+ }
+ }
+ }
+ }
+
+ function _DataControlListenerManager() {
+ this._SQLDataControlCallbackMap = {};
+ this._MAPDataControlCallbackMap = {};
+ this.lastListenerId = 0;
+ this.changeEvent = changeEvent.bind(this);
+ }
+
+ _DataControlListenerManager.prototype.addChangeListener = function(type, providerId, dataId, changeCallback, errorCallback) {
+ var _realWatchId = 0;
+ if (DataType.SQL === type) {
+ for (var i in this._SQLDataControlCallbackMap) {
+ if (this._SQLDataControlCallbackMap.hasOwnProperty(i) &&
+ this._SQLDataControlCallbackMap[i].providerId === providerId &&
+ this._SQLDataControlCallbackMap[i].dataId === dataId) {
+ _realWatchId = this._SQLDataControlCallbackMap[i].realWatchId;
+ }
+ }
+ } else {
+ for (var i in this._MAPDataControlCallbackMap) {
+ if (this._MAPDataControlCallbackMap.hasOwnProperty(i) &&
+ this._MAPDataControlCallbackMap[i].providerId === providerId &&
+ this._MAPDataControlCallbackMap[i].dataId === dataId) {
+ _realWatchId = this._MAPDataControlCallbackMap[i].realWatchId;
+ }
+ }
+ }
+
+ if (!_realWatchId) {
+ var callback = function(result) {
+ if (native_.isFailure(result)) {
+ native_.callIfPossible(errorCallback, native_.getErrorObject(result));
+ return;
+ }
+ }
+ var result =
+ callNativeWithCallback('DataControlConsumerObject_addChangeListener', {
+ providerId: providerId,
+ dataId: dataId,
+ type: type
+ }, callback);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ } else {
+ _realWatchId = converter_.toLong(result.watchId, true);
+ }
+ if (type_.isEmptyObject(this._SQLDataControlCallbackMap) &&
+ type_.isEmptyObject(this._MAPDataControlCallbackMap)) {
+ AddListener(DATA_CONTROL_MANAGER_LISTENER_ID, this.changeEvent);
+ }
+ }
+
+ if (DataType.SQL === type) {
+ this._SQLDataControlCallbackMap[++this.lastListenerId] = {'providerId': providerId,
+ 'dataId': dataId,
+ 'changeCallback': changeCallback,
+ 'realWatchId': _realWatchId};
+ } else {
+ this._MAPDataControlCallbackMap[++this.lastListenerId] = {'providerId': providerId,
+ 'dataId': dataId,
+ 'changeCallback': changeCallback,
+ 'realWatchId': _realWatchId};
+ }
+
+ return this.lastListenerId;
+ };
+
+ _DataControlListenerManager.prototype.removeChangeListener = function(type, providerId, dataId, listenerId) {
+ var _realWatchId = 0;
+ if (DataType.SQL === type && !type_.isUndefined(this._SQLDataControlCallbackMap[listenerId])) {
+ _realWatchId = this._SQLDataControlCallbackMap[listenerId].realWatchId;
+ delete this._SQLDataControlCallbackMap[listenerId];
+ for (var i in this._SQLDataControlCallbackMap) {
+ if (this._SQLDataControlCallbackMap.hasOwnProperty(i) &&
+ this._SQLDataControlCallbackMap[i].realWatchId === _realWatchId) {
+ return;
+ }
+ }
+ } else if (DataType.MAP === type && !type_.isUndefined(this._MAPDataControlCallbackMap[listenerId])) {
+ _realWatchId = this._MAPDataControlCallbackMap[listenerId].realWatchId;
+ delete this._MAPDataControlCallbackMap[listenerId];
+ for (var i in this._MAPDataControlCallbackMap) {
+ if (this._MAPDataControlCallbackMap.hasOwnProperty(i) &&
+ this._MAPDataControlCallbackMap[i].realWatchId === _realWatchId) {
+ return;
+ }
+ }
+ } else {
+ console.log("Type invalid or listener was not added")
+ return;
+ }
+
+ if (0 != _realWatchId) {
+ callNative('DataControlConsumerObject_removeChangeListener',{
+ providerId: providerId,
+ dataId: dataId,
+ watchId: _realWatchId,
+ type: type
+ })
+
+ if (type_.isEmptyObject(this._SQLDataControlCallbackMap) &&
+ type_.isEmptyObject(this._MAPDataControlCallbackMap)) {
+ RemoveListener(DATA_CONTROL_MANAGER_LISTENER_ID);
+ }
+ }
+ };
+
+ return _DataControlListenerManager;
+
+})();
+
+var listenersManager = new DataControlListenersManager();
+
+// TODO refactor setMessageListener to start using common functionality
extension.setMessageListener(function(json) {
var result = JSON_.parse(json);
- var callback = callbacks[result['callbackId']];
- setTimeout(function() {
- callback(result);
- delete callbacks[result['callbackId']];
- }, 0);
+ if (result.hasOwnProperty("callbackId")) {
+ var callback = callbacks[result['callbackId']];
+ setTimeout(function() {
+ callback(result);
+ delete callbacks[result['callbackId']];
+ }, 0);
+ }
+ if (result.hasOwnProperty("listenerId")) {
+ var id = result['listenerId'];
+ delete result['listenerId'];
+ var f = listeners_[id];
+ setTimeout(function() {
+ f(result);
+ }, 0);
+ }
});
function nextCallbackId() {
return callNative(cmd, args);
}
+function AddListener(name, callback) {
+ if (!type_.isString(name) || !name.length) {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ listeners_[name] = callback;
+};
+
+function RemoveListener(name) {
+ if (listeners_.hasOwnProperty(name)) {
+ delete listeners_[name];
+ }
+};
+
function SetReadOnlyProperty(obj, n, v) {
Object.defineProperty(obj, n, {value: v, writable: false});
}
-var DataType = {
- 'MAP': 'MAP',
- 'SQL': 'SQL'
-};
-
function DataControlManager() {
// constructor of DataControlManager
}
var args = validator_.validateArgs(arguments, [
{'name': 'providerId', 'type': types_.STRING},
{'name': 'dataId', 'type': types_.STRING},
- {'name': 'type', 'type': types_.ENUM, 'values': ['MAP', 'SQL']}
+ {'name': 'type', 'type': types_.ENUM, 'values': [DataType.SQL, DataType.MAP]}
]);
var returnObject = null;
- if (type === 'SQL') {
+ if (DataType.SQL === type) {
returnObject = new SQLDataControlConsumer();
- } else if (type === 'MAP') {
+ } else if (DataType.MAP == type) {
returnObject = new MappedDataControlConsumer();
}
+
SetReadOnlyProperty(returnObject, 'type', args.type); // read only property
SetReadOnlyProperty(returnObject, 'providerId', args.providerId); // read only property
SetReadOnlyProperty(returnObject, 'dataId', args.dataId); // read only property
// constructor of DataControlConsumerObject
}
+DataControlConsumerObject.prototype.addChangeListener = function() {
+ var args = validator_.validateArgs(arguments, [
+ {'name': 'dataChangeCallback', 'type': types_.FUNCTION, optional: false, nullable: false},
+ {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+ ]);
+
+ var type = DataType.SQL;
+ if (this instanceof MappedDataControlConsumer) {
+ type = DataType.MAP;
+ }
+
+ return listenersManager.addChangeListener(type, this.providerId, this.dataId,
+ args.dataChangeCallback, args.errorCallback);
+}
+
+DataControlConsumerObject.prototype.removeChangeListener = function() {
+
+ var args = validator_.validateArgs(arguments, [
+ {'name': 'watchId', 'type': types_.LONG}
+ ]);
+ var type = DataType.SQL;
+ if (this instanceof MappedDataControlConsumer) {
+ type = DataType.MAP;
+ }
+
+ listenersManager.removeChangeListener(type, this.providerId, this.dataId, args.watchId);
+}
function SQLDataControlConsumer() {
// constructor of SQLDataControlConsumer
#include <algorithm>
#include <functional>
#include <map>
-#include <memory>
#include <string>
#include <vector>
namespace {
// The privileges that required in Datacontrol API
const std::string kPrivilegeDatacontrol = "http://tizen.org/privilege/datacontrol.consumer";
-
+const std::string kPrivilegeDatasharing = "http://tizen.org/privilege/datasharing";
+const std::string kPrivilegeAppmanagerLaunch = "http://tizen.org/privilege/appmanager.launch";
+const std::string SQL = "SQL";
+const std::string MAP = "MAP";
} // namespace
using common::InvalidValuesException;
using common::SecurityException;
using common::UnknownException;
using common::NotFoundException;
+using common::AbortException;
using common::ScopeExit;
using common::operator+;
+using namespace common;
+
struct DatacontrolInformation {
int callbackId;
int requestId;
DataControlManagerGetdatacontrolconsumer);
REGISTER_SYNC("SQLDataControlConsumer_insert", SQLDataControlConsumerInsert);
REGISTER_SYNC("MappedDataControlConsumer_getValue", MappedDataControlConsumerGetvalue);
+ REGISTER_SYNC("DataControlConsumerObject_removeChangeListener", RemoveChangeListener);
#undef REGISTER_SYNC
+#define REGISTER_ASYNC(c, x) \
+ RegisterSyncHandler(c, std::bind(&DatacontrolInstance::x, this, _1, _2));
+ REGISTER_ASYNC("DataControlConsumerObject_addChangeListener", AddChangeListener);
+#undef REGISTER_ASYNC
}
DatacontrolInstance::~DatacontrolInstance() {
}
}
+int DatacontrolInstance::CreateMAPHandle(const std::string& providerId, const std::string& dataId,
+ data_control_h* handle) {
+ LoggerD("Enter");
+ int result = DATA_CONTROL_ERROR_NONE;
+
+ result = ::data_control_map_create(handle);
+ RETURN_IF_FAIL(result, "Creating map data control handle is failed with error");
+
+ result = ::data_control_map_set_provider_id(*handle, providerId.c_str());
+ RETURN_IF_FAIL(result, "Setting provider id is failed with error");
+
+ result = ::data_control_map_set_data_id(*handle, dataId.c_str());
+ RETURN_IF_FAIL(result, "Setting data id is failed the error");
+
+ return result;
+}
+
+int DatacontrolInstance::CreateSQLHandle(const std::string& providerId, const std::string& dataId,
+ data_control_h* handle) {
+ LoggerD("Enter");
+ int result = DATA_CONTROL_ERROR_NONE;
+
+ result = ::data_control_sql_create(handle);
+ RETURN_IF_FAIL(result, "Creating sql data control handle is failed with error");
+
+ result = ::data_control_sql_set_provider_id(*handle, providerId.c_str());
+ RETURN_IF_FAIL(result, "Setting provider id is failed with error");
+
+ result = ::data_control_sql_set_data_id(*handle, dataId.c_str());
+ RETURN_IF_FAIL(result, "Setting data id is failed the error");
+
+ return result;
+}
+
+PlatformResult DatacontrolInstance::ChangeTypeToString(data_control_data_change_type_e type_e,
+ std::string* type) {
+ LoggerD("Enter");
+
+ switch (type_e) {
+ case DATA_CONTROL_DATA_CHANGE_SQL_UPDATE:
+ *type = "SQL_UPDATE";
+ break;
+ case DATA_CONTROL_DATA_CHANGE_SQL_INSERT:
+ *type = "SQL_INSERT";
+ break;
+ case DATA_CONTROL_DATA_CHANGE_SQL_DELETE:
+ *type = "SQL_DELETE";
+ break;
+ case DATA_CONTROL_DATA_CHANGE_MAP_SET:
+ *type = "MAP_SET";
+ break;
+ case DATA_CONTROL_DATA_CHANGE_MAP_ADD:
+ *type = "MAP_ADD";
+ break;
+ case DATA_CONTROL_DATA_CHANGE_MAP_REMOVE:
+ *type = "MAP_REMOVE";
+ break;
+ default:
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Undefined data change type");
+ break;
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+void DatacontrolInstance::callback(data_control_h provider, data_control_data_change_type_e type,
+ bundle* bundle_data, void* user_data) {
+ LoggerD("Enter");
+
+ auto data = static_cast<ReplyCallbackData*>(user_data);
+
+ char* provider_id = nullptr;
+ char* data_id = nullptr;
+ int result = DATA_CONTROL_ERROR_NONE;
+
+ if (DATA_CONTROL_DATA_CHANGE_SQL_UPDATE == type || DATA_CONTROL_DATA_CHANGE_SQL_INSERT == type ||
+ DATA_CONTROL_DATA_CHANGE_SQL_DELETE == type) {
+ if (MAP == data->event_type) {
+ LoggerI("Callback registered for different type");
+ return;
+ }
+
+ result = data_control_sql_get_provider_id(provider, &provider_id);
+
+ if (DATA_CONTROL_ERROR_NONE == result) {
+ result = data_control_sql_get_data_id(provider, &data_id);
+ }
+ } else {
+ if (SQL == data->event_type) {
+ LoggerI("Callback registered for different type");
+ return;
+ }
+
+ result = data_control_map_get_provider_id(provider, &provider_id);
+
+ if (DATA_CONTROL_ERROR_NONE == result) {
+ result = data_control_map_get_data_id(provider, &data_id);
+ }
+ }
+
+ picojson::value event = picojson::value(picojson::object());
+ picojson::object& obj = event.get<picojson::object>();
+
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ obj.insert(std::make_pair("callbackId", picojson::value(std::to_string(data->callbackId))));
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ LogAndReportError(PlatformResult(ErrorCode::IO_ERR, "Get callback data failed"), &obj);
+ Instance::PostMessage(data->_instance, event.serialize().c_str());
+ return;
+ }
+
+ std::string event_type = "";
+ PlatformResult status = ChangeTypeToString(type, &event_type);
+
+ if (status.IsError()) {
+ obj.insert(std::make_pair("callbackId", picojson::value(std::to_string(data->callbackId))));
+ LogAndReportError(status, &obj);
+ Instance::PostMessage(data->_instance, event.serialize().c_str());
+ return;
+ }
+
+ obj.insert(std::make_pair("type", picojson::value(event_type)));
+
+ obj.insert(std::make_pair("providerId", picojson::value(std::string(provider_id))));
+ obj.insert(std::make_pair("dataId", picojson::value(std::string(data_id))));
+
+ obj.insert(std::make_pair("columns", picojson::value(picojson::array())));
+ obj.insert(std::make_pair("values", picojson::value(picojson::array())));
+
+ bundle_foreach(
+ bundle_data,
+ [](const char* key, const int type, const bundle_keyval_t* kv, void* user_data) {
+ LoggerD("Enter");
+
+ picojson::object& row_data = *(static_cast<picojson::object*>(user_data));
+
+ void* basic_val = NULL;
+ size_t basic_size = 0;
+
+ LoggerD("Key:%s, Type:%d\n", key, type);
+ bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(kv), &basic_val, &basic_size);
+
+ row_data["columns"].get<picojson::array>().push_back(picojson::value(std::string(key)));
+ row_data["values"].get<picojson::array>().push_back(
+ picojson::value(std::string(static_cast<char*>(basic_val))));
+ },
+ &obj);
+
+ obj.insert(std::make_pair("listenerId", picojson::value("DataControlManagerChangeCallback")));
+
+ Instance::PostMessage(data->_instance, event.serialize().c_str());
+}
+
+// result_callback method is used only for pass information to errorCallback if any error
+// occur while adding listener
+void DatacontrolInstance::result_callback(data_control_h provider, data_control_error_e result,
+ int callback_id, void* user_data) {
+ LoggerD("Enter");
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ auto data = static_cast<ReplyCallbackData*>(user_data);
+ picojson::value event = picojson::value(picojson::object());
+ picojson::object& obj = event.get<picojson::object>();
+ obj.insert(std::make_pair("callbackId", picojson::value(std::to_string(data->callbackId))));
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ LogAndReportError(IOException("AddChangeListener failed"), obj);
+ Instance::PostMessage(data->_instance, event.serialize().c_str());
+ if (0 != callback_id) {
+ data->_instance->EraseMap(callback_id);
+ }
+ }
+}
+
+void DatacontrolInstance::AddChangeListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Enter");
+
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeDatasharing, &out);
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeAppmanagerLaunch, &out);
+
+ CHECK_EXIST(args, "providerId", out)
+ CHECK_EXIST(args, "dataId", out)
+ CHECK_EXIST(args, "type", out)
+ CHECK_EXIST(args, "callbackId", out)
+
+ const std::string& providerId = args.get("providerId").get<std::string>();
+ const std::string& dataId = args.get("dataId").get<std::string>();
+ const std::string& type = args.get("type").get<std::string>();
+ int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+ int result = DATA_CONTROL_ERROR_NONE;
+ data_control_h handle = nullptr;
+ std::function<int(data_control_h)> del;
+
+ if (SQL == type) {
+ result = CreateSQLHandle(providerId, dataId, &handle);
+ del = data_control_sql_destroy;
+ } else {
+ result = CreateMAPHandle(providerId, dataId, &handle);
+ del = data_control_map_destroy;
+ }
+
+ auto deleter = [&del](data_control_h handle) {
+ if (handle && DATA_CONTROL_ERROR_NONE != del(handle)) {
+ LoggerE("Destroy handle failed");
+ }
+ };
+
+ std::unique_ptr<std::remove_pointer<data_control_h>::type, decltype(deleter)> handle_ptr(handle,
+ deleter);
+
+ std::shared_ptr<ReplyCallbackData> user_data(new ReplyCallbackData());
+ user_data->_instance = this;
+ user_data->callbackId = callbackId;
+ user_data->event_type = type;
+
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ result_callback(handle, DATA_CONTROL_ERROR_IO_ERROR, 0, user_data.get());
+ return;
+ }
+
+ int watch_id = 0;
+ result = ::data_control_add_data_change_cb(handle, callback, user_data.get(), result_callback,
+ user_data.get(), &watch_id);
+
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ result_callback(handle, DATA_CONTROL_ERROR_IO_ERROR, 0, user_data.get());
+ return;
+ }
+
+ reply_map.insert(std::pair<int, ReplyCallbackDataPtr>(watch_id, user_data));
+
+ picojson::value return_value = picojson::value(picojson::object());
+ picojson::object& return_value_obj = return_value.get<picojson::object>();
+
+ return_value_obj.insert(std::make_pair("watchId", picojson::value(std::to_string(watch_id))));
+ ReportSuccess(return_value, out);
+}
+
+void DatacontrolInstance::RemoveChangeListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Enter");
+
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeDatasharing, &out);
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeAppmanagerLaunch, &out);
+
+ CHECK_EXIST(args, "providerId", out)
+ CHECK_EXIST(args, "dataId", out)
+ CHECK_EXIST(args, "watchId", out)
+ CHECK_EXIST(args, "type", out)
+
+ const std::string& providerId = args.get("providerId").get<std::string>();
+ const std::string& dataId = args.get("dataId").get<std::string>();
+ const std::string& type = args.get("type").get<std::string>();
+ int watch_id = static_cast<int>(args.get("watchId").get<double>());
+ data_control_h handle = nullptr;
+ std::function<int(data_control_h)> del;
+ int result = DATA_CONTROL_ERROR_NONE;
+
+ if (SQL == type) {
+ result = CreateSQLHandle(providerId, dataId, &handle);
+ del = data_control_sql_destroy;
+ } else {
+ result = CreateMAPHandle(providerId, dataId, &handle);
+ del = data_control_map_destroy;
+ }
+
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ LogAndReportError(IOException("RemoveChangeListener failed"), out,
+ ("RemoveChangeListener failed: %d (%s)", result, get_error_message(result)));
+ return;
+ }
+
+ auto deleter = [&del](data_control_h handle) {
+ if (handle && DATA_CONTROL_ERROR_NONE != del(handle)) {
+ LoggerE("Destroy handle failed");
+ }
+ };
+
+ std::unique_ptr<std::remove_pointer<data_control_h>::type, decltype(deleter)> handle_ptr(handle,
+ deleter);
+
+ result = ::data_control_remove_data_change_cb(handle, watch_id);
+
+ if (DATA_CONTROL_ERROR_NONE != result) {
+ // According to native documentation only IOError can be returned to webapi, other errors are
+ // handled earlier
+ LogAndReportError(IOException("RemoveChangeListener failed"), out,
+ ("RemoveChangeListener failed: %d (%s)", result, get_error_message(result)));
+ return;
+ }
+
+ reply_map.erase(watch_id);
+
+ ReportSuccess(out);
+}
+
#undef CHECK_EXIST
} // namespace datacontrol
#define DATACONTROL_DATACONTROL_INSTANCE_H_
#include <data_control.h>
+#include <map>
+#include <memory>
#include <string>
#include "common/extension.h"
namespace extension {
namespace datacontrol {
+class DatacontrolInstance;
+
+struct ReplyCallbackData {
+ DatacontrolInstance* _instance;
+ int callbackId;
+ std::string event_type;
+};
+
+typedef std::shared_ptr<ReplyCallbackData> ReplyCallbackDataPtr;
+typedef std::map<int, ReplyCallbackDataPtr> ReplyCallbackDataMap;
+
class DatacontrolInstance : public common::ParsedInstance {
public:
DatacontrolInstance();
int RunSQLDataControlJob(const std::string& providerId, const std::string& dataId, int callbackId,
int userRequestId, DataControlJob job);
+ int CreateMAPHandle(const std::string& providerId, const std::string& dataId,
+ data_control_h* handle);
+
+ int CreateSQLHandle(const std::string& providerId, const std::string& dataId,
+ data_control_h* handle);
+
+ void EraseMap(int watch_id) {
+ reply_map.erase(watch_id);
+ };
+
+ static void callback(data_control_h provider, data_control_data_change_type_e type,
+ bundle* bundle_data, void* user_data);
+ static void result_callback(data_control_h provider, data_control_error_e result, int callback_id,
+ void* user_data);
+ static common::PlatformResult ChangeTypeToString(data_control_data_change_type_e type_e,
+ std::string* type);
+
private:
void DataControlManagerGetdatacontrolconsumer(const picojson::value& args, picojson::object& out);
void SQLDataControlConsumerInsert(const picojson::value& args, picojson::object& out);
void MappedDataControlConsumerRemovevalue(const picojson::value& args, picojson::object& out);
void MappedDataControlConsumerGetvalue(const picojson::value& args, picojson::object& out);
void MappedDataControlConsumerUpdatevalue(const picojson::value& args, picojson::object& out);
+ void AddChangeListener(const picojson::value& args, picojson::object& out);
+ void RemoveChangeListener(const picojson::value& args, picojson::object& out);
+
+ ReplyCallbackDataMap reply_map;
};
} // namespace datacontrol
#include "common/filesystem/filesystem_provider.h"
#include "common/logger.h"
#include "common/picojson.h"
+#include "common/scope_exit.h"
#include "common/tools.h"
#include "common/typeutil.h"
-#include "common/scope_exit.h"
namespace extension {
namespace download {
if (CONNECTION_TYPE_DISCONNECTED == connection_type) {
LogAndReportError(
- common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "Connection problem occured"),
- &out, ("Connection type is disconnected"));
+ common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "Connection problem occured"), &out,
+ ("Connection type is disconnected"));
return;
}
SCOPE_EXIT {
(void)closedir(dp);
};
- struct dirent entry;
- struct dirent* result = nullptr;
- while (0 == (status = readdir_r(dp, &entry, &result)) && result != nullptr) {
- if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0) continue;
+ errno = 0;
+ struct dirent* entry = nullptr;
+ while (nullptr != (entry = readdir(dp))) {
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
- std::string oldLocation = originPath + std::string("/") + std::string(result->d_name);
- std::string newLocation = destPath + std::string("/") + std::string(result->d_name);
+ std::string oldLocation = originPath + std::string("/") + std::string(entry->d_name);
+ std::string newLocation = destPath + std::string("/") + std::string(entry->d_name);
FilesystemError fstatus = FilesystemError::None;
- if (result->d_type == DT_DIR) {
+ if (entry->d_type == DT_DIR) {
fstatus = copyDirectory(oldLocation, newLocation);
- } else if (result->d_type == DT_REG) {
+ } else if (entry->d_type == DT_REG) {
fstatus = copyFile(oldLocation, newLocation);
}
if (fstatus != FilesystemError::None) {
return fstatus;
}
}
- if (status != 0) {
+
+ if (0 != errno) {
LoggerE("error occured");
return FilesystemError::Other;
}
std::vector<std::string> fileList;
DIR* dp = nullptr;
- struct dirent entry;
- struct dirent* result = nullptr;
- int status = 0;
+ struct dirent* entry = nullptr;
dp = opendir(path.c_str());
if (dp != NULL) {
- while ((status = readdir_r(dp, &entry, &result)) == 0 && result != nullptr) {
- if (strcmp(result->d_name, ".") != 0 && strcmp(result->d_name, "..") != 0)
- fileList.push_back(path + "/" + std::string(result->d_name));
+ errno = 0;
+ while (nullptr != (entry = readdir(dp))) {
+ if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
+ fileList.push_back(path + "/" + std::string(entry->d_name));
}
(void)closedir(dp);
- if (status == 0) {
+ if (0 == errno) {
success_cb(fileList);
} else {
LoggerE("error occured");
(void)closedir(dir);
};
- struct dirent entry;
- struct dirent* result = nullptr;
- int status;
+ errno = 0;
+ struct dirent* entry = nullptr;
- while ((0 == (status = readdir_r(dir, &entry, &result)) && result != nullptr)) {
- std::string name = result->d_name;
+ while (nullptr != (entry = readdir(dir))) {
+ std::string name = entry->d_name;
if (name == "." || name == "..") {
continue;
}
_result.nlink++;
}
- if (status != 0) {
+ if (0 != errno) {
LoggerE("Cannot count files in directory: %s", GetErrorString(errno).c_str());
return _result;
}
--- /dev/null
+/*
+ * Copyright (c) 2017 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 "humanactivitymonitor/gesture_manager.h"
+
+#include <gesture_recognition.h>
+
+#include "common/extension.h"
+#include "common/logger.h"
+#include "common/optional.h"
+#include "common/picojson.h"
+#include "common/scope_exit.h"
+#include "common/tools.h"
+
+namespace extension {
+namespace humanactivitymonitor {
+
+using common::PlatformResult;
+using common::ErrorCode;
+using common::tools::ReportError;
+using common::tools::ReportSuccess;
+
+namespace {
+
+const std::string kListenerId = "listenerId";
+const std::string kListener = "GestureRecognitionListener";
+const std::string kType = "type";
+const std::string kTimestamp = "timestamp";
+const std::string kAlwayOn = "alwaysOn";
+const std::string kAction = "action";
+const std::string kEvent = "event";
+const std::string kError = "error";
+const std::string kOnError = "onerror";
+const std::string kOnDetect = "ondetect";
+
+ErrorCode getErrorCode(int error) {
+ switch (error) {
+ case GESTURE_ERROR_NONE:
+ return ErrorCode::NO_ERROR;
+ case GESTURE_ERROR_INVALID_PARAMETER:
+ return ErrorCode::INVALID_VALUES_ERR;
+ case GESTURE_ERROR_OPERATION_FAILED:
+ return ErrorCode::IO_ERR;
+ case GESTURE_ERROR_NOT_SUPPORTED:
+ return ErrorCode::NOT_SUPPORTED_ERR;
+ case GESTURE_ERROR_INVALID_OPERATION:
+ case GESTURE_ERROR_OUT_OF_MEMORY:
+ case GESTURE_ERROR_PERMISSION_DENIED:
+ case GESTURE_ERROR_ALREADY_STARTED:
+ case GESTURE_ERROR_NOT_STARTED:
+ default:
+ return ErrorCode::ABORT_ERR;
+ }
+}
+
+PlatformResult StrToGestureType(const std::string& type, gesture_type_e* type_e) {
+ if ("GESTURE_DOUBLE_TAP" == type) {
+ *type_e = GESTURE_DOUBLE_TAP;
+ } else if ("GESTURE_MOVE_TO_EAR" == type) {
+ *type_e = GESTURE_MOVE_TO_EAR;
+ } else if ("GESTURE_NO_MOVE" == type) {
+ *type_e = GESTURE_NO_MOVE;
+ } else if ("GESTURE_PICK_UP" == type) {
+ *type_e = GESTURE_PICK_UP;
+ } else if ("GESTURE_SHAKE" == type) {
+ *type_e = GESTURE_SHAKE;
+ } else if ("GESTURE_SNAP" == type) {
+ *type_e = GESTURE_SNAP;
+ } else if ("GESTURE_TILT" == type) {
+ *type_e = GESTURE_TILT;
+ } else if ("GESTURE_TURN_FACE_DOWN" == type) {
+ *type_e = GESTURE_TURN_FACE_DOWN;
+ } else if ("GESTURE_WRIST_UP" == type) {
+ *type_e = GESTURE_WRIST_UP;
+ } else {
+ return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Unknown gesture type");
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+std::string GestureTypeToStr(gesture_type_e type) {
+ switch (type) {
+ case GESTURE_DOUBLE_TAP:
+ return "GESTURE_DOUBLE_TAP";
+ case GESTURE_MOVE_TO_EAR:
+ return "GESTURE_MOVE_TO_EAR";
+ case GESTURE_NO_MOVE:
+ return "GESTURE_NO_MOVE";
+ case GESTURE_PICK_UP:
+ return "GESTURE_PICK_UP";
+ case GESTURE_SHAKE:
+ return "GESTURE_SHAKE";
+ case GESTURE_SNAP:
+ return "GESTURE_SNAP";
+ case GESTURE_TILT:
+ return "GESTURE_TILT";
+ case GESTURE_TURN_FACE_DOWN:
+ return "GESTURE_TURN_FACE_DOWN";
+ case GESTURE_WRIST_UP:
+ return "GESTURE_WRIST_UP";
+ default:
+ return "GESTURE_UNKNOWN_TYPE";
+ }
+}
+std::string GestureEventToStr(gesture_event_e event, gesture_type_e gesture) {
+ switch (event) {
+ // GESTURE_EVENT_DETECTED == GESTURE_SHAKE_DETECTED == GESTURE_SNAP_X_NEGATIVE == 1
+ case GESTURE_EVENT_DETECTED:
+ if (GESTURE_SHAKE == gesture) {
+ return "GESTURE_SHAKE_DETECTED";
+ } else if (GESTURE_SNAP == gesture) {
+ return "GESTURE_SNAP_X_NEGATIVE";
+ } else {
+ return "GESTURE_EVENT_DETECTED";
+ }
+ // GESTURE_SHAKE_FINISHED == GESTURE_SNAP_X_POSITIVE == 2
+ case GESTURE_SHAKE_FINISHED:
+ if (GESTURE_SHAKE == gesture) {
+ return "GESTURE_SHAKE_FINISHED";
+ } else {
+ return "GESTURE_SNAP_X_POSITIVE";
+ }
+ case GESTURE_SNAP_Y_NEGATIVE:
+ return "GESTURE_SNAP_Y_NEGATIVE";
+ case GESTURE_SNAP_Y_POSITIVE:
+ return "GESTURE_SNAP_Y_POSITIVE";
+ case GESTURE_SNAP_Z_NEGATIVE:
+ return "GESTURE_SNAP_Z_NEGATIVE";
+ case GESTURE_SNAP_Z_POSITIVE:
+ return "GESTURE_SNAP_Z_POSITIVE";
+ default:
+ return "GESTURE_EVENT_NONE";
+ }
+}
+
+void GestureRecognitionDefaultCb(gesture_type_e gesture, const gesture_data_h data,
+ double timestamp, gesture_error_e error, void* user_data) {
+ ScopeLogger();
+
+ GestureManager* manager = static_cast<GestureManager*>(user_data);
+ if (!manager) {
+ LoggerW("User data is null");
+ return;
+ }
+
+ manager->CompleteGestureListenerCb(gesture, data, timestamp, error, false);
+}
+
+void GestureRecognitionAlwaysOnCb(gesture_type_e gesture, const gesture_data_h data,
+ double timestamp, gesture_error_e error, void* user_data) {
+ ScopeLogger();
+ GestureManager* manager = static_cast<GestureManager*>(user_data);
+
+ if (!manager) {
+ LoggerW("User data is null");
+ return;
+ }
+
+ manager->CompleteGestureListenerCb(gesture, data, timestamp, error, true);
+}
+
+} // namespace
+
+GestureManager::GestureManager()
+ : m_callback(nullptr), m_recognition_default_map(), m_recognition_always_on_map() {
+ ScopeLogger();
+}
+
+GestureManager::~GestureManager() {
+ ScopeLogger();
+
+ int ret = GESTURE_ERROR_NONE;
+
+ for (auto& it : m_recognition_default_map) {
+ ret = gesture_stop_recognition(it.second);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_stop_recognition() failed");
+ }
+
+ ret = gesture_release(it.second);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_release() failed");
+ }
+ }
+
+ for (auto& it : m_recognition_always_on_map) {
+ ret = gesture_stop_recognition(it.second);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_stop_recognition() failed");
+ }
+
+ ret = gesture_release(it.second);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_release() failed");
+ }
+ }
+
+ m_recognition_default_map.clear();
+ m_recognition_always_on_map.clear();
+}
+
+PlatformResult GestureManager::IsSupported(const std::string& type, bool* is_supported) {
+ ScopeLogger();
+
+ gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+ PlatformResult result = StrToGestureType(type, &type_e);
+ if (!result) {
+ return result;
+ }
+
+ int ret = gesture_is_supported(type_e, is_supported);
+ if (GESTURE_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ getErrorCode(ret), "Checking gesture failed",
+ ("Checking gesture failed, error: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+gesture_event_e GestureManager::GetGestureEvent(const gesture_data_h data) {
+ ScopeLogger();
+
+ gesture_event_e event = GESTURE_EVENT_NONE;
+ int ret = gesture_get_event(data, &event);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_get_event() failed, error %d (%s)", ret, get_error_message(ret));
+ }
+
+ return event;
+}
+
+void GestureManager::FillTiltData(const gesture_data_h data, picojson::object* obj) {
+ ScopeLogger();
+
+ int x = 0;
+ int y = 0;
+
+ int ret = gesture_get_tilt(data, &x, &y);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_get_tilt() failed, error %d (%s)", ret, get_error_message(ret));
+ }
+
+ obj->insert(std::make_pair("x", picojson::value(static_cast<double>(x))));
+ obj->insert(std::make_pair("y", picojson::value(static_cast<double>(y))));
+}
+
+void GestureManager::CompleteGestureListenerCb(gesture_type_e gesture, const gesture_data_h data,
+ double timestamp, gesture_error_e error,
+ bool always_on) {
+ ScopeLogger();
+
+ picojson::value response = picojson::value(picojson::object());
+ auto& obj = response.get<picojson::object>();
+
+ obj.insert(std::make_pair(kAlwayOn, picojson::value(always_on)));
+ obj.insert(std::make_pair(kListenerId, picojson::value(kListener)));
+
+ if (GESTURE_ERROR_NONE != error) {
+ obj.insert(std::make_pair(kAction, picojson::value(kOnError)));
+
+ PlatformResult result =
+ LogAndCreateResult(getErrorCode(error), "Error occurred during recognition");
+ ReportError(result, &obj);
+ } else {
+ gesture_event_e event = GetGestureEvent(data);
+ if (GESTURE_EVENT_NONE == event) {
+ LoggerD("Gesture event none detected.");
+ return;
+ }
+
+ std::string gesture_str = GestureTypeToStr(gesture);
+ if ("GESTURE_UNKNOWN_TYPE" == gesture_str) {
+ LoggerE("Unknown gesture type");
+ return;
+ }
+
+ obj.insert(std::make_pair(kAction, picojson::value(kOnDetect)));
+
+ picojson::value result = picojson::value(picojson::object());
+ auto& result_obj = result.get<picojson::object>();
+
+ result_obj.insert(std::make_pair(kEvent, picojson::value(GestureEventToStr(event, gesture))));
+ result_obj.insert(std::make_pair(kTimestamp, picojson::value(timestamp)));
+ result_obj.insert(std::make_pair(kType, picojson::value(gesture_str)));
+
+ if (GESTURE_TILT == gesture) {
+ FillTiltData(data, &result_obj);
+ }
+
+ ReportSuccess(result, obj);
+ }
+
+ if (!m_callback) {
+ LoggerE("Callback is not defined");
+ } else {
+ m_callback(&response);
+ }
+}
+
+PlatformResult GestureManager::AddListener(gesture_type_e type, gesture_option_e option,
+ RecognitionMap& gesture_map,
+ gesture_recognition_cb callback) {
+ ScopeLogger();
+
+ gesture_h handle = nullptr;
+
+ int ret = gesture_create(&handle);
+ if (GESTURE_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ getErrorCode(ret), "Creating handle failed",
+ ("Creating handle failed, error: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = gesture_start_recognition(handle, type, option, callback, this);
+ if (GESTURE_ERROR_NONE != ret) {
+ gesture_release(handle);
+ return LogAndCreateResult(
+ getErrorCode(ret), "Starting recognition failed",
+ ("Starting recognition failed, error: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ gesture_map[type] = handle;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult GestureManager::AddGestureRecognitionListener(const std::string& type,
+ bool always_on, JsonCallback cb) {
+ ScopeLogger();
+
+ gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+ PlatformResult result = StrToGestureType(type, &type_e);
+ if (!result) {
+ return result;
+ }
+
+ gesture_option_e option = GESTURE_OPTION_DEFAULT;
+ gesture_recognition_cb callback = GestureRecognitionDefaultCb;
+ RecognitionMap* gesture_map = &m_recognition_default_map;
+
+ if (!m_callback) {
+ m_callback = cb;
+ }
+
+ if (always_on) {
+ option = GESTURE_OPTION_ALWAYS_ON;
+ callback = GestureRecognitionAlwaysOnCb;
+ gesture_map = &m_recognition_always_on_map;
+ }
+
+ return AddListener(type_e, option, *gesture_map, callback);
+}
+
+PlatformResult GestureManager::RemoveGestureRecognitionListener(const std::string& type,
+ bool always_on) {
+ ScopeLogger();
+
+ auto& recognition_map = always_on ? m_recognition_always_on_map : m_recognition_default_map;
+ gesture_type_e type_e = GESTURE_DOUBLE_TAP;
+ PlatformResult result = StrToGestureType(type, &type_e);
+ if (!result) {
+ LoggerD("Unknown gesture type.");
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ gesture_h handle = nullptr;
+ RecognitionMap::iterator it = recognition_map.find(type_e);
+
+ if (recognition_map.end() != it) {
+ handle = it->second;
+ }
+
+ if (handle) {
+ int ret = gesture_stop_recognition(handle);
+ if (GESTURE_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ getErrorCode(ret), "Stoping recognition failed",
+ ("Stoping recognition failed, error: %d (%s)", ret, get_error_message(ret)));
+ }
+
+ ret = gesture_release(handle);
+ if (GESTURE_ERROR_NONE != ret) {
+ LoggerE("gesture_release() failed");
+ }
+
+ recognition_map.erase(it);
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // namespace humanactivitymonitor
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2017 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 HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
+#define HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
+
+#include <gesture_recognition.h>
+#include <functional>
+#include <string>
+
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+namespace extension {
+namespace humanactivitymonitor {
+
+using JsonCallback = std::function<void(picojson::value*)>;
+
+typedef std::map<gesture_type_e, gesture_h> RecognitionMap;
+
+class GestureManager {
+ public:
+ GestureManager();
+ virtual ~GestureManager();
+
+ common::PlatformResult IsSupported(const std::string& types, bool* is_supported);
+ common::PlatformResult AddGestureRecognitionListener(const std::string& type, bool always_on,
+ JsonCallback cb);
+ common::PlatformResult RemoveGestureRecognitionListener(const std::string& type, bool always_on);
+ void CompleteGestureListenerCb(gesture_type_e gesture, const gesture_data_h data,
+ double timestamp, gesture_error_e error, bool always_on);
+
+ private:
+ gesture_event_e GetGestureEvent(const gesture_data_h data);
+ void FillTiltData(const gesture_data_h data, picojson::object* obj);
+ common::PlatformResult AddListener(gesture_type_e type, gesture_option_e option,
+ RecognitionMap& gesture_map, gesture_recognition_cb callback);
+
+ JsonCallback m_callback;
+ RecognitionMap m_recognition_default_map;
+ RecognitionMap m_recognition_always_on_map;
+};
+
+} // namespace humanactivitymonitor
+} // namespace extension
+
+#endif // HUMANACTIVITYMONITOR_GESTURE_MANAGER_H
'humanactivitymonitor_instance.h',
'humanactivitymonitor_manager.cc',
'humanactivitymonitor_manager.h',
+ 'gesture_manager.cc',
+ 'gesture_manager.h',
],
'conditions': [
['tizen == 1', {
AWAKE: 'AWAKE'
};
+var GestureType = {
+ GESTURE_DOUBLE_TAP : 'GESTURE_DOUBLE_TAP',
+ GESTURE_MOVE_TO_EAR : 'GESTURE_MOVE_TO_EAR',
+ GESTURE_NO_MOVE : 'GESTURE_NO_MOVE',
+ GESTURE_PICK_UP : 'GESTURE_PICK_UP',
+ GESTURE_SHAKE : 'GESTURE_SHAKE',
+ GESTURE_SNAP : 'GESTURE_SNAP',
+ GESTURE_TILT : 'GESTURE_TILT',
+ GESTURE_TURN_FACE_DOWN : 'GESTURE_TURN_FACE_DOWN',
+ GESTURE_WRIST_UP : 'GESTURE_WRIST_UP',
+};
+
function convertActivityData(type, data) {
switch (type) {
case HumanActivityType.PEDOMETER:
}
};
+HumanActivityMonitorManager.prototype.isGestureSupported = function() {
+ var args = validator_.validateMethod(arguments, [{
+ name : 'type',
+ type: types_.ENUM,
+ values: Object.keys(GestureType)
+ }
+ ]);
+
+ var callArgs = {};
+ callArgs.type = args.type;
+
+ var result = native_.callSync('GestureManager_isGestureSupported', callArgs);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ return native_.getResultObject(result);
+};
+
+function GestureListenerManager(native, listenerName) {
+ this.listeners = {};
+ //below maps keep information about number of registered listeners for the specific type
+ //there are two maps as one keeps information about listeners which should be always called
+ //and one keeps information about number of the listeners which should be called only
+ //if power-saving mode is off
+ this.typeCountMapDefault = {};
+ this.typeCountMapAlwaysOn = {};
+ this.nextId = 1;
+ this.nativeSet = false;
+ this.native = native;
+ this.listenerName = listenerName;
+ for (var type in GestureType) {
+ this.typeCountMapDefault[type] = this.typeCountMapAlwaysOn[type] = 0;
+ }
+};
+
+GestureListenerManager.prototype.onListenerCalled = function(msg) {
+ var d = undefined;
+ var result = undefined;
+ var alwaysOn = msg.alwaysOn;
+ switch (msg.action) {
+ case 'ondetect':
+ d = new GestureData(this.native.getResultObject(msg));
+ break;
+ case 'onerror':
+ d = this.native.getErrorObject(msg);
+ break;
+ default:
+ utils_.log('Unknown mode: ' + msg.action);
+ return;
+ }
+
+ for (var watchId in this.listeners) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ var listener = this.listeners[watchId];
+ var call = alwaysOn ? listener.alwaysOn : true;
+ if (call && listener[msg.action]) {
+ listener[msg.action](d);
+ }
+ }
+ }
+};
+
+GestureListenerManager.prototype.addListener = function(successCb, errorCb, type, alwaysOn) {
+ var listener = {
+ 'type' : type,
+ 'alwaysOn' : alwaysOn,
+ 'ondetect' : successCb,
+ 'onerror' : errorCb
+ };
+
+ var typeCountMap = alwaysOn ? this.typeCountMapAlwaysOn : this.typeCountMapDefault;
+ if (typeCountMap[type] === 0) {
+ var result = this.native.callSync('GestureManager_addGestureRecognitionListener', listener);
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+ }
+
+ typeCountMap[type]++;
+ var id = this.nextId++;
+ this.listeners[id] = listener;
+
+ if (!this.nativeSet) {
+ this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
+ this.nativeSet = true;
+ }
+
+ return id;
+};
+
+GestureListenerManager.prototype.removeListener = function(watchId) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ var listener = this.listeners[watchId];
+ var typeCountMap = listener.alwaysOn ? this.typeCountMapAlwaysOn : this.typeCountMapDefault;
+
+ if (typeCountMap[listener.type] === 1) {
+ var result = this.native.callSync('GestureManager_removeGestureRecognitionListener', listener);
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+ }
+
+ delete this.listeners[watchId];
+ typeCountMap[listener.type]--;
+ }
+
+ if (this.nativeSet && type_.isEmptyObject(this.listeners)) {
+ this.native.removeListener(this.listenerName);
+ this.nativeSet = false;
+ }
+};
+
+var GESTURE_RECOGNITION_LISTENER = 'GestureRecognitionListener';
+var gestureRecognitionListener = new GestureListenerManager(native_, GESTURE_RECOGNITION_LISTENER);
+
+HumanActivityMonitorManager.prototype.addGestureRecognitionListener = function() {
+ var args = validator_.validateMethod(arguments, [{
+ name : 'type',
+ type: types_.ENUM,
+ values: Object.keys(GestureType)
+ },
+ {
+ name : 'eventCallback',
+ type : types_.FUNCTION
+ },
+ {
+ name : 'errorCallback',
+ type : types_.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name : 'alwaysOn',
+ type : types_.BOOLEAN,
+ optional : true,
+ nullable : true
+ }]);
+
+ return gestureRecognitionListener.addListener(args.eventCallback, args.errorCallback, args.type, args.alwaysOn);
+};
+
+HumanActivityMonitorManager.prototype.removeGestureRecognitionListener = function() {
+ var args = validator_.validateMethod(arguments, [{
+ name : 'watchId',
+ type : types_.LONG,
+ }]);
+
+ gestureRecognitionListener.removeListener(args.watchId);
+};
+
function StepDifference(data) {
SetReadOnlyProperty(this, 'stepCountDifference', data.stepCountDifference);
SetReadOnlyProperty(this, 'timestamp', data.timestamp);
SetReadOnlyProperty(this, 'average', data.average);
}
+function GestureData(data) {
+ if (data) {
+ SetReadOnlyProperty(this, 'type', data.type);
+ SetReadOnlyProperty(this, 'event', data.event);
+ SetReadOnlyProperty(this, 'timestamp', data.timestamp);
+
+ if (data.type === 'GESTURE_TILT') {
+ SetReadOnlyProperty(this, 'x', data.x);
+ SetReadOnlyProperty(this, 'y', data.y);
+ } else {
+ SetReadOnlyProperty(this, 'x', null);
+ SetReadOnlyProperty(this, 'y', null);
+ }
+ }
+}
+
HumanActivityRecorderPressureData.prototype = new HumanActivityRecorderData();
HumanActivityRecorderPressureData.prototype.constructor = HumanActivityRecorderPressureData;
using common::ErrorCode;
using common::TaskQueue;
-HumanActivityMonitorInstance::HumanActivityMonitorInstance() {
+HumanActivityMonitorInstance::HumanActivityMonitorInstance() : gesture_manager_() {
LoggerD("Enter");
using std::placeholders::_1;
using std::placeholders::_2;
HumanActivityMonitorManagerStopRecorder);
REGISTER_SYNC("HumanActivityMonitorManager_readRecorderData",
HumanActivityMonitorManagerReadRecorderData);
+ REGISTER_SYNC("GestureManager_isGestureSupported", GestureManagerIsGestureSupported);
+ REGISTER_SYNC("GestureManager_addGestureRecognitionListener",
+ GestureManagerAddGestureRecognitionListener);
+ REGISTER_SYNC("GestureManager_removeGestureRecognitionListener",
+ GestureManagerRemoveGestureRecognitionListener);
#undef REGISTER_SYNC
}
ReportSuccess(out);
}
+void HumanActivityMonitorInstance::GestureManagerIsGestureSupported(const picojson::value& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+
+ CHECK_EXIST(args, "type", out)
+ const auto& type = args.get("type").get<std::string>();
+ bool is_supported = false;
+
+ PlatformResult result = gesture_manager_.IsSupported(type, &is_supported);
+ if (result) {
+ ReportSuccess(picojson::value(is_supported), out);
+ } else {
+ LogAndReportError(result, &out, ("Failed: gesture_manager_->IsSupported()"));
+ }
+}
+
+void HumanActivityMonitorInstance::GestureManagerAddGestureRecognitionListener(
+ const picojson::value& args, picojson::object& out) {
+ LoggerD("Enter");
+
+ CHECK_EXIST(args, "type", out)
+ CHECK_EXIST(args, "alwaysOn", out)
+ const auto& type = args.get("type").get<std::string>();
+ bool always_on = args.get("alwaysOn").get<bool>();
+
+ auto cb = [this](picojson::value* data) -> void {
+ if (!data) {
+ LoggerE("No data passed to json callback");
+ return;
+ }
+
+ Instance::PostMessage(this, data->serialize().c_str());
+ };
+
+ PlatformResult result = gesture_manager_.AddGestureRecognitionListener(type, always_on, cb);
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out, ("Failed: gesture_manager_->AddGestureRecognitionListener()"));
+ }
+}
+
+void HumanActivityMonitorInstance::GestureManagerRemoveGestureRecognitionListener(
+ const picojson::value& args, picojson::object& out) {
+ LoggerD("Enter");
+
+ CHECK_EXIST(args, "type", out)
+ CHECK_EXIST(args, "alwaysOn", out)
+ const auto& type = args.get("type").get<std::string>();
+ bool always_on = args.get("alwaysOn").get<bool>();
+
+ PlatformResult result = gesture_manager_.RemoveGestureRecognitionListener(type, always_on);
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out,
+ ("Failed: gesture_manager_->RemoveGestureRecognitionListener()"));
+ }
+}
+
#undef CHECK_EXIST
} // namespace humanactivitymonitor
#include "common/extension.h"
#include "common/platform_result.h"
+#include "humanactivitymonitor/gesture_manager.h"
#include "humanactivitymonitor/humanactivitymonitor_manager.h"
namespace extension {
void HumanActivityMonitorManagerStopRecorder(const picojson::value& args, picojson::object& out);
void HumanActivityMonitorManagerReadRecorderData(const picojson::value& args,
picojson::object& out);
+ void GestureManagerIsGestureSupported(const picojson::value& args, picojson::object& out);
+ void GestureManagerAddGestureRecognitionListener(const picojson::value& args,
+ picojson::object& out);
+ void GestureManagerRemoveGestureRecognitionListener(const picojson::value& args,
+ picojson::object& out);
std::shared_ptr<HumanActivityMonitorManager> manager_;
+ GestureManager gesture_manager_;
common::PlatformResult Init();
};
'packages': [
'capi-system-info',
'capi-network-nfc',
- 'capi-appfw-application'
+ 'capi-appfw-app-control',
]
},
}],
m_is_ndef_listener_set(false),
m_se_handle(nullptr),
m_is_hce_listener_set(false),
+ m_is_preferred_app_set(false),
responder_(nullptr) {
LoggerD("Entered");
// NFC library initialization
if (m_is_hce_listener_set) {
nfc_manager_unset_hce_event_cb();
}
+ if (m_is_preferred_app_set) {
+ nfc_se_unset_preferred_handler();
+ }
// NFC library deinitialization
int ret = nfc_manager_deinitialize();
success_cb(aids);
}
+PlatformResult NFCAdapter::SetPreferredApp() {
+ LoggerD("Entered");
+
+ if (m_is_preferred_app_set) {
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ int ret = nfc_se_set_preferred_handler();
+ if (ret != NFC_ERROR_NONE) {
+ LoggerE("SetPreferredApp failed: %d", ret);
+ return NFCUtil::CodeToResult(ret, NFCUtil::getNFCErrorMessage(ret).c_str(), true);
+ }
+ m_is_preferred_app_set = true;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult NFCAdapter::UnsetPreferredApp() {
+ LoggerD("Entered");
+
+ if (!m_is_preferred_app_set) {
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ int ret = nfc_se_unset_preferred_handler();
+ if (ret != NFC_ERROR_NONE) {
+ LoggerE("SetPreferredApp failed: %d", ret);
+ return NFCUtil::CodeToResult(ret, NFCUtil::getNFCErrorMessage(ret).c_str(), true);
+ }
+
+ m_is_preferred_app_set = false;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // nfc
} // extension
void GetAIDsForCategory(const std::string& type, nfc_card_emulation_category_type_e category,
const std::function<void(const AIDDataVector&)>& success_cb,
const std::function<void(const common::PlatformResult&)>& error_cb);
+ common::PlatformResult SetPreferredApp();
+ common::PlatformResult UnsetPreferredApp();
private:
NFCAdapter();
bool m_is_ndef_listener_set;
nfc_se_h m_se_handle;
bool m_is_hce_listener_set;
+ bool m_is_preferred_app_set;
IResponder* responder_;
};
var transactionEventListenerEse = new ListenerManager(native_, TRANSACTION_EVENT_ESE_LISTENER);
var transactionEventListenerUicc = new ListenerManager(native_, TRANSACTION_EVENT_UICC_LISTENER);
var HCEEventListener = new ListenerManager(native_, HCE_EVENT_LISTENER);
-
+var isWebkitVisibilityChangeListenerSet = false;
//////////////////NFCManager /////////////////
}
};
+function WebkitVisibilityChangeListener() {
+ var result;
+ if (true === privUtils_.global.document.hidden) {
+ result = native_.call('NFCAdapter_unsetPreferredApp');
+ } else if (false === privUtils_.global.document.hidden) {
+ result = native_.call('NFCAdapter_setPreferredApp');
+ }
+
+ if (native_.isFailure(result)) {
+ privUtils_.log('Failed to (un)set: ' + result.error.message);
+ }
+}
+
+NFCAdapter.prototype.setPreferredApp = function() {
+ var result = native_.call('NFCAdapter_setPreferredApp');
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ } else {
+ if (false === isWebkitVisibilityChangeListenerSet) {
+ privUtils_.global.document.addEventListener("webkitvisibilitychange", WebkitVisibilityChangeListener);
+ isWebkitVisibilityChangeListenerSet = true;
+ }
+ }
+};
+
+NFCAdapter.prototype.unsetPreferredApp = function() {
+ var result = native_.call('NFCAdapter_unsetPreferredApp');
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ } else {
+ if (true === isWebkitVisibilityChangeListenerSet) {
+ privUtils_.global.document.removeEventListener("webkitvisibilitychange", WebkitVisibilityChangeListener);
+ isWebkitVisibilityChangeListenerSet = false;
+ }
+ }
+};
+
function InternalRecordData(tnf, type, payload, id) {
this.tnf = tnf;
this.type = type;
REGISTER_SYNC("NFCAdapter_registerAID", RegisterAID);
REGISTER_SYNC("NFCAdapter_unregisterAID", UnregisterAID);
REGISTER_ASYNC("NFCAdapter_getAIDsForCategory", GetAIDsForCategory);
+ REGISTER_SYNC("NFCAdapter_setPreferredApp", SetPreferredApp);
+ REGISTER_SYNC("NFCAdapter_unsetPreferredApp", UnsetPreferredApp);
REGISTER_SYNC("NFCPeer_setReceiveNDEFListener", SetReceiveNDEFListener);
REGISTER_SYNC("NFCPeer_unsetReceiveNDEFListener", UnsetReceiveNDEFListener);
required_category, success_cb, error_cb));
}
+void NFCInstance::SetPreferredApp(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeNfcCardEmulation, &out);
+
+ PlatformResult result = NFCAdapter::GetInstance()->SetPreferredApp();
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void NFCInstance::UnsetPreferredApp(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeNfcCardEmulation, &out);
+
+ PlatformResult result = NFCAdapter::GetInstance()->UnsetPreferredApp();
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
} // namespace nfc
} // namespace extension
void RegisterAID(const picojson::value& args, picojson::object& out);
void UnregisterAID(const picojson::value& args, picojson::object& out);
void GetAIDsForCategory(const picojson::value& args, picojson::object& out);
+ void SetPreferredApp(const picojson::value& args, picojson::object& out);
+ void UnsetPreferredApp(const picojson::value& args, picojson::object& out);
};
} // namespace nfc
return vec;
}
-PlatformResult NFCUtil::CodeToResult(const int errorCode, const std::string& message) {
+PlatformResult NFCUtil::CodeToResult(const int errorCode, const std::string& message,
+ const bool newAPIVersion) {
LoggerD("Entered");
switch (errorCode) {
case NFC_ERROR_INVALID_PARAMETER:
case NFC_ERROR_OUT_OF_MEMORY:
case NFC_ERROR_NOT_INITIALIZED:
default:
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, message);
+ if (newAPIVersion) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, message);
+ } else {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, message);
+ }
}
}
class NFCUtil {
public:
static UCharVector ToVector(const unsigned char* ch, const int size);
- static common::PlatformResult CodeToResult(const int errorCode, const std::string& message);
+ static common::PlatformResult CodeToResult(const int errorCode, const std::string& message,
+ const bool newAPIVersion = false);
static std::string getNFCErrorString(const int error_code);
static const std::string getNFCErrorMessage(const int error_code);
static std::string ToStringNFCTag(const nfc_tag_type_e tag_type);
--- /dev/null
+/*
+ * Copyright (c) 2015-2017 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 "notification/common_notification.h"
+
+#include <app_control_internal.h>
+#include <notification_internal.h>
+
+#include "common/converter.h"
+#include "common/filesystem/filesystem_provider.h"
+#include "common/logger.h"
+#include "common/scope_exit.h"
+
+namespace extension {
+namespace notification {
+
+using namespace common;
+
+const InformationEnumMap CommonNotification::info_map_ = {{0, NOTIFICATION_TEXT_TYPE_INFO_1},
+ {1, NOTIFICATION_TEXT_TYPE_INFO_2},
+ {2, NOTIFICATION_TEXT_TYPE_INFO_3}};
+
+const InformationEnumMap CommonNotification::info_sub_map_ = {
+ {0, NOTIFICATION_TEXT_TYPE_INFO_SUB_1},
+ {1, NOTIFICATION_TEXT_TYPE_INFO_SUB_2},
+ {2, NOTIFICATION_TEXT_TYPE_INFO_SUB_3}};
+
+const ImageEnumMap CommonNotification::thumbnails_map_ = {{0, NOTIFICATION_IMAGE_TYPE_LIST_1},
+ {1, NOTIFICATION_IMAGE_TYPE_LIST_2},
+ {2, NOTIFICATION_IMAGE_TYPE_LIST_3},
+ {3, NOTIFICATION_IMAGE_TYPE_LIST_4}};
+
+const InformationEnumMap CommonNotification::buttons_texts_map_ = {
+ {0, NOTIFICATION_TEXT_TYPE_BUTTON_1}, {1, NOTIFICATION_TEXT_TYPE_BUTTON_2},
+ {2, NOTIFICATION_TEXT_TYPE_BUTTON_3}, {3, NOTIFICATION_TEXT_TYPE_BUTTON_4},
+ {4, NOTIFICATION_TEXT_TYPE_BUTTON_5}, {5, NOTIFICATION_TEXT_TYPE_BUTTON_6}};
+
+const ImageEnumMap CommonNotification::buttons_icon_paths_map_ = {
+ {0, NOTIFICATION_IMAGE_TYPE_BUTTON_1}, {1, NOTIFICATION_IMAGE_TYPE_BUTTON_2},
+ {2, NOTIFICATION_IMAGE_TYPE_BUTTON_3}, {3, NOTIFICATION_IMAGE_TYPE_BUTTON_4},
+ {4, NOTIFICATION_IMAGE_TYPE_BUTTON_5}, {5, NOTIFICATION_IMAGE_TYPE_BUTTON_6}};
+
+CommonNotification::CommonNotification() {
+}
+
+CommonNotification::~CommonNotification() {
+}
+
+bool CommonNotification::IsColorFormatNumeric(const std::string& color) {
+ LoggerD("Enter");
+ std::string hexCode = "0123456789abcdef";
+ if (7 != color.length() || '#' != color[0]) {
+ return false;
+ }
+
+ for (size_t i = 1; i < color.length(); i++) {
+ if (hexCode.find(color[i]) == std::string::npos) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+PlatformResult CommonNotification::SetLayout(notification_h noti_handle,
+ const std::string& noti_type) {
+ LoggerD("Enter");
+ notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
+
+ if ("SIMPLE" == noti_type) {
+ long number;
+ PlatformResult status = GetNumber(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &number);
+ if (status.IsError()) {
+ LoggerE("Failed: GetNumber");
+ return status;
+ }
+ if (number > 0)
+ noti_layout = NOTIFICATION_LY_NOTI_EVENT_MULTIPLE;
+ else
+ noti_layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
+ } else if ("THUMBNAIL" == noti_type) {
+ noti_layout = NOTIFICATION_LY_NOTI_THUMBNAIL;
+ }
+ if ("ONGOING" == noti_type) {
+ noti_layout = NOTIFICATION_LY_ONGOING_EVENT;
+ } else if ("PROGRESS" == noti_type) {
+ noti_layout = NOTIFICATION_LY_ONGOING_PROGRESS;
+ }
+ int ret = notification_set_layout(noti_handle, noti_layout);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification layout error",
+ ("Set notification layout error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+static bool ServiceExtraDataCb(app_control_h service, const char* key, void* user_data) {
+ LoggerD("Enter");
+ if (nullptr == user_data || nullptr == key) {
+ LoggerE("User data or key not exist");
+ return true;
+ }
+
+ picojson::array* control_data = static_cast<picojson::array*>(user_data);
+
+ int length = 0;
+ char** value = nullptr;
+ SCOPE_EXIT {
+ free(value);
+ };
+
+ int ret = app_control_get_extra_data_array(service, key, &value, &length);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get app control extra data error: %d", ret);
+ return true;
+ }
+
+ if (!value || !length) {
+ LoggerE("Get app control extra data value error");
+ return true;
+ }
+
+ picojson::array values = picojson::array();
+ for (int index = 0; index < length; ++index) {
+ values.push_back(picojson::value(value[index]));
+ }
+
+ picojson::object data_control_elem = picojson::object();
+ data_control_elem["key"] = picojson::value(key);
+ data_control_elem["value"] = picojson::value(values);
+
+ control_data->push_back(picojson::value(data_control_elem));
+
+ return true;
+}
+
+PlatformResult CommonNotification::Create(notification_type_e noti_type,
+ notification_h* noti_handle) {
+ LoggerD("Enter");
+ *noti_handle = notification_create(noti_type);
+ if (!*noti_handle) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot make new notification object");
+ }
+
+ if (NOTIFICATION_TYPE_ONGOING == noti_type) {
+ int ret =
+ notification_set_display_applist(*noti_handle, NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY |
+ NOTIFICATION_DISPLAY_APP_INDICATOR);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot set notification display applist",
+ ("Cannot make new notification object: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::StatusTypeFromPlatform(notification_type_e noti_type,
+ notification_ly_type_e noti_layout,
+ std::string* type) {
+ LoggerD("Enter");
+ if (NOTIFICATION_TYPE_NOTI == noti_type) {
+ if (NOTIFICATION_LY_NOTI_EVENT_SINGLE == noti_layout ||
+ NOTIFICATION_LY_NOTI_EVENT_MULTIPLE == noti_layout) {
+ *type = "SIMPLE";
+ } else if (NOTIFICATION_LY_NOTI_THUMBNAIL == noti_layout) {
+ *type = "THUMBNAIL";
+ }
+ } else if (NOTIFICATION_TYPE_ONGOING == noti_type) {
+ if (NOTIFICATION_LY_ONGOING_EVENT == noti_layout) {
+ *type = "ONGOING";
+ } else if (NOTIFICATION_LY_ONGOING_PROGRESS == noti_layout) {
+ *type = "PROGRESS";
+ }
+ } else {
+ return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Notification type not found");
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::StatusTypeToPlatform(const std::string& type,
+ notification_type_e* noti_type) {
+ LoggerD("Enter");
+ if ("SIMPLE" == type || "THUMBNAIL" == type) {
+ *noti_type = NOTIFICATION_TYPE_NOTI;
+ } else if ("ONGOING" == type || "PROGRESS" == type) {
+ *noti_type = NOTIFICATION_TYPE_ONGOING;
+ } else {
+ return LogAndCreateResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalide notification type",
+ ("Invalide noti type: %s", type.c_str()));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetImage(notification_h noti_handle,
+ notification_image_type_e image_type,
+ std::string* image_path) {
+ LoggerD("Enter");
+ char* path = nullptr;
+
+ *image_path = "";
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_image(noti_handle, image_type, &path)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification image error",
+ ("Get notification image error, image_type: %d", image_type));
+ }
+ if (path) {
+ *image_path = path;
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetImage(notification_h noti_handle,
+ notification_image_type_e image_type,
+ const std::string& image_path) {
+ LoggerD("Enter");
+ int ret = notification_set_image(noti_handle, image_type, image_path.c_str());
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::UNKNOWN_ERR, "Set notification image error",
+ ("Set notification image error, image_type: %d, error: %d", image_type, ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetText(notification_h noti_handle,
+ notification_text_type_e text_type,
+ std::string* noti_text) {
+ LoggerD("Enter");
+ char* text = nullptr;
+
+ *noti_text = "";
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_text(noti_handle, text_type, &text)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification text error",
+ ("Get notification text error, text_type: %d", text_type));
+ }
+
+ if (text) *noti_text = text;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetText(notification_h noti_handle,
+ notification_text_type_e text_type,
+ const std::string& noti_text) {
+ LoggerD("Enter");
+ int ret = notification_set_text(noti_handle, text_type, noti_text.c_str(), nullptr,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(
+ ErrorCode::UNKNOWN_ERR, "Set notification text error",
+ ("Set notification text error, text_type: %d, error: %d", text_type, ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetNumber(notification_h noti_handle,
+ notification_text_type_e text_type, long* number) {
+ LoggerD("Enter");
+ std::string text;
+ PlatformResult status = GetText(noti_handle, text_type, &text);
+ CHECK_ERROR(status);
+
+ if (text.length())
+ *number = std::stol(text);
+ else
+ *number = -1;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetLedColor(notification_h noti_handle, std::string* led_color) {
+ LoggerD("Enter");
+ unsigned int color = 0;
+ notification_led_op_e type = NOTIFICATION_LED_OP_ON;
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_led(noti_handle, &type, (int*)&color)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
+ "Get notification led displaying option error");
+ }
+
+ *led_color = "";
+ std::stringstream stream;
+
+ if (NOTIFICATION_LED_OP_OFF != type) {
+ color = 0x00FFFFFF & color;
+ stream << std::hex << color;
+ *led_color = "#" + stream.str();
+
+ while (led_color->length() < 7) {
+ led_color->insert(1, "0");
+ }
+
+ std::transform(led_color->begin(), led_color->end(), led_color->begin(), ::tolower);
+ }
+
+ LoggerD("color:%s", (*led_color).c_str());
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetLedPeriod(notification_h noti_handle,
+ unsigned long* on_period,
+ unsigned long* off_period) {
+ LoggerD("Enter");
+ int on_time = 0;
+ int off_time = 0;
+
+ if (NOTIFICATION_ERROR_NONE !=
+ notification_get_led_time_period(noti_handle, &on_time, &off_time)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification led on/off period error");
+ }
+
+ if (on_period) *on_period = on_time;
+ if (off_period) *off_period = off_time;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetSoundPath(notification_h noti_handle,
+ std::string* sound_path) {
+ LoggerD("Enter");
+ *sound_path = "";
+
+ const char* path = nullptr;
+ notification_sound_type_e type = NOTIFICATION_SOUND_TYPE_NONE;
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_sound(noti_handle, &type, &path)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification sound error");
+ }
+
+ LoggerD("Sound type = %d", type);
+
+ if (path && (NOTIFICATION_SOUND_TYPE_USER_DATA == type)) {
+ *sound_path = path;
+ }
+
+ LoggerD("Sound path = %s", sound_path->c_str());
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetSoundPath(notification_h noti_handle,
+ const std::string& sound_path) {
+ LoggerD("Enter");
+ int ret =
+ notification_set_sound(noti_handle, NOTIFICATION_SOUND_TYPE_USER_DATA, sound_path.c_str());
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification sound error",
+ ("Set notification sound error: %d", ret));
+ }
+
+ LoggerD("Sound path = %s", sound_path.c_str());
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetVibration(notification_h noti_handle, bool* vibration) {
+ LoggerD("Enter");
+ notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_vibration(noti_handle, &vib_type, nullptr)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification vibration error");
+ }
+
+ if (NOTIFICATION_VIBRATION_TYPE_DEFAULT == vib_type ||
+ NOTIFICATION_VIBRATION_TYPE_USER_DATA == vib_type) {
+ *vibration = true;
+ } else {
+ *vibration = false;
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetApplicationControl(app_control_h app_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ char* operation = nullptr;
+ char* uri = nullptr;
+ char* mime = nullptr;
+ char* category = nullptr;
+ SCOPE_EXIT {
+ free(operation);
+ free(uri);
+ free(mime);
+ free(category);
+ };
+
+ int ret = app_control_get_operation(app_handle, &operation);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control operation error",
+ ("Get application control operation error: %d", ret));
+ }
+ if (operation) {
+ out["operation"] = picojson::value(operation);
+ LoggerD("operation = %s", operation);
+ }
+
+ if (APP_CONTROL_ERROR_NONE != app_control_get_uri(app_handle, &uri)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control uri error");
+ }
+ if (uri) {
+ out["uri"] = picojson::value(uri);
+ LoggerD("uri = %s", uri);
+ }
+
+ if (APP_CONTROL_ERROR_NONE != app_control_get_mime(app_handle, &mime)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control mime error");
+ }
+ if (mime) {
+ out["mime"] = picojson::value(mime);
+ LoggerD("mime = %s", mime);
+ }
+
+ if (APP_CONTROL_ERROR_NONE != app_control_get_category(app_handle, &category)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control category error");
+ }
+ if (category) {
+ out["category"] = picojson::value(category);
+ LoggerD("category = %s", category);
+ }
+
+ picojson::array app_control_data = picojson::array();
+ if (APP_CONTROL_ERROR_NONE !=
+ app_control_foreach_extra_data(app_handle, ServiceExtraDataCb, (void*)&app_control_data)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control data error");
+ }
+ out["data"] = picojson::value(app_control_data);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetApplicationControl(app_control_h app_handle,
+ const picojson::object& app_ctrl) {
+ LoggerD("Enter");
+ picojson::value val(app_ctrl);
+ const std::string& operation = FromJson<std::string>(app_ctrl, "operation");
+
+ int ret;
+ if (operation.length()) {
+ ret = app_control_set_operation(app_handle, operation.c_str());
+ } else {
+ ret = app_control_set_operation(app_handle, APP_CONTROL_OPERATION_DEFAULT);
+ }
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control operation error",
+ ("Set application control operation error: %d", ret));
+ }
+
+ if (val.contains("uri") && !IsNull(app_ctrl, "uri")) {
+ const std::string& uri = FromJson<std::string>(app_ctrl, "uri");
+ ret = app_control_set_uri(app_handle, uri.c_str());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control uri error",
+ ("Set application control uri error: %d", ret));
+ }
+ }
+
+ if (val.contains("mime") && !IsNull(app_ctrl, "mime")) {
+ const std::string& mime = FromJson<std::string>(app_ctrl, "mime");
+ ret = app_control_set_mime(app_handle, mime.c_str());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control mime error",
+ ("Set application control mime error: %d", ret));
+ }
+ }
+
+ if (val.contains("category") && !IsNull(app_ctrl, "category")) {
+ const std::string& category = FromJson<std::string>(app_ctrl, "category");
+ ret = app_control_set_category(app_handle, category.c_str());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control category error",
+ ("Set application control category error: %d", ret));
+ }
+ }
+
+ if (!picojson::value(app_ctrl).contains("data") || IsNull(app_ctrl, "data")) {
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ auto& items = FromJson<picojson::array>(app_ctrl, "data");
+
+ int idx = 0;
+
+ for (auto item : items) {
+ const picojson::object& obj = JsonCast<picojson::object>(item);
+ const std::string key = FromJson<std::string>(obj, "key");
+ const picojson::array values = FromJson<picojson::array>(obj, "value");
+ const char** arrayValue = (const char**)calloc(sizeof(char*), values.size());
+ SCOPE_EXIT {
+ free(arrayValue);
+ };
+ idx = 0;
+ for (auto& item : values) {
+ arrayValue[idx] = JsonCast<std::string>(item).c_str();
+ ++idx;
+ }
+ ret = app_control_add_extra_data_array(app_handle, key.c_str(), arrayValue, values.size());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control extra data error",
+ ("Set application control extra data error: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetApplicationId(app_control_h app_handle, std::string* app_id) {
+ LoggerD("Enter");
+ char* app_id_str = nullptr;
+ SCOPE_EXIT {
+ free(app_id_str);
+ };
+
+ *app_id = "";
+
+ if (APP_CONTROL_ERROR_NONE != app_control_get_app_id(app_handle, &app_id_str)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get applicaiton ID failed");
+ }
+
+ if (nullptr != app_id_str) {
+ *app_id = app_id_str;
+ }
+
+ LoggerD("Get appId = %s", /*(*app_id).c_str()*/ app_id_str);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetApplicationId(app_control_h app_handle,
+ const std::string& app_id) {
+ LoggerD("Enter");
+ int ret = app_control_set_app_id(app_handle, app_id.c_str());
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set applicaiton ID error",
+ ("Set applicaiton ID error: %d", ret));
+ }
+
+ LoggerD("Set appId = %s", app_id.c_str());
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetProgressValue(notification_h noti_handle,
+ const std::string& progress_type,
+ double* progress_value) {
+ LoggerD("Enter");
+ double tmp_progress_value = 0.0;
+
+ if (kProgressTypeByte == progress_type) {
+ if (NOTIFICATION_ERROR_NONE != notification_get_size(noti_handle, &tmp_progress_value)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification size error");
+ }
+ } else if (kProgressTypePercentage == progress_type) {
+ if (NOTIFICATION_ERROR_NONE != notification_get_progress(noti_handle, &tmp_progress_value)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification progress error");
+ }
+ // native api uses range 0-1, but webapi expects 0-100, so we need to multiply result with 100
+ tmp_progress_value *= 100;
+ } else {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown notification progress type",
+ ("Unknown notification progress type: %s ", progress_type.c_str()));
+ }
+
+ LoggerD("Progress %s = %lf", progress_type.c_str(), tmp_progress_value);
+
+ *progress_value = tmp_progress_value;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetProgressValue(notification_h noti_handle,
+ const std::string& progress_type,
+ double progress_value, bool is_update) {
+ LoggerD("Enter");
+ int ret;
+
+ if (kProgressTypeByte == progress_type) {
+ ret = notification_set_size(noti_handle, progress_value);
+
+ if (is_update) {
+ ret = notification_update_size(noti_handle, NOTIFICATION_PRIV_ID_NONE, progress_value);
+ }
+ } else if (kProgressTypePercentage == progress_type) {
+ // native api uses range 0-1, but webapi expects 0-100, so we need to divide by 100
+ ret = notification_set_progress(noti_handle, progress_value / 100);
+
+ if (is_update) {
+ ret = notification_update_progress(noti_handle, NOTIFICATION_PRIV_ID_NONE, progress_value);
+ }
+ } else {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown notification progress type",
+ ("Unknown notification progress type: %s ", progress_type.c_str()));
+ }
+
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification progress/size error",
+ ("Set notification progress/size error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetPostedTime(notification_h noti_handle, time_t* posted_time) {
+ LoggerD("Enter");
+ *posted_time = 0;
+
+ if (NOTIFICATION_ERROR_NONE != notification_get_insert_time(noti_handle, posted_time)) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification posted time error");
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetNotiHandle(int id, notification_h* noti_handle) {
+ LoggerD("Enter");
+ *noti_handle = notification_load(nullptr, id);
+ if (nullptr == *noti_handle) {
+ return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Not found or removed notification id");
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetAppControl(notification_h noti_handle,
+ app_control_h* app_control) {
+ LoggerD("Enter");
+ int ret = notification_get_launch_option(noti_handle, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL,
+ static_cast<void*>(app_control));
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification get launch option error",
+ ("Notification get launch option error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::CreateAppControl(app_control_h* app_control) {
+ LoggerD("Enter");
+ int ret = app_control_create(app_control);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Application create error",
+ ("Application create error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetAppControl(notification_h noti_handle,
+ app_control_h app_control) {
+ LoggerD("Enter");
+ int ret = notification_set_launch_option(noti_handle, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL,
+ static_cast<void*>(app_control));
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification set launch option error",
+ ("Notification set launch option error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::UpdateNotificationAfterPost(notification_h noti_handle, int id,
+ picojson::object* out_ptr) {
+ time_t posted_time;
+ PlatformResult status = GetPostedTime(noti_handle, &posted_time);
+ CHECK_ERROR(status);
+
+ picojson::object& out = *out_ptr;
+ out["postedTime"] = picojson::value(static_cast<double>(posted_time) * 1000.0);
+ out["id"] = picojson::value(std::to_string(id));
+ out["type"] = picojson::value("STATUS");
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::PostNotification(const picojson::object& args, bool is_update,
+ picojson::object* out_ptr,
+ GetHandleFromJsonFun getHandle) {
+ LoggerD("Enter");
+ notification_h noti_handle = nullptr;
+ int ret = NOTIFICATION_ERROR_NONE;
+ int id = NOTIFICATION_PRIV_ID_NONE;
+
+ SCOPE_EXIT {
+ notification_free(noti_handle);
+ };
+
+ const auto& noti_val_it = args.find("notification");
+ if (args.end() == noti_val_it) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot post notification");
+ }
+ PlatformResult status = getHandle(noti_val_it->second, is_update, ¬i_handle);
+ CHECK_ERROR(status);
+
+ if (is_update) {
+ ret = notification_update(noti_handle);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Update notification error",
+ ("Update notification error: %d", ret));
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+ } else {
+ ret = notification_insert(noti_handle, &id);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot insert notification",
+ ("Cannot insert notification: %d", ret));
+ }
+ }
+
+ return UpdateNotificationAfterPost(noti_handle, id, out_ptr);
+}
+
+PlatformResult CommonNotification::AddCommonMembersToJson(int id, notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ out["id"] = picojson::value(std::to_string(id));
+ out["type"] = picojson::value("STATUS");
+
+ time_t posted_time = 0;
+ PlatformResult ret = GetPostedTime(noti_handle, &posted_time);
+ CHECK_ERROR(ret);
+ out["postedTime"] = picojson::value(static_cast<double>(posted_time) * 1000.0);
+
+ std::string value_str;
+ ret = GetText(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE, &value_str);
+ CHECK_ERROR(ret);
+ out["title"] = picojson::value(value_str);
+
+ ret = GetText(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &value_str);
+ CHECK_ERROR(ret);
+ if (value_str.length()) {
+ out["content"] = picojson::value(value_str);
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddTypeToJson(notification_h noti_handle, const std::string& key,
+ picojson::object* out_ptr,
+ std::string* noti_type_str) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+ // Notification type
+ notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
+ int ret = notification_get_type(noti_handle, ¬i_type);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification get type error",
+ ("Notification get type error: %d", ret));
+ }
+
+ notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
+ ret = notification_get_layout(noti_handle, ¬i_layout);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification get layout error",
+ ("Notification get layout error: %d", ret));
+ }
+
+ PlatformResult status = StatusTypeFromPlatform(noti_type, noti_layout, noti_type_str);
+ CHECK_ERROR(status);
+ out[key] = picojson::value(*noti_type_str);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddProgressTypeAndValueToJson(notification_h noti_handle,
+ const std::string& noti_type_str,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::object& out = *out_ptr;
+ std::string progress_type;
+ // native code does not support progress_type value, we are using NOTIFICATION_IMAGE_TYPE_LIST_5
+ // to store this field on native level
+ PlatformResult status = GetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_LIST_5, &progress_type);
+ CHECK_ERROR(status)
+
+ // notification service daemon doesn't set progress type - NOTIFICATION_IMAGE_TYPE_LIST_5 is used
+ // as workaround, so use default if notification type is different from "PROGRESS"
+ if ("PROGRESS" != noti_type_str) {
+ progress_type = progress_type == kProgressTypeByte ? progress_type : kProgressTypePercentage;
+ }
+ out["progressType"] = picojson::value(progress_type);
+
+ double progress_value;
+ status = GetProgressValue(noti_handle, progress_type, &progress_value);
+ CHECK_ERROR(status);
+ out["progressValue"] = picojson::value(progress_value);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddEventsNumberToJson(notification_h noti_handle,
+ const std::string& key,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ long number = 0;
+ PlatformResult status = GetNumber(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &number);
+ CHECK_ERROR(status);
+ if (number >= 0) {
+ out[key] = picojson::value(static_cast<double>(number));
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddDetailInfosToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ picojson::value result_json = picojson::value(picojson::array());
+ picojson::array& detail_info_array = result_json.get<picojson::array>();
+
+ if (info_map_.size() != info_sub_map_.size()) {
+ return LogAndCreateResult(ErrorCode::VALIDATION_ERR,
+ "Different notification information types element size");
+ }
+
+ picojson::value detail_info = picojson::value(picojson::object());
+ picojson::object& detail_info_obj = detail_info.get<picojson::object>();
+
+ std::string text;
+ size_t info_map_size = info_map_.size();
+ for (size_t idx = 0; idx < info_map_size; ++idx) {
+ PlatformResult status = GetText(noti_handle, info_map_.at(idx), &text);
+ CHECK_ERROR(status);
+
+ if (text.length()) {
+ detail_info_obj["mainText"] = picojson::value(text);
+
+ status = AddTextToJson(noti_handle, info_sub_map_.at(idx), "subText", &detail_info_obj);
+ CHECK_ERROR(status);
+ detail_info_array.push_back(detail_info);
+ }
+ }
+ out["detailInfo"] = result_json;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddPathToJson(notification_h noti_handle,
+ notification_image_type_e type,
+ const std::string& key,
+ picojson::object* out_ptr) {
+ picojson::object& out = *out_ptr;
+
+ std::string value_str;
+ PlatformResult status = GetImage(noti_handle, type, &value_str);
+ CHECK_ERROR(status);
+ if (value_str.length()) {
+ out[key] = picojson::value(FilesystemProvider::Create().GetVirtualPath(value_str));
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddTextToJson(notification_h noti_handle,
+ notification_text_type_e type,
+ const std::string& key,
+ picojson::object* out_ptr) {
+ picojson::object& out = *out_ptr;
+
+ std::string value_str;
+ PlatformResult ret = GetText(noti_handle, type, &value_str);
+ CHECK_ERROR(ret);
+ if (value_str.length()) {
+ out[key] = picojson::value(value_str);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddLedOnOffPeriodToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ unsigned long on_period = 0;
+ unsigned long off_period = 0;
+ PlatformResult status = GetLedPeriod(noti_handle, &on_period, &off_period);
+ CHECK_ERROR(status);
+
+ out["ledOnPeriod"] = picojson::value(static_cast<double>(on_period));
+ out["ledOffPeriod"] = picojson::value(static_cast<double>(off_period));
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddPathsArrayToJson(notification_h noti_handle, ImageEnumMap map,
+ const std::string& key,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ picojson::value result_json = picojson::value(picojson::array());
+ picojson::array& result_array = result_json.get<picojson::array>();
+
+ std::string path;
+ size_t map_size = map.size();
+ for (size_t idx = 0; idx < map_size; ++idx) {
+ PlatformResult status = GetImage(noti_handle, map.at(idx), &path);
+ CHECK_ERROR(status);
+
+ if (path.length()) {
+ result_array.push_back(picojson::value(FilesystemProvider::Create().GetVirtualPath(path)));
+ }
+ }
+
+ out[key] = result_json;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddTextsArrayToJson(notification_h noti_handle,
+ InformationEnumMap map,
+ const std::string& key,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ picojson::value result_json = picojson::value(picojson::array());
+ picojson::array& result_array = result_json.get<picojson::array>();
+
+ std::string text;
+ size_t map_size = map.size();
+ for (size_t idx = 0; idx < map_size; ++idx) {
+ PlatformResult status = GetText(noti_handle, map.at(idx), &text);
+
+ CHECK_ERROR(status);
+ if (text.length()) {
+ result_array.push_back(picojson::value(text));
+ }
+ }
+
+ out[key] = result_json;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddLedColorToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ std::string color;
+ PlatformResult status = GetLedColor(noti_handle, &color);
+ CHECK_ERROR(status);
+ if (color.length()) {
+ out["ledColor"] = picojson::value(color);
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddSoundPathToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ std::string sound_path;
+ PlatformResult status = GetSoundPath(noti_handle, &sound_path);
+ CHECK_ERROR(status);
+ if (sound_path.length()) {
+ out["soundPath"] = picojson::value(FilesystemProvider::Create().GetVirtualPath(sound_path));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddVibrationToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ bool vibration;
+ PlatformResult status = GetVibration(noti_handle, &vibration);
+ CHECK_ERROR(status);
+ out["vibration"] = picojson::value(vibration);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::AddAppControlInfoToJson(notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ picojson::object& out = *out_ptr;
+
+ if (app_handle) {
+ picojson::object app_control = picojson::object();
+ PlatformResult status = GetApplicationControl(app_handle, &app_control);
+ CHECK_ERROR(status);
+ if (app_control.size()) {
+ out["appControl"] = picojson::value(app_control);
+ }
+
+ std::string app_id;
+ status = GetApplicationId(app_handle, &app_id);
+ CHECK_ERROR(status);
+ if (app_id.length()) {
+ out["appId"] = picojson::value(app_id);
+ }
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::InitNotiFromJson(const picojson::object& noti_obj,
+ const std::string& type_key, bool is_update,
+ notification_h* noti_handle) {
+ LoggerD("Enter");
+ notification_h tmp_noti = nullptr;
+
+ const std::string& status_type = FromJson<std::string>(noti_obj, type_key.c_str());
+
+ notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
+ PlatformResult status = StatusTypeToPlatform(status_type, ¬i_type);
+ CHECK_ERROR(status);
+
+ if (is_update) {
+ int id = std::stoi(FromJson<std::string>(noti_obj, "id"));
+
+ status = GetNotiHandle(id, &tmp_noti);
+ CHECK_ERROR(status);
+ } else {
+ status = Create(noti_type, &tmp_noti);
+ CHECK_ERROR(status);
+ }
+ std::unique_ptr<std::remove_pointer<notification_h>::type, int (*)(notification_h)> tmp_noti_ptr(
+ tmp_noti, ¬ification_free); // automatically release the memory
+
+ status = SetLayout(tmp_noti, status_type);
+ CHECK_ERROR(status);
+
+ *noti_handle = tmp_noti_ptr.release();
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetCommonMembersFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ PlatformResult status =
+ SetText(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE, FromJson<std::string>(noti_obj, "title"));
+ CHECK_ERROR(status);
+
+ SetTextFromJson(noti_value, NOTIFICATION_TEXT_TYPE_CONTENT, "content", noti_handle);
+ CHECK_ERROR(status);
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetPathFromJson(const picojson::value& noti_value,
+ notification_image_type_e type,
+ const std::string& key,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ if (noti_value.contains(key) && !IsNull(noti_obj, key.c_str())) {
+ const std::string& value_str = FromJson<std::string>(noti_obj, key.c_str());
+ std::string real_path = FilesystemProvider::Create().GetRealPath(value_str);
+
+ PlatformResult status = SetImage(noti_handle, type, real_path);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetLedColorFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ if (noti_value.contains("ledColor") && !IsNull(noti_obj, "ledColor")) {
+ std::string color_str = FromJson<std::string>(noti_obj, "ledColor");
+ std::transform(color_str.begin(), color_str.end(), color_str.begin(), ::tolower);
+
+ if (!IsColorFormatNumeric(color_str)) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Led color is not numeric value",
+ ("Led color is not numeric value: %s", color_str.c_str()));
+ }
+
+ std::stringstream stream;
+ unsigned int color = 0;
+ notification_led_op_e type = NOTIFICATION_LED_OP_ON;
+ std::string color_code = color_str.substr(1, color_str.length()).insert(0, "ff");
+
+ stream << std::hex << color_code;
+ stream >> color;
+
+ if (0 != color)
+ type = NOTIFICATION_LED_OP_ON_CUSTOM_COLOR;
+ else
+ type = NOTIFICATION_LED_OP_OFF;
+
+ int ret = notification_set_led(noti_handle, type, static_cast<int>(color));
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led color eror",
+ ("Set notification led color eror: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetLedOnPeriodFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ unsigned long on_period = static_cast<unsigned long>(FromJson<double>(noti_obj, "ledOnPeriod"));
+
+ unsigned long off_period = 0;
+ PlatformResult status = GetLedPeriod(noti_handle, nullptr, &off_period);
+ CHECK_ERROR(status);
+
+ int ret = notification_set_led_time_period(noti_handle, on_period, off_period);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led on period error",
+ ("Set notification led on period error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetLedOffPeriodFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ unsigned long off_period = static_cast<unsigned long>(FromJson<double>(noti_obj, "ledOffPeriod"));
+ unsigned long on_period = 0;
+ PlatformResult status = GetLedPeriod(noti_handle, &on_period, nullptr);
+ CHECK_ERROR(status);
+
+ int ret = notification_set_led_time_period(noti_handle, on_period, off_period);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led off period error",
+ ("Set notification led off period error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetProgressTypeAndValueFromJson(
+ const picojson::value& noti_value, bool is_update, notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ // progressType
+ // native code does not support progress_type value, we are using NOTIFICATION_IMAGE_TYPE_LIST_5
+ // to store this field on native level
+ const std::string& progress_type = FromJson<std::string>(noti_obj, "progressType");
+ PlatformResult status = SetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_LIST_5, progress_type);
+ CHECK_ERROR(status);
+
+ // progressValue
+ double progress_value = -1;
+ if (noti_value.contains("progressValue") && !IsNull(noti_obj, "progressValue")) {
+ progress_value = FromJson<double>(noti_obj, "progressValue");
+ }
+ status = SetProgressValue(noti_handle, progress_type, progress_value, is_update);
+ CHECK_ERROR(status);
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetAppControlInfoFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ app_control_h app_control = nullptr;
+ SCOPE_EXIT {
+ if (app_control) {
+ app_control_destroy(app_control);
+ }
+ };
+
+ PlatformResult status = CreateAppControl(&app_control);
+ CHECK_ERROR(status);
+
+ if (noti_value.contains("appControl") && !IsNull(noti_obj, "appControl")) {
+ status = SetApplicationControl(app_control, FromJson<picojson::object>(noti_obj, "appControl"));
+ CHECK_ERROR(status);
+ }
+
+ if (noti_value.contains("appId") && !IsNull(noti_obj, "appId")) {
+ status = SetApplicationId(app_control, FromJson<std::string>(noti_obj, "appId"));
+ CHECK_ERROR(status);
+ }
+
+ status = SetAppControl(noti_handle, app_control);
+ CHECK_ERROR(status);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetEventsNumberFromJson(const picojson::value& noti_value,
+ const std::string& key,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ if (noti_value.contains(key) && !IsNull(noti_obj, key.c_str())) {
+ long number = (long)FromJson<double>(noti_obj, key.c_str());
+ PlatformResult status =
+ SetText(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, std::to_string(number));
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetDetailInfosFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ if (noti_value.contains("detailInfo") && !IsNull(noti_obj, "detailInfo")) {
+ const picojson::array& array = FromJson<picojson::array>(noti_obj, "detailInfo");
+
+ if (array.size() > info_map_.size()) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
+ "Too many values in notification detailInfo array");
+ }
+ size_t idx = 0;
+
+ for (auto& item : array) {
+ const picojson::object& obj = JsonCast<picojson::object>(item);
+
+ PlatformResult status =
+ SetText(noti_handle, info_map_.at(idx), FromJson<std::string>(obj, "mainText"));
+ CHECK_ERROR(status);
+
+ SetTextFromJson(picojson::value(obj), info_sub_map_.at(idx), "subText", noti_handle);
+ CHECK_ERROR(status);
+ ++idx;
+ }
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetVibrationFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+ bool vibration = FromJson<bool>(noti_obj, "vibration");
+
+ bool platform_vibration;
+ PlatformResult status = GetVibration(noti_handle, &platform_vibration);
+ CHECK_ERROR(status);
+
+ if (platform_vibration != vibration) {
+ notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
+
+ if (vibration) {
+ vib_type = NOTIFICATION_VIBRATION_TYPE_DEFAULT;
+ }
+
+ int ret = notification_set_vibration(noti_handle, vib_type, nullptr);
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification vibration error",
+ ("Set notification vibration error: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetSoundPathFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ if (noti_value.contains("soundPath") && !IsNull(noti_obj, "soundPath")) {
+ const std::string& value_str = FromJson<std::string>(noti_obj, "soundPath");
+ std::string real_path = FilesystemProvider::Create().GetRealPath(value_str);
+
+ PlatformResult status = SetSoundPath(noti_handle, real_path);
+ CHECK_ERROR(status);
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetPathsArrayFromJson(const picojson::value& noti_value,
+ ImageEnumMap map, const std::string& key,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ if (noti_value.contains(key) && !IsNull(noti_obj, key.c_str())) {
+ const picojson::array& array = FromJson<picojson::array>(noti_obj, key.c_str());
+ if (array.size() > map.size()) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Too many values in array");
+ }
+ size_t idx = 0;
+ for (auto& item : array) {
+ const std::string& text = JsonCast<std::string>(item);
+ std::string real_path = FilesystemProvider::Create().GetRealPath(text);
+
+ PlatformResult status = SetImage(noti_handle, map.at(idx), real_path);
+ CHECK_ERROR(status);
+
+ ++idx;
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetTextsArrayFromJson(const picojson::value& noti_value,
+ InformationEnumMap map,
+ const std::string& key,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ if (noti_value.contains(key) && !IsNull(noti_obj, key.c_str())) {
+ const picojson::array& array = FromJson<picojson::array>(noti_obj, key.c_str());
+ if (array.size() > map.size()) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Too many values in array");
+ }
+
+ size_t idx = 0;
+ for (auto& item : array) {
+ const std::string& text = JsonCast<std::string>(item);
+ PlatformResult status = SetText(noti_handle, map.at(idx), text);
+ CHECK_ERROR(status);
+
+ ++idx;
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetTextFromJson(const picojson::value& noti_value,
+ notification_text_type_e type,
+ const std::string& key,
+ notification_h noti_handle) {
+ LoggerD("Entered");
+ const picojson::object& noti_obj = noti_value.get<picojson::object>();
+
+ if (noti_value.contains(key) && !IsNull(noti_obj, key.c_str())) {
+ PlatformResult status =
+ SetText(noti_handle, type, FromJson<std::string>(noti_obj, key.c_str()));
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // namespace notification
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2015-2017 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 NOTIFICATION_COMMON_NOTIFICATION_H_
+#define NOTIFICATION_COMMON_NOTIFICATION_H_
+
+#include <app_control.h>
+#include <notification.h>
+#include <functional>
+
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+#include "common/XW_Extension.h"
+
+namespace extension {
+namespace notification {
+
+#define CHECK_ERROR(ret) \
+ if (ret.IsError()) { \
+ return ret; \
+ }
+
+const std::string kProgressTypePercentage = "PERCENTAGE";
+const std::string kProgressTypeByte = "BYTE";
+
+typedef std::map<int, notification_text_type_e> InformationEnumMap;
+typedef std::map<int, notification_image_type_e> ImageEnumMap;
+
+XW_EXPORT typedef std::function<common::PlatformResult(const picojson::value& noti_val,
+ bool is_update, notification_h* noti_handle)>
+ GetHandleFromJsonFun;
+
+class CommonNotification {
+ public:
+ XW_EXPORT static common::PlatformResult GetAppControl(notification_h noti_handle,
+ app_control_h* app_control);
+ static common::PlatformResult GetNotiHandle(int id, notification_h* noti_handle);
+ XW_EXPORT static common::PlatformResult SetAppControl(notification_h noti_handle,
+ app_control_h app_control);
+
+ static const InformationEnumMap info_map_;
+ static const InformationEnumMap info_sub_map_;
+ static const ImageEnumMap thumbnails_map_;
+ static const InformationEnumMap buttons_texts_map_;
+ static const ImageEnumMap buttons_icon_paths_map_;
+
+ static common::PlatformResult StatusTypeFromPlatform(notification_type_e noti_type,
+ notification_ly_type_e noti_layout,
+ std::string* type);
+ static common::PlatformResult StatusTypeToPlatform(const std::string& type,
+ notification_type_e* noti_type);
+ static common::PlatformResult Create(notification_type_e noti_type, notification_h* noti_handle);
+ static common::PlatformResult GetImage(notification_h noti_handle,
+ notification_image_type_e image_type,
+ std::string* image_path);
+ static common::PlatformResult SetImage(notification_h noti_handle,
+ notification_image_type_e image_type,
+ const std::string& image_path);
+ static common::PlatformResult GetText(notification_h noti_handle,
+ notification_text_type_e text_type, std::string* noti_text);
+ static common::PlatformResult SetText(notification_h noti_handle,
+ notification_text_type_e text_type,
+ const std::string& noti_text);
+ static common::PlatformResult GetNumber(notification_h noti_handle,
+ notification_text_type_e text_type, long* number);
+ static common::PlatformResult GetLedColor(notification_h noti_handle, std::string* led_color);
+ static common::PlatformResult GetLedPeriod(notification_h noti_handle, unsigned long* on_period,
+ unsigned long* off_period);
+ static common::PlatformResult GetSoundPath(notification_h noti_handle, std::string* sound_path);
+ static common::PlatformResult SetSoundPath(notification_h noti_handle,
+ const std::string& sound_path);
+ static common::PlatformResult GetVibration(notification_h noti_handle, bool* vibration);
+ static common::PlatformResult GetApplicationControl(app_control_h app_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult SetApplicationControl(app_control_h app_handle,
+ const picojson::object& app_ctrl);
+ static common::PlatformResult GetApplicationId(app_control_h app_handle, std::string* app_id);
+ static common::PlatformResult SetApplicationId(app_control_h app_handle,
+ const std::string& app_id);
+ static common::PlatformResult GetProgressValue(notification_h noti_handle,
+ const std::string& progess_type,
+ double* progress_value);
+ static common::PlatformResult SetProgressValue(notification_h noti_handle,
+ const std::string& progress_type,
+ double progress_value, bool is_update);
+ static common::PlatformResult GetPostedTime(notification_h noti_handle, time_t* posted_time);
+ static common::PlatformResult SetLayout(notification_h noti_handle, const std::string& noti_type);
+ static common::PlatformResult CreateAppControl(app_control_h* app_control);
+
+ static bool IsColorFormatNumeric(const std::string& color);
+ static common::PlatformResult UpdateNotificationAfterPost(notification_h noti_handle, int id,
+ picojson::object* out_ptr);
+
+ // ToJson section
+ static common::PlatformResult AddCommonMembersToJson(int id, notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddTypeToJson(notification_h noti_handle, const std::string& key,
+ picojson::object* out_ptr,
+ std::string* noti_type_str);
+ static common::PlatformResult AddProgressTypeAndValueToJson(notification_h noti_handle,
+ const std::string& noti_type_str,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddEventsNumberToJson(notification_h noti_handle,
+ const std::string& key,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddDetailInfosToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddPathToJson(notification_h noti_handle,
+ notification_image_type_e type,
+ const std::string& key, picojson::object* out_ptr);
+ static common::PlatformResult AddTextToJson(notification_h noti_handle,
+ notification_text_type_e type, const std::string& key,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddIconPathToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddSubIconPathToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddBackgroundImagePathToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddLedOnOffPeriodToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddLedColorToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddSoundPathToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddVibrationToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddAppControlInfoToJson(notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddPathsArrayToJson(notification_h noti_handle, ImageEnumMap map,
+ const std::string& key,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddTextsArrayToJson(notification_h noti_handle,
+ InformationEnumMap map, const std::string& key,
+ picojson::object* out_ptr);
+
+ // FromJson section
+ static common::PlatformResult InitNotiFromJson(const picojson::object& args,
+ const std::string& type_key, bool is_update,
+ notification_h* noti_handle);
+ static common::PlatformResult SetCommonMembersFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+ static common::PlatformResult SetPathFromJson(const picojson::value& noti_value,
+ notification_image_type_e type,
+ const std::string& key, notification_h noti_handle);
+ static common::PlatformResult SetLedColorFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetLedOnPeriodFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetLedOffPeriodFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetProgressTypeAndValueFromJson(const picojson::value& noti_value,
+ bool is_update,
+ notification_h noti_handle);
+ static common::PlatformResult SetAppControlInfoFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetEventsNumberFromJson(const picojson::value& noti_value,
+ const std::string& key,
+ notification_h noti_handle);
+ static common::PlatformResult SetDetailInfosFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetVibrationFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetSoundPathFromJson(const picojson::value& noti_value,
+ notification_h noti_handle);
+ static common::PlatformResult SetPathsArrayFromJson(const picojson::value& noti_value,
+ ImageEnumMap map, const std::string& key,
+ notification_h noti_handle);
+ static common::PlatformResult SetTextsArrayFromJson(const picojson::value& noti_value,
+ InformationEnumMap map,
+ const std::string& key,
+ notification_h noti_handle);
+ static common::PlatformResult SetTextFromJson(const picojson::value& noti_value,
+ notification_text_type_e type,
+ const std::string& key, notification_h noti_handle);
+
+ static common::PlatformResult PostNotification(const picojson::object& args, bool is_update,
+ picojson::object* out_ptr,
+ GetHandleFromJsonFun getHandle);
+
+ protected:
+ CommonNotification();
+ virtual ~CommonNotification();
+};
+
+} // namespace notification
+} // namespace extension
+
+#endif /* NOTIFICATION_COMMON_NOTIFICATION_H_ */
'notification_manager.h',
'notification_manager.cc',
'status_notification.cc',
- 'status_notification.h'
+ 'status_notification.h',
+ 'user_notification.cc',
+ 'user_notification.h',
+ 'common_notification.cc',
+ 'common_notification.h'
],
'conditions': [
['tizen == 1', {
'packages': [
'notification',
'capi-system-device',
+ 'capi-appfw-app-control',
]
},
}],
],
+ 'direct_dependent_settings': {
+ 'libraries' : [
+ '-ltizen_notification',
+ ],
+ },
},
],
}
PROGRESS: 'PROGRESS'
};
+var UserNotificationType = {
+ SIMPLE: 'SIMPLE',
+ THUMBNAIL: 'THUMBNAIL',
+ ONGOING: 'ONGOING',
+ PROGRESS: 'PROGRESS'
+};
+
var NotificationProgressType = {
PERCENTAGE: 'PERCENTAGE',
BYTE: 'BYTE'
NotificationManager.prototype.post = function(notification) {
var args = validator_.validateArgs(arguments, [
- {name: 'notification', type: types_.PLATFORM_OBJECT, values: StatusNotification}
+ {name: 'notification', type: types_.PLATFORM_OBJECT, values: Notification}
]);
var data = {
+ //add marker for UserNotification implementation
+ newImpl: (args.notification instanceof tizen.UserNotification),
notification: args.notification
};
NotificationManager.prototype.update = function(notification) {
var args = validator_.validateArgs(arguments, [
- {name: 'notification', type: types_.PLATFORM_OBJECT, values: StatusNotification}
+ {name: 'notification', type: types_.PLATFORM_OBJECT, values: Notification}
]);
if (!arguments.length) {
}
var data = {
+ //add marker for UserNotification implementation
+ newImpl: (args.notification instanceof tizen.UserNotification),
notification: args.notification
};
return returnObject;
};
+NotificationManager.prototype.getNotification = function(id) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'id', type: types_.STRING}
+ ]);
+
+ if (!arguments.length) {
+ throw new WebAPIException(WebAPIException.NOT_FOUND_ERR);
+ }
+
+ var data = {
+ //add marker for UserNotification implementation
+ newImpl: true,
+ id: args.id
+ };
+
+ var result = native_.callSync('NotificationManager_get', data);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ var n = native_.getResultObject(result);
+
+ _edit.allow();
+ var returnObject = new UserNotification(n.userType, n.title, n);
+ _edit.disallow();
+
+ return returnObject;
+};
+
NotificationManager.prototype.getAll = function() {
var result = native_.callSync('NotificationManager_getAll', {});
return notifications;
};
+NotificationManager.prototype.getAllNotifications = function() {
+ var result = native_.callSync('NotificationManager_getAll', {
+ //add marker for UserNotification implementation
+ newImpl: true
+ });
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ var n = native_.getResultObject(result);
+ var notifications = [];
+
+ _edit.allow();
+ for (var i = 0; i < n.length; i++) {
+ notifications.push(new UserNotification(n[i].userType, n[i].title, n[i]));
+ }
+ _edit.disallow();
+
+ return notifications;
+};
+
/**
* Plays the custom effect of the service LED that is located to the front of a device.
*
}
};
+NotificationManager.prototype.saveNotificationAsTemplate = function(name, notification) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'name', type: types_.STRING},
+ {name: 'notification', type: types_.PLATFORM_OBJECT, values: Notification}
+ ]);
+
+ //add marker for UserNotification implementation
+ args.newImpl = (args.notification instanceof tizen.UserNotification);
+
+ var result = native_.callSync('NotificationManager_saveNotificationAsTemplate', args);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+NotificationManager.prototype.createNotificationFromTemplate = function(name) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'name', type: types_.STRING}
+ ]);
+
+ if (!arguments.length) {
+ throw new WebAPIException(WebAPIException.NOT_FOUND_ERR);
+ }
+
+ var result = native_.callSync('NotificationManager_createNotificationFromTemplate', args);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ var n = native_.getResultObject(result);
+
+ _edit.allow();
+ var returnObject = new UserNotification(n.userType, n.title, n);
+ _edit.disallow();
+
+ return returnObject;
+};
+
+var _checkProgressValue = function(v, _progressType) {
+ if ((_progressType === NotificationProgressType.PERCENTAGE && (v >= 0 && v <= 100))
+ || (_progressType === NotificationProgressType.BYTE &&
+ converter_.toUnsignedLong(v) >= 0)) {
+ return true;
+ }
+ return false;
+};
+
+var _checkDetailInfo = function(v) {
+ if (type_.isNull(v)) {
+ return true;
+ }
+ if (!type_.isArray(v)) {
+ return false;
+ }
+ for (var i = 0; i < v.length; ++i) {
+ if (!(v[i] instanceof tizen.NotificationDetailInfo)) {
+ return false;
+ }
+ }
+ return true;
+};
+
+var _setDetailInfo = function(v) {
+ var _d = [];
+ for (var i = 0; i < v.length; ++i) {
+ _d.push(new tizen.NotificationDetailInfo(v[i].mainText, v[i].subText || null));
+ }
+ return _d;
+};
+
+var _checkStringArray = function(v) {
+ if (type_.isNull(v)) {
+ return true;
+ }
+ if (!type_.isArray(v)) {
+ return false;
+ }
+ for (var i = 0; i < v.length; ++i) {
+ if (!type_.isString(v[i])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+var _isHex = function(v) {
+ return v.length === 7 && v.substr(0, 1) === '#' && (/^([0-9A-Fa-f]{2})+$/).test(v.substr(1, 7));
+};
+
function NotificationInitDict(data) {
var _iconPath = null;
var _appId = null;
var _progressType = NotificationProgressType.PERCENTAGE;
var _progressValue = null;
- var checkProgressValue = function(v) {
- if ((_progressType === NotificationProgressType.PERCENTAGE && (v >= 0 && v <= 100))
- || (_progressType === NotificationProgressType.BYTE &&
- converter_.toUnsignedLong(v) >= 0)) {
- return true;
- }
- return false;
- };
var _number = null;
var _subIconPath = null;
var _detailInfo = [];
- var checkDetailInfo = function(v) {
- if (type_.isNull(v)) {
- return true;
- }
- if (!type_.isArray(v)) {
- return false;
- }
- for (var i = 0; i < v.length; ++i) {
- if (!(v[i] instanceof tizen.NotificationDetailInfo)) {
- return false;
- }
- }
- return true;
- };
- var setDetailInfo = function(v) {
- var _d = [];
- for (var i = 0; i < v.length; ++i) {
- _d.push(new tizen.NotificationDetailInfo(v[i].mainText, v[i].subText || null));
- }
- return _d;
- };
var _ledColor = null;
- var isHex = function(v) {
- return v.length === 7 && v.substr(0, 1) === '#' && (/^([0-9A-Fa-f]{2})+$/).test(v.substr(1, 7));
- };
var _ledOnPeriod = 0;
var _ledOffPeriod = 0;
var _backgroundImagePath = null;
var _thumbnails = [];
- var checkThumbnails = function(v) {
- if (type_.isNull(v)) {
- return true;
- }
- if (!type_.isArray(v)) {
- return false;
- }
- for (var i = 0; i < v.length; ++i) {
- if (!type_.isString(v[i])) {
- return false;
- }
- }
- return true;
- };
+
Object.defineProperties(this, {
iconPath: {
_progressValue = v;
return;
}
- if (checkProgressValue(v)) {
+ if (_checkProgressValue(v, _progressType)) {
_progressValue = (_progressType === NotificationProgressType.PERCENTAGE)
? v / 100
: converter_.toUnsignedLong(v);
return _detailInfo;
},
set: function(v) {
- _detailInfo = _edit.canEdit && v ? setDetailInfo(v) : checkDetailInfo(v) ? v : _detailInfo;
+ _detailInfo = _edit.canEdit && v ? _setDetailInfo(v) : _checkDetailInfo(v) ? v : _detailInfo;
},
enumerable: true
},
return _ledColor;
},
set: function(v) {
- _ledColor = (type_.isString(v) && isHex(v)) || type_.isNull(v) ? v : _ledColor;
+ _ledColor = (type_.isString(v) && _isHex(v)) || type_.isNull(v) ? v : _ledColor;
},
enumerable: true
},
return _thumbnails;
},
set: function(v) {
- _thumbnails = checkThumbnails(v) ? v : _thumbnails;
+ _thumbnails = _checkStringArray(v) ? v : _thumbnails;
},
enumerable: true
}
StatusNotification.prototype = new Notification();
StatusNotification.prototype.constructor = StatusNotification;
-
function NotificationDetailInfo(mainText, subText) {
validator_.isConstructorCall(this, NotificationDetailInfo);
});
}
+function TextContentsInitDict(data) {
+ if (!this) return;
+ var _progressType = NotificationProgressType.PERCENTAGE;
+ var _progressValue = null;
+ var _number = null;
+ var _detailInfo = [];
+ var _buttonsTexts = [];
+ var _contentForOff = null;
+
+ Object.defineProperties(this, {
+ progressType: {
+ get: function() {
+ return _progressType;
+ },
+ set: function(v) {
+ _progressType = Object.keys(NotificationProgressType).indexOf(v) >= 0 ? v : _progressType;
+ },
+ enumerable: true
+ },
+ progressValue: {
+ get: function() {
+ if (null === _progressValue) {
+ return _progressValue;
+ }
+
+ return (_progressType === NotificationProgressType.PERCENTAGE)
+ ? _progressValue * 100
+ : _progressValue;
+ },
+ set: function(v) {
+ if (type_.isNull(v)) {
+ _progressValue = v;
+ return;
+ }
+ if (_checkProgressValue(v, _progressType)) {
+ _progressValue = (_progressType === NotificationProgressType.PERCENTAGE)
+ ? v / 100
+ : converter_.toUnsignedLong(v);
+ }
+ },
+ enumerable: true
+ },
+ eventsNumber: {
+ get: function() {
+ return _number;
+ },
+ set: function(v) {
+ _number = type_.isNumber(v) || type_.isNull(v) ? v : _number;
+ },
+ enumerable: true
+ },
+ detailInfo: {
+ get: function() {
+ return _detailInfo;
+ },
+ set: function(v) {
+ _detailInfo = _edit.canEdit && v ? _setDetailInfo(v) : _checkDetailInfo(v) ? v : _detailInfo;
+ },
+ enumerable: true
+ },
+ buttonsTexts: {
+ get: function() {
+ return _buttonsTexts;
+ },
+ set: function(v) {
+ _buttonsTexts = _checkStringArray(v) ? v : _buttonsTexts;
+ },
+ enumerable: true
+ },
+ contentForOff: {
+ get: function() {
+ return _contentForOff;
+ },
+ set: function(v) {
+ _contentForOff = type_.isString(v) || type_.isNull(v) ? v : _contentForOff;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ this['progressType'] = data['progressType'];
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function ImagesInitDict(data) {
+ if (!this) return;
+ var _iconPath = null;
+ var _subIconPath = null;
+ var _indicatorIconPath = null;
+ var _lockScreenIconPath = null;
+ var _buttonIconPaths = [];
+ var _backgroundImagePath = null;
+
+ Object.defineProperties(this, {
+ iconPath: {
+ get: function() {
+ return _iconPath;
+ },
+ set: function(v) {
+ _iconPath = type_.isString(v) || type_.isNull(v) ? v : _iconPath;
+ },
+ enumerable: true
+ },
+ subIconPath: {
+ get: function() {
+ return _subIconPath;
+ },
+ set: function(v) {
+ _subIconPath = type_.isString(v) || type_.isNull(v) ? v : _subIconPath;
+ },
+ enumerable: true
+ },
+ indicatorIconPath: {
+ get: function() {
+ return _indicatorIconPath;
+ },
+ set: function(v) {
+ _indicatorIconPath = type_.isString(v) || type_.isNull(v) ? v : _indicatorIconPath;
+ },
+ enumerable: true
+ },
+ lockScreenIconPath: {
+ get: function() {
+ return _lockScreenIconPath;
+ },
+ set: function(v) {
+ _lockScreenIconPath = type_.isString(v) || type_.isNull(v) ? v : _lockScreenIconPath;
+ },
+ enumerable: true
+ },
+ buttonIconPaths: {
+ get: function() {
+ return _buttonIconPaths;
+ },
+ set: function(v) {
+ _buttonIconPaths = _checkStringArray(v) ? v : _buttonIconPaths;
+ },
+ enumerable: true
+ },
+ backgroundImagePath: {
+ get: function() {
+ return _backgroundImagePath;
+ },
+ set: function(v) {
+ _backgroundImagePath = type_.isString(v) || type_.isNull(v) ? v : _backgroundImagePath;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function ThumbnailsInitDict(data) {
+ if (!this) return;
+ var _lockScreenThumbnailIconPath = null;
+ var _thumbnailIconPath = null;
+ var _thumbnails = [];
+
+ Object.defineProperties(this, {
+ lockScreenThumbnailIconPath: {
+ get: function() {
+ return _lockScreenThumbnailIconPath;
+ },
+ set: function(v) {
+ _lockScreenThumbnailIconPath = type_.isString(v) || type_.isNull(v) ? v : _lockScreenThumbnailIconPath;
+ },
+ enumerable: true
+ },
+ thumbnailIconPath: {
+ get: function() {
+ return _thumbnailIconPath;
+ },
+ set: function(v) {
+ _thumbnailIconPath = type_.isString(v) || type_.isNull(v) ? v : _thumbnailIconPath;
+ },
+ enumerable: true
+ },
+ thumbnails: {
+ get: function() {
+ return _thumbnails;
+ },
+ set: function(v) {
+ _thumbnails = _checkStringArray(v) ? v : _thumbnails;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function ActionsInitDict(data) {
+ if (!this) return;
+ var _soundPath = null;
+ var _vibration = false;
+ var _appControl = null;
+ var _appId = null;
+
+ Object.defineProperties(this, {
+ soundPath: {
+ get: function() {
+ return _soundPath;
+ },
+ set: function(v) {
+ _soundPath = type_.isString(v) || type_.isNull(v) ? v : _soundPath;
+ },
+ enumerable: true
+ },
+ vibration: {
+ get: function() {
+ return _vibration;
+ },
+ set: function(v) {
+ _vibration = type_.isBoolean(v) ? v : _vibration;
+ },
+ enumerable: true
+ },
+ appControl: {
+ get: function() {
+ return _appControl;
+ },
+ set: function(v) {
+ _appControl = _edit.canEdit && v
+ ? new tizen.ApplicationControl(v.operation, v.uri || null, v.mime || null, v.category
+ || null, v.data || [])
+ : v instanceof tizen.ApplicationControl || type_.isNull(v) ? v : _appControl;
+ },
+ enumerable: true
+ },
+ appId: {
+ get: function() {
+ return _appId;
+ },
+ set: function(v) {
+ _appId = type_.isString(v) && !(/\s/.test(v)) || type_.isNull(v) ? v : _appId;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function GroupContentsInitDict(data) {
+ if (!this) return;
+ var _groupTitle = null;
+ var _groupContent = null;
+ var _groupContentForOff = null;
+
+ Object.defineProperties(this, {
+ groupTitle: {
+ get: function() {
+ return _groupTitle;
+ },
+ set: function(v) {
+ _groupTitle = type_.isString(v) || type_.isNull(v) ? v : _groupTitle;
+ },
+ enumerable: true
+ },
+ groupContent: {
+ get: function() {
+ return _groupContent;
+ },
+ set: function(v) {
+ _groupContent = type_.isString(v) || type_.isNull(v) ? v : _groupContent;
+ },
+ enumerable: true
+ },
+ groupContentForOff: {
+ get: function() {
+ return _groupContentForOff;
+ },
+ set: function(v) {
+ _groupContentForOff = type_.isString(v) || type_.isNull(v) ? v : _groupContentForOff;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function LedsInitDict(data) {
+ if (!this) return;
+ var _ledColor = null;
+ var _ledOnPeriod = 0;
+ var _ledOffPeriod = 0;
+
+ Object.defineProperties(this, {
+ ledColor: {
+ get: function() {
+ return _ledColor;
+ },
+ set: function(v) {
+ _ledColor = (type_.isString(v) && _isHex(v)) || type_.isNull(v) ? v : _ledColor;
+ },
+ enumerable: true
+ },
+ ledOnPeriod: {
+ get: function() {
+ return _ledOnPeriod;
+ },
+ set: function(v) {
+ _ledOnPeriod = type_.isNumber(v) ? v : _ledOnPeriod;
+ },
+ enumerable: true
+ },
+ ledOffPeriod: {
+ get: function() {
+ return _ledOffPeriod;
+ },
+ set: function(v) {
+ _ledOffPeriod = type_.isNumber(v) ? v : _ledOffPeriod;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
+function UserNotification(userType, title, notificationGroupedInitDict) {
+ validator_.isConstructorCall(this, UserNotification);
+ type_.isObject(notificationGroupedInitDict) ?
+ notificationGroupedInitDict.title = title :
+ notificationGroupedInitDict = {title: title};
+ UserNotificationInitDict.call(this, notificationGroupedInitDict);
+ Notification.call(this, notificationGroupedInitDict);
+
+ this.textContents = new TextContentsInitDict(notificationGroupedInitDict.textContents);
+ this.images = new ImagesInitDict(notificationGroupedInitDict.images);
+ this.thumbnails = new ThumbnailsInitDict(notificationGroupedInitDict.thumbnails);
+ this.actions = new ActionsInitDict(notificationGroupedInitDict.actions);
+ this.leds = new LedsInitDict(notificationGroupedInitDict.leds);
+ this.groupContents = new GroupContentsInitDict(notificationGroupedInitDict.groupContents);
+
+ var _userType = (Object.keys(UserNotificationType)).indexOf(userType) >= 0
+ ? userType : StatusNotificationType.SIMPLE;
+
+ Object.defineProperties(this, {
+ userType: {
+ get: function() {
+ return _userType;
+ },
+ set: function(v) {
+ _userType = (Object.keys(StatusNotificationType)).indexOf(v) >= 0 && _edit.canEdit
+ ? v : _userType;
+ },
+ enumerable: true
+ }
+ });
+}
+
+UserNotification.prototype = new Notification();
+UserNotification.prototype.constructor = UserNotification;
+
+function UserNotificationInitDict(data) {
+ var _textContents = null;
+ var _images = null;
+ var _thumbnails = null;
+ var _actions = null;
+ var _groupContents = null;
+ var _leds = null;
+
+ Object.defineProperties(this, {
+ textContents: {
+ get: function() {
+ return _textContents;
+ },
+ set: function(v) {
+ _textContents = type_.isObject(v) || type_.isNull(v) ? v : _textContents;
+ },
+ enumerable: true
+ },
+ images: {
+ get: function() {
+ return _images;
+ },
+ set: function(v) {
+ _images = type_.isObject(v) || type_.isNull(v) ? v : _images;
+ },
+ enumerable: true
+ },
+ thumbnails: {
+ get: function() {
+ return _thumbnails;
+ },
+ set: function(v) {
+ _thumbnails = type_.isObject(v) || type_.isNull(v) ? v : _thumbnails;
+ },
+ enumerable: true
+ },
+ actions: {
+ get: function() {
+ return _actions;
+ },
+ set: function(v) {
+ _actions = type_.isObject(v) || type_.isNull(v) ? v : _actions;
+ },
+ enumerable: true
+ },
+ groupContents: {
+ get: function() {
+ return _groupContents;
+ },
+ set: function(v) {
+ _groupContents = type_.isObject(v) || type_.isNull(v) ? v : _groupContents;
+ },
+ enumerable: true
+ },
+ leds: {
+ get: function() {
+ return _leds;
+ },
+ set: function(v) {
+ _leds = type_.isObject(v) || type_.isNull(v) ? v : _leds;
+ },
+ enumerable: true
+ }
+ });
+
+ if (data instanceof _global.Object) {
+ for (var prop in data) {
+ if (this.hasOwnProperty(prop)) {
+ this[prop] = data[prop];
+ }
+ }
+ }
+}
+
exports = new NotificationManager();
tizen.StatusNotification = StatusNotification;
+tizen.UserNotification = UserNotification;
tizen.NotificationDetailInfo = NotificationDetailInfo;
SetExtensionName("tizen.notification");
SetJavaScriptAPI(kSource_notification_api);
- const char* entry_points[] = {"tizen.StatusNotification", "tizen.NotificationDetailInfo", NULL};
+ const char* entry_points[] = {"tizen.StatusNotification", "tizen.UserNotification",
+ "tizen.NotificationDetailInfo", NULL};
SetExtraJSEntryPoints(entry_points);
}
#include "notification/notification_instance.h"
-#include <functional>
-
#include "common/logger.h"
#include "common/picojson.h"
#include "common/platform_result.h"
REGISTER_SYNC("NotificationManager_removeAll", NotificationManagerRemoveAll);
REGISTER_SYNC("NotificationManager_playLEDCustomEffect", NotificationManagerPlayLEDCustomEffect);
REGISTER_SYNC("NotificationManager_stopLEDCustomEffect", NotificationManagerStopLEDCustomEffect);
+ REGISTER_SYNC("NotificationManager_saveNotificationAsTemplate", NotificationManagerSaveTemplate);
+ REGISTER_SYNC("NotificationManager_createNotificationFromTemplate",
+ NotificationManagerCreateFromTemplate);
#undef REGISTER_SYNC
manager_ = NotificationManager::GetInstance();
LoggerD("Enter");
picojson::value val{picojson::object{}};
- PlatformResult status = manager_->Post(args.get<picojson::object>(), val.get<picojson::object>());
+
+ using namespace std::placeholders;
+ std::function<PlatformResult(const picojson::object& args, picojson::object&)> impl{};
+ if (args.contains("newImpl") && args.get("newImpl").get<bool>()) {
+ LoggerD("New implementation");
+ impl = std::bind(&NotificationManager::PostUserNoti, manager_, _1, _2);
+ } else {
+ LoggerW("Deprecated object used");
+ impl = std::bind(&NotificationManager::Post, manager_, _1, _2);
+ }
+
+ PlatformResult status = impl(args.get<picojson::object>(), val.get<picojson::object>());
if (status.IsSuccess()) {
ReportSuccess(val, out);
CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
LoggerD("Enter");
- PlatformResult status = manager_->Update(args.get<picojson::object>());
+ using namespace std::placeholders;
+ std::function<PlatformResult(const picojson::object& args)> impl{};
+ if (args.contains("newImpl") && args.get("newImpl").get<bool>()) {
+ LoggerD("New implementation");
+ impl = std::bind(&NotificationManager::UpdateUserNoti, manager_, _1);
+ } else {
+ LoggerW("Deprecated object used");
+ impl = std::bind(&NotificationManager::Update, manager_, _1);
+ }
+
+ PlatformResult status = impl(args.get<picojson::object>());
if (status.IsSuccess()) {
ReportSuccess(out);
LoggerD("Enter");
picojson::value val{picojson::object{}};
- PlatformResult status = manager_->Get(args.get<picojson::object>(), val.get<picojson::object>());
+ PlatformResult status =
+ manager_->Get(args.get<picojson::object>(), val.get<picojson::object>(),
+ args.contains("newImpl") && args.get("newImpl").get<bool>());
if (status.IsSuccess()) {
ReportSuccess(val, out);
LoggerD("Enter");
picojson::value val{picojson::array{}};
- PlatformResult status = manager_->GetAll(val.get<picojson::array>());
+ PlatformResult status = manager_->GetAll(
+ val.get<picojson::array>(), args.contains("newImpl") && args.get("newImpl").get<bool>());
if (status.IsSuccess()) {
ReportSuccess(val, out);
}
}
+void NotificationInstance::NotificationManagerSaveTemplate(const picojson::value& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
+
+ PlatformResult status = manager_->SaveTemplate(args.get<picojson::object>());
+
+ if (status.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(status, &out);
+ }
+}
+
+void NotificationInstance::NotificationManagerCreateFromTemplate(const picojson::value& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
+ picojson::value val{picojson::object{}};
+
+ PlatformResult status =
+ manager_->CreateFromTemplate(args.get<picojson::object>(), val.get<picojson::object>());
+
+ if (status.IsSuccess()) {
+ ReportSuccess(val, out);
+ } else {
+ LogAndReportError(status, &out);
+ }
+}
+
#undef CHECK_EXIST
} // namespace notification
void NotificationManagerPlayLEDCustomEffect(const picojson::value& args, picojson::object& out);
void NotificationManagerStopLEDCustomEffect(const picojson::value& args, picojson::object& out);
+ void NotificationManagerSaveTemplate(const picojson::value& args, picojson::object& out);
+ void NotificationManagerCreateFromTemplate(const picojson::value& args, picojson::object& out);
};
} // namespace notification
#include <fcntl.h>
#include <unistd.h>
+#include <app_common.h>
#include <app_control_internal.h>
#include <device/led.h>
#include <notification_internal.h>
#include "common/logger.h"
#include "common/scope_exit.h"
+#include "notification/common_notification.h"
#include "notification/status_notification.h"
+#include "notification/user_notification.h"
namespace extension {
namespace notification {
PlatformResult NotificationManager::Post(const picojson::object& args, picojson::object& out) {
LoggerD("Enter");
- return StatusNotification::FromJson(args, false, &out);
+ return StatusNotification::PostStatusNotification(args, false, &out);
+}
+
+PlatformResult NotificationManager::PostUserNoti(const picojson::object& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+ return UserNotification::PostUserNotification(args, false, &out);
}
PlatformResult NotificationManager::Update(const picojson::object& args) {
LoggerD("Enter");
- return StatusNotification::FromJson(args, true, NULL);
+ return StatusNotification::PostStatusNotification(args, true, nullptr);
+}
+
+PlatformResult NotificationManager::UpdateUserNoti(const picojson::object& args) {
+ LoggerD("Enter");
+ return UserNotification::PostUserNotification(args, true, nullptr);
}
PlatformResult NotificationManager::Remove(const picojson::object& args) {
LoggerD("Enter");
int id = std::stoi(FromJson<std::string>(args, "id"));
- int ret = notification_delete_by_priv_id(NULL, NOTIFICATION_TYPE_NONE, id);
- if (ret != NOTIFICATION_ERROR_NONE) {
+ int ret = notification_delete_by_priv_id(nullptr, NOTIFICATION_TYPE_NONE, id);
+ if (NOTIFICATION_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Cannot remove notification error",
("Cannot remove notification error: %d", ret));
}
PlatformResult NotificationManager::RemoveAll() {
LoggerD("Enter");
int ret = notification_delete_all(NOTIFICATION_TYPE_NOTI);
- if (ret != NOTIFICATION_ERROR_NONE) {
+ if (NOTIFICATION_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification noti remove all failed",
("Notification remove all failed: %d", ret));
}
ret = notification_delete_all(NOTIFICATION_TYPE_ONGOING);
- if (ret != NOTIFICATION_ERROR_NONE) {
+ if (NOTIFICATION_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification ongoing remove all failed",
("Notification remove all failed: %d", ret));
}
return PlatformResult(ErrorCode::NO_ERROR);
}
-PlatformResult NotificationManager::Get(const picojson::object& args, picojson::object& out) {
+PlatformResult NotificationManager::Get(const picojson::object& args, picojson::object& out,
+ bool is_new_impl) {
LoggerD("Enter");
int id;
try {
LoggerE("Failed: GetAppControl");
return status;
}
- status = StatusNotification::ToJson(id, noti_handle, app_control, &out);
+
+ if (!is_new_impl) {
+ status = StatusNotification::ToJson(id, noti_handle, app_control, &out);
+ } else {
+ status = UserNotification::ToJson(id, noti_handle, app_control, &out);
+ }
if (status.IsError()) {
LoggerE("Failed: ToJson");
return status;
return PlatformResult(ErrorCode::NO_ERROR);
}
-PlatformResult NotificationManager::GetAll(picojson::array& out) {
+PlatformResult NotificationManager::GetAll(picojson::array& out, bool is_new_impl) {
LoggerD("Enter");
notification_h noti = nullptr;
notification_list_h noti_list = nullptr;
noti = notification_list_get_data(noti_list_iter);
if (nullptr != noti) {
int noti_priv = -1;
- ret = notification_get_id(noti, NULL, ¬i_priv);
+ ret = notification_get_id(noti, nullptr, ¬i_priv);
if (NOTIFICATION_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot get notification id error",
("Cannot get notification id, error: %d", ret));
picojson::object noti_item = picojson::object();
- status = StatusNotification::ToJson(noti_priv, noti, app_control, ¬i_item);
+ if (!is_new_impl) {
+ status = StatusNotification::ToJson(noti_priv, noti, app_control, ¬i_item);
+ } else {
+ status = UserNotification::ToJson(noti_priv, noti, app_control, ¬i_item);
+ }
if (status.IsError()) return status;
out.push_back(picojson::value(noti_item));
unsigned int platformFlags = 0;
for (auto flag : flags) {
std::string flagStr = JsonCast<std::string>(flag);
- if (flagStr == "LED_CUSTOM_DEFAULT")
+ if ("LED_CUSTOM_DEFAULT" == flagStr)
platformFlags |= LED_CUSTOM_DEFAULT;
- else if (flagStr == "LED_CUSTOM_DUTY_ON")
+ else if ("LED_CUSTOM_DUTY_ON" == flagStr)
platformFlags |= LED_CUSTOM_DUTY_ON;
}
int ret;
ret = device_led_play_custom(timeOn, timeOff, color, platformFlags);
- if (ret != DEVICE_ERROR_NONE) {
+ if (DEVICE_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot play LED custom effect",
("Cannot play LED custom effect: ", ret));
}
LoggerD("Enter");
int ret = device_led_stop_custom();
- if (ret != DEVICE_ERROR_NONE) {
+ if (DEVICE_ERROR_NONE != ret) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot stop LED custom effect",
("Cannot stop LED custom effect: ", ret));
}
return PlatformResult(ErrorCode::NO_ERROR);
}
+common::PlatformResult NotificationManager::SaveTemplate(const picojson::object& args) {
+ LoggerD("Enter");
+ std::string name = FromJson<std::string>(args, "name");
+ notification_h noti_handle = nullptr;
+ int ret;
+ SCOPE_EXIT {
+ notification_free(noti_handle);
+ };
+
+ PlatformResult status = PlatformResult(ErrorCode::NO_ERROR);
+ const auto& new_impl_it = args.find("newImpl");
+ const auto& noti_val_it = args.find("notification");
+ if (args.end() != new_impl_it && args.end() != noti_val_it && new_impl_it->second.get<bool>()) {
+ status = UserNotification::GetNotiHandleFromJson(noti_val_it->second, false, ¬i_handle);
+ } else {
+ status = StatusNotification::GetNotiHandleFromJson(noti_val_it->second, false, ¬i_handle);
+ }
+
+ if (status.IsError()) {
+ return status;
+ }
+
+ ret = notification_save_as_template(noti_handle, name.c_str());
+ if (NOTIFICATION_ERROR_NONE != ret) {
+ LoggerD("Error: %d (%s)", ret, get_error_message(ret));
+ if (NOTIFICATION_ERROR_MAX_EXCEEDED == ret) {
+ return LogAndCreateResult(ErrorCode::QUOTA_EXCEEDED_ERR,
+ "Maximum number of templates exceeded",
+ ("Maximum number of templates exceeded, error: %d", ret));
+ } else {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Saving template failed",
+ ("Saving template failed, error: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+common::PlatformResult NotificationManager::CreateFromTemplate(const picojson::object& args,
+ picojson::object& out) {
+ LoggerD("Enter");
+ std::string name = FromJson<std::string>(args, "name");
+
+ notification_h noti_handle = nullptr;
+ noti_handle = notification_create_from_template(name.c_str());
+ if (!noti_handle) {
+ return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "The template with given name not found",
+ ("The template with given name not found, handle is nullptr"));
+ }
+
+ SCOPE_EXIT {
+ notification_free(noti_handle);
+ };
+
+ // This method is designed to return only UserNotification objects
+ PlatformResult status = UserNotification::ToJson(0, noti_handle, nullptr, &out);
+ if (status.IsError()) {
+ LoggerE("Failed: ToJson");
+ return status;
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace notification
} // namespace extension
static NotificationManager* GetInstance();
common::PlatformResult Post(const picojson::object& args, picojson::object& out);
+ common::PlatformResult PostUserNoti(const picojson::object& args, picojson::object& out);
common::PlatformResult Update(const picojson::object& args);
+ common::PlatformResult UpdateUserNoti(const picojson::object& args);
common::PlatformResult Remove(const picojson::object& args);
common::PlatformResult RemoveAll();
- common::PlatformResult Get(const picojson::object& args, picojson::object& out);
- common::PlatformResult GetAll(picojson::array& out);
+ common::PlatformResult Get(const picojson::object& args, picojson::object& out,
+ bool is_new_impl = false);
+ common::PlatformResult GetAll(picojson::array& out, bool is_new_impl = false);
common::PlatformResult PlayLEDCustomEffect(const picojson::object& args);
common::PlatformResult StopLEDCustomEffect();
+ // TODO needed also below functions for new design?
+ common::PlatformResult SaveTemplate(const picojson::object& args);
+ common::PlatformResult CreateFromTemplate(const picojson::object& args, picojson::object& out);
+
private:
NotificationManager();
virtual ~NotificationManager();
#include "notification/status_notification.h"
-#include <app_control_internal.h>
-#include <notification.h>
-#include <notification_internal.h>
-
#include "common/converter.h"
#include "common/filesystem/filesystem_provider.h"
#include "common/logger.h"
using namespace common;
-const std::string kProgressTypePercentage = "PERCENTAGE";
-const std::string kProgressTypeByte = "BYTE";
-
-const InformationEnumMap StatusNotification::info_map_ = {{0, NOTIFICATION_TEXT_TYPE_INFO_1},
- {1, NOTIFICATION_TEXT_TYPE_INFO_2},
- {2, NOTIFICATION_TEXT_TYPE_INFO_3}};
-
-const InformationEnumMap StatusNotification::info_sub_map_ = {
- {0, NOTIFICATION_TEXT_TYPE_INFO_SUB_1},
- {1, NOTIFICATION_TEXT_TYPE_INFO_SUB_2},
- {2, NOTIFICATION_TEXT_TYPE_INFO_SUB_3}};
-
-const ImageEnumMap StatusNotification::thumbnails_map_ = {{0, NOTIFICATION_IMAGE_TYPE_LIST_1},
- {1, NOTIFICATION_IMAGE_TYPE_LIST_2},
- {2, NOTIFICATION_IMAGE_TYPE_LIST_3},
- {3, NOTIFICATION_IMAGE_TYPE_LIST_4}};
-
StatusNotification::StatusNotification() {
}
StatusNotification::~StatusNotification() {
}
-bool StatusNotification::IsColorFormatNumberic(const std::string& color) {
- LoggerD("Enter");
- std::string hexCode = "0123456789abcdef";
- if (color.length() != 7 || '#' != color[0]) {
- return false;
- }
-
- for (size_t i = 1; i < color.length(); i++) {
- if (std::string::npos == hexCode.find(color[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-PlatformResult StatusNotification::SetLayout(notification_h noti_handle,
- const std::string& noti_type) {
- LoggerD("Enter");
- notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
-
- if (noti_type == "SIMPLE") {
- long number;
- PlatformResult status = GetNumber(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &number);
- if (status.IsError()) {
- LoggerE("Failed: GetNumber");
- return status;
- }
- if (number > 0)
- noti_layout = NOTIFICATION_LY_NOTI_EVENT_MULTIPLE;
- else
- noti_layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
- } else if (noti_type == "THUMBNAIL") {
- noti_layout = NOTIFICATION_LY_NOTI_THUMBNAIL;
- }
- if (noti_type == "ONGOING") {
- noti_layout = NOTIFICATION_LY_ONGOING_EVENT;
- } else if (noti_type == "PROGRESS") {
- noti_layout = NOTIFICATION_LY_ONGOING_PROGRESS;
- }
- int ret = notification_set_layout(noti_handle, noti_layout);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification layout error",
- ("Set notification layout error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-static bool ServiceExtraDataCb(app_control_h service, const char* key, void* user_data) {
- LoggerD("Enter");
- if (nullptr == user_data || nullptr == key) {
- LoggerE("User data or key not exist");
- return true;
- }
-
- picojson::array* control_data = static_cast<picojson::array*>(user_data);
-
- int length = 0;
- char** value = NULL;
- SCOPE_EXIT {
- free(value);
- };
-
- int ret = app_control_get_extra_data_array(service, key, &value, &length);
- if (ret != APP_CONTROL_ERROR_NONE) {
- LoggerE("Get app control extra data error: %d", ret);
- return true;
- }
-
- if (!value || !length) {
- LoggerE("Get app control extra data value error");
- return true;
- }
-
- picojson::array values = picojson::array();
- for (int index = 0; index < length; ++index) {
- values.push_back(picojson::value(value[index]));
- }
-
- picojson::object data_control_elem = picojson::object();
- data_control_elem["key"] = picojson::value(key);
- data_control_elem["value"] = picojson::value(values);
-
- control_data->push_back(picojson::value(data_control_elem));
-
- return true;
-}
-
-PlatformResult StatusNotification::Create(notification_type_e noti_type,
- notification_h* noti_handle) {
- LoggerD("Enter");
- *noti_handle = notification_create(noti_type);
- if (!*noti_handle) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot make new notification object");
- }
-
- if (NOTIFICATION_TYPE_ONGOING == noti_type) {
- int ret =
- notification_set_display_applist(*noti_handle, NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY |
- NOTIFICATION_DISPLAY_APP_INDICATOR);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot set notification display applist",
- ("Cannot make new notification object: %d", ret));
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::StatusTypeFromPlatform(notification_type_e noti_type,
- notification_ly_type_e noti_layout,
- std::string* type) {
- LoggerD("Enter");
- if (noti_type == NOTIFICATION_TYPE_NOTI) {
- if (noti_layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE ||
- noti_layout == NOTIFICATION_LY_NOTI_EVENT_MULTIPLE) {
- *type = "SIMPLE";
- } else if (noti_layout == NOTIFICATION_LY_NOTI_THUMBNAIL) {
- *type = "THUMBNAIL";
- }
- } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
- if (noti_layout == NOTIFICATION_LY_ONGOING_EVENT) {
- *type = "ONGOING";
- } else if (noti_layout == NOTIFICATION_LY_ONGOING_PROGRESS) {
- *type = "PROGRESS";
- }
- } else {
- return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Notification type not found");
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::StatusTypeToPlatform(const std::string& type,
- notification_type_e* noti_type) {
- LoggerD("Enter");
- if (type == "SIMPLE" || type == "THUMBNAIL") {
- *noti_type = NOTIFICATION_TYPE_NOTI;
- } else if (type == "ONGOING" || type == "PROGRESS") {
- *noti_type = NOTIFICATION_TYPE_ONGOING;
- } else {
- return LogAndCreateResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalide notification type",
- ("Invalide noti type: %s", type.c_str()));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetImage(notification_h noti_handle,
- notification_image_type_e image_type,
- std::string* image_path) {
- LoggerD("Enter");
- char* path = NULL;
-
- *image_path = "";
-
- if (notification_get_image(noti_handle, image_type, &path) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification image error",
- ("Get notification image error, image_type: %d", image_type));
- }
- if (path) {
- *image_path = path;
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetImage(notification_h noti_handle,
- notification_image_type_e image_type,
- const std::string& image_path) {
- LoggerD("Enter");
- int ret = notification_set_image(noti_handle, image_type, image_path.c_str());
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(
- ErrorCode::UNKNOWN_ERR, "Set notification image error",
- ("Set notification image error, image_type: %d, error: %d", image_type, ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetText(notification_h noti_handle,
- notification_text_type_e text_type,
- std::string* noti_text) {
- LoggerD("Enter");
- char* text = NULL;
-
- *noti_text = "";
-
- if (notification_get_text(noti_handle, text_type, &text) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification text error",
- ("Get notification text error, text_type: %d", text_type));
- }
-
- if (text) *noti_text = text;
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetText(notification_h noti_handle,
- notification_text_type_e text_type,
- const std::string& noti_text) {
- LoggerD("Enter");
- int ret = notification_set_text(noti_handle, text_type, noti_text.c_str(), NULL,
- NOTIFICATION_VARIABLE_TYPE_NONE);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(
- ErrorCode::UNKNOWN_ERR, "Set notification text error",
- ("Set notification text error, text_type: %d, error: %d", text_type, ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetNumber(notification_h noti_handle,
- notification_text_type_e text_type, long* number) {
- LoggerD("Enter");
- std::string text;
- PlatformResult status = GetText(noti_handle, text_type, &text);
- if (status.IsError()) return status;
-
- if (text.length())
- *number = std::stol(text);
- else
- *number = -1;
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetDetailInfos(notification_h noti_handle,
- picojson::array* out) {
- LoggerD("Enter");
- if (info_map_.size() != info_sub_map_.size()) {
- return LogAndCreateResult(ErrorCode::VALIDATION_ERR,
- "Different notification information types element size");
- }
-
- picojson::value detail_info = picojson::value(picojson::object());
- picojson::object& detail_info_obj = detail_info.get<picojson::object>();
-
- std::string text;
- size_t info_map_size = info_map_.size();
- for (size_t idx = 0; idx < info_map_size; ++idx) {
- PlatformResult status = GetText(noti_handle, info_map_.at(idx), &text);
- if (status.IsError()) return status;
-
- if (!text.length()) break;
-
- detail_info_obj["mainText"] = picojson::value(text);
-
- status = GetText(noti_handle, info_sub_map_.at(idx), &text);
- if (status.IsError()) return status;
-
- if (text.length()) {
- detail_info_obj["subText"] = picojson::value(text);
- }
-
- out->push_back(detail_info);
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetDetailInfos(notification_h noti_handle,
- const picojson::array& value) {
- LoggerD("Enter");
- size_t idx = 0;
-
- size_t info_map_size = info_map_.size();
- for (auto& item : value) {
- const picojson::object& obj = JsonCast<picojson::object>(item);
-
- PlatformResult status =
- SetText(noti_handle, info_map_.at(idx), common::FromJson<std::string>(obj, "mainText"));
- if (status.IsError()) return status;
-
- if (picojson::value(obj).contains("subText") && !IsNull(obj, "subText")) {
- PlatformResult status = SetText(noti_handle, info_sub_map_.at(idx),
- common::FromJson<std::string>(obj, "subText"));
- if (status.IsError()) return status;
- }
-
- ++idx;
-
- if (idx > info_map_size) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
- "Too many values in notification detailInfo array");
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetLedColor(notification_h noti_handle, std::string* led_color) {
- LoggerD("Enter");
- unsigned int color = 0;
- notification_led_op_e type = NOTIFICATION_LED_OP_ON;
-
- if (notification_get_led(noti_handle, &type, (int*)&color) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
- "Get notification led displaying option error");
- }
-
- *led_color = "";
- std::stringstream stream;
-
- if (NOTIFICATION_LED_OP_OFF != type) {
- color = 0x00FFFFFF & color;
- stream << std::hex << color;
- *led_color = "#" + stream.str();
-
- while (led_color->length() < 7) {
- led_color->insert(1, "0");
- }
-
- std::transform(led_color->begin(), led_color->end(), led_color->begin(), ::tolower);
- }
-
- LoggerD("color:%s", (*led_color).c_str());
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetLedColor(notification_h noti_handle,
- const std::string& led_color) {
- LoggerD("Enter");
- std::string color_str = led_color;
- std::transform(color_str.begin(), color_str.end(), color_str.begin(), ::tolower);
-
- if (!IsColorFormatNumberic(color_str)) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Led color is not numeric value",
- ("Led color is not numeric value: %s", color_str.c_str()));
- }
-
- std::stringstream stream;
- unsigned int color = 0;
- notification_led_op_e type = NOTIFICATION_LED_OP_ON;
- std::string color_code = color_str.substr(1, color_str.length()).insert(0, "ff");
-
- stream << std::hex << color_code;
- stream >> color;
-
- if (color != 0)
- type = NOTIFICATION_LED_OP_ON_CUSTOM_COLOR;
- else
- type = NOTIFICATION_LED_OP_OFF;
-
- int ret = notification_set_led(noti_handle, type, static_cast<int>(color));
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led color eror",
- ("Set notification led color eror: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetLedPeriod(notification_h noti_handle,
- unsigned long* on_period,
- unsigned long* off_period) {
- LoggerD("Enter");
- int on_time = 0;
- int off_time = 0;
-
- if (notification_get_led_time_period(noti_handle, &on_time, &off_time) !=
- NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification led on/off period error");
- }
-
- if (on_period) *on_period = on_time;
- if (off_period) *off_period = off_time;
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetLedOnPeriod(notification_h noti_handle,
- unsigned long on_period) {
- LoggerD("Enter");
- unsigned long off_period = 0;
- PlatformResult status = GetLedPeriod(noti_handle, nullptr, &off_period);
- if (status.IsError()) return status;
-
- int ret = notification_set_led_time_period(noti_handle, on_period, off_period);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led on period error",
- ("Set notification led on period error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetLedOffPeriod(notification_h noti_handle,
- unsigned long off_period) {
- LoggerD("Enter");
- unsigned long on_period = 0;
- PlatformResult status = GetLedPeriod(noti_handle, &on_period, nullptr);
- if (status.IsError()) return status;
-
- int ret = notification_set_led_time_period(noti_handle, on_period, off_period);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification led off period error",
- ("Set notification led off period error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetThumbnails(notification_h noti_handle, picojson::array* out) {
- LoggerD("Enter");
- std::string text;
- size_t thumbnails_map_size = thumbnails_map_.size();
- for (size_t idx = 0; idx < thumbnails_map_size; ++idx) {
- PlatformResult status = GetImage(noti_handle, thumbnails_map_.at(idx), &text);
- if (status.IsError()) return status;
-
- if (!text.length()) break;
-
- // CHECK GetVirtualPath ??
- out->push_back(picojson::value(common::FilesystemProvider::Create().GetVirtualPath(text)));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetThumbnails(notification_h noti_handle,
- const picojson::array& value) {
- LoggerD("Enter");
- size_t idx = 0;
-
- size_t thumbnails_map_size = thumbnails_map_.size();
- for (auto& item : value) {
- const std::string& text = JsonCast<std::string>(item);
- std::string real_path = common::FilesystemProvider::Create().GetRealPath(text);
-
- PlatformResult status = SetImage(noti_handle, thumbnails_map_.at(idx), real_path);
- if (status.IsError()) return status;
-
- ++idx;
-
- if (idx > thumbnails_map_size) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
- "Too many values in notification thumbnail array");
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetSoundPath(notification_h noti_handle,
- std::string* sound_path) {
- LoggerD("Enter");
- *sound_path = "";
-
- const char* path = NULL;
- notification_sound_type_e type = NOTIFICATION_SOUND_TYPE_NONE;
-
- if (notification_get_sound(noti_handle, &type, &path) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification sound error");
- }
-
- LoggerD("Sound type = %d", type);
-
- if (path && (type == NOTIFICATION_SOUND_TYPE_USER_DATA)) {
- *sound_path = path;
- }
-
- LoggerD("Sound path = %s", sound_path->c_str());
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetSoundPath(notification_h noti_handle,
- const std::string& sound_path) {
- LoggerD("Enter");
- int ret =
- notification_set_sound(noti_handle, NOTIFICATION_SOUND_TYPE_USER_DATA, sound_path.c_str());
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification sound error",
- ("Set notification sound error: %d", ret));
- }
-
- LoggerD("Sound path = %s", sound_path.c_str());
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetVibration(notification_h noti_handle, bool* vibration) {
- LoggerD("Enter");
- notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
-
- if (notification_get_vibration(noti_handle, &vib_type, NULL) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification vibration error");
- }
-
- if (NOTIFICATION_VIBRATION_TYPE_DEFAULT == vib_type ||
- NOTIFICATION_VIBRATION_TYPE_USER_DATA == vib_type) {
- *vibration = true;
- } else {
- *vibration = false;
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetVibration(notification_h noti_handle, bool vibration) {
- LoggerD("Enter");
- bool platform_vibration;
- PlatformResult status = GetVibration(noti_handle, &platform_vibration);
- if (status.IsError()) return status;
-
- if (platform_vibration != vibration) {
- notification_vibration_type_e vib_type = NOTIFICATION_VIBRATION_TYPE_NONE;
-
- if (vibration) {
- vib_type = NOTIFICATION_VIBRATION_TYPE_DEFAULT;
- }
-
- int ret = notification_set_vibration(noti_handle, vib_type, NULL);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification vibration error",
- ("Set notification vibration error: %d", ret));
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetApplicationControl(app_control_h app_handle,
- picojson::object* out_ptr) {
- LoggerD("Enter");
- picojson::object& out = *out_ptr;
-
- char* operation = NULL;
- char* uri = NULL;
- char* mime = NULL;
- char* category = NULL;
- SCOPE_EXIT {
- free(operation);
- free(uri);
- free(mime);
- free(category);
- };
-
- int ret = app_control_get_operation(app_handle, &operation);
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control operation error",
- ("Get application control operation error: %d", ret));
- }
- if (operation) {
- out["operation"] = picojson::value(operation);
- LoggerD("operation = %s", operation);
- }
-
- if (app_control_get_uri(app_handle, &uri) != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control uri error");
- }
- if (uri) {
- out["uri"] = picojson::value(uri);
- LoggerD("uri = %s", uri);
- }
-
- if (app_control_get_mime(app_handle, &mime) != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control mime error");
- }
- if (mime) {
- out["mime"] = picojson::value(mime);
- LoggerD("mime = %s", mime);
- }
-
- if (app_control_get_category(app_handle, &category) != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control category error");
- }
- if (category) {
- out["category"] = picojson::value(category);
- LoggerD("category = %s", category);
- }
-
- picojson::array app_control_data = picojson::array();
- if (app_control_foreach_extra_data(app_handle, ServiceExtraDataCb, (void*)&app_control_data) !=
- APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get application control data error");
- }
- out["data"] = picojson::value(app_control_data);
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetApplicationControl(app_control_h app_handle,
- const picojson::object& app_ctrl) {
- LoggerD("Enter");
- picojson::value val(app_ctrl);
- const std::string& operation = common::FromJson<std::string>(app_ctrl, "operation");
-
- int ret;
- if (operation.length()) {
- ret = app_control_set_operation(app_handle, operation.c_str());
- } else {
- ret = app_control_set_operation(app_handle, APP_CONTROL_OPERATION_DEFAULT);
- }
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control operation error",
- ("Set application control operation error: %d", ret));
- }
-
- if (val.contains("uri") && !IsNull(app_ctrl, "uri")) {
- const std::string& uri = common::FromJson<std::string>(app_ctrl, "uri");
- ret = app_control_set_uri(app_handle, uri.c_str());
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control uri error",
- ("Set application control uri error: %d", ret));
- }
- }
-
- if (val.contains("mime") && !IsNull(app_ctrl, "mime")) {
- const std::string& mime = common::FromJson<std::string>(app_ctrl, "mime");
- ret = app_control_set_mime(app_handle, mime.c_str());
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control mime error",
- ("Set application control mime error: %d", ret));
- }
- }
-
- if (val.contains("category") && !IsNull(app_ctrl, "category")) {
- const std::string& category = common::FromJson<std::string>(app_ctrl, "category");
- ret = app_control_set_category(app_handle, category.c_str());
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control category error",
- ("Set application control category error: %d", ret));
- }
- }
-
- if (!picojson::value(app_ctrl).contains("data") || IsNull(app_ctrl, "data")) {
- return PlatformResult(ErrorCode::NO_ERROR);
- }
-
- auto& items = common::FromJson<picojson::array>(app_ctrl, "data");
-
- int idx = 0;
-
- for (auto item : items) {
- const picojson::object& obj = JsonCast<picojson::object>(item);
- const std::string key = common::FromJson<std::string>(obj, "key");
- const picojson::array values = common::FromJson<picojson::array>(obj, "value");
- const char** arrayValue = (const char**)calloc(sizeof(char*), values.size());
- SCOPE_EXIT {
- free(arrayValue);
- };
- idx = 0;
- for (auto& item : values) {
- arrayValue[idx] = JsonCast<std::string>(item).c_str();
- ++idx;
- }
- ret = app_control_add_extra_data_array(app_handle, key.c_str(), arrayValue, values.size());
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set application control extra data error",
- ("Set application control extra data error: %d", ret));
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetApplicationId(app_control_h app_handle, std::string* app_id) {
- LoggerD("Enter");
- char* app_id_str = NULL;
- SCOPE_EXIT {
- free(app_id_str);
- };
-
- *app_id = "";
-
- if (app_control_get_app_id(app_handle, &app_id_str) != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get applicaiton ID failed");
- }
-
- if (app_id_str != NULL) {
- *app_id = app_id_str;
- }
-
- LoggerD("Get appId = %s", /*(*app_id).c_str()*/ app_id_str);
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetApplicationId(app_control_h app_handle,
- const std::string& app_id) {
- LoggerD("Enter");
- int ret = app_control_set_app_id(app_handle, app_id.c_str());
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set applicaiton ID error",
- ("Set applicaiton ID error: %d", ret));
- }
-
- LoggerD("Set appId = %s", app_id.c_str());
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetProgressValue(notification_h noti_handle,
- const std::string& progess_type,
- double* progress_value) {
- LoggerD("Enter");
- double tmp_progress_value = 0.0;
-
- if (progess_type == kProgressTypeByte) {
- if (notification_get_size(noti_handle, &tmp_progress_value) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification size error");
- }
- } else if (progess_type == kProgressTypePercentage) {
- if (notification_get_progress(noti_handle, &tmp_progress_value) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification progress error");
- }
- // native api uses range 0-1, but webapi expects 0-100, so we need to multiply result with 100
- tmp_progress_value *= 100;
- } else {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown notification progress type",
- ("Unknown notification progress type: %s ", progess_type.c_str()));
- }
-
- LOGGER(DEBUG) << "Progress " << progess_type << " = " << tmp_progress_value;
-
- *progress_value = tmp_progress_value;
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetProgressValue(notification_h noti_handle,
- const std::string& progress_type,
- double progress_value, bool is_update) {
- LoggerD("Enter");
- int ret;
-
- if (progress_type == kProgressTypeByte) {
- ret = notification_set_size(noti_handle, progress_value);
-
- if (is_update) {
- ret = notification_update_size(noti_handle, NOTIFICATION_PRIV_ID_NONE, progress_value);
- }
- } else if (progress_type == kProgressTypePercentage) {
- // native api uses range 0-1, but webapi expects 0-100, so we need to divide by 100
- ret = notification_set_progress(noti_handle, progress_value / 100);
-
- if (is_update) {
- ret = notification_update_progress(noti_handle, NOTIFICATION_PRIV_ID_NONE, progress_value);
- }
- } else {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown notification progress type",
- ("Unknown notification progress type: %s ", progress_type.c_str()));
- }
-
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Set notification progress/size error",
- ("Set notification progress/size error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetPostedTime(notification_h noti_handle, time_t* posted_time) {
- LoggerD("Enter");
- *posted_time = 0;
-
- if (notification_get_insert_time(noti_handle, posted_time) != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification posted time error");
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetNotiHandle(int id, notification_h* noti_handle) {
- LoggerD("Enter");
- *noti_handle = notification_load(NULL, id);
- if (NULL == *noti_handle) {
- return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Not found or removed notification id");
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::GetAppControl(notification_h noti_handle,
- app_control_h* app_control) {
- LoggerD("Enter");
- int ret = notification_get_launch_option(noti_handle, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL,
- static_cast<void*>(app_control));
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification get launch option error",
- ("Notification get launch option error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::CreateAppControl(app_control_h* app_control) {
- LoggerD("Enter");
- int ret = app_control_create(app_control);
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Application create error",
- ("Application create error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-PlatformResult StatusNotification::SetAppControl(notification_h noti_handle,
- app_control_h app_control) {
- LoggerD("Enter");
- int ret = notification_set_launch_option(noti_handle, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL,
- static_cast<void*>(app_control));
- if (ret != APP_CONTROL_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification set launch option error",
- ("Notification set launch option error: %d", ret));
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
PlatformResult StatusNotification::ToJson(int id, notification_h noti_handle,
app_control_h app_handle, picojson::object* out_ptr) {
LoggerD("Enter");
picojson::object& out = *out_ptr;
- out["id"] = picojson::value(std::to_string(id));
- out["type"] = picojson::value("STATUS");
-
- // Nitification type
- notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
- int ret = notification_get_type(noti_handle, ¬i_type);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification get type error",
- ("Notification get type error: %d", ret));
- }
-
- notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
- ret = notification_get_layout(noti_handle, ¬i_layout);
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification get layout error",
- ("Notification get layout error: %d", ret));
- }
+ PlatformResult status = AddCommonMembersToJson(id, noti_handle, out_ptr);
+ CHECK_ERROR(status);
std::string noti_type_str;
- PlatformResult status = StatusTypeFromPlatform(noti_type, noti_layout, ¬i_type_str);
- if (status.IsError()) return status;
- out["statusType"] = picojson::value(noti_type_str);
-
- std::string value_str;
- status = GetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["iconPath"] =
- picojson::value(common::FilesystemProvider::Create().GetVirtualPath(value_str));
- }
-
- status = GetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_SUB, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["subIconPath"] =
- picojson::value(common::FilesystemProvider::Create().GetVirtualPath(value_str));
- }
-
- long number;
- status = GetNumber(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &number);
- if (status.IsError()) return status;
- if (number >= 0) {
- out["number"] = picojson::value(static_cast<double>(number));
- }
-
- picojson::array detail_infos = picojson::array();
- status = GetDetailInfos(noti_handle, &detail_infos);
- if (status.IsError()) return status;
- if (detail_infos.size()) {
- out["detailInfo"] = picojson::value(detail_infos);
- }
-
- status = GetLedColor(noti_handle, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["ledColor"] = picojson::value(value_str);
- }
-
- unsigned long on_period;
- unsigned long off_period;
- status = GetLedPeriod(noti_handle, &on_period, &off_period);
- if (status.IsError()) return status;
- out["ledOnPeriod"] = picojson::value(static_cast<double>(on_period));
- out["ledOffPeriod"] = picojson::value(static_cast<double>(off_period));
+ status = AddTypeToJson(noti_handle, "statusType", out_ptr, ¬i_type_str);
+ CHECK_ERROR(status);
- status = GetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["backgroundImagePath"] =
- picojson::value(common::FilesystemProvider::Create().GetVirtualPath(value_str));
- }
+ // iconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, "iconPath", out_ptr);
+ CHECK_ERROR(status);
- picojson::array thumbnails = picojson::array();
- status = GetThumbnails(noti_handle, &thumbnails);
- if (status.IsError()) return status;
- if (thumbnails.size()) {
- out["thumbnails"] = picojson::value(thumbnails);
- }
+ // subIconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_SUB, "subIconPath", out_ptr);
+ CHECK_ERROR(status);
- status = GetSoundPath(noti_handle, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["soundPath"] =
- picojson::value(common::FilesystemProvider::Create().GetVirtualPath(value_str));
- }
+ // eventsNumber
+ status = AddEventsNumberToJson(noti_handle, "number", &out);
+ CHECK_ERROR(status);
- bool vibration;
- status = GetVibration(noti_handle, &vibration);
- if (status.IsError()) return status;
- out["vibration"] = picojson::value(vibration);
+ // detailInfo
+ status = AddDetailInfosToJson(noti_handle, &out);
+ CHECK_ERROR(status);
- picojson::object app_control = picojson::object();
- status = GetApplicationControl(app_handle, &app_control);
- if (status.IsError()) return status;
- if (app_control.size()) {
- out["appControl"] = picojson::value(app_control);
- }
+ // ledColor
+ status = AddLedColorToJson(noti_handle, &out);
+ CHECK_ERROR(status);
- status = GetApplicationId(app_handle, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["appId"] = picojson::value(value_str);
- }
+ // ledOnPeriod, ledOffPeriod
+ status = AddLedOnOffPeriodToJson(noti_handle, &out);
+ CHECK_ERROR(status);
- std::string progress_type;
- status = GetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_LIST_5, &progress_type);
- if (status.IsError()) return status;
+ // backgroundImagePath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, "backgroundImagePath",
+ out_ptr);
+ CHECK_ERROR(status);
- // push service daemon doesn't set progress type
- // so use default if notification type is different from "PROGRESS"
- if ("PROGRESS" != noti_type_str) {
- progress_type = progress_type == kProgressTypeByte ? progress_type : kProgressTypePercentage;
- }
- out["progressType"] = picojson::value(progress_type);
+ // thumbnails
+ status = AddPathsArrayToJson(noti_handle, thumbnails_map_, "thumbnails", out_ptr);
+ CHECK_ERROR(status);
- double progress_value;
- status = GetProgressValue(noti_handle, progress_type, &progress_value);
- if (status.IsError()) return status;
- out["progressValue"] = picojson::value(progress_value);
+ // soundPath
+ status = AddSoundPathToJson(noti_handle, &out);
+ CHECK_ERROR(status);
- time_t posted_time;
- status = GetPostedTime(noti_handle, &posted_time);
- if (status.IsError()) return status;
- out["postedTime"] = picojson::value(static_cast<double>(posted_time) * 1000.0);
+ // vibration
+ status = AddVibrationToJson(noti_handle, &out);
+ CHECK_ERROR(status);
- status = GetText(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE, &value_str);
- if (status.IsError()) return status;
- out["title"] = picojson::value(value_str);
+ // appControl, appId
+ status = AddAppControlInfoToJson(noti_handle, app_handle, &out);
+ CHECK_ERROR(status);
- status = GetText(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &value_str);
- if (status.IsError()) return status;
- if (value_str.length()) {
- out["content"] = picojson::value(value_str);
- }
+ // progressType, progressValue
+ status = AddProgressTypeAndValueToJson(noti_handle, noti_type_str, &out);
+ CHECK_ERROR(status);
return PlatformResult(ErrorCode::NO_ERROR);
}
-PlatformResult StatusNotification::FromJson(const picojson::object& args, bool is_update,
- picojson::object* out_ptr) {
+PlatformResult StatusNotification::GetNotiHandleFromJson(const picojson::value& noti_val,
+ bool is_update,
+ notification_h* noti_handle) {
LoggerD("Enter");
- picojson::object noti_obj = common::FromJson<picojson::object>(args, "notification");
-
- const std::string& status_type = common::FromJson<std::string>(noti_obj, "statusType");
-
- notification_type_e noti_type;
- PlatformResult status = StatusTypeToPlatform(status_type, ¬i_type);
- if (status.IsError()) return status;
-
- int id = NOTIFICATION_PRIV_ID_NONE;
- int ret;
-
- notification_h noti_handle = nullptr;
- app_control_h app_control = NULL;
-
- SCOPE_EXIT {
- if (app_control) {
- app_control_destroy(app_control);
- }
- notification_free(noti_handle);
- };
-
- if (is_update) {
- id = std::stoi(common::FromJson<std::string>(noti_obj, "id"));
-
- PlatformResult status = GetNotiHandle(id, ¬i_handle);
- if (status.IsError()) return status;
-
- } else {
- status = Create(noti_type, ¬i_handle);
- if (status.IsError()) return status;
- }
-
- status = SetLayout(noti_handle, status_type);
- if (status.IsError()) {
- return status;
- }
+ picojson::object noti_obj = noti_val.get<picojson::object>();
- picojson::value val(noti_obj);
- if (val.contains("iconPath") && !IsNull(noti_obj, "iconPath")) {
- const std::string& value_str = common::FromJson<std::string>(noti_obj, "iconPath");
- std::string real_path = common::FilesystemProvider::Create().GetRealPath(value_str);
+ notification_h tmp_noti = nullptr;
+ // statusType, id
+ PlatformResult status = InitNotiFromJson(noti_obj, "statusType", is_update, &tmp_noti);
+ CHECK_ERROR(status);
+ std::unique_ptr<std::remove_pointer<notification_h>::type, int (*)(notification_h)> tmp_noti_ptr(
+ tmp_noti, ¬ification_free); // automatically release the memory
- status = SetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, real_path);
- if (status.IsError()) {
- return status;
- }
- }
+ // title, content
+ status = SetCommonMembersFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("subIconPath") && !IsNull(noti_obj, "subIconPath")) {
- const std::string& value_str = common::FromJson<std::string>(noti_obj, "subIconPath");
- std::string real_path = common::FilesystemProvider::Create().GetRealPath(value_str);
+ // iconPath
+ status = SetPathFromJson(noti_val, NOTIFICATION_IMAGE_TYPE_ICON, "iconPath", tmp_noti);
+ CHECK_ERROR(status);
- status = SetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_SUB, real_path);
- if (status.IsError()) {
- return status;
- }
- }
+ // subIconPath
+ status = SetPathFromJson(noti_val, NOTIFICATION_IMAGE_TYPE_ICON_SUB, "subIconPath", tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("number") && !IsNull(noti_obj, "number")) {
- long number = (long)common::FromJson<double>(noti_obj, "number");
- status = SetText(noti_handle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, std::to_string(number));
- if (status.IsError()) {
- return status;
- }
- }
+ // number
+ status = SetEventsNumberFromJson(noti_val, "number", tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("detailInfo") && !IsNull(noti_obj, "detailInfo")) {
- status = SetDetailInfos(noti_handle, common::FromJson<picojson::array>(noti_obj, "detailInfo"));
- if (status.IsError()) {
- return status;
- }
- }
+ // detailInfo
+ status = SetDetailInfosFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("ledColor") && !IsNull(noti_obj, "ledColor")) {
- status = SetLedColor(noti_handle, common::FromJson<std::string>(noti_obj, "ledColor"));
- if (status.IsError()) {
- return status;
- }
- }
+ // ledColor
+ status = SetLedColorFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- status = SetLedOnPeriod(
- noti_handle, static_cast<unsigned long>(common::FromJson<double>(noti_obj, "ledOnPeriod")));
- if (status.IsError()) {
- return status;
- }
+ // ledOnPeriod
+ status = SetLedOnPeriodFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- status = SetLedOffPeriod(
- noti_handle, static_cast<unsigned long>(common::FromJson<double>(noti_obj, "ledOffPeriod")));
- if (status.IsError()) {
- return status;
- }
+ // ledOffPeriod
+ status = SetLedOffPeriodFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("backgroundImagePath") && !IsNull(noti_obj, "backgroundImagePath")) {
- const std::string& value_str = common::FromJson<std::string>(noti_obj, "backgroundImagePath");
- std::string real_path = common::FilesystemProvider::Create().GetRealPath(value_str);
+ // backgroundImagePath
+ status = SetPathFromJson(noti_val, NOTIFICATION_IMAGE_TYPE_BACKGROUND, "backgroundImagePath",
+ tmp_noti);
+ CHECK_ERROR(status);
- status = SetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, real_path);
- if (status.IsError()) {
- return status;
- }
- }
+ // thumbnails
+ status = SetPathsArrayFromJson(noti_val, thumbnails_map_, "thumbnails", tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("thumbnails") && !IsNull(noti_obj, "thumbnails")) {
- status = SetThumbnails(noti_handle, common::FromJson<picojson::array>(noti_obj, "thumbnails"));
- if (status.IsError()) {
- return status;
- }
- }
+ // soundPath
+ status = SetSoundPathFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- if (val.contains("soundPath") && !IsNull(noti_obj, "soundPath")) {
- const std::string& value_str = common::FromJson<std::string>(noti_obj, "soundPath");
- std::string real_path = common::FilesystemProvider::Create().GetRealPath(value_str);
+ // vibration
+ status = SetVibrationFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- status = SetSoundPath(noti_handle, real_path);
- if (status.IsError()) {
- return status;
- }
- }
+ // appControl, appId
+ status = SetAppControlInfoFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
- status = SetVibration(noti_handle, common::FromJson<bool>(noti_obj, "vibration"));
- if (status.IsError()) {
- return status;
- }
+ // progressType, progressValue
+ status = SetProgressTypeAndValueFromJson(noti_val, is_update, tmp_noti);
+ CHECK_ERROR(status);
- status = CreateAppControl(&app_control);
- if (status.IsError()) {
- return status;
- }
-
- if (val.contains("appControl") && !IsNull(noti_obj, "appControl")) {
- status = SetApplicationControl(app_control,
- common::FromJson<picojson::object>(noti_obj, "appControl"));
- if (status.IsError()) {
- return status;
- }
- }
-
- if (val.contains("appId") && !IsNull(noti_obj, "appId")) {
- status = SetApplicationId(app_control, common::FromJson<std::string>(noti_obj, "appId"));
- if (status.IsError()) {
- return status;
- }
- }
-
- const std::string& progress_type = common::FromJson<std::string>(noti_obj, "progressType");
- status = SetImage(noti_handle, NOTIFICATION_IMAGE_TYPE_LIST_5, progress_type);
- if (status.IsError()) {
- return status;
- }
-
- double progressValue;
- if (val.contains("progressValue") && !IsNull(noti_obj, "progressValue")) {
- progressValue = common::FromJson<double>(noti_obj, "progressValue");
- } else {
- progressValue = -1;
- }
-
- status = SetProgressValue(noti_handle, progress_type, progressValue, is_update);
-
- if (status.IsError()) {
- return status;
- }
-
- status = SetText(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE,
- common::FromJson<std::string>(noti_obj, "title"));
- if (status.IsError()) {
- return status;
- }
-
- if (val.contains("content") && !IsNull(noti_obj, "content")) {
- status = SetText(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT,
- common::FromJson<std::string>(noti_obj, "content"));
- if (status.IsError()) {
- return status;
- }
- }
-
- status = SetAppControl(noti_handle, app_control);
-
- if (is_update) {
- ret = notification_update(noti_handle);
-
- } else {
- ret = notification_insert(noti_handle, &id);
- if (NOTIFICATION_ERROR_NONE != ret) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot insert notification");
- }
- }
- if (ret != NOTIFICATION_ERROR_NONE) {
- return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Post/Update notification error",
- ("Post/Update notification error: %d", ret));
- }
-
- time_t posted_time;
- status = GetPostedTime(noti_handle, &posted_time);
- if (status.IsError()) {
- return status;
- }
-
- if (is_update) {
- return PlatformResult(ErrorCode::NO_ERROR);
- }
-
- picojson::object& out = *out_ptr;
- out["id"] = picojson::value(std::to_string(id));
- out["postedTime"] = picojson::value(static_cast<double>(posted_time) * 1000.0);
- out["type"] = picojson::value("STATUS");
+ *noti_handle = tmp_noti_ptr.release();
return PlatformResult(ErrorCode::NO_ERROR);
}
+PlatformResult StatusNotification::PostStatusNotification(const picojson::object& args,
+ bool is_update,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ return PostNotification(args, is_update, out_ptr, GetNotiHandleFromJson);
+}
+
} // namespace notification
} // namespace extension
#include "common/picojson.h"
#include "common/platform_result.h"
+#include "common/XW_Extension.h"
+
+#include "notification/common_notification.h"
+
namespace extension {
namespace notification {
-typedef std::map<int, notification_text_type_e> InformationEnumMap;
-typedef std::map<int, notification_image_type_e> ImageEnumMap;
-
-class StatusNotification {
+class StatusNotification : public CommonNotification {
public:
- static common::PlatformResult ToJson(int id, notification_h noti_handle, app_control_h app_handle,
- picojson::object* out_ptr);
- static common::PlatformResult FromJson(const picojson::object& args, bool is_update,
- picojson::object* out_ptr);
- static common::PlatformResult GetAppControl(notification_h noti_handle,
- app_control_h* app_control);
- static common::PlatformResult GetNotiHandle(int id, notification_h* noti_handle);
+ XW_EXPORT static common::PlatformResult ToJson(int id, notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr);
+ XW_EXPORT static common::PlatformResult GetNotiHandleFromJson(const picojson::value& noti_val,
+ bool is_update,
+ notification_h* noti_handle);
+ static common::PlatformResult PostStatusNotification(const picojson::object& args, bool is_update,
+ picojson::object* out_ptr);
private:
StatusNotification();
virtual ~StatusNotification();
-
- static const InformationEnumMap info_map_;
- static const InformationEnumMap info_sub_map_;
- static const ImageEnumMap thumbnails_map_;
-
- static common::PlatformResult StatusTypeFromPlatform(notification_type_e noti_type,
- notification_ly_type_e noti_layout,
- std::string* type);
- static common::PlatformResult StatusTypeToPlatform(const std::string& type,
- notification_type_e* noti_type);
- static common::PlatformResult Create(notification_type_e noti_type, notification_h* noti_handle);
- static common::PlatformResult GetImage(notification_h noti_handle,
- notification_image_type_e image_type,
- std::string* image_path);
- static common::PlatformResult SetImage(notification_h noti_handle,
- notification_image_type_e image_type,
- const std::string& image_path);
- static common::PlatformResult GetText(notification_h noti_handle,
- notification_text_type_e text_type, std::string* noti_text);
- static common::PlatformResult SetText(notification_h noti_handle,
- notification_text_type_e text_type,
- const std::string& noti_text);
- static common::PlatformResult GetNumber(notification_h noti_handle,
- notification_text_type_e text_type, long* number);
- static common::PlatformResult GetDetailInfos(notification_h noti_handle, picojson::array* out);
- static common::PlatformResult SetDetailInfos(notification_h noti_handle,
- const picojson::array& value);
- static common::PlatformResult GetLedColor(notification_h noti_handle, std::string* led_color);
- static common::PlatformResult SetLedColor(notification_h noti_handle,
- const std::string& led_color);
- static common::PlatformResult GetLedPeriod(notification_h noti_handle, unsigned long* on_period,
- unsigned long* off_period);
- static common::PlatformResult SetLedOnPeriod(notification_h noti_handle, unsigned long on_period);
- static common::PlatformResult SetLedOffPeriod(notification_h noti_handle,
- unsigned long off_period);
- static common::PlatformResult GetThumbnails(notification_h noti_handle, picojson::array* out);
- static common::PlatformResult SetThumbnails(notification_h noti_handle,
- const picojson::array& value);
- static common::PlatformResult GetSoundPath(notification_h noti_handle, std::string* sound_path);
- static common::PlatformResult SetSoundPath(notification_h noti_handle,
- const std::string& sound_path);
- static common::PlatformResult GetVibration(notification_h noti_handle, bool* vibration);
- static common::PlatformResult SetVibration(notification_h noti_handle, bool vibration);
- static common::PlatformResult GetApplicationControl(app_control_h app_handle,
- picojson::object* out_ptr);
- static common::PlatformResult SetApplicationControl(app_control_h app_handle,
- const picojson::object& app_ctrl);
- static common::PlatformResult GetApplicationId(app_control_h app_handle, std::string* app_id);
- static common::PlatformResult SetApplicationId(app_control_h app_handle,
- const std::string& app_id);
- static common::PlatformResult GetProgressValue(notification_h noti_handle,
- const std::string& progess_type,
- double* progress_value);
- static common::PlatformResult SetProgressValue(notification_h noti_handle,
- const std::string& progress_type,
- double progress_value, bool is_update);
- static common::PlatformResult GetPostedTime(notification_h noti_handle, time_t* posted_time);
- static common::PlatformResult SetLayout(notification_h noti_handle, const std::string& noti_type);
- static common::PlatformResult SetAppControl(notification_h noti_handle,
- app_control_h app_control);
- static common::PlatformResult CreateAppControl(app_control_h* app_control);
-
- static bool IsColorFormatNumberic(const std::string& color);
};
} // namespace notification
--- /dev/null
+/*
+ * Copyright (c) 2017 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 "notification/user_notification.h"
+
+#include "common/converter.h"
+#include "common/logger.h"
+#include "common/scope_exit.h"
+
+namespace extension {
+namespace notification {
+
+using namespace common;
+
+UserNotification::UserNotification() {
+}
+
+UserNotification::~UserNotification() {
+}
+
+PlatformResult UserNotification::ToJson(int id, notification_h noti_handle,
+ app_control_h app_handle, picojson::object* out_ptr) {
+ LoggerD("Enter");
+ PlatformResult ret = AddCommonMembersToJson(id, noti_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ std::string noti_type_str;
+ ret = AddTypeToJson(noti_handle, "userType", out_ptr, ¬i_type_str);
+ CHECK_ERROR(ret);
+
+ ret = AddTextContentsToJson(noti_handle, noti_type_str, out_ptr);
+ CHECK_ERROR(ret);
+
+ ret = AddImagesToJson(noti_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ ret = AddThumbnailsToJson(noti_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ ret = AddActionsToJson(noti_handle, app_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ ret = AddGroupContentsToJson(noti_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ ret = AddLedsToJson(noti_handle, out_ptr);
+ CHECK_ERROR(ret);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::GetNotiHandleFromJson(const picojson::value& noti_val,
+ bool is_update,
+ notification_h* noti_handle) {
+ LoggerD("Enter");
+ picojson::object noti_obj = noti_val.get<picojson::object>();
+
+ notification_h tmp_noti = nullptr;
+ PlatformResult status = InitNotiFromJson(noti_obj, "userType", is_update, &tmp_noti);
+ CHECK_ERROR(status);
+ std::unique_ptr<std::remove_pointer<notification_h>::type, int (*)(notification_h)> tmp_noti_ptr(
+ tmp_noti, ¬ification_free); // automatically release the memory
+
+ status = SetCommonMembersFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetTextContentsFromJson(noti_val, is_update, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetImagesFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetThumbnailsFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetActionsFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetGroupContentsFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ status = SetLedsFromJson(noti_val, tmp_noti);
+ CHECK_ERROR(status);
+
+ *noti_handle = tmp_noti_ptr.release();
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::PostUserNotification(const picojson::object& args, bool is_update,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+ return PostNotification(args, is_update, out_ptr, GetNotiHandleFromJson);
+}
+
+PlatformResult UserNotification::AddTextContentsToJson(notification_h noti_handle,
+ std::string noti_type_str,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value text_contents = picojson::value(picojson::object());
+ picojson::object& text_contents_obj = text_contents.get<picojson::object>();
+
+ // progressType, progressValue
+ PlatformResult status =
+ AddProgressTypeAndValueToJson(noti_handle, noti_type_str, &text_contents_obj);
+ CHECK_ERROR(status);
+
+ // eventsNumber
+ status = AddEventsNumberToJson(noti_handle, "eventsNumber", &text_contents_obj);
+ CHECK_ERROR(status);
+
+ // detailInfo
+ status = AddDetailInfosToJson(noti_handle, &text_contents_obj);
+ CHECK_ERROR(status);
+
+ // buttonsTexts
+ status = AddTextsArrayToJson(noti_handle, buttons_texts_map_, "buttonsTexts", &text_contents_obj);
+ CHECK_ERROR(status);
+
+ // contentForOff
+ status = AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ "contentForOff", &text_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["textContents"] = text_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddImagesToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value images_contents = picojson::value(picojson::object());
+ picojson::object& images_contents_obj = images_contents.get<picojson::object>();
+
+ // iconPath
+ PlatformResult status =
+ AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, "iconPath", &images_contents_obj);
+ CHECK_ERROR(status);
+
+ // subIconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_SUB, "subIconPath",
+ &images_contents_obj);
+ CHECK_ERROR(status);
+
+ // indicatorIconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ "indicatorIconPath", &images_contents_obj);
+ CHECK_ERROR(status);
+
+ // lockScreenIconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_FOR_LOCK, "lockScreenIconPath",
+ &images_contents_obj);
+ CHECK_ERROR(status);
+
+ // buttonIconPaths
+ status = AddPathsArrayToJson(noti_handle, buttons_icon_paths_map_, "buttonIconPaths",
+ &images_contents_obj);
+ CHECK_ERROR(status);
+
+ // backgroundImagePath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, "backgroundImagePath",
+ &images_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["images"] = images_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddThumbnailsToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value thumbnails_contents = picojson::value(picojson::object());
+ picojson::object& thumbnails_contents_obj = thumbnails_contents.get<picojson::object>();
+
+ // lockScreenThumbnailIconPath
+ PlatformResult status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_THUMBNAIL_FOR_LOCK,
+ "lockScreenThumbnailIconPath", &thumbnails_contents_obj);
+ CHECK_ERROR(status);
+
+ // thumbnailIconPath
+ status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_THUMBNAIL, "thumbnailIconPath",
+ &thumbnails_contents_obj);
+ CHECK_ERROR(status);
+
+ // thumbnails
+ status =
+ AddPathsArrayToJson(noti_handle, thumbnails_map_, "thumbnails", &thumbnails_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["thumbnails"] = thumbnails_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddActionsToJson(notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value actions_contents = picojson::value(picojson::object());
+ picojson::object& actions_contents_obj = actions_contents.get<picojson::object>();
+
+ // soundPath
+ PlatformResult status = AddSoundPathToJson(noti_handle, &actions_contents_obj);
+ CHECK_ERROR(status);
+
+ // vibration
+ status = AddVibrationToJson(noti_handle, &actions_contents_obj);
+ CHECK_ERROR(status);
+
+ // appControl, appId
+ status = AddAppControlInfoToJson(noti_handle, app_handle, &actions_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["actions"] = actions_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddGroupContentsToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value group_contents = picojson::value(picojson::object());
+ picojson::object& group_contents_obj = group_contents.get<picojson::object>();
+
+ // groupTitle
+ PlatformResult status = AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_GROUP_TITLE,
+ "groupTitle", &group_contents_obj);
+ CHECK_ERROR(status);
+
+ // groupContent
+ status = AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_GROUP_CONTENT, "groupContent",
+ &group_contents_obj);
+ CHECK_ERROR(status);
+
+ // groupContentForOff
+ status =
+ AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_GROUP_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ "groupContentForOff", &group_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["groupContents"] = group_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddLedsToJson(notification_h noti_handle,
+ picojson::object* out_ptr) {
+ LoggerD("Enter");
+
+ picojson::value leds_contents = picojson::value(picojson::object());
+ picojson::object& leds_contents_obj = leds_contents.get<picojson::object>();
+
+ // ledColor
+ PlatformResult status = AddLedColorToJson(noti_handle, &leds_contents_obj);
+ CHECK_ERROR(status);
+
+ // ledOnPeriod, ledOffPeriod
+ status = AddLedOnOffPeriodToJson(noti_handle, &leds_contents_obj);
+ CHECK_ERROR(status);
+
+ (*out_ptr)["leds"] = leds_contents;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetTextContentsFromJson(const picojson::value& noti_value,
+ bool is_update,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ if (noti_value.contains("textContents") &&
+ noti_value.get("textContents").is<picojson::object>()) {
+ LoggerD("nullable member textContents is present - parsing it");
+ const picojson::value& text_contents_value = noti_value.get("textContents");
+
+ // progressType, progressValue
+ PlatformResult status =
+ SetProgressTypeAndValueFromJson(text_contents_value, is_update, noti_handle);
+ CHECK_ERROR(status);
+
+ // eventsNumber
+ status = SetEventsNumberFromJson(text_contents_value, "eventsNumber", noti_handle);
+ CHECK_ERROR(status);
+
+ // detailInfo
+ status = SetDetailInfosFromJson(text_contents_value, noti_handle);
+ CHECK_ERROR(status);
+
+ // buttonsTexts
+ status =
+ SetTextsArrayFromJson(text_contents_value, buttons_texts_map_, "buttonsTexts", noti_handle);
+ CHECK_ERROR(status);
+
+ // contentForOff
+ status = SetTextFromJson(text_contents_value,
+ NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ "contentForOff", noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetImagesFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+ if (noti_value.contains("images") && noti_value.get("images").is<picojson::object>()) {
+ LoggerD("nullable member images is present - parsing it");
+ const picojson::value& images_value = noti_value.get("images");
+
+ // iconPath
+ PlatformResult status =
+ SetPathFromJson(images_value, NOTIFICATION_IMAGE_TYPE_ICON, "iconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // subIconPath
+ status =
+ SetPathFromJson(images_value, NOTIFICATION_IMAGE_TYPE_ICON_SUB, "subIconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // indicatorIconPath
+ status = SetPathFromJson(images_value, NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ "indicatorIconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // lockScreenIconPath
+ status = SetPathFromJson(images_value, NOTIFICATION_IMAGE_TYPE_ICON_FOR_LOCK,
+ "lockScreenIconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // buttonIconPaths
+ status = SetPathsArrayFromJson(images_value, buttons_icon_paths_map_, "buttonIconPaths",
+ noti_handle);
+ CHECK_ERROR(status);
+
+ // backgroundImagePath
+ status = SetPathFromJson(images_value, NOTIFICATION_IMAGE_TYPE_BACKGROUND,
+ "backgroundImagePath", noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetThumbnailsFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+
+ if (noti_value.contains("thumbnails") && noti_value.get("thumbnails").is<picojson::object>()) {
+ LoggerD("nullable member thumbnails is present - parsing it");
+ const picojson::value& thumbnails_value = noti_value.get("thumbnails");
+
+ // lockScreenThumbnailIconPath
+ PlatformResult status =
+ SetPathFromJson(thumbnails_value, NOTIFICATION_IMAGE_TYPE_THUMBNAIL_FOR_LOCK,
+ "lockScreenThumbnailIconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // thumbnailIconPath
+ status = SetPathFromJson(thumbnails_value, NOTIFICATION_IMAGE_TYPE_THUMBNAIL,
+ "thumbnailIconPath", noti_handle);
+ CHECK_ERROR(status);
+
+ // thumbnails
+ status = SetPathsArrayFromJson(thumbnails_value, thumbnails_map_, "thumbnails", noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetActionsFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+
+ if (noti_value.contains("actions") && noti_value.get("actions").is<picojson::object>()) {
+ LoggerD("nullable member actions is present - parsing it");
+ const picojson::value& actions_value = noti_value.get("actions");
+
+ // soundPath
+ PlatformResult status = SetSoundPathFromJson(actions_value, noti_handle);
+ CHECK_ERROR(status);
+
+ // vibration
+ status = SetVibrationFromJson(actions_value, noti_handle);
+ CHECK_ERROR(status);
+
+ // appControl, appId
+ status = SetAppControlInfoFromJson(actions_value, noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetGroupContentsFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+
+ if (noti_value.contains("groupContents") &&
+ noti_value.get("groupContents").is<picojson::object>()) {
+ LoggerD("nullable member groupContents is present - parsing it");
+ const picojson::value& group_contents_value = noti_value.get("groupContents");
+
+ // groupTitle
+ PlatformResult status = SetTextFromJson(
+ group_contents_value, NOTIFICATION_TEXT_TYPE_GROUP_TITLE, "groupTitle", noti_handle);
+ CHECK_ERROR(status);
+
+ // groupContent
+ status = SetTextFromJson(group_contents_value, NOTIFICATION_TEXT_TYPE_GROUP_CONTENT,
+ "groupContent", noti_handle);
+ CHECK_ERROR(status);
+
+ // groupContentForOff
+ status = SetTextFromJson(group_contents_value,
+ NOTIFICATION_TEXT_TYPE_GROUP_CONTENT_FOR_DISPLAY_OPTION_IS_OFF,
+ "groupContentForOff", noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetLedsFromJson(const picojson::value& noti_value,
+ notification_h noti_handle) {
+ LoggerD("Enter");
+
+ if (noti_value.contains("leds") && noti_value.get("leds").is<picojson::object>()) {
+ LoggerD("nullable member leds is present - parsing it");
+ const picojson::value& leds_value = noti_value.get("leds");
+
+ // ledColor
+ PlatformResult status = SetLedColorFromJson(leds_value, noti_handle);
+ CHECK_ERROR(status);
+
+ // ledOnPeriod
+ status = SetLedOnPeriodFromJson(leds_value, noti_handle);
+ CHECK_ERROR(status);
+
+ // ledOffPeriod
+ status = SetLedOffPeriodFromJson(leds_value, noti_handle);
+ CHECK_ERROR(status);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // namespace notification
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2017 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 NOTIFICATION_USER_NOTIFICATION_H_
+#define NOTIFICATION_USER_NOTIFICATION_H_
+
+#include "notification/common_notification.h"
+
+namespace extension {
+namespace notification {
+
+class UserNotification : public CommonNotification {
+ public:
+ XW_EXPORT static common::PlatformResult ToJson(int id, notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr);
+ XW_EXPORT static common::PlatformResult GetNotiHandleFromJson(const picojson::value& noti_val,
+ bool is_update,
+ notification_h* noti_handle);
+ static common::PlatformResult PostUserNotification(const picojson::object& args, bool is_update,
+ picojson::object* out_ptr);
+
+ static common::PlatformResult AddTextContentsToJson(notification_h noti_handle,
+ std::string noti_type_str,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddImagesToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddThumbnailsToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddActionsToJson(notification_h noti_handle,
+ app_control_h app_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddGroupContentsToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+ static common::PlatformResult AddLedsToJson(notification_h noti_handle,
+ picojson::object* out_ptr);
+
+ static common::PlatformResult SetTextContentsFromJson(const picojson::value& noti_val,
+ bool is_update, notification_h noti_handle);
+ static common::PlatformResult SetImagesFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+ static common::PlatformResult SetThumbnailsFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+ static common::PlatformResult SetActionsFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+ static common::PlatformResult SetGroupContentsFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+ static common::PlatformResult SetLedsFromJson(const picojson::value& noti_val,
+ notification_h noti_handle);
+
+ private:
+ UserNotification();
+ virtual ~UserNotification();
+};
+
+} // namespace notification
+} // namespace extension
+
+#endif /* NOTIFICATION_USER_NOTIFICATION_H_ */
'variables': {
'packages': [
'capi-system-device',
- 'deviced',
'vconf',
]
},
['tizen == 1', {
'variables': {
'packages': [
- 'capi-appfw-application',
+ 'capi-appfw-preference',
]
},
}],
'variables': {
'packages': [
'push',
- 'capi-appfw-application',
+ 'capi-appfw-app-control',
'libpcrecpp',
]
},
GRAVITY : 'GRAVITY',
GYROSCOPE : 'GYROSCOPE',
GYROSCOPE_ROTATION_VECTOR : 'GYROSCOPE_ROTATION_VECTOR',
- LINEAR_ACCELERATION : 'LINEAR_ACCELERATION'
+ LINEAR_ACCELERATION : 'LINEAR_ACCELERATION',
+ MAGNETIC_UNCALIBRATED : 'MAGNETIC_UNCALIBRATED',
+ GYROSCOPE_UNCALIBRATED : 'GYROSCOPE_UNCALIBRATED',
+ ACCELERATION : 'ACCELERATION'
};
var ProximityState = {
'GRAVITY' : {},
'GYROSCOPE' : {},
'GYROSCOPE_ROTATION_VECTOR' : {},
- 'LINEAR_ACCELERATION' : {}
+ 'LINEAR_ACCELERATION' : {},
+ 'MAGNETIC_UNCALIBRATED' : {},
+ 'GYROSCOPE_UNCALIBRATED' : {},
+ 'ACCELERATION' : {}
};
var errorWrapper = function (err) {
return new GyroscopeRotationVectorSensor();
} else if (_supportedSensors[index] === SensorType.LINEAR_ACCELERATION){
return new LinearAccelerationSensor();
+ } else if (_supportedSensors[index] === SensorType.MAGNETIC_UNCALIBRATED) {
+ return new MagneticUncalibratedSensor();
+ } else if (_supportedSensors[index] === SensorType.GYROSCOPE_UNCALIBRATED) {
+ return new GyroscopeUncalibratedSensor();
+ } else if (_supportedSensors[index] === SensorType.ACCELERATION) {
+ return new AccelerationSensor();
}
};
_sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args));
};
+//// MagneticUncalibratedSensor
+var MagneticUncalibratedSensor = function(data) {
+ Sensor.call(this, SensorType.MAGNETIC_UNCALIBRATED);
+};
+
+MagneticUncalibratedSensor.prototype = new Sensor();
+
+MagneticUncalibratedSensor.prototype.constructor = Sensor;
+
+MagneticUncalibratedSensor.prototype.getMagneticUncalibratedSensorData = function() {
+ var args = validator_.validateArgs(arguments, [
+ {
+ name : 'successCallback',
+ type : types_.FUNCTION
+ },
+ {
+ name : 'errorCallback',
+ type : types_.FUNCTION,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args));
+};
+
+//// GyroscopeUncalibratedSensor
+var GyroscopeUncalibratedSensor = function(data) {
+ Sensor.call(this, SensorType.GYROSCOPE_UNCALIBRATED);
+};
+
+GyroscopeUncalibratedSensor.prototype = new Sensor();
+
+GyroscopeUncalibratedSensor.prototype.constructor = Sensor;
+
+GyroscopeUncalibratedSensor.prototype.getGyroscopeUncalibratedSensorData = function() {
+ var args = validator_.validateArgs(arguments, [
+ {
+ name : 'successCallback',
+ type : types_.FUNCTION
+ },
+ {
+ name : 'errorCallback',
+ type : types_.FUNCTION,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args));
+};
+
+//// AccelerationSensor
+var AccelerationSensor = function(data) {
+ Sensor.call(this, SensorType.ACCELERATION);
+};
+
+AccelerationSensor.prototype = new Sensor();
+
+AccelerationSensor.prototype.constructor = Sensor;
+
+AccelerationSensor.prototype.getAccelerationSensorData = function() {
+ var args = validator_.validateArgs(arguments, [
+ {
+ name : 'successCallback',
+ type : types_.FUNCTION
+ },
+ {
+ name : 'errorCallback',
+ type : types_.FUNCTION,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args));
+};
////////////////////// Sensor Data classes/////////////////////////////////////////////////////
////Base SensorData class
_sensorListeners[SensorType.LINEAR_ACCELERATION] = new SensorListener(SensorType.LINEAR_ACCELERATION,
SensorLinearAccelerationData);
+//// SensorMagneticUncalibratedData
+var SensorMagneticUncalibratedData = function(data) {
+ SensorData.call(this);
+ Object.defineProperties(this, {
+ x : {value: data.x, writable: false, enumerable: true},
+ y : {value: data.y, writable: false, enumerable: true},
+ z : {value: data.z, writable: false, enumerable: true},
+ xAxisBias : {value: data.xAxisBias, writable: false, enumerable: true},
+ yAxisBias : {value: data.yAxisBias, writable: false, enumerable: true},
+ zAxisBias : {value: data.zAxisBias, writable: false, enumerable: true}
+ });
+};
+
+SensorMagneticUncalibratedData.prototype = new SensorData();
+
+SensorMagneticUncalibratedData.prototype.constructor = SensorData;
+
+_sensorListeners[SensorType.MAGNETIC_UNCALIBRATED] = new SensorListener(SensorType.MAGNETIC_UNCALIBRATED,
+ SensorMagneticUncalibratedData);
+
+//// SensorGyroscopeUncalibratedData
+var SensorGyroscopeUncalibratedData = function(data) {
+ SensorData.call(this);
+ Object.defineProperties(this, {
+ x : {value: data.x, writable: false, enumerable: true},
+ y : {value: data.y, writable: false, enumerable: true},
+ z : {value: data.z, writable: false, enumerable: true},
+ xAxisDrift : {value: data.xAxisDrift, writable: false, enumerable: true},
+ yAxisDrift : {value: data.yAxisDrift, writable: false, enumerable: true},
+ zAxisDrift : {value: data.zAxisDrift, writable: false, enumerable: true}
+ });
+
+};
+
+SensorGyroscopeUncalibratedData.prototype = new SensorData();
+
+SensorGyroscopeUncalibratedData.prototype.constructor = SensorData;
+
+_sensorListeners[SensorType.GYROSCOPE_UNCALIBRATED] = new SensorListener(SensorType.GYROSCOPE_UNCALIBRATED,
+ SensorGyroscopeUncalibratedData);
+
+//// SensorAccelerationData
+var SensorAccelerationData = function(data) {
+ SensorData.call(this);
+ Object.defineProperties(this, {
+ x : {value: data.x, writable: false, enumerable: true},
+ y : {value: data.y, writable: false, enumerable: true},
+ z : {value: data.z, writable: false, enumerable: true},
+ });
+};
+
+SensorAccelerationData.prototype = new SensorData();
+
+SensorAccelerationData.prototype.constructor = SensorData;
+
+_sensorListeners[SensorType.ACCELERATION] = new SensorListener(SensorType.ACCELERATION,
+ SensorAccelerationData);
//////////////////////SensorHardwareInfo classes//////////////////////////////////////////////////////////
function SensorHardwareInfo(data) {
(*out)["z"] = picojson::value(static_cast<double>(sensor_event->values[2]));
break;
}
+ case SENSOR_GEOMAGNETIC_UNCALIBRATED: {
+ (*out)["x"] = picojson::value(static_cast<double>(sensor_event->values[0]));
+ (*out)["y"] = picojson::value(static_cast<double>(sensor_event->values[1]));
+ (*out)["z"] = picojson::value(static_cast<double>(sensor_event->values[2]));
+ (*out)["xAxisBias"] = picojson::value(static_cast<double>(sensor_event->values[3]));
+ (*out)["yAxisBias"] = picojson::value(static_cast<double>(sensor_event->values[4]));
+ (*out)["zAxisBias"] = picojson::value(static_cast<double>(sensor_event->values[5]));
+ break;
+ }
+ case SENSOR_GYROSCOPE_UNCALIBRATED: {
+ (*out)["x"] = picojson::value(static_cast<double>(sensor_event->values[0]));
+ (*out)["y"] = picojson::value(static_cast<double>(sensor_event->values[1]));
+ (*out)["z"] = picojson::value(static_cast<double>(sensor_event->values[2]));
+ (*out)["xAxisDrift"] = picojson::value(static_cast<double>(sensor_event->values[3]));
+ (*out)["yAxisDrift"] = picojson::value(static_cast<double>(sensor_event->values[4]));
+ (*out)["zAxisDrift"] = picojson::value(static_cast<double>(sensor_event->values[5]));
+ break;
+ }
+ case SENSOR_ACCELEROMETER: {
+ (*out)["x"] = picojson::value(static_cast<double>(sensor_event->values[0]));
+ (*out)["y"] = picojson::value(static_cast<double>(sensor_event->values[1]));
+ (*out)["z"] = picojson::value(static_cast<double>(sensor_event->values[2]));
+ break;
+ }
default: {
LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unsupported type"), out);
return;
AddSensor(
new SensorData(instance, SENSOR_GYROSCOPE_ROTATION_VECTOR, "GYROSCOPE_ROTATION_VECTOR", 4));
AddSensor(new SensorData(instance, SENSOR_LINEAR_ACCELERATION, "LINEAR_ACCELERATION", 3));
+ AddSensor(new SensorData(instance, SENSOR_GEOMAGNETIC_UNCALIBRATED, "MAGNETIC_UNCALIBRATED", 6));
+ AddSensor(new SensorData(instance, SENSOR_GYROSCOPE_UNCALIBRATED, "GYROSCOPE_UNCALIBRATED", 6));
+ AddSensor(new SensorData(instance, SENSOR_ACCELEROMETER, "ACCELERATION", 3));
}
SensorService::~SensorService() {
]
},
}],
- ['tizen_is_emulator == 1', {
- 'defines': ['TIZEN_IS_EMULATOR'],
- }],
],
},
],
value : data.isCharging,
writable : false,
enumerable : true
+ },
+ timeToDischarge : {
+ value : data.timeToDischarge,
+ writable : false,
+ enumerable : true
+ },
+ timeToFullCharge : {
+ value : data.timeToFullCharge,
+ writable : false,
+ enumerable : true
}
});
}
const char* kPlatformCoreSsse3 = "ssse3";
const char* kPlatformCoreVfpv2 = "vfpv2";
const char* kPlatformCoreVfpv3 = "vfpv3";
+const char* kPlatformCoreVfpv4 = "vfpv4";
/*API feature*/
/*Network feature*/
}
result += kPlatformCoreVfpv3;
}
+
+ ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.vfpv4", &bool_result);
+ if (ret.IsError()) {
+ return ret;
+ }
+ if (bool_result) {
+ if (!result.empty()) {
+ result += kPlatformCoreDelimiter;
+ }
+ result += kPlatformCoreVfpv4;
+ }
if (result.empty()) {
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "platformCoreFpuArch result is empty");
}
return true;
}
+#define MODEL_NAME "http://tizen.org/system/model_name"
+#define MODEL_EMULATOR "Emulator"
+bool _is_emulator(void) {
+ int ret;
+ char* model_name = NULL;
+ static bool emul = false;
+ static int set = 0;
+
+ if (set) return emul;
+
+ ret = system_info_get_platform_string(MODEL_NAME, &model_name);
+ if (ret < 0) {
+ LoggerD("Cannot get model name(%d)", ret);
+ return emul;
+ }
+
+ if (!strncmp(MODEL_EMULATOR, model_name, strlen(model_name) + 1)) emul = true;
+
+ set = 1;
+ free(model_name);
+
+ return emul;
+}
+
PlatformResult SystemInfoDeviceCapability::GetPlatformCoreCpuFrequency(int* return_value) {
LoggerD("Entered");
std::string freq;
std::string file_name;
-#ifdef TIZEN_IS_EMULATOR
- file_name = "/proc/cpuinfo";
-#else
- file_name = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
-#endif
+ if (_is_emulator())
+ file_name = "/proc/cpuinfo";
+ else
+ file_name = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
std::ifstream cpuinfo_freq(file_name);
if (!cpuinfo_freq.is_open()) {
("Failed to get cpu frequency"));
}
-#ifdef TIZEN_IS_EMULATOR
- // get frequency value from cpuinfo file
- // example entry for frequency looks like below
- // cpu MHz : 3392.046
- std::size_t found;
- do {
- getline(cpuinfo_freq, freq);
- found = freq.find("cpu MHz");
- } while (std::string::npos == found && !cpuinfo_freq.eof());
+ if (_is_emulator()) {
+ // get frequency value from cpuinfo file
+ // example entry for frequency looks like below
+ // cpu MHz : 3392.046
+ std::size_t found;
+ do {
+ getline(cpuinfo_freq, freq);
+ found = freq.find("cpu MHz");
+ } while (std::string::npos == found && !cpuinfo_freq.eof());
- found = freq.find(":");
- if (std::string::npos != found) {
- *return_value = std::stoi(freq.substr(found + 2));
+ found = freq.find(":");
+ if (std::string::npos != found) {
+ *return_value = std::stoi(freq.substr(found + 2));
+ }
+ } else {
+ getline(cpuinfo_freq, freq);
+ *return_value = std::stoi(freq) / 1000; // unit: MHz
}
-#else
- getline(cpuinfo_freq, freq);
- *return_value = std::stoi(freq) / 1000; // unit: MHz
-#endif
cpuinfo_freq.close();
LoggerD("cpu frequency : %d", *return_value);
#include <vconf-internal-keys.h>
#include <vconf.h>
+#include "common/GDBus/connection.h"
#include "common/filesystem/filesystem_provider.h"
#include "common/scope_exit.h"
#include "systeminfo/systeminfo-utils.h"
// Battery
const double kRemainingBatteryChargeMax = 100.0;
const int kVconfErrorNone = 0;
+const char* kBatteryTarget = "org.tizen.resourced";
+const char* kBatteryObject = "/Org/Tizen/ResourceD/Logging";
+const char* kBatteryInterface = "org.tizen.resourced.logging";
+const char* kBatteryGetBatteryChargingTime = "GetBatteryChargingTime";
+const char* kBatteryGetBatteryRemainingTime = "GetBatteryRemainingTime";
// Display
const double kDisplayBrightnessDivideValue = 100;
// Device Orientation
return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, (log_msg + std::to_string(ret)),
("vconf_get_int error: %d (%s)", ret, get_error_message(ret)));
}
- out->insert(std::make_pair("isCharging", picojson::value(0 != value)));
+ bool isCharging = (0 != value);
+ out->insert(std::make_pair("isCharging", picojson::value(isCharging)));
+
+ if (nullptr == common::dbus::Connection::getInstance().getDBus()) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "dbus wasn't initialized");
+ }
+
+ GError* error = nullptr;
+ GVariant* variant = nullptr;
+ if (isCharging) {
+ variant = g_dbus_connection_call_sync(common::dbus::Connection::getInstance().getDBus(),
+ kBatteryTarget, kBatteryObject, kBatteryInterface,
+ kBatteryGetBatteryChargingTime, g_variant_new("()"), NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ } else {
+ variant = g_dbus_connection_call_sync(common::dbus::Connection::getInstance().getDBus(),
+ kBatteryTarget, kBatteryObject, kBatteryInterface,
+ kBatteryGetBatteryRemainingTime,
+ g_variant_new("(i)", 0), // 0 - POWER_NORMAL_MODE
+ NULL, // 1 - POWER_SAVING_MODE
+ G_DBUS_CALL_FLAGS_NONE, // 2 - ULTRA_SAVING_MODE
+ -1, // for now, only 0 is supported
+ NULL, &error);
+ }
+
+ if (!variant || error) {
+ std::string message = error ? error->message : "";
+ g_error_free(error);
+ return LogAndCreateResult(
+ ErrorCode::UNKNOWN_ERR, "DBus returned error",
+ ("Failed to call %s method - %s",
+ isCharging ? "GetBatteryChargingTime" : "GetBatteryRemainingTime", message.c_str()));
+ } else {
+ int time = 0;
+ g_variant_get(variant, "(i)", &time);
+ g_variant_unref(variant);
+ if (isCharging) {
+ out->insert(std::make_pair("timeToFullCharge", picojson::value(static_cast<double>(time))));
+ out->insert(std::make_pair("timeToDischarge", picojson::value()));
+ } else {
+ out->insert(std::make_pair("timeToFullCharge", picojson::value()));
+ out->insert(std::make_pair("timeToDischarge", picojson::value(static_cast<double>(time))));
+ }
+ }
+
return PlatformResult(ErrorCode::NO_ERROR);
}
Utils.prototype.warn = console.warn.bind(console);
Utils.prototype.log = _enableJsLogs ? console.log.bind(console) : function(){};
+Utils.prototype.global = _global;
+
Utils.prototype.repackFilter = function(filter) {
if (filter instanceof tizen.AttributeFilter) {
return {