[Notification] Add API for using buttons and a text input in a notification and getti... 26/268826/6
authorMarcin Bialek <m.bialek@samsung.com>
Mon, 3 Jan 2022 09:40:45 +0000 (10:40 +0100)
committerMarcin Bialek <m.bialek@samsung.com>
Tue, 18 Jan 2022 18:20:10 +0000 (19:20 +0100)
To add buttons tizen.NotificationButton can be used. It allows setting text, an image and an action. An array of buttons can be provided as a value for
"buttons" key in InputInitDict. To use a text input, an object with proper values can be provided as a value for "textInput" key. To get notifications
block state, tizen.notification.getBlockState() function can be used.

[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-284
[Verification] Features have been tested with an example application which uses new API.

Change-Id: I0d3d2110b3cf37d17e4cf632d18263f493606653

src/notification/common_notification.cc
src/notification/common_notification.h
src/notification/notification_api.js
src/notification/notification_extension.cc
src/notification/notification_instance.cc
src/notification/notification_instance.h
src/notification/notification_manager.cc
src/notification/notification_manager.h
src/notification/user_notification.cc
src/notification/user_notification.h

index dbf904d..cee4084 100644 (file)
@@ -54,6 +54,15 @@ const ImageEnumMap CommonNotification::buttons_icon_paths_map_ = {
     {2, NOTIFICATION_IMAGE_TYPE_BUTTON_3}, {3, NOTIFICATION_IMAGE_TYPE_BUTTON_4},
     {4, NOTIFICATION_IMAGE_TYPE_BUTTON_5}, {5, NOTIFICATION_IMAGE_TYPE_BUTTON_6}};
 
+const ButtonIndexEnumMap CommonNotification::buttons_index_map_ = {
+    {0, NOTIFICATION_BUTTON_1}, {1, NOTIFICATION_BUTTON_2}, {2, NOTIFICATION_BUTTON_3},
+    {3, NOTIFICATION_BUTTON_4}, {4, NOTIFICATION_BUTTON_5}, {5, NOTIFICATION_BUTTON_6}};
+
+const EventTypeEnumMap CommonNotification::buttons_events_map_ = {
+    {0, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1}, {1, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2},
+    {2, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3}, {3, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4},
+    {4, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5}, {5, NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6}};
+
 CommonNotification::CommonNotification() {
 }
 
@@ -688,6 +697,95 @@ PlatformResult CommonNotification::SetAppControl(notification_h noti_handle,
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult CommonNotification::AddButton(notification_h noti_handle,
+                                             notification_button_index_e index) {
+  ScopeLogger();
+  int ret = notification_add_button(noti_handle, index);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification add button error",
+                              ("Notification add button error: %d", ret));
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetDisplayApplist(notification_h noti_handle, int* applist) {
+  ScopeLogger();
+  int flags = 0;
+  int ret = notification_get_display_applist(noti_handle, &flags);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
+                              "Notification get display applist error",
+                              ("Notification get display applist error: %d", ret));
+  }
+
+  if (applist) {
+    *applist = flags;
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetDisplayApplist(notification_h noti_handle, int applist) {
+  ScopeLogger();
+  int ret = notification_set_display_applist(noti_handle, applist);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
+                              "Notification set display applist error",
+                              ("Notification set display applist error: %d", ret));
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::GetEventHandler(notification_h noti_handle,
+                                                   notification_event_type_e event_type,
+                                                   app_control_h* event_handler) {
+  ScopeLogger();
+  app_control_h handler;
+  int ret = notification_get_event_handler(noti_handle, event_type, &handler);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification get event handler error",
+                              ("Notification get event handler error: %d", ret));
+  }
+
+  if (event_handler) {
+    *event_handler = handler;
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetEventHandler(notification_h noti_handle,
+                                                   notification_event_type_e event_type,
+                                                   app_control_h event_handler) {
+  ScopeLogger();
+  int ret = notification_set_event_handler(noti_handle, event_type, event_handler);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification set event handler error",
+                              ("Notification set event handler error: %d", ret));
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult CommonNotification::SetTextInput(notification_h noti_handle, int max_length) {
+  ScopeLogger();
+  int ret = notification_set_text_input(noti_handle, max_length);
+
+  if (NOTIFICATION_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Notification set text input error",
+                              ("Notification set text input 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;
@@ -966,6 +1064,33 @@ PlatformResult CommonNotification::AddTextsArrayToJson(notification_h noti_handl
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult CommonNotification::AddEventHandlerToJson(notification_h noti_handle,
+                                                         notification_event_type_e type,
+                                                         const std::string& key,
+                                                         picojson::object* out_ptr) {
+  ScopeLogger();
+  picojson::object& out = *out_ptr;
+  app_control_h event_handler = nullptr;
+  SCOPE_EXIT {
+    if (event_handler) {
+      app_control_destroy(event_handler);
+    }
+  };
+
+  PlatformResult status = GetEventHandler(noti_handle, type, &event_handler);
+  CHECK_ERROR(status);
+  if (event_handler) {
+    picojson::object app_control;
+    status = GetApplicationControl(event_handler, &app_control);
+    CHECK_ERROR(status);
+    if (app_control.size()) {
+      out[key] = picojson::value(app_control);
+    }
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult CommonNotification::AddLedColorToJson(notification_h noti_handle,
                                                      picojson::object* out_ptr) {
   ScopeLogger();
@@ -1376,5 +1501,33 @@ PlatformResult CommonNotification::SetTextFromJson(const picojson::value& noti_v
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult CommonNotification::SetEventHandlerFromJson(const picojson::value& noti_val,
+                                                           notification_event_type_e type,
+                                                           const std::string& key,
+                                                           notification_h noti_handle) {
+  ScopeLogger();
+  const picojson::object& noti_obj = noti_val.get<picojson::object>();
+  app_control_h event_handler = nullptr;
+  SCOPE_EXIT {
+    if (event_handler) {
+      app_control_destroy(event_handler);
+    }
+  };
+
+  if (noti_val.contains(key) && !IsNull(noti_obj, key.c_str())) {
+    PlatformResult status = CreateAppControl(&event_handler);
+    CHECK_ERROR(status);
+
+    const auto& app_control = FromJson<picojson::object>(noti_obj, key.c_str());
+    status = SetApplicationControl(event_handler, app_control);
+    CHECK_ERROR(status);
+
+    status = SetEventHandler(noti_handle, type, event_handler);
+    CHECK_ERROR(status);
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 }  // namespace notification
 }  // namespace extension
index 7bb17c4..4646c93 100644 (file)
@@ -39,6 +39,8 @@ const std::string kProgressTypeByte = "BYTE";
 
 typedef std::map<int, notification_text_type_e> InformationEnumMap;
 typedef std::map<int, notification_image_type_e> ImageEnumMap;
+typedef std::map<int, notification_button_index_e> ButtonIndexEnumMap;
+typedef std::map<int, notification_event_type_e> EventTypeEnumMap;
 
 typedef std::function<common::PlatformResult(const picojson::value& noti_val, bool is_update,
                                              notification_h* noti_handle)>
@@ -57,6 +59,8 @@ class CommonNotification {
   static const ImageEnumMap thumbnails_map_;
   static const InformationEnumMap buttons_texts_map_;
   static const ImageEnumMap buttons_icon_paths_map_;
+  static const ButtonIndexEnumMap buttons_index_map_;
+  static const EventTypeEnumMap buttons_events_map_;
 
   static common::PlatformResult StatusTypeFromPlatform(notification_type_e noti_type,
                                                        notification_ly_type_e noti_layout,
@@ -99,6 +103,17 @@ class CommonNotification {
                                                  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 AddButton(notification_h noti_handle,
+                                          notification_button_index_e index);
+  static common::PlatformResult GetDisplayApplist(notification_h noti_handle, int* applist);
+  static common::PlatformResult SetDisplayApplist(notification_h noti_handle, int applist);
+  static common::PlatformResult GetEventHandler(notification_h noti_handle,
+                                                notification_event_type_e event_type,
+                                                app_control_h* event_handler);
+  static common::PlatformResult SetEventHandler(notification_h noti_handle,
+                                                notification_event_type_e event_type,
+                                                app_control_h event_handler);
+  static common::PlatformResult SetTextInput(notification_h noti_handle, int max_length);
   static common::PlatformResult CreateAppControl(app_control_h* app_control);
 
   static bool IsColorFormatNumeric(const std::string& color);
@@ -148,6 +163,10 @@ class CommonNotification {
   static common::PlatformResult AddTextsArrayToJson(notification_h noti_handle,
                                                     InformationEnumMap map, const std::string& key,
                                                     picojson::object* out_ptr);
+  static common::PlatformResult AddEventHandlerToJson(notification_h noti_handle,
+                                                      notification_event_type_e type,
+                                                      const std::string& key,
+                                                      picojson::object* out_ptr);
 
   // FromJson section
   static common::PlatformResult InitNotiFromJson(const picojson::object& args,
@@ -188,6 +207,10 @@ class CommonNotification {
   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 SetEventHandlerFromJson(const picojson::value& noti_val,
+                                                        notification_event_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,
index 1ca6622..0f77e5d 100644 (file)
@@ -283,6 +283,16 @@ NotificationManager.prototype.getAllNotifications = function() {
     return notifications;
 };
 
+NotificationManager.prototype.getBlockState = function() {
+    var result = native_.callSync('NotificationManagerGetBlockState', {});
+
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
+
+    return native_.getResultObject(result);
+};
+
 /**
  * Plays the custom effect of the service LED that is located to the front of a device.
  *
@@ -1147,6 +1157,199 @@ function LedsInitDict(data) {
     }
 }
 
+function NotificationButton(text, appControl, imagePath) {
+    validator_.isConstructorCall(this, NotificationButton);
+
+    var _text = type_.isString(text) ? text : '';
+    var _appControl =
+        appControl instanceof tizen.ApplicationControl
+            ? appControl
+            : type_.isObject(appControl)
+                ? new tizen.ApplicationControl(
+                    appControl.operation,
+                    appControl.uri || null,
+                    appControl.mime || null,
+                    appControl.category || null,
+                    appControl.data || []
+                )
+                : null;
+    var _imagePath = type_.isString(imagePath) ? imagePath : null;
+
+    Object.defineProperties(this, {
+        text: {
+            get: function() {
+                return _text;
+            },
+            set: function(v) {
+                _text = type_.isString(v) ? v : _text;
+            },
+            enumerable: true
+        },
+        appControl: {
+            get: function() {
+                return _appControl;
+            },
+            set: function(v) {
+                _appControl =
+                    v instanceof tizen.ApplicationControl
+                        ? v
+                        : type_.isObject(v)
+                            ? new tizen.ApplicationControl(
+                                v.operation,
+                                v.uri || null,
+                                v.mime || null,
+                                v.category || null,
+                                v.data || []
+                            )
+                            : _appControl;
+            },
+            enumerable: true
+        },
+        imagePath: {
+            get: function() {
+                return _imagePath;
+            },
+            set: function(v) {
+                _imagePath = type_.isString(v) ? v : _imagePath;
+            },
+            enumerable: true
+        }
+    });
+}
+
+function TextInputInitDict(data) {
+    if (!this) return;
+    var _appControl = null;
+    var _buttonText = null;
+    var _imagePath = null;
+    var _maxLength = null;
+    var _placeholder = null;
+
+    Object.defineProperties(this, {
+        appControl: {
+            get: function() {
+                return _appControl;
+            },
+            set: function(v) {
+                _appControl =
+                    v instanceof tizen.ApplicationControl
+                        ? v
+                        : type_.isObject(v)
+                            ? new tizen.ApplicationControl(
+                                v.operation,
+                                v.uri || null,
+                                v.mime || null,
+                                v.category || null,
+                                v.data || []
+                            )
+                            : _appControl;
+            },
+            enumerable: true
+        },
+        buttonText: {
+            get: function() {
+                return _buttonText;
+            },
+            set: function(v) {
+                _buttonText = type_.isString(v) || type_.isNull(v) ? v : _buttonText;
+            },
+            enumerable: true
+        },
+        imagePath: {
+            get: function() {
+                return _imagePath;
+            },
+            set: function(v) {
+                _imagePath = type_.isString(v) || type_.isNull(v) ? v : _imagePath;
+            },
+            enumerable: true
+        },
+        maxLength: {
+            get: function() {
+                return _maxLength;
+            },
+            set: function(v) {
+                _maxLength = type_.isNumber(v) || type_.isNull(v) ? v : _maxLength;
+            },
+            enumerable: true
+        },
+        placeholder: {
+            get: function() {
+                return _placeholder;
+            },
+            set: function(v) {
+                _placeholder = type_.isString(v) || type_.isNull(v) ? v : _placeholder;
+            },
+            enumerable: true
+        }
+    });
+
+    if (data instanceof _global.Object) {
+        for (var prop in data) {
+            if (this.hasOwnProperty(prop)) {
+                this[prop] = data[prop];
+            }
+        }
+    }
+}
+
+var _setButtons = function(v) {
+    return v.map(function(b) {
+        return new tizen.NotificationButton(b.text, b.appControl, b.imagePath);
+    });
+};
+
+var _checkButtons = function(v) {
+    if (type_.isNull(v)) {
+        return true;
+    }
+    if (!type_.isArray(v)) {
+        return false;
+    }
+    return v.every(function(b) {
+        return b instanceof tizen.NotificationButton;
+    });
+};
+
+function InputInitDict(data) {
+    if (!this) return;
+    var _buttons = [];
+    var _textInput = null;
+
+    Object.defineProperties(this, {
+        buttons: {
+            get: function() {
+                return _buttons;
+            },
+            set: function(v) {
+                _buttons = _checkButtons(v)
+                    ? v
+                    : type_.isArray(v)
+                        ? _setButtons(v)
+                        : _buttons;
+            },
+            enumerable: true
+        },
+        textInput: {
+            get: function() {
+                return _textInput;
+            },
+            set: function(v) {
+                _textInput = type_.isObject(v) || type_.isNull(v) ? v : _textInput;
+            },
+            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)
@@ -1165,6 +1368,7 @@ function UserNotification(userType, title, notificationGroupedInitDict) {
     this.groupContents = new GroupContentsInitDict(
         notificationGroupedInitDict.groupContents
     );
+    this.inputs = new InputInitDict(notificationGroupedInitDict.inputs);
 
     var _userType =
         Object.keys(UserNotificationType).indexOf(userType) >= 0
@@ -1197,6 +1401,7 @@ function UserNotificationInitDict(data) {
     var _actions = null;
     var _groupContents = null;
     var _leds = null;
+    var _inputs = null;
 
     Object.defineProperties(this, {
         textContents: {
@@ -1253,6 +1458,15 @@ function UserNotificationInitDict(data) {
                 _leds = type_.isObject(v) || type_.isNull(v) ? v : _leds;
             },
             enumerable: true
+        },
+        inputs: {
+            get: function() {
+                return _inputs;
+            },
+            set: function(v) {
+                _inputs = type_.isObject(v) || type_.isNull(v) ? v : _inputs;
+            },
+            enumerable: true
         }
     });
 
@@ -1269,3 +1483,4 @@ exports = new NotificationManager();
 tizen.StatusNotification = StatusNotification;
 tizen.UserNotification = UserNotification;
 tizen.NotificationDetailInfo = NotificationDetailInfo;
+tizen.NotificationButton = NotificationButton;
index 2a9495c..9ea07fc 100644 (file)
@@ -29,7 +29,8 @@ NotificationExtension::NotificationExtension() {
   SetJavaScriptAPI(kSource_notification_api);
 
   const char* entry_points[] = {"tizen.StatusNotification", "tizen.UserNotification",
-                                "tizen.NotificationDetailInfo", NULL};
+                                "tizen.NotificationDetailInfo", "tizen.NotificationButton",
+                                NULL};
   SetExtraJSEntryPoints(entry_points);
 }
 
index 7d2a079..ec77110 100644 (file)
@@ -51,6 +51,7 @@ NotificationInstance::NotificationInstance() {
   REGISTER_METHOD(NotificationManagerStopLEDCustomEffect);
   REGISTER_METHOD(NotificationManagerSaveNotificationAsTemplate);
   REGISTER_METHOD(NotificationManagerCreateNotificationFromTemplate);
+  REGISTER_METHOD(NotificationManagerGetBlockState);
 #undef REGISTER_METHOD
 
   manager_ = NotificationManager::GetInstance();
@@ -186,6 +187,19 @@ void NotificationInstance::NotificationManagerGetAll(const picojson::value& args
   }
 }
 
+void NotificationInstance::NotificationManagerGetBlockState(const picojson::value& args,
+                                                            picojson::object& out) {
+  ScopeLogger();
+  picojson::value val;
+  PlatformResult status = manager_->GetBlockState(val);
+
+  if (status.IsSuccess()) {
+    ReportSuccess(val, out);
+  } else {
+    LogAndReportError(status, &out);
+  }
+}
+
 void NotificationInstance::NotificationManagerPlayLEDCustomEffect(const picojson::value& args,
                                                                   picojson::object& out) {
   ScopeLogger();
index 0d73090..509ace8 100644 (file)
@@ -37,6 +37,7 @@ class NotificationInstance : public common::ParsedInstance {
   void NotificationManagerRemoveAll(const picojson::value& args, picojson::object& out);
   void NotificationManagerGet(const picojson::value& args, picojson::object& out);
   void NotificationManagerGetAll(const picojson::value& args, picojson::object& out);
+  void NotificationManagerGetBlockState(const picojson::value& args, picojson::object& out);
 
   void NotificationManagerPlayLEDCustomEffect(const picojson::value& args, picojson::object& out);
   void NotificationManagerStopLEDCustomEffect(const picojson::value& args, picojson::object& out);
index 8d0a0e2..e249b61 100644 (file)
@@ -38,6 +38,11 @@ namespace notification {
 
 using namespace common;
 
+const BlockStateEnumMap NotificationManager::block_state_map_ = {
+    {NOTIFICATION_BLOCK_STATE_ALLOWED, "ALLOWED"},
+    {NOTIFICATION_BLOCK_STATE_BLOCKED, "BLOCKED"},
+    {NOTIFICATION_BLOCK_STATE_DO_NOT_DISTURB, "DO_NOT_DISTURB"}};
+
 NotificationManager::NotificationManager() {
   ScopeLogger();
 }
@@ -215,6 +220,27 @@ PlatformResult NotificationManager::GetAll(picojson::array& out, bool is_new_imp
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult NotificationManager::GetBlockState(picojson::value& out) {
+  ScopeLogger();
+
+  notification_block_state_e state;
+  int ret = notification_get_noti_block_state(&state);
+
+  if (ret != NOTIFICATION_ERROR_NONE) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get block state error",
+                              ("Get block state error: %d", ret));
+  }
+
+  const auto& state_iter = block_state_map_.find(state);
+  if (state_iter == block_state_map_.end()) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown state",
+                              ("Unknown state: %d", state));
+  }
+
+  out = picojson::value(state_iter->second);
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult NotificationManager::PlayLEDCustomEffect(const picojson::object& args) {
   ScopeLogger();
 
index 883ee57..6a49cd4 100644 (file)
 namespace extension {
 namespace notification {
 
+typedef std::map<notification_block_state_e, std::string> BlockStateEnumMap;
+
 class NotificationManager {
  public:
+  static const BlockStateEnumMap block_state_map_;
+
   static NotificationManager* GetInstance();
 
   common::PlatformResult Post(const picojson::object& args, picojson::object& out);
@@ -38,6 +42,7 @@ class NotificationManager {
   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 GetBlockState(picojson::value& out);
 
   common::PlatformResult PlayLEDCustomEffect(const picojson::object& args);
   common::PlatformResult StopLEDCustomEffect();
index d7960de..6282a3b 100644 (file)
@@ -59,6 +59,9 @@ PlatformResult UserNotification::ToJson(int id, notification_h noti_handle,
   ret = AddLedsToJson(noti_handle, out_ptr);
   CHECK_ERROR(ret);
 
+  ret = AddInputsToJson(noti_handle, out_ptr);
+  CHECK_ERROR(ret);
+
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
@@ -95,6 +98,9 @@ PlatformResult UserNotification::GetNotiHandleFromJson(const picojson::value& no
   status = SetLedsFromJson(noti_val, tmp_noti);
   CHECK_ERROR(status);
 
+  status = SetInputsFromJson(noti_val, tmp_noti);
+  CHECK_ERROR(status);
+
   *noti_handle = tmp_noti_ptr.release();
 
   return PlatformResult(ErrorCode::NO_ERROR);
@@ -277,6 +283,97 @@ PlatformResult UserNotification::AddLedsToJson(notification_h noti_handle,
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult UserNotification::AddButtonsToJson(notification_h noti_handle,
+                                                  picojson::object* out_ptr) {
+  ScopeLogger();
+  picojson::object& out = *out_ptr;
+  picojson::array buttons_array;
+
+  for (size_t i = 0; i < buttons_texts_map_.size(); i++) {
+    LoggerD("processing button %u", i);
+    picojson::object item;
+
+    PlatformResult status = AddTextToJson(noti_handle, buttons_texts_map_.at(i), "text", &item);
+    CHECK_ERROR(status);
+    // There is no native function to check the number of buttons in a notification. Instead, it
+    // is assumed that there are no more buttons if the text in a currently processed one does not
+    // exist or it is null.
+    if (!picojson::value(item).contains("text") || IsNull(item, "text")) {
+      LoggerD("no text in the current button, end of buttons");
+      break;
+    }
+
+    status = AddEventHandlerToJson(noti_handle, buttons_events_map_.at(i), "appControl", &item);
+    CHECK_ERROR(status);
+
+    status = AddPathToJson(noti_handle, buttons_icon_paths_map_.at(i), "imagePath", &item);
+    CHECK_ERROR(status);
+
+    buttons_array.push_back(picojson::value(item));
+  }
+
+  out["buttons"] = picojson::value(buttons_array);
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddTextInputToJson(notification_h noti_handle,
+                                                    picojson::object* out_ptr) {
+  ScopeLogger();
+  picojson::object& out = *out_ptr;
+  picojson::object text_input_obj;
+
+  // There is no native function to check whether the text input is present
+  // in the notification or not. However, if there is one, an event handler
+  // for NOTIFICATION_EVENT_TYPE_CLICK_ON_TEXT_INPUT_BUTTON must be set. The
+  // function below returns an error if it is not set (it calls native function
+  // notification_get_event_handler which returns an error in such a case)
+  // or no error otherwise.
+  PlatformResult status =
+      AddEventHandlerToJson(noti_handle, NOTIFICATION_EVENT_TYPE_CLICK_ON_TEXT_INPUT_BUTTON,
+                            "appControl", &text_input_obj);
+
+  // If AddEventHandlerToJson returns an error, it is assumed that there is no
+  // text input in the notification.
+  if (status.IsSuccess() && picojson::value(text_input_obj).contains("appControl")) {
+    LoggerD("valid appControl, adding text input to json");
+    // There is no native function to get max length of a text input
+    // so an arbitrary value is set.
+    text_input_obj["maxLength"] = picojson::value(160.0);
+
+    status = AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_TEXT_INPUT_BUTTON, "buttonText",
+                           &text_input_obj);
+    CHECK_ERROR(status);
+
+    status = AddTextToJson(noti_handle, NOTIFICATION_TEXT_TYPE_TEXT_INPUT_PLACEHOLDER,
+                           "placeholder", &text_input_obj);
+    CHECK_ERROR(status);
+
+    status = AddPathToJson(noti_handle, NOTIFICATION_IMAGE_TYPE_TEXT_INPUT_BUTTON, "imagePath",
+                           &text_input_obj);
+    CHECK_ERROR(status);
+
+    out["textInput"] = picojson::value(text_input_obj);
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::AddInputsToJson(notification_h noti_handle,
+                                                 picojson::object* out_ptr) {
+  ScopeLogger();
+  picojson::object& out = *out_ptr;
+  picojson::object inputs_obj;
+
+  PlatformResult status = AddButtonsToJson(noti_handle, &inputs_obj);
+  CHECK_ERROR(status);
+
+  status = AddTextInputToJson(noti_handle, &inputs_obj);
+  CHECK_ERROR(status);
+
+  out["inputs"] = picojson::value(inputs_obj);
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult UserNotification::SetTextContentsFromJson(const picojson::value& noti_value,
                                                          bool is_update,
                                                          notification_h noti_handle) {
@@ -453,5 +550,104 @@ PlatformResult UserNotification::SetLedsFromJson(const picojson::value& noti_val
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult UserNotification::SetButtonsFromJson(const picojson::value& noti_val,
+                                                    notification_h noti_handle) {
+  ScopeLogger();
+  const picojson::object& noti_obj = noti_val.get<picojson::object>();
+
+  if (noti_val.contains("buttons") && noti_val.get("buttons").is<picojson::array>()) {
+    const picojson::array& buttons_array = FromJson<picojson::array>(noti_obj, "buttons");
+
+    if (buttons_array.size() > buttons_index_map_.size()) {
+      return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Too many values in array");
+    }
+
+    int i = 0;
+    for (const auto& item : buttons_array) {
+      LoggerD("processing button %d", i);
+      if (!item.is<picojson::object>()) {
+        return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid button object");
+      }
+
+      PlatformResult status = AddButton(noti_handle, buttons_index_map_.at(i));
+      CHECK_ERROR(status);
+
+      status = SetTextFromJson(item, buttons_texts_map_.at(i), "text", noti_handle);
+      CHECK_ERROR(status);
+
+      status = SetEventHandlerFromJson(item, buttons_events_map_.at(i), "appControl", noti_handle);
+      CHECK_ERROR(status);
+
+      status = SetPathFromJson(item, buttons_icon_paths_map_.at(i), "imagePath", noti_handle);
+      CHECK_ERROR(status);
+
+      i++;
+    }
+
+    if (i > 0) {
+      PlatformResult status = SetDisplayApplist(noti_handle, NOTIFICATION_DISPLAY_APP_ACTIVE);
+      CHECK_ERROR(status);
+    }
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetTextInputFromJson(const picojson::value& noti_val,
+                                                      notification_h noti_handle) {
+  ScopeLogger();
+
+  if (noti_val.contains("textInput") && noti_val.get("textInput").is<picojson::object>()) {
+    const picojson::value& text_input_val = noti_val.get("textInput");
+    const picojson::object& text_input_obj = text_input_val.get<picojson::object>();
+
+    if (text_input_val.contains("maxLength") && text_input_val.get("maxLength").is<double>()) {
+      LoggerD("valid maxLength, setting text input");
+      const unsigned long max_length =
+          static_cast<unsigned long>(FromJson<double>(text_input_obj, "maxLength"));
+      PlatformResult status = SetTextInput(noti_handle, max_length);
+      CHECK_ERROR(status);
+
+      status = SetEventHandlerFromJson(text_input_val,
+                                       NOTIFICATION_EVENT_TYPE_CLICK_ON_TEXT_INPUT_BUTTON,
+                                       "appControl", noti_handle);
+
+      status = SetTextFromJson(text_input_val, NOTIFICATION_TEXT_TYPE_TEXT_INPUT_PLACEHOLDER,
+                               "placeholder", noti_handle);
+      CHECK_ERROR(status);
+
+      status = SetTextFromJson(text_input_val, NOTIFICATION_TEXT_TYPE_TEXT_INPUT_BUTTON,
+                               "buttonText", noti_handle);
+      CHECK_ERROR(status);
+
+      status = SetPathFromJson(text_input_val, NOTIFICATION_IMAGE_TYPE_TEXT_INPUT_BUTTON,
+                               "imagePath", noti_handle);
+      CHECK_ERROR(status);
+
+      status = SetDisplayApplist(noti_handle, NOTIFICATION_DISPLAY_APP_ACTIVE);
+      CHECK_ERROR(status);
+    }
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult UserNotification::SetInputsFromJson(const picojson::value& noti_val,
+                                                   notification_h noti_handle) {
+  ScopeLogger();
+
+  if (noti_val.contains("inputs") && noti_val.get("inputs").is<picojson::object>()) {
+    const picojson::value& inputs_val = noti_val.get("inputs");
+
+    PlatformResult status = SetButtonsFromJson(inputs_val, noti_handle);
+    CHECK_ERROR(status);
+
+    status = SetTextInputFromJson(inputs_val, noti_handle);
+    CHECK_ERROR(status);
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 }  // namespace notification
 }  // namespace extension
index 86f1c9c..daec902 100644 (file)
@@ -47,6 +47,12 @@ class UserNotification : public CommonNotification {
                                                        picojson::object* out_ptr);
   static common::PlatformResult AddLedsToJson(notification_h noti_handle,
                                               picojson::object* out_ptr);
+  static common::PlatformResult AddButtonsToJson(notification_h noti_handle,
+                                                 picojson::object* out_ptr);
+  static common::PlatformResult AddTextInputToJson(notification_h noti_handle,
+                                                   picojson::object* out_ptr);
+  static common::PlatformResult AddInputsToJson(notification_h noti_handle,
+                                                picojson::object* out_ptr);
 
   static common::PlatformResult SetTextContentsFromJson(const picojson::value& noti_val,
                                                         bool is_update, notification_h noti_handle);
@@ -60,6 +66,12 @@ class UserNotification : public CommonNotification {
                                                          notification_h noti_handle);
   static common::PlatformResult SetLedsFromJson(const picojson::value& noti_val,
                                                 notification_h noti_handle);
+  static common::PlatformResult SetButtonsFromJson(const picojson::value& noti_val,
+                                                   notification_h noti_handle);
+  static common::PlatformResult SetTextInputFromJson(const picojson::value& noti_val,
+                                                     notification_h noti_handle);
+  static common::PlatformResult SetInputsFromJson(const picojson::value& noti_val,
+                                                  notification_h noti_handle);
 
  private:
   UserNotification();