summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Keeler <jacob.keeler@livioradio.com>2017-09-07 13:46:34 -0400
committerGitHub <noreply@github.com>2017-09-07 13:46:34 -0400
commit36a45c9310b920e361a464545bc102eb1f0ebfc4 (patch)
tree5f3234dc7a3e6d5059d5b92edb75789ef5d7a33b
parent6b5c69d658022613154a7555e26a4d15a1d114da (diff)
parentfeeec44f77aeca1ae4fa438d62d9b534cb2e9f6a (diff)
downloadsdl_core-36a45c9310b920e361a464545bc102eb1f0ebfc4.tar.gz
Merge pull request #1746 from ChrisB-Elektrobit/feature/metadata_tagging
Feature/metadata tagging
-rw-r--r--src/components/application_manager/include/application_manager/commands/mobile/show_request.h11
-rw-r--r--src/components/application_manager/include/application_manager/smart_object_keys.h2
-rw-r--r--src/components/application_manager/src/commands/mobile/show_request.cc62
-rw-r--r--src/components/application_manager/src/smart_object_keys.cc2
-rw-r--r--src/components/application_manager/test/commands/mobile/show_test.cc179
-rw-r--r--src/components/interfaces/HMI_API.xml42
-rw-r--r--src/components/interfaces/MOBILE_API.xml62
7 files changed, 358 insertions, 2 deletions
diff --git a/src/components/application_manager/include/application_manager/commands/mobile/show_request.h b/src/components/application_manager/include/application_manager/commands/mobile/show_request.h
index cbe2ca396a..a10997bacd 100644
--- a/src/components/application_manager/include/application_manager/commands/mobile/show_request.h
+++ b/src/components/application_manager/include/application_manager/commands/mobile/show_request.h
@@ -78,6 +78,17 @@ class ShowRequest : public CommandRequestImpl {
*/
bool CheckStringsOfShowRequest();
+ /**
+ * @brief Handle the conversion of metadata information from the incoming
+ * mobile json message format to the outgoing hmi json message format
+ */
+ void HandleMetadata(const char* field_id,
+ int32_t field_index,
+ smart_objects::SmartObject& msg_params);
+
+ mobile_apis::Result::eType core_result_code_;
+ std::string core_response_info_;
+
DISALLOW_COPY_AND_ASSIGN(ShowRequest);
};
diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h
index ccac1ec67b..25fa435364 100644
--- a/src/components/application_manager/include/application_manager/smart_object_keys.h
+++ b/src/components/application_manager/include/application_manager/smart_object_keys.h
@@ -93,6 +93,7 @@ extern const char* main_field_1;
extern const char* main_field_2;
extern const char* main_field_3;
extern const char* main_field_4;
+extern const char* metadata_tags;
extern const char* eta;
extern const char* time_to_destination;
extern const char* total_distance;
@@ -410,6 +411,7 @@ namespace hmi_request {
extern const char* parent_id;
extern const char* field_name;
extern const char* field_text;
+extern const char* field_types;
extern const char* alert_strings;
extern const char* duration;
extern const char* soft_buttons;
diff --git a/src/components/application_manager/src/commands/mobile/show_request.cc b/src/components/application_manager/src/commands/mobile/show_request.cc
index cf2509cdb9..5b8e98d7ea 100644
--- a/src/components/application_manager/src/commands/mobile/show_request.cc
+++ b/src/components/application_manager/src/commands/mobile/show_request.cc
@@ -45,10 +45,46 @@ namespace commands {
ShowRequest::ShowRequest(const MessageSharedPtr& message,
ApplicationManager& application_manager)
- : CommandRequestImpl(message, application_manager) {}
+ : CommandRequestImpl(message, application_manager)
+ , core_result_code_(mobile_apis::Result::INVALID_ENUM) {}
ShowRequest::~ShowRequest() {}
+void ShowRequest::HandleMetadata(const char* field_id,
+ int32_t field_index,
+ smart_objects::SmartObject& msg_params) {
+ smart_objects::SmartObject& metadata_tags =
+ (*message_)[strings::msg_params][strings::metadata_tags];
+
+ if (metadata_tags.keyExists(field_id)) {
+ if (field_index != -1) {
+ msg_params[hmi_request::show_strings][field_index]
+ [hmi_request::field_types] =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+
+ const size_t num_tags = metadata_tags[field_id].length();
+ for (size_t i = 0; i < num_tags; ++i) {
+ const int32_t current_tag = metadata_tags[field_id][i].asInt();
+ msg_params[hmi_request::show_strings][field_index]
+ [hmi_request::field_types][i] = current_tag;
+ }
+ } else {
+ LOG4CXX_INFO(logger_,
+ "metadata tag provided with no item for "
+ << field_id << ", ignoring with warning");
+ // tag provided with no item, ignore with warning
+ if (mobile_apis::Result::INVALID_ENUM == core_result_code_) {
+ core_result_code_ = mobile_apis::Result::WARNINGS;
+ core_response_info_ =
+ "Metadata tag was provided for a field with no data.";
+ }
+ }
+ } else {
+ LOG4CXX_INFO(logger_,
+ "No metadata tagging provided for field: " << field_id);
+ }
+}
+
void ShowRequest::Run() {
LOG4CXX_AUTO_TRACE(logger_);
@@ -125,38 +161,53 @@ void ShowRequest::Run() {
smart_objects::SmartObject(smart_objects::SmartType_Array);
int32_t index = 0;
+ int32_t main_field_1_index = -1;
if ((*message_)[strings::msg_params].keyExists(strings::main_field_1)) {
msg_params[hmi_request::show_strings][index][hmi_request::field_name] =
static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField1);
msg_params[hmi_request::show_strings][index][hmi_request::field_text] =
(*message_)[strings::msg_params][strings::main_field_1];
+ main_field_1_index = index;
++index;
}
+ int32_t main_field_2_index = -1;
if ((*message_)[strings::msg_params].keyExists(strings::main_field_2)) {
msg_params[hmi_request::show_strings][index][hmi_request::field_name] =
static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField2);
msg_params[hmi_request::show_strings][index][hmi_request::field_text] =
(*message_)[strings::msg_params][strings::main_field_2];
+ main_field_2_index = index;
++index;
}
+ int32_t main_field_3_index = -1;
if ((*message_)[strings::msg_params].keyExists(strings::main_field_3)) {
msg_params[hmi_request::show_strings][index][hmi_request::field_name] =
static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField3);
msg_params[hmi_request::show_strings][index][hmi_request::field_text] =
(*message_)[strings::msg_params][strings::main_field_3];
+ main_field_3_index = index;
++index;
}
+ int32_t main_field_4_index = -1;
if ((*message_)[strings::msg_params].keyExists(strings::main_field_4)) {
msg_params[hmi_request::show_strings][index][hmi_request::field_name] =
static_cast<int32_t>(hmi_apis::Common_TextFieldName::mainField4);
msg_params[hmi_request::show_strings][index][hmi_request::field_text] =
(*message_)[strings::msg_params][strings::main_field_4];
+ main_field_4_index = index;
++index;
}
+ if ((*message_)[strings::msg_params].keyExists(strings::metadata_tags)) {
+ HandleMetadata(strings::main_field_1, main_field_1_index, msg_params);
+ HandleMetadata(strings::main_field_2, main_field_2_index, msg_params);
+ HandleMetadata(strings::main_field_3, main_field_3_index, msg_params);
+ HandleMetadata(strings::main_field_4, main_field_4_index, msg_params);
+ }
+
if ((*message_)[strings::msg_params].keyExists(strings::media_clock)) {
msg_params[hmi_request::show_strings][index][hmi_request::field_name] =
static_cast<int32_t>(hmi_apis::Common_TextFieldName::mediaClock);
@@ -239,8 +290,15 @@ void ShowRequest::on_event(const event_engine::Event& event) {
response_info =
message[strings::params][hmi_response::message].asString();
}
+ mobile_apis::Result::eType converted_result_code =
+ MessageHelper::HMIToMobileResult(result_code);
+ if (mobile_apis::Result::SUCCESS == converted_result_code &&
+ mobile_apis::Result::INVALID_ENUM != core_result_code_) {
+ converted_result_code = core_result_code_;
+ response_info = core_response_info_;
+ }
SendResponse(result,
- MessageHelper::HMIToMobileResult(result_code),
+ converted_result_code,
response_info.empty() ? NULL : response_info.c_str(),
&(message[strings::msg_params]));
break;
diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc
index d5041ef836..45bab026b4 100644
--- a/src/components/application_manager/src/smart_object_keys.cc
+++ b/src/components/application_manager/src/smart_object_keys.cc
@@ -57,6 +57,7 @@ const char* main_field_1 = "mainField1";
const char* main_field_2 = "mainField2";
const char* main_field_3 = "mainField3";
const char* main_field_4 = "mainField4";
+const char* metadata_tags = "metadataTags";
const char* eta = "eta";
const char* time_to_destination = "timeToDestination";
const char* total_distance = "totalDistance";
@@ -368,6 +369,7 @@ namespace hmi_request {
const char* parent_id = "parentID";
const char* field_name = "fieldName";
const char* field_text = "fieldText";
+const char* field_types = "fieldTypes";
const char* alert_strings = "alertStrings";
const char* duration = "duration";
const char* soft_buttons = "softButtons";
diff --git a/src/components/application_manager/test/commands/mobile/show_test.cc b/src/components/application_manager/test/commands/mobile/show_test.cc
index 86889ac5cd..29ab902f5c 100644
--- a/src/components/application_manager/test/commands/mobile/show_test.cc
+++ b/src/components/application_manager/test/commands/mobile/show_test.cc
@@ -150,6 +150,59 @@ class ShowRequestTest : public CommandRequestTest<CommandsTestMocks::kIsNice> {
EXPECT_CALL(*mock_app_, set_show_command(_)).Times(0);
}
+ void TestSetupHelperWithMetadata(
+ MessageSharedPtr msg,
+ hmi_apis::Common_TextFieldName::eType field_name,
+ const char* field,
+ size_t num_tags,
+ int32_t* field_tags,
+ bool set_field_text = true) {
+ SmartObject msg_params(smart_objects::SmartType_Map);
+ (*msg)[am::strings::params][am::strings::connection_key] = kConnectionKey;
+ (*msg)[am::strings::params][am::strings::function_id] = kFunctionID;
+ if (set_field_text) {
+ msg_params[field] = text_field_;
+ }
+ msg_params[am::strings::metadata_tags][field] =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ for (size_t i = 0; i < num_tags; ++i) {
+ const int32_t current_tag = field_tags[i];
+ msg_params[am::strings::metadata_tags][field][i] = current_tag;
+ }
+ (*msg)[am::strings::msg_params] = msg_params;
+
+ EXPECT_EQ((*msg)[am::strings::msg_params], msg_params);
+
+ EXPECT_CALL(app_mngr_, application(kConnectionKey))
+ .WillOnce(Return(mock_app_));
+ EXPECT_CALL(*mock_app_, app_id()).WillOnce(Return(kAppId));
+
+ msg_params.erase(field);
+ msg_params.erase(am::strings::metadata_tags);
+
+ msg_params[am::strings::app_id] = kAppId;
+ msg_params[am::hmi_request::show_strings] =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ if (set_field_text) {
+ msg_params[am::hmi_request::show_strings][0]
+ [am::hmi_request::field_name] =
+ static_cast<int32_t>(field_name);
+ msg_params[am::hmi_request::show_strings][0]
+ [am::hmi_request::field_text] = text_field_;
+ msg_params[am::hmi_request::show_strings][0]
+ [am::hmi_request::field_types] =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ for (size_t i = 0; i < num_tags; ++i) {
+ const int32_t current_tag = field_tags[i];
+ msg_params[am::hmi_request::show_strings][0]
+ [am::hmi_request::field_types][i] = current_tag;
+ }
+ }
+
+ EXPECT_CALL(app_mngr_, ManageHMICommand(_));
+ EXPECT_CALL(*mock_app_, set_show_command(msg_params));
+ }
+
void SetUp() OVERRIDE {
Mock::VerifyAndClearExpectations(&mock_message_helper_);
}
@@ -582,6 +635,132 @@ TEST_F(ShowRequestTest, Run_MainField4_WrongSyntax) {
command->Run();
}
+TEST_F(ShowRequestTest, Run_MainField1_MetadataTag) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_1";
+ const size_t num_tags = 1;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaArtist};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField1,
+ am::strings::main_field_1,
+ num_tags,
+ tags);
+ command->Run();
+}
+
+TEST_F(ShowRequestTest, Run_MainField1_MultipleMetadataTags) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_1";
+ const size_t num_tags = 5;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaTitle,
+ hmi_apis::Common_MetadataType::mediaArtist,
+ hmi_apis::Common_MetadataType::rating,
+ hmi_apis::Common_MetadataType::humidity,
+ hmi_apis::Common_MetadataType::currentTemperature};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField1,
+ am::strings::main_field_1,
+ num_tags,
+ tags);
+ command->Run();
+}
+
+TEST_F(ShowRequestTest, Run_MainField2_MetadataTag) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_2";
+ const size_t num_tags = 1;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaArtist};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField2,
+ am::strings::main_field_2,
+ num_tags,
+ tags);
+ command->Run();
+}
+
+TEST_F(ShowRequestTest, Run_MainField3_MetadataTag) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_3";
+ const size_t num_tags = 1;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaArtist};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField3,
+ am::strings::main_field_3,
+ num_tags,
+ tags);
+ command->Run();
+}
+
+TEST_F(ShowRequestTest, Run_MainField4_MetadataTag) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_4";
+ const size_t num_tags = 1;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaArtist};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField4,
+ am::strings::main_field_4,
+ num_tags,
+ tags);
+ command->Run();
+}
+
+TEST_F(ShowRequestTest, Run_MainField1_MetadataTagWithNoFieldData) {
+ MessageSharedPtr msg = CreateMsgParams();
+
+ SharedPtr<ShowRequest> command(CreateCommand<ShowRequest>(msg));
+
+ text_field_ = "Main_Field_1";
+ const size_t num_tags = 1;
+ int32_t tags[num_tags] = {hmi_apis::Common_MetadataType::mediaArtist};
+ TestSetupHelperWithMetadata(msg,
+ hmi_apis::Common_TextFieldName::mainField1,
+ am::strings::main_field_1,
+ num_tags,
+ tags,
+ false);
+ command->Run();
+
+ MessageSharedPtr ev_msg = CreateMessage(smart_objects::SmartType_Map);
+ (*ev_msg)[am::strings::params][am::hmi_response::code] =
+ hmi_apis::Common_Result::SUCCESS;
+ (*ev_msg)[am::strings::msg_params][am::strings::app_id] = kConnectionKey;
+ (*ev_msg)[am::strings::msg_params][am::strings::info] = "";
+
+ Event event(hmi_apis::FunctionID::UI_Show);
+ event.set_smart_object(*ev_msg);
+
+ MessageSharedPtr ui_command_result;
+ EXPECT_CALL(
+ app_mngr_,
+ ManageMobileCommand(_, am::commands::Command::CommandOrigin::ORIGIN_SDL))
+ .WillOnce(DoAll(SaveArg<0>(&ui_command_result), Return(true)));
+
+ command->on_event(event);
+
+ EXPECT_EQ((*ui_command_result)[am::strings::msg_params][am::strings::success]
+ .asBool(),
+ true);
+ EXPECT_EQ(
+ (*ui_command_result)[am::strings::msg_params][am::strings::result_code]
+ .asInt(),
+ static_cast<int32_t>(mobile_apis::Result::WARNINGS));
+}
+
TEST_F(ShowRequestTest, Run_MediaClock_SUCCESS) {
MessageSharedPtr msg = CreateMsgParams();
diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml
index 554461cc86..32360aa357 100644
--- a/src/components/interfaces/HMI_API.xml
+++ b/src/components/interfaces/HMI_API.xml
@@ -559,6 +559,45 @@
<element name="turnText"/>
</enum>
+<enum name="MetadataType">
+ <element name="mediaTitle">
+ <description>The data in this field contains the title of the currently playing audio track.</description>
+ </element>
+ <element name="mediaArtist">
+ <description>The data in this field contains the artist or creator of the currently playing audio track.</description>
+ </element>
+ <element name="mediaAlbum">
+ <description>The data in this field contains the album title of the currently playing audio track.</description>
+ </element>
+ <element name="mediaYear">
+ <description>The data in this field contains the creation year of the currently playing audio track.</description>
+ </element>
+ <element name="mediaGenre">
+ <description>The data in this field contains the genre of the currently playing audio track.</description>
+ </element>
+ <element name="mediaStation">
+ <description>The data in this field contains the name of the current source for the media.</description>
+ </element>
+ <element name="rating">
+ <description>The data in this field is a rating.</description>
+ </element>
+ <element name="currentTemperature">
+ <description>The data in this field is the current temperature.</description>
+ </element>
+ <element name="maximumTemperature">
+ <description>The data in this field is the maximum temperature for the day.</description>
+ </element>
+ <element name="minimumTemperature">
+ <description>The data in this field is the minimum temperature for the day.</description>
+ </element>
+ <element name="weatherTerm">
+ <description>The data in this field describes the current weather (ex. cloudy, clear, etc.).</description>
+ </element>
+ <element name="humidity">
+ <description>The data in this field describes the current humidity value.</description>
+ </element>
+</enum>
+
<enum name="ImageFieldName">
<element name="softButtonImage">
<description>The image field for SoftButton</description>
@@ -2092,6 +2131,9 @@
<param name="fieldText" type="String" maxlength="500" mandatory="true">
<description>The text itself.</description>
</param>
+ <param name="fieldTypes" type="Common.MetadataType" minsize="0" maxsize="5" array="true" mandatory="false">
+ <description>The type of data contained in the field.</description>
+ </param>
</struct>
<struct name="KeyboardProperties">
diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml
index 2d550f04f2..73fe9f3d0c 100644
--- a/src/components/interfaces/MOBILE_API.xml
+++ b/src/components/interfaces/MOBILE_API.xml
@@ -756,6 +756,45 @@
</enum>
+ <enum name="MetadataType">
+ <element name="mediaTitle">
+ <description>The data in this field contains the title of the currently playing audio track.</description>
+ </element>
+ <element name="mediaArtist">
+ <description>The data in this field contains the artist or creator of the currently playing audio track.</description>
+ </element>
+ <element name="mediaAlbum">
+ <description>The data in this field contains the album title of the currently playing audio track.</description>
+ </element>
+ <element name="mediaYear">
+ <description>The data in this field contains the creation year of the currently playing audio track.</description>
+ </element>
+ <element name="mediaGenre">
+ <description>The data in this field contains the genre of the currently playing audio track.</description>
+ </element>
+ <element name="mediaStation">
+ <description>The data in this field contains the name of the current source for the media.</description>
+ </element>
+ <element name="rating">
+ <description>The data in this field is a rating.</description>
+ </element>
+ <element name="currentTemperature">
+ <description>The data in this field is the current temperature.</description>
+ </element>
+ <element name="maximumTemperature">
+ <description>The data in this field is the maximum temperature for the day.</description>
+ </element>
+ <element name="minimumTemperature">
+ <description>The data in this field is the minimum temperature for the day.</description>
+ </element>
+ <element name="weatherTerm">
+ <description>The data in this field describes the current weather (ex. cloudy, clear, etc.).</description>
+ </element>
+ <element name="humidity">
+ <description>The data in this field describes the current humidity value.</description>
+ </element>
+ </enum>
+
<enum name="ImageFieldName">
<element name="softButtonImage">
<description>The image field for SoftButton</description>
@@ -976,6 +1015,21 @@
</param>
</struct>
+ <struct name="MetadataTags">
+ <param name="mainField1" type="MetadataType" minsize="0" maxsize="5" array="true" mandatory="false">
+ <description>The type of data contained in the "mainField1" text field.</description>
+ </param>
+ <param name="mainField2" type="MetadataType" minsize="0" maxsize="5" array="true" mandatory="false">
+ <description>The type of data contained in the "mainField2" text field.</description>
+ </param>
+ <param name="mainField3" type="MetadataType" minsize="0" maxsize="5" array="true" mandatory="false">
+ <description>The type of data contained in the "mainField3" text field.</description>
+ </param>
+ <param name="mainField4" type="MetadataType" minsize="0" maxsize="5" array="true" mandatory="false">
+ <description>The type of data contained in the "mainField4" text field.</description>
+ </param>
+ </struct>
+
<struct name="Choice">
<description>A choice is an option given to the user, which can be selected either by menu, or through voice recognition system.</description>
<param name="choiceID" type="Integer" minvalue="0" maxvalue="65535" mandatory="true"/>
@@ -3788,6 +3842,14 @@
</description>
</param>
+ <param name="metadataTags" type="MetadataTags" mandatory="false">
+ <description>
+ App defined metadata information. See MetadataTags. Uses mainField1, mainField2, mainField3, mainField4.
+ If omitted on supported displays, the currently set metadata tags will not change.
+ If any text field contains no tags, the metadata tag for that textfield should be removed.
+ </description>
+ </param>
+
</function>
<function name="Show" functionID="ShowID" messagetype="response">