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);
}
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 {
LoggerD("operation field is empty");
}
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");
}
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 {
LoggerD("MIME field is empty");
}
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 {
LoggerD("category field is empty");
}
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 ? "SINGLE" : "GROUP";
+ 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("launchMode", picojson::value(launch_mode_str)));
+ app_control_obj->insert(std::make_pair(kLaunchModeAppControlField, picojson::value(launch_mode_str)));
}
- app_control_obj->insert(std::make_pair("data", picojson::value(picojson::array())));
+ 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();