%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 2.34
+Version: 2.35
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
return; \
}
-void ApplicationManager::AsyncResponse(PlatformResult& result,
+void ApplicationManager::AsyncResponse(const PlatformResult& result,
std::shared_ptr<picojson::value>* response) {
ScopeLogger();
LogAndReportError(result, &(*response)->get<picojson::object>());
kill();
}
-void ApplicationManager::Launch(const picojson::value& args) {
+namespace {
+
+PlatformResult PrepareAppControlForLaunchAppControl(const picojson::value& args,
+ app_control_h* app_control) {
ScopeLogger();
- int callback_id = -1;
- const auto& callback = args.get(kCallbackId);
- if (callback.is<double>()) {
- callback_id = static_cast<int>(callback.get<double>());
+ const auto& control = args.get("appControl");
+ if (!control.is<picojson::object>()) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
}
+ const picojson::object& app_control_obj = control.get<picojson::object>();
- std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
- picojson::object& obj = response->get<picojson::object>();
- obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+ app_control_h tmp_app_control = nullptr;
+ auto result = ApplicationUtils::ApplicationControlToService(app_control_obj, &tmp_app_control);
+ std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+ app_control_ptr(tmp_app_control, &app_control_destroy);
- const auto& app_id = args.get("id");
- if (!app_id.is<std::string>()) {
- PlatformResult ret =
- LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
- AsyncResponse(ret, &response);
- return;
+ if (result.IsError()) {
+ LoggerE("Application control to service failed.");
+ return result;
}
- const std::string& id = app_id.get<std::string>();
- auto launch = [id](const std::shared_ptr<picojson::value>& response) -> void {
- ScopeLogger("launch");
- PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
- const char* app_id = id.c_str();
- const int retry_count = 3;
+ std::string app_id;
+ const auto& id = args.get("id");
+ if (id.is<std::string>()) {
+ app_id = id.get<std::string>();
+ }
- int retry = 0;
- int ret = 0;
+ if (!app_id.empty()) {
+ LoggerD("app_id: %s", app_id.c_str());
- while (retry < retry_count) {
- ret = aul_open_app(app_id);
+ int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
- if (ret >= 0) {
- break;
- }
-
- // delay 300ms for each retry
- struct timespec sleep_time = {0, 300L * 1000L * 1000L};
- nanosleep(&sleep_time, nullptr);
- ++retry;
-
- LoggerD("Retry launch request: %d", retry);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
}
+ }
- if (ret < 0) {
- result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred.");
-
- LoggerD("Aul open return: %d (%s)", ret, get_error_message(ret));
- switch (ret) {
- case AUL_R_EINVAL:
- case AUL_R_ERROR:
- case AUL_R_ENOAPP:
- result =
- LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error.",
- ("aul_open_app returns Not Found error"));
- break;
-
- case AUL_R_ECOMM:
- result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred.",
- ("aul_open_app returns internal IPC error"));
- break;
- }
-
- LogAndReportError(result, &response->get<picojson::object>());
- } else {
- LoggerD("Launch request success");
- ReportSuccess(response->get<picojson::object>());
- }
- };
+ *app_control = app_control_ptr.release();
- launch(response);
- Instance::PostMessage(&this->instance_, response->serialize().c_str());
+ return PlatformResult(ErrorCode::NO_ERROR);
}
+} // namespace
+
void ApplicationManager::LaunchAppControl(const picojson::value& args) {
ScopeLogger();
response_obj.insert(
std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
- PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
- const auto& control = args.get("appControl");
- if (!control.is<picojson::object>()) {
- result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
- AsyncResponse(result, &response);
- return;
- }
- const picojson::object& app_control_obj = control.get<picojson::object>();
-
- std::string launch_mode_str;
- const auto& launch_mode = control.get("launchMode");
- if (launch_mode.is<std::string>()) {
- launch_mode_str = launch_mode.get<std::string>();
- }
-
app_control_h app_control = nullptr;
- result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
- std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
- app_control, &app_control_destroy); // automatically release the memory
-
- if (result.IsError()) {
- LoggerE("Application control to service failed.");
- AsyncResponse(result, &response);
+ auto prepare_app_control_result = PrepareAppControlForLaunchAppControl(args, &app_control);
+ if (prepare_app_control_result.IsError()) {
+ AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
return;
}
- std::string app_id;
- const auto& id = args.get("id");
- if (id.is<std::string>()) {
- app_id = id.get<std::string>();
- }
+ std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+ app_control_ptr(app_control, &app_control_destroy);
- std::string reply_callback;
+ std::string reply_callback_id;
const auto& reply = args.get("replyCallback");
if (reply.is<std::string>()) {
- reply_callback = reply.get<std::string>();
+ reply_callback_id = reply.get<std::string>();
}
- auto launch = [this, app_control_ptr, app_id, launch_mode_str,
- reply_callback](const std::shared_ptr<picojson::value>& response) -> void {
- ScopeLogger("Entered into asynchronous function, launch");
+ struct LaunchAppControlCallbackData {
+ ApplicationInstance* instance;
+ std::shared_ptr<picojson::value> response;
+ std::string reply_callback_id;
+ }* launch_app_user_data = new (std::nothrow)
+ LaunchAppControlCallbackData{&this->instance_, response, reply_callback_id};
- if (!app_id.empty()) {
- LoggerD("app_id: %s", app_id.c_str());
+ if (!launch_app_user_data) {
+ LoggerE("Memory allocation fail!");
+ AsyncResponse(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response);
+ return;
+ }
- int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
+ app_control_reply_cb reply_callback = nullptr;
+ if (!reply_callback_id.empty()) {
+ launch_app_user_data->reply_callback_id = reply_callback_id;
- if (APP_CONTROL_ERROR_NONE != ret) {
- LogAndReportError(
- PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
- &response->get<picojson::object>(),
- ("Failed to set app id: %d (%s)", ret, get_error_message(ret)));
- return;
- }
- }
+ reply_callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
+ void* user_data) {
+ ScopeLogger("reply_callback");
- if (!launch_mode_str.empty()) {
- app_control_launch_mode_e launch_mode;
-
- if ("SINGLE" == launch_mode_str) {
- launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
- } else if ("GROUP" == launch_mode_str) {
- launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP;
- } else {
- ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
- &response->get<picojson::object>());
+ LaunchAppControlCallbackData* callback_data =
+ static_cast<LaunchAppControlCallbackData*>(user_data);
+ if (!callback_data) {
+ LoggerD("reply_callback failed: user_data is nullptr");
return;
}
- int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode);
- if (APP_CONTROL_ERROR_NONE != ret) {
- LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."),
- &response->get<picojson::object>(),
- ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret)));
- return;
+ 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(kListenerId, picojson::value(callback_data->reply_callback_id)));
+
+ if (APP_CONTROL_RESULT_SUCCEEDED == result) {
+ LoggerD("App started");
+ return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array())));
+ if (!ApplicationUtils::ServiceToApplicationControlDataArray(
+ reply, &return_value_obj.find("data")->second.get<picojson::array>())) {
+ return_value_obj.erase("data");
+ }
+ ReportSuccess(return_value_obj);
+ } else {
+ ReportError(return_value_obj);
}
- }
- app_control_reply_cb callback = nullptr;
- struct ReplayCallbackData {
- ApplicationInstance* app_instance;
- std::string reply_callback;
+ Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
+ delete callback_data;
};
+ }
- ReplayCallbackData* user_data = nullptr;
+ app_control_result_cb result_callback = [](app_control_h launch_request,
+ app_control_error_e launch_result, void* user_data) {
+ ScopeLogger("LaunchAppControl result_callback");
- if (!reply_callback.empty()) {
- user_data = new ReplayCallbackData();
- user_data->app_instance = &this->instance_;
- user_data->reply_callback = reply_callback;
+ LaunchAppControlCallbackData* callback_data =
+ static_cast<LaunchAppControlCallbackData*>(user_data);
- callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
- void* user_data) {
- LoggerD("send_launch_request callback");
+ auto result = ApplicationUtils::TranslateAppControlError(launch_result);
- picojson::value return_value = picojson::value(picojson::object());
- picojson::object& return_value_obj = return_value.get<picojson::object>();
- ReplayCallbackData* reply_callback = static_cast<ReplayCallbackData*>(user_data);
+ if (result.IsError()) {
+ LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
+ } else {
+ ReportSuccess(callback_data->response->get<picojson::object>());
+ }
- if (APP_CONTROL_RESULT_SUCCEEDED == result) {
- const std::string data = "data";
- return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array())));
- if (!ApplicationUtils::ServiceToApplicationControlDataArray(
- reply, &return_value_obj.find(data)->second.get<picojson::array>())) {
- return_value_obj.erase(data);
- }
- ReportSuccess(return_value_obj);
- } else {
- ReportError(return_value_obj);
- }
+ Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
- return_value_obj.insert(
- std::make_pair("listenerId", picojson::value(reply_callback->reply_callback)));
- Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str());
- delete reply_callback;
- };
+ if (result.IsError() || (callback_data->reply_callback_id).empty()) {
+ delete callback_data;
}
+ };
- const int retry_count = 3;
+ /*
+ * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
+ * Previous implementation, using synchronous app_control_send_launch_request,
+ * tries to launch the application 3 times, before reporting an error.
+ * New implementation, using app_control_send_launch_request_async makes only one attempt.
+ * If problems, such as failed application start occur, multiple attempts may solve the problem.
+ */
+ auto launch_result =
+ ApplicationUtils::TranslateAppControlError(static_cast<app_control_error_e>(app_control_send_launch_request_async(
+ app_control_ptr.get(), result_callback, reply_callback, launch_app_user_data)));
+
+ if (launch_result.IsError()) {
+ delete launch_app_user_data;
+ AsyncResponse(launch_result, &response);
+ } else {
+ LoggerD("App launched");
+ }
+}
- int retry = 0;
- int ret = 0;
+namespace {
- while (retry < retry_count) {
- LoggerD("Calling launch request. Attempt number: %d", retry);
+PlatformResult TranslateLaunchError(app_control_error_e return_code) {
+ ScopeLogger();
- ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data);
- LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret));
- if (APP_CONTROL_ERROR_NONE == ret) {
- break;
- }
+ auto result = ApplicationUtils::TranslateAppControlError(return_code);
+ if (ErrorCode::SECURITY_ERR == result.error_code()) {
+ result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
+ }
- // delay 300ms for each retry
- struct timespec sleep_time = {0, 300L * 1000L * 1000L};
- nanosleep(&sleep_time, nullptr);
- ++retry;
- }
+ return result;
+}
+
+PlatformResult PrepareAppControlForLaunch(const picojson::value& args, app_control_h* app_control) {
+ ScopeLogger();
+
+ const auto& app_id = args.get("id");
+ if (!app_id.is<std::string>()) {
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
+ }
+ const auto app_id_str = app_id.get<std::string>();
+
+ app_control_h tmp_app_control = nullptr;
+ int result = app_control_create(&tmp_app_control);
+ if (APP_CONTROL_ERROR_NONE != result) {
+ LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result));
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
+ }
+
+ std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+ app_control_ptr(tmp_app_control, &app_control_destroy);
+
+ if (!app_id_str.empty()) {
+ LoggerD("app_id: %s", app_id_str.c_str());
+
+ int ret = app_control_set_app_id(app_control_ptr.get(), app_id_str.c_str());
if (APP_CONTROL_ERROR_NONE != ret) {
- delete user_data;
-
- switch (ret) {
- case APP_CONTROL_ERROR_INVALID_PARAMETER:
- LogAndReportError(
- PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."),
- &response->get<picojson::object>(),
- ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"));
- return;
- case APP_CONTROL_ERROR_OUT_OF_MEMORY:
- LogAndReportError(
- PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."),
- &response->get<picojson::object>(),
- ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"));
- return;
- case APP_CONTROL_ERROR_LAUNCH_REJECTED:
- case APP_CONTROL_ERROR_APP_NOT_FOUND:
- LogAndReportError(
- PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."),
- &response->get<picojson::object>(),
- ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"));
- return;
- default:
- LogAndReportError(
- PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."),
- &response->get<picojson::object>(),
- ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret)));
- return;
- }
+ LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
}
- ReportSuccess(response->get<picojson::object>());
+ }
+
+ *app_control = app_control_ptr.release();
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // namespace
+void ApplicationManager::Launch(const picojson::value& args) {
+ ScopeLogger();
+
+ int callback_id = -1;
+ const auto& callback = args.get(kCallbackId);
+ if (callback.is<double>()) {
+ callback_id = static_cast<int>(callback.get<double>());
+ }
+
+ std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
+ picojson::object& response_obj = response->get<picojson::object>();
+ response_obj.insert(
+ std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+
+ app_control_h app_control = nullptr;
+ auto prepare_app_control_result = PrepareAppControlForLaunch(args, &app_control);
+ if (prepare_app_control_result.IsError()) {
+ AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
+ return;
+ }
+
+ std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+ app_control_ptr(app_control, &app_control_destroy);
+
+ struct LaunchCallbackData {
+ ApplicationInstance* instance;
+ std::shared_ptr<picojson::value> response;
+ }* launch_user_data = new (std::nothrow) LaunchCallbackData{&this->instance_, response};
+
+ app_control_result_cb result_callback = [](app_control_h launch_request,
+ app_control_error_e launch_result, void* user_data) {
+ ScopeLogger("Launch result_callback");
+
+ LaunchCallbackData* callback_data = static_cast<LaunchCallbackData*>(user_data);
+
+ auto result = TranslateLaunchError(launch_result);
+
+ if (result.IsError()) {
+ LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
+ } else {
+ ReportSuccess(callback_data->response->get<picojson::object>());
+ }
+
+ Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
+
+ delete callback_data;
};
- launch(response);
- Instance::PostMessage(&this->instance_, response->serialize().c_str());
+ /*
+ * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
+ * Previous implementation, using synchronous app_control_send_launch_request,
+ * tries to launch the application 3 times, before reporting an error.
+ * New implementation, using app_control_send_launch_request_async makes only one attempt.
+ * If problems, such as failed application start occur, multiple attempts may solve the problem.
+ */
+ auto launch_result = TranslateLaunchError(static_cast<app_control_error_e>(app_control_send_launch_request_async(
+ app_control_ptr.get(), result_callback, nullptr, launch_user_data)));
+
+ if (launch_result.IsError()) {
+ delete launch_user_data;
+ AsyncResponse(launch_result, &response);
+ } else {
+ LoggerD("App launched");
+ }
}
// internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
void StartAppInfoEventListener(picojson::object* out);
void StopAppInfoEventListener();
void GetApplicationInformationSize(const picojson::value& args, picojson::object* out);
- void AsyncResponse(common::PlatformResult& result, std::shared_ptr<picojson::value>* response);
+ void AsyncResponse(const common::PlatformResult& result,
+ std::shared_ptr<picojson::value>* response);
void BroadcastEventHelper(const picojson::value& args, picojson::object& out, bool trusted);
common::PlatformResult StartEventListener(const std::string& event_name,
app_meta_data->insert(std::make_pair("value", picojson::value(value)));
}
+namespace {
+
+const std::string kOperationAppControlField = "operation";
+const std::string kURIAppControlField = "uri";
+const std::string kMIMEAppControlField = "mime";
+const std::string kCategoryAppControlField = "category";
+const std::string kLaunchModeAppControlField = "launchMode";
+const std::string kDataAppControlField = "data";
+
+const std::string kGroupLaunchMode = "GROUP";
+const std::string kSingleLaunchMode = "SINGLE";
+
+using AppControlTextFieldSetter = std::function<int(app_control_h, const char*)>;
+// clang-format off
+const std::map<std::string, AppControlTextFieldSetter> AppControlTextFieldSetters = {
+ { kOperationAppControlField, app_control_set_operation },
+ { kURIAppControlField, app_control_set_uri },
+ { kMIMEAppControlField, app_control_set_mime },
+ { kCategoryAppControlField, app_control_set_category }
+}; // clang-format on
+
+PlatformResult SetAppControlTextField(app_control_h app_control, const std::string& field_name,
+ const std::string& value) {
+ ScopeLogger("Field: %s, value: %s", field_name.c_str(), value.c_str());
+
+ auto setter_it = AppControlTextFieldSetters.find(field_name);
+ if (AppControlTextFieldSetters.end() == setter_it) {
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
+ }
+ auto setter = setter_it->second;
+
+ auto result = setter(app_control, value.c_str());
+ auto result_translated =
+ ApplicationUtils::TranslateAppControlError(static_cast<app_control_error_e>(result));
+
+ if (result_translated.IsError()) {
+ LoggerD("Setting app_control's %s field failed: %s", field_name.c_str(),
+ result_translated.message().c_str());
+ }
+
+ return result_translated;
+}
+
+app_control_launch_mode_e LaunchModeStringToEnum(const std::string& launch_mode) {
+ ScopeLogger();
+
+ return launch_mode == kGroupLaunchMode ? APP_CONTROL_LAUNCH_MODE_GROUP
+ : APP_CONTROL_LAUNCH_MODE_SINGLE;
+}
+
+bool LaunchModeIsInvalid(const std::string& launch_mode) {
+ ScopeLogger();
+
+ auto is_valid = launch_mode == kSingleLaunchMode || launch_mode == kGroupLaunchMode;
+ LoggerD("Launch mode: %s (%s)", launch_mode.c_str(), is_valid ? "valid" : "invalid");
+
+ return !is_valid;
+}
+
+PlatformResult SetAppControlLaunchModeField(app_control_h app_control,
+ const std::string& launch_mode_str) {
+ ScopeLogger();
+
+ if (LaunchModeIsInvalid(launch_mode_str)) {
+ LoggerD("Invalid launchMode value: %s", launch_mode_str.c_str());
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+ "Invalid launchMode value: " + launch_mode_str);
+ }
+
+ auto result = app_control_set_launch_mode(app_control, LaunchModeStringToEnum(launch_mode_str));
+ return ApplicationUtils::TranslateAppControlError(static_cast<app_control_error_e>(result));
+}
+
+PlatformResult SetAppControlDataField(app_control_h app_control, const picojson::array& data) {
+ ScopeLogger();
+
+ for (auto iter = data.begin(); iter != data.end(); ++iter) {
+ if (iter->is<picojson::object>()) {
+ PlatformResult ret = ApplicationUtils::ApplicationControlDataToServiceExtraData(
+ iter->get<picojson::object>(), app_control);
+ if (ret.IsError()) {
+ return ret;
+ }
+ } else {
+ LoggerD("Invalid data value: not an object");
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid data type: not an object");
+ }
+ }
+
+ return PlatformResult{ErrorCode::NO_ERROR};
+}
+
+PlatformResult SetAppControlFieldIfValueSpecified(
+ app_control_h app_control, const std::string& field_name,
+ const picojson::object::const_iterator& iterator) {
+ ScopeLogger();
+
+ if (iterator->second.is<std::string>()) {
+ if (field_name != kLaunchModeAppControlField) {
+ return SetAppControlTextField(app_control, field_name, iterator->second.get<std::string>());
+ }
+ return SetAppControlLaunchModeField(app_control, iterator->second.get<std::string>());
+ } else if (iterator->second.is<picojson::array>() && kDataAppControlField == field_name) {
+ return SetAppControlDataField(app_control, iterator->second.get<picojson::array>());
+ }
+
+ return PlatformResult{ErrorCode::NO_ERROR};
+}
+
+} // namespace
+
PlatformResult ApplicationUtils::ApplicationControlToService(
const picojson::object& app_control_obj, app_control_h* app_control) {
ScopeLogger();
- const auto it_operation = app_control_obj.find("operation");
- const auto it_uri = app_control_obj.find("uri");
- const auto it_mime = app_control_obj.find("mime");
- const auto it_category = app_control_obj.find("category");
- const auto it_data = app_control_obj.find("data");
+
+ const auto it_operation = app_control_obj.find(kOperationAppControlField);
+ const auto it_uri = app_control_obj.find(kURIAppControlField);
+ const auto it_mime = app_control_obj.find(kMIMEAppControlField);
+ const auto it_category = app_control_obj.find(kCategoryAppControlField);
+ const auto it_data = app_control_obj.find(kDataAppControlField);
+ const auto it_launch_mode = app_control_obj.find(kLaunchModeAppControlField);
const auto it_app_control_end = app_control_obj.end();
if (it_operation == it_app_control_end || it_uri == it_app_control_end ||
it_mime == it_app_control_end || it_category == it_app_control_end ||
it_data == it_app_control_end || !it_operation->second.is<std::string>() ||
- !it_data->second.is<picojson::array>()) {
+ !it_data->second.is<picojson::array>() || it_launch_mode == it_app_control_end) {
return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter was passed.");
}
app_control_h app_control_tmp = nullptr;
int result = app_control_create(&app_control_tmp);
-
if (APP_CONTROL_ERROR_NONE != result) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Creation AppControl failed.",
- ("Problem with create handle."));
+ LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result));
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
}
std::unique_ptr<std::remove_pointer<app_control_h>::type, int (*)(app_control_h)> app_control_ptr(
app_control_tmp, &app_control_destroy);
- // operation
- app_control_set_operation(app_control_tmp, it_operation->second.get<std::string>().c_str());
+ auto set_field_result = PlatformResult(ErrorCode::UNKNOWN_ERR);
- // uri
- if (it_uri->second.is<std::string>()) {
- app_control_set_uri(app_control_tmp, it_uri->second.get<std::string>().c_str());
+ set_field_result =
+ SetAppControlFieldIfValueSpecified(app_control_tmp, kOperationAppControlField, it_operation);
+ if (set_field_result.IsError()) {
+ return set_field_result;
}
- // mime
- if (it_mime->second.is<std::string>()) {
- app_control_set_mime(app_control_tmp, it_mime->second.get<std::string>().c_str());
+ set_field_result =
+ SetAppControlFieldIfValueSpecified(app_control_tmp, kURIAppControlField, it_uri);
+ if (set_field_result.IsError()) {
+ return set_field_result;
}
- // category
- if (it_category->second.is<std::string>()) {
- app_control_set_category(app_control_tmp, it_category->second.get<std::string>().c_str());
+ set_field_result =
+ SetAppControlFieldIfValueSpecified(app_control_tmp, kMIMEAppControlField, it_mime);
+ if (set_field_result.IsError()) {
+ return set_field_result;
}
- // ApplicationControlData
- const picojson::array& data = it_data->second.get<picojson::array>();
+ set_field_result =
+ SetAppControlFieldIfValueSpecified(app_control_tmp, kCategoryAppControlField, it_category);
+ if (set_field_result.IsError()) {
+ return set_field_result;
+ }
- for (auto iter = data.begin(); iter != data.end(); ++iter) {
- if (iter->is<picojson::object>()) {
- PlatformResult ret =
- ApplicationControlDataToServiceExtraData(iter->get<picojson::object>(), app_control_tmp);
- if (ret.IsError()) {
- LoggerE("Failed ApplicationControlDataToServiceExtraData()");
- return ret;
- }
- }
+ set_field_result = SetAppControlFieldIfValueSpecified(app_control_tmp, kLaunchModeAppControlField,
+ it_launch_mode);
+ if (set_field_result.IsError()) {
+ return set_field_result;
+ }
+
+ set_field_result =
+ SetAppControlFieldIfValueSpecified(app_control_tmp, kDataAppControlField, it_data);
+ if (set_field_result.IsError()) {
+ return set_field_result;
}
*app_control = app_control_ptr.release();
if (it_key == it_app_control_data_end || it_value == it_app_control_data_end ||
!it_key->second.is<std::string>() || !it_value->second.is<picojson::array>()) {
return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter was passed.",
- ("Problem with key or value."));
+ ("Invalid key or value."));
}
const std::string& key = it_key->second.get<std::string>();
const picojson::array& value = it_value->second.get<picojson::array>();
- const size_t size = value.size();
- const char** arr = new const char*[size];
- size_t i = 0;
+ std::vector<const char*> value_data;
- for (auto iter = value.begin(); iter != value.end(); ++iter, ++i) {
- arr[i] = iter->get<std::string>().c_str();
+ for (auto& v : value) {
+ value_data.push_back(v.get<std::string>().c_str());
}
- if (1 == size) {
- app_control_add_extra_data(app_control, key.c_str(), arr[0]);
- } else {
- app_control_add_extra_data_array(app_control, key.c_str(), arr, size);
+ auto result = app_control_add_extra_data_array(app_control, key.c_str(), value_data.data(),
+ value_data.size());
+ if (APP_CONTROL_ERROR_INVALID_PARAMETER == result) {
+ if (0 == key.length()) {
+ LoggerD("app_control_add_extra_data_array failed: zero-length key");
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+ "Invalid AppControlData key: key length is 0.");
+ }
+ LoggerD("app_control_add_extra_data_array failed: invalid parameter passed");
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+ "Invalid AppControlData value, associated with key: " + key);
+ } else if (APP_CONTROL_ERROR_KEY_REJECTED == result) {
+ LoggerD("app_control_add_extra_data_array failed: key rejected");
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid AppControlData's key: " + key);
}
- delete[] arr;
return PlatformResult(ErrorCode::NO_ERROR);
}
};
ret = app_control_get_operation(app_control, &tmp_str);
- if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) {
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get operation failed: %d (%s)", ret, get_error_message(ret));
+ } else if (tmp_str) {
LoggerD("operation: %s", tmp_str);
- app_control_obj->insert(std::make_pair("operation", picojson::value(std::string(tmp_str))));
+ app_control_obj->insert(
+ std::make_pair(kOperationAppControlField, picojson::value(std::string(tmp_str))));
} else {
- LoggerE("Get operation failed: %d (%s)", ret, get_error_message(ret));
+ LoggerD("operation field is empty");
}
clear(tmp_str);
ret = app_control_get_uri(app_control, &tmp_str);
- if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) {
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get URI failed: %d (%s)", ret, get_error_message(ret));
+ } else if (tmp_str) {
LoggerD("URI: %s", tmp_str);
- app_control_obj->insert(std::make_pair("uri", picojson::value(std::string(tmp_str))));
+ app_control_obj->insert(
+ std::make_pair(kURIAppControlField, picojson::value(std::string(tmp_str))));
+ } else {
+ LoggerD("URI field is empty");
}
clear(tmp_str);
ret = app_control_get_mime(app_control, &tmp_str);
- if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) {
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get MIME failed: %d (%s)", ret, get_error_message(ret));
+ } else if (tmp_str) {
LoggerD("MIME: %s", tmp_str);
- app_control_obj->insert(std::make_pair("mime", picojson::value(std::string(tmp_str))));
+ app_control_obj->insert(
+ std::make_pair(kMIMEAppControlField, picojson::value(std::string(tmp_str))));
} else {
- LoggerE("Get mime failed: %d (%s)", ret, get_error_message(ret));
+ LoggerD("MIME field is empty");
}
clear(tmp_str);
ret = app_control_get_category(app_control, &tmp_str);
- if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) {
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get category failed: %d (%s)", ret, get_error_message(ret));
+ } else if (tmp_str) {
LoggerD("category: %s", tmp_str);
- app_control_obj->insert(std::make_pair("category", picojson::value(std::string(tmp_str))));
+ app_control_obj->insert(
+ std::make_pair(kCategoryAppControlField, picojson::value(std::string(tmp_str))));
} else {
- LoggerE("Get category failed: %d (%s)", ret, get_error_message(ret));
+ LoggerD("category field is empty");
}
clear(tmp_str);
- app_control_obj->insert(std::make_pair("data", picojson::value(picojson::array())));
+ app_control_launch_mode_e launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
+ ret = app_control_get_launch_mode(app_control, &launch_mode);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ LoggerE("Get launch mode failed: %d (%s)", ret, get_error_message(ret));
+ } else {
+ std::string launch_mode_str =
+ launch_mode == APP_CONTROL_LAUNCH_MODE_SINGLE ? kSingleLaunchMode : kGroupLaunchMode;
+ LoggerD("launch mode: %s", launch_mode_str.c_str());
+ app_control_obj->insert(
+ std::make_pair(kLaunchModeAppControlField, picojson::value(launch_mode_str)));
+ }
+
+ app_control_obj->insert(std::make_pair(kDataAppControlField, picojson::value(picojson::array())));
ServiceToApplicationControlDataArray(
- app_control, &app_control_obj->find("data")->second.get<picojson::array>());
+ app_control, &app_control_obj->find(kDataAppControlField)->second.get<picojson::array>());
}
void ApplicationUtils::ServiceExtraDataToApplicationControlData(
return APP_CONTROL_ERROR_NONE == ret;
}
+PlatformResult ApplicationUtils::TranslateAppControlError(app_control_error_e return_code) {
+ ScopeLogger("Return code: %d (%s)", static_cast<int>(return_code),
+ get_error_message(static_cast<int>(return_code)));
+
+ switch (return_code) {
+ case APP_CONTROL_ERROR_NONE:
+ return PlatformResult(ErrorCode::NO_ERROR);
+
+ case APP_CONTROL_ERROR_INVALID_PARAMETER:
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
+
+ case APP_CONTROL_ERROR_APP_NOT_FOUND:
+ return PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found.");
+
+ case APP_CONTROL_ERROR_PERMISSION_DENIED:
+ return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied.");
+
+ case APP_CONTROL_ERROR_OUT_OF_MEMORY:
+ case APP_CONTROL_ERROR_KEY_NOT_FOUND:
+ case APP_CONTROL_ERROR_KEY_REJECTED:
+ case APP_CONTROL_ERROR_INVALID_DATA_TYPE:
+ case APP_CONTROL_ERROR_LAUNCH_REJECTED:
+ case APP_CONTROL_ERROR_LAUNCH_FAILED:
+ case APP_CONTROL_ERROR_TIMED_OUT:
+ case APP_CONTROL_ERROR_IO_ERROR:
+ default:
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
+ }
+}
+
bool ApplicationUtils::ServiceExtraDataCallback(app_control_h app_control, const char* key,
void* user_data) {
ScopeLogger();
static bool ServiceToApplicationControlDataArray(app_control_h app_control,
picojson::array* data);
+ static common::PlatformResult TranslateAppControlError(app_control_error_e error_code);
+
private:
static bool ServiceExtraDataCallback(app_control_h app_control, const char* key, void* user_data);
};
struct stat syminfo;
if (lstat(path->getFullPath().c_str(), &info) != 0) {
- LoggerE("File:[%s] error no:%d", path->getFullPath().c_str(), errno);
+ int tmp_errno = errno;
+ LoggerE("File: [%s] error no: %d", path->getFullPath().c_str(), tmp_errno);
- switch (errno) {
+ switch (tmp_errno) {
case EACCES:
SLoggerE("File: [%s]", path->getFullPath().c_str());
return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Node access denied");
],
},
},
+ 'defines': ['PICOJSON_USE_RVALUE_REFERENCE'],
},
],
- 'defines': ['PICOJSON_USE_RVALUE_REFERENCE'],
}
function stringToRegex(str) {
var _regString = '^';
if (str === '') {
- return new RegExp(_regString, 'i');
+ return new RegExp(_regString + "$", 'i');
}
// single '\' sign is not visible in JS string, escaping % wildcard need to be done by '\\%'
str = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
var data = {id: this.id, offset: args.offset, blocking: false};
if (undefined === args.whence) {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
if ((this.mode === 'w') || (this.mode === 'a')) {
setTimeout(function() {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is write-only'));
}, 0);
+ return;
}
var data = {id: this.id, encoding: args.inputEncoding, blocking: false};
if (!type_.isNullOrUndefined(args.count)) {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
if ('r' === this.mode) {
setTimeout(function() {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is read-only'));
}, 0);
+ return;
}
var data =
{id: this.id, string: args.string, encoding: args.outputEncoding, blocking: false};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
var data = {id: this.id, blocking: false};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
} else if (this.mode === 'r') {
setTimeout(function() {
native_.callIfPossible(
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is read-only'));
}, 0);
+ return;
}
var encodedData = ArrayToString(blobToUint8Array(args.blob));
setTimeout(function() {
native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
}, 0);
+ return;
}
};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
if ((this.mode === 'w') || (this.mode === 'a')) {
setTimeout(function() {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is write-only'));
}, 0);
+ return;
}
var data = {id: this.id, blocking: false};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
} else if (this.mode === 'r') {
setTimeout(function() {
native_.callIfPossible(
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is read-only'));
}, 0);
+ return;
}
var encodedData = ArrayToString(args.data);
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
if (this.mode === 'r') {
setTimeout(function() {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is read-only'));
}, 0);
+ return;
}
var data = {id: this.id, blocking: false};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
if (this.mode === 'r') {
setTimeout(function() {
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle state is read-only'));
}, 0);
+ return;
}
var data = {id: this.id, blocking: false};
args.errorCallback,
new WebAPIException(WebAPIException.IO_ERR, 'FileHandle is not opened'));
}, 0);
+ return;
}
var data = {id: this.id, blocking: false};
picojson::value event = picojson::value(picojson::object());
picojson::object& obj = event.get<picojson::object>();
- obj.insert(std::make_pair("callbackId", picojson::value(data->callbackId)));
+ obj.emplace(std::make_pair("callbackId", picojson::value(data->callbackId)));
if (PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER == cause) {
- obj.insert(std::make_pair("result", picojson::value(CheckRequestResultToString(result))));
- obj.insert(std::make_pair("privilege", picojson::value(privilege)));
+ obj.emplace(std::make_pair("result", picojson::value(CheckRequestResultToString(result))));
+ obj.emplace(std::make_pair("privilege", picojson::value(privilege)));
} else {
LogAndReportError(
common::PlatformResult(common::ErrorCode::ABORT_ERR, "Get callback data failed"), &obj);
picojson::value event = picojson::value(picojson::object());
picojson::object& obj = event.get<picojson::object>();
- obj.insert(std::make_pair("callbackId", picojson::value(data->callbackId)));
+ obj.emplace(std::make_pair("callbackId", picojson::value(data->callbackId)));
if (PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER == cause) {
picojson::value result_array = picojson::value(picojson::array());
picojson::array& array_obj = result_array.get<picojson::array>();
+ array_obj.reserve(privileges_count);
for (size_t i = 0; i < privileges_count; i++) {
picojson::value result_elem = picojson::value(picojson::object());
picojson::object& obj = result_elem.get<picojson::object>();
obj["privilege"] = picojson::value(privileges[i]);
obj["result"] = picojson::value(CheckRequestResultToString(result[i]));
- array_obj.push_back(result_elem);
+ array_obj.push_back(std::move(result_elem));
}
- obj.insert(std::make_pair("result", result_array));
+ obj.emplace(std::make_pair("result", result_array));
} else {
LogAndReportError(
common::PlatformResult(common::ErrorCode::ABORT_ERR, "Get callback data failed"), &obj);
ScopeLogger();
const picojson::array& privileges = args.get("privileges").get<picojson::array>();
- unsigned int size = static_cast<int>(privileges.size());
-
std::vector<const char*> privilege_array;
- size_t i = 0;
+ privilege_array.reserve(privileges.size());
- for (auto iter = privileges.begin(); iter != privileges.end(); ++iter, ++i) {
+ for (auto iter = privileges.begin(); iter != privileges.end(); ++iter) {
privilege_array.push_back(iter->get<std::string>().c_str());
}
- std::vector<ppm_check_result_e> results(size);
- int ret = ppm_check_permissions(privilege_array.data(), size, results.data());
+ std::vector<ppm_check_result_e> results(privileges.size());
+ int ret = ppm_check_permissions(privilege_array.data(), privileges.size(), results.data());
if (PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE != ret) {
LogAndReportError(convertError(ret), &out,
picojson::value result_array = picojson::value(picojson::array());
picojson::array& array_obj = result_array.get<picojson::array>();
+ array_obj.reserve(privileges.size());
- for (size_t i = 0; i < size; i++) {
+ for (size_t i = 0; i < privileges.size(); i++) {
picojson::value result_elem = picojson::value(picojson::object());
picojson::object& obj = result_elem.get<picojson::object>();
obj["privilege"] = picojson::value(privilege_array[i]);
obj["type"] = picojson::value(CheckResultToString(results[i]));
- array_obj.push_back(result_elem);
+ array_obj.push_back(std::move(result_elem));
}
ReportSuccess(result_array, out);
ScopeLogger();
const double callback_id = args.get("callbackId").get<double>();
-
const picojson::array& privileges = args.get("privileges").get<picojson::array>();
- unsigned int size = static_cast<int>(privileges.size());
-
std::vector<const char*> privilege_array;
- size_t i = 0;
+ privilege_array.reserve(privileges.size());
- for (auto iter = privileges.begin(); iter != privileges.end(); ++iter, ++i) {
+ for (auto iter = privileges.begin(); iter != privileges.end(); ++iter) {
privilege_array.push_back(iter->get<std::string>().c_str());
}
user_data->_instance = this;
user_data->callbackId = callback_id;
- int ret = ppm_request_permissions(privilege_array.data(), size, ResponseMultipleCallback,
- static_cast<void*>(user_data));
+ int ret = ppm_request_permissions(privilege_array.data(), privileges.size(),
+ ResponseMultipleCallback, static_cast<void*>(user_data));
if (PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE != ret) {
+ delete user_data;
LogAndReportError(convertError(ret), &out,
("checkPermission error: %d (%s)", ret, get_error_message(ret)));
return;
};
ListenerManager.prototype.removeListener = function(watchId) {
- if (this.listeners[watchId] === null || this.listeners[watchId] === undefined) {
- return;
- }
-
if (this.listeners.hasOwnProperty(watchId)) {
delete this.listeners[watchId];
}