summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2014-05-24 04:24:22 -0400
committerJustin Dickow <jjdickow@gmail.com>2014-05-24 04:24:22 -0400
commit5278419709d35ccb4a9a5b0ac464714be2378930 (patch)
tree88d246709c255ab86273b0301be2216a4c02024b
parentcc4b778f42c4525adddcfc8ce495efab22fcc75d (diff)
downloadsmartdevicelink-feature/handshake.tar.gz
remove submodulefeature/handshake
-rw-r--r--.gitmodules3
m---------src/components/policy0
-rw-r--r--src/components/policy/CMakeLists.txt34
-rw-r--r--src/components/policy/doc/doxygen/components/AppMgr/index.txt5
-rw-r--r--src/components/policy/doc/doxygen/components/HMI/index.txt5
-rw-r--r--src/components/policy/doc/doxygen/components/JSONHandler/Formatters/index.txt9
-rw-r--r--src/components/policy/doc/doxygen/components/JSONHandler/index.txt8
-rw-r--r--src/components/policy/doc/doxygen/components/ProtocolHandler/index.txt5
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Type casts.txt204
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Value representation.txt25
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/index.txt9
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Schema Structure.txt101
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Validation.txt9
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/index.txt10
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/Use of Smart Objects/index.txt6
-rw-r--r--src/components/policy/doc/doxygen/components/SmartObjects/index.txt11
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Client Specification/ConnectionManagement.txt11
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DataTransfer.txt11
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DeviceManagement.txt14
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Client Specification/index.txt18
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/BluetoothAdapter.txt19
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/TCPAdapter.txt20
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/index.txt89
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Interaction.txt7
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/MultiThreading.txt9
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/TrasportManager.txt15
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Internal Design/index.txt15
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase1.txt74
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase2.txt96
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase3.txt131
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/Use Cases/index.txt11
-rw-r--r--src/components/policy/doc/doxygen/components/TransportManager/index.txt9
-rw-r--r--src/components/policy/doc/doxygen/components/index.txt10
-rw-r--r--src/components/policy/doc/doxygen/info.txt5
-rw-r--r--src/components/policy/doc/doxygen/mainpage.txt9
-rw-r--r--src/components/policy/doc/doxygen/tools/InterfaceGenerator/Arhitecture.txt5
-rw-r--r--src/components/policy/doc/doxygen/tools/InterfaceGenerator/CMake Integration.txt13
-rw-r--r--src/components/policy/doc/doxygen/tools/InterfaceGenerator/How To Use.txt31
-rw-r--r--src/components/policy/doc/doxygen/tools/InterfaceGenerator/Use of Output.txt11
-rw-r--r--src/components/policy/doc/doxygen/tools/InterfaceGenerator/index.txt12
-rw-r--r--src/components/policy/doc/doxygen/tools/index.txt5
-rw-r--r--src/components/policy/doc/grc/conf.smartDeviceLinkCore34
-rw-r--r--src/components/policy/doc/grc/grc.conf3
-rw-r--r--src/components/policy/doc/install.txt91
-rw-r--r--src/components/policy/doc/qnx_build.txt28
-rw-r--r--src/components/policy/doc/readme.txt67
-rw-r--r--src/components/policy/src/policy/CMakeLists.txt119
-rw-r--r--src/components/policy/src/policy/Readme.txt3
-rw-r--r--src/components/policy/src/policy/include/policy/policy_helper.h157
-rw-r--r--src/components/policy/src/policy/include/policy/policy_listener.h54
-rw-r--r--src/components/policy/src/policy/include/policy/policy_manager.h328
-rw-r--r--src/components/policy/src/policy/include/policy/policy_manager_impl.h268
-rw-r--r--src/components/policy/src/policy/include/policy/policy_table.h62
-rw-r--r--src/components/policy/src/policy/include/policy/policy_types.h289
-rw-r--r--src/components/policy/src/policy/include/policy/pt_ext_representation.h292
-rw-r--r--src/components/policy/src/policy/include/policy/pt_representation.h271
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h85
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h164
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_queries.h104
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_representation.h158
-rw-r--r--src/components/policy/src/policy/include/policy/sql_wrapper.h44
-rw-r--r--src/components/policy/src/policy/include/policy/syncp_adapter.h62
-rw-r--r--src/components/policy/src/policy/include/policy/user_consent_manager.h44
-rw-r--r--src/components/policy/src/policy/policy_table_interface.xml225
-rw-r--r--src/components/policy/src/policy/policy_table_interface_ext.xml279
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/CMakeLists.txt54
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_database.h130
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_error.h80
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_query.h251
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/policy.ini4
-rwxr-xr-xsrc/components/policy/src/policy/qdb_wrapper/qdbserver.sh6
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/src/sql_database.cc100
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/src/sql_error.cc66
-rw-r--r--src/components/policy/src/policy/qdb_wrapper/src/sql_query.cc268
-rw-r--r--src/components/policy/src/policy/specification.txt1
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/CMakeLists.txt44
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_database.h149
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_error.h109
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_query.h219
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/src/sql_database.cc102
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/src/sql_error.cc153
-rw-r--r--src/components/policy/src/policy/sqlite_wrapper/src/sql_query.cc157
-rw-r--r--src/components/policy/src/policy/src/policy_helper.cc485
-rw-r--r--src/components/policy/src/policy/src/policy_manager_impl.cc1224
-rw-r--r--src/components/policy/src/policy/src/policy_table.cc64
-rw-r--r--src/components/policy/src/policy/src/sql_pt_ext_queries.cc199
-rw-r--r--src/components/policy/src/policy/src/sql_pt_ext_representation.cc1296
-rw-r--r--src/components/policy/src/policy/src/sql_pt_queries.cc577
-rw-r--r--src/components/policy/src/policy/src/sql_pt_representation.cc1230
-rw-r--r--src/components/policy/src/policy/src/syncp_adapter.cc67
-rw-r--r--src/components/policy/src/policy/usage_statistics/CMakeLists.txt37
-rw-r--r--src/components/policy/src/policy/usage_statistics/include/usage_statistics/counter.h93
-rw-r--r--src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h84
-rw-r--r--src/components/policy/src/policy/usage_statistics/src/counter.cc117
-rw-r--r--src/components/policy/test/policy/CMakeLists.txt95
-rw-r--r--src/components/policy/test/policy/include/generated_code_with_sqlite_test.h400
-rw-r--r--src/components/policy/test/policy/include/mock_policy_listener.h68
-rw-r--r--src/components/policy/test/policy/include/mock_pt_ext_representation.h119
-rw-r--r--src/components/policy/test/policy/include/mock_pt_representation.h106
-rw-r--r--src/components/policy/test/policy/log4cxx.properties21
-rw-r--r--src/components/policy/test/policy/qdb_wrapper/CMakeLists.txt29
-rw-r--r--src/components/policy/test/policy/qdb_wrapper/src/test_sql_database.cc142
-rw-r--r--src/components/policy/test/policy/qdb_wrapper/src/test_sql_query.cc284
-rwxr-xr-xsrc/components/policy/test/policy/qdbserver.sh6
-rw-r--r--src/components/policy/test/policy/sqlite_wrapper/CMakeLists.txt26
-rw-r--r--src/components/policy/test/policy/sqlite_wrapper/src/test_sql_database.cc151
-rw-r--r--src/components/policy/test/policy/sqlite_wrapper/src/test_sql_query.cc299
-rw-r--r--src/components/policy/test/policy/src/generated_code_test.cc60
-rw-r--r--src/components/policy/test/policy/src/generated_code_with_sqlite_test.cc172
-rw-r--r--src/components/policy/test/policy/src/test_policy_manager_impl.cc437
-rw-r--r--src/components/policy/test/policy/src/test_shared_library.cc71
-rw-r--r--src/components/policy/test/policy/src/test_sql_pt_ext_representation.cc299
-rw-r--r--src/components/policy/test/policy/src/test_sql_pt_representation.cc448
-rw-r--r--src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc275
-rw-r--r--src/components/policy/test/policy/test-qdb.ini10
-rw-r--r--src/components/policy/test/policy/usage_statistics/CMakeLists.txt16
-rw-r--r--src/components/policy/test/policy/usage_statistics/include/statistics_manager_mock.h22
-rw-r--r--src/components/policy/test/policy/usage_statistics/src/test_counter.cc115
-rw-r--r--src/components/policy/test/policy/valid_sdl_pt_update.json1817
119 files changed, 17176 insertions, 3 deletions
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index e083e7db8..000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "src/components/policy"]
- path = src/components/policy
- url = git@adc.luxoft.com:applink
diff --git a/src/components/policy b/src/components/policy
deleted file mode 160000
-Subproject 721df989143d9c1c886f9fa5c1007d04cd5baae
diff --git a/src/components/policy/CMakeLists.txt b/src/components/policy/CMakeLists.txt
new file mode 100644
index 000000000..5a8de7304
--- /dev/null
+++ b/src/components/policy/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (c) 2013, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+# --- Policy
+add_subdirectory(./src/policy)
+
+
diff --git a/src/components/policy/doc/doxygen/components/AppMgr/index.txt b/src/components/policy/doc/doxygen/components/AppMgr/index.txt
new file mode 100644
index 000000000..17584b09e
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/AppMgr/index.txt
@@ -0,0 +1,5 @@
+/*! \page components_appmgr App Manager
+
+Here will be information about App Manager component
+
+*/ \ No newline at end of file
diff --git a/src/components/policy/doc/doxygen/components/HMI/index.txt b/src/components/policy/doc/doxygen/components/HMI/index.txt
new file mode 100644
index 000000000..361763118
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/HMI/index.txt
@@ -0,0 +1,5 @@
+/*! \page components_hmi HMI
+
+Here will be information about HMI component
+
+*/ \ No newline at end of file
diff --git a/src/components/policy/doc/doxygen/components/JSONHandler/Formatters/index.txt b/src/components/policy/doc/doxygen/components/JSONHandler/Formatters/index.txt
new file mode 100644
index 000000000..9854b88d5
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/JSONHandler/Formatters/index.txt
@@ -0,0 +1,9 @@
+/*! \page components_jsonhandler_formatters Smart Objects Formatters
+
+In order to create JSON string representation from Smart Object or create Smart Object data structure from JSON string representation JSON Handler component has special classes called formatters.
+
+The interface of formatter is quite simple and defined by NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonBase class. Actually it has two methods - NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonBase::objToJsonValue to convert JSON string to object and NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonBase::jsonValueToObj to create JSON string from object.
+
+Current implementation has two different implementations of NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonBase class: NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonALRPCv1 for ALRPC.v1 and NsSmartDeviceLink::NsJSONHandler::Formatters::CFormatterJsonALRPCv2 for ALRPC.v2. These implementations handle specifics of each format.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/JSONHandler/index.txt b/src/components/policy/doc/doxygen/components/JSONHandler/index.txt
new file mode 100644
index 000000000..a65c8ddc7
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/JSONHandler/index.txt
@@ -0,0 +1,8 @@
+/*! \page components_jsonhandler JSON Handler
+
+Here will be information about JSON Handler component
+
+Detailed information:
+ - \subpage components_jsonhandler_formatters "Smart Objects Formatters"
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/ProtocolHandler/index.txt b/src/components/policy/doc/doxygen/components/ProtocolHandler/index.txt
new file mode 100644
index 000000000..c5b5ceb79
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/ProtocolHandler/index.txt
@@ -0,0 +1,5 @@
+/*! \page components_protocolhandler Protocol Handler
+
+Here will be information about Protocol Handler component
+
+*/ \ No newline at end of file
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Type casts.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Type casts.txt
new file mode 100644
index 000000000..3ae636c92
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Type casts.txt
@@ -0,0 +1,204 @@
+/*! \page components_smartobjects_types_cast Type cast for SmartObjects
+
+One of easy and probably intuitive way to work with values in the Smart Object is simple use of the type casts. Implementation of NsSmartDeviceLink::NsSmartObjects::CSmartObject class has all necessary declarations to support all required types.
+
+Example 1 (Work with int value):
+
+<pre>
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = 1; //Assign int value
+
+int i = (int)obj; //Get int value
+
+</pre>
+
+Example 2 (Work with long value):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = 100l; //Assign long value
+
+long l = (long)obj; //Get long value
+
+</pre>
+
+Example 3 (Work with double value):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = 3.14; //Assign double value
+
+double d = (double)obj; //Get double value
+
+</pre>
+
+Example 4 (Work with char value):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = 'a'; //Assign char value
+
+char c = (char)obj; //Get char value
+
+</pre>
+
+Example 5 (Work with bool value):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = true; //Assign bool value
+
+bool b = (bool)obj; //Get bool value
+
+</pre>
+
+Example 6 (Work with string values):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj1;
+
+obj1 = "Hello, world"; //Assign char* string value
+
+obj2 = std::string("Hello, world"); //Assign std::string value
+
+std::string s1 = (std::string)obj1;
+
+std::string s2 = (std::string)obj2;
+
+</pre>
+
+Example 7 (Work with arrays):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject simpleArray;
+
+simpleArray[0] = 1;
+
+simpleArray[1] = true;
+
+simpleArray[2] = 'a';
+
+simpleArray[3] = 3.14;
+
+int val0 = (int)simpleArray[0];
+
+bool val1 = (bool)simpleArray[1];
+
+char val2 = (char)simpleArray[2];
+
+double val3 = (double)simpleArray[3];
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject deepArray;
+
+deepArray[0] = 1;
+
+deepArray[1][0] = 3.14;
+
+deepArray[1][1][0] = true;
+
+int val0 = (int)obj[0];
+
+double val1_0 = (double)obj[1][0];
+
+bool val1_1_0 = (bool)obj[1][1][0];
+
+</pre>
+
+
+Example 8 (Work with maps):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject simpleMap;
+
+simpleMap["name"] = "My name";
+
+simpleMap["count"] = 10;
+
+simpleMap["isValid"] = true;
+
+std::string name = (std::string)obj["name"];
+
+int count = (int)obj["count"];
+
+bool isValid = (bool)obj["isValid"];
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject deepMap;
+
+deepMap["request"]["name"] = "My Request";
+
+deepMap["request"]["id"] = 123;
+
+deepMap["response"]["name"] = "My Response";
+
+deepMap["response"]["id"] = 456;
+
+deepMap["we"]["need"]["to"]["go"]["deeper"] = true;
+
+std::string requestName = (std::string)deepMap["request"]["name"];
+
+int requestId = (int)deepMap["request"]["id"];
+
+std::string responseName = (std::string)deepMap["response"]["name"];
+
+int responseId = (int)deepMap["response"]["id"];
+
+deepFlag = (bool)deepMap["we"]["need"]["to"]["go"]["deeper"];
+
+</pre>
+
+
+Example 9 (Removing elements from Map):
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject mapObj;
+
+mapObj["first"] = "first value";
+mapObj["second"] = "second value";
+mapObj["to delete"] = 1234;
+mapObj["third"] = "third value";
+
+bool result = mapObj.erase("to delete");
+
+</pre>
+
+
+Example 10 (Using alternative method of accessing SmartObject values)
+
+<pre>
+
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj = 1; //Assign int value
+int i = obj.asInt(); //Get int value
+
+obj = 100l; //Assign long value
+long l = obj.asLong(); //Get long value
+
+obj = 3.14; //Assign double value
+double d = obj.asDouble(); //Get double value
+
+obj = true;
+bool b = obj.asBool(); // Get bool value
+
+obj = 'c';
+char c = obj.asChar(); // Get char value
+
+obj = "some string";
+std::string str = obj.asString(); // Get string value
+
+</pre>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Value representation.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Value representation.txt
new file mode 100644
index 000000000..6505ae6f4
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/Value representation.txt
@@ -0,0 +1,25 @@
+/*! \page components_smartobjects_types_repr Type value representation methods for SmartObjects
+
+As alternative to the type casts NsSmartDeviceLink::NsSmartObjects::CSmartObject class defines set of usable methods that allow to represent object values as desired type. Use of these methods may change code style and readability but functionally it completely similar to the type casts of Smart Objects.
+
+Example:
+
+<pre>
+NsSmartDeviceLink::NsSmartObjects::CSmartObject obj;
+
+obj[0] = 1;
+
+obj[1] = true;
+
+obj[2] = 'a';
+
+obj[3] = 3.14;
+
+int i = obj[0].asInt();
+
+char c = obj[1].asChar();
+
+double d = obj[2].asDouble();
+</pre>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/index.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/index.txt
new file mode 100644
index 000000000..9ca3fb3e9
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Types/index.txt
@@ -0,0 +1,9 @@
+/*! \page components_smartobjects_types Smart Objects Types
+
+Current implementation of Smart Objects contains definitions that allow working with every Smart Object
+as variable of one of the basic types: bool, int, long, double, char, string (both as char* and std::string), array and map.
+
+There are two different ways to work with type values in SmartObjects:
+ - \subpage components_smartobjects_types_cast "Type cast for SmartObjects"
+ - \subpage components_smartobjects_types_repr "Type value representation methods for SmartObjects"
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Schema Structure.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Schema Structure.txt
new file mode 100644
index 000000000..2e611f74b
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Schema Structure.txt
@@ -0,0 +1,101 @@
+/*! \page components_smartobjects_validation_items Schema structure: Schema Items
+
+In order to create new Schema (new object of class NsSmartDeviceLink::NsSmartObjects::CSmartSchema) client first must define all required Schema Items. Actually every Schema is a tree of respective Schema Items. Each node and leaf of that tree defines structural rules for some Smart Object data structure.
+
+Schema Items are represented as class hierarchy. The base class for all schema items is a NsSmartDeviceLink::NsSmartObjects::ISchemaItem class. This base class defines generic validation interface for Schema Items.
+
+To define special elements with always successful or always failing validation there are two special Schema Items: NsSmartDeviceLink::NsSmartObjects::CAlwaysTrueSchemaItem and NsSmartDeviceLink::NsSmartObjects::CAlwaysFalseSchemaItem.
+
+NsSmartDeviceLink::NsSmartObjects::CBoolSchemaItem is used for boolean values and has no parameters (only verifies that respective Smart Object is really has boolean value).
+
+NsSmartDeviceLink::NsSmartObjects::TNumberSchemaItem is template Schema Item that can be used for both integer and floating point values. In addition to the regular type verification it is possible to set min and max value range (these values are optional).
+
+NsSmartDeviceLink::NsSmartObjects::TEnumSchemaItem is used to verify any custom client-defined enum.
+
+NsSmartDeviceLink::NsSmartObjects::CStringSchemaItem is used to verify a string values. As optional parameter max length of the string could be set.
+
+NsSmartDeviceLink::NsSmartObjects::CArraySchemaItem provides validation for array. Can be used to verify special type and array size.
+
+NsSmartDeviceLink::NsSmartObjects::CObjectSchemaItem used in case when Schema Item includes another Schema Item. Actually this is only way to create tree node of new Schema. All other Schema Items will be used only to become leafs of validation tree.
+
+After creation of all required Schema Items (which is actually bind in the tree) it is possible to create Schema.
+Schema can be initialized not only by raw root Schema Item, but also by special abstraction called Member (defined by NsSmartDeviceLink::NsSmartObjects::CObjectSchemaItem::SMember class). So every root item (NsSmartDeviceLink::NsSmartObjects::CObjectSchemaItem) firstly should be wrapped as Member. This wrapping process also allows to set "is mandatory" status for every Member.
+
+ and pass root Schema Item as initial parameter to the new Schema.
+
+Currently Schemas are generated by the InterfaceGenerator. For supported ALRPC.v1/.v2 Schema has following structure:
+
+<pre>
+
+ROOT
+ |
+ -- PARAMS
+ | |
+ | -- FUNCTION_ID
+ | |
+ | -- MESSAGE_TYPE
+ | |
+ | -- CORRELATION_ID
+ | |
+ | -- PROTOCOL_VERSION
+ | |
+ | -- PROTOCOL_TYPE
+ |
+ -- MSG_PARAMS
+ |
+ -- OBJECT
+ |
+ -- (Actually contains function-specific leaf item)
+ ...
+</pre>
+
+Example:
+
+<pre>
+
+// Function parameter success.
+//
+// true, if successful
+// false, if failed
+TSharedPtr<ISchemaItem> success_SchemaItem = CBoolSchemaItem::create(TSchemaItemParameter<bool>());
+
+// Function parameter resultCode.
+//
+// See Result
+TSharedPtr<ISchemaItem> resultCode_SchemaItem = TEnumSchemaItem<Result::eType>::create(resultCode_allowedEnumSubsetValues, TSchemaItemParameter<Result::eType>());
+
+// Function parameter info.
+//
+// Provides additional human readable info regarding the result.
+TSharedPtr<ISchemaItem> info_SchemaItem = CStringSchemaItem::create(TSchemaItemParameter<size_t>(1000), TSchemaItemParameter<std::string>());
+
+schemaMembersMap["success"] = CObjectSchemaItem::SMember(success_SchemaItem, true);
+
+schemaMembersMap["resultCode"] = CObjectSchemaItem::SMember(resultCode_SchemaItem, true);
+
+schemaMembersMap["info"] = CObjectSchemaItem::SMember(info_SchemaItem, false);
+
+std::map<std::string, CObjectSchemaItem::SMember> paramsMembersMap;
+
+paramsMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_FUNCTION_ID] = CObjectSchemaItem::SMember(TEnumSchemaItem<FunctionID::eType>::create(FunctionIDItems), true);
+
+paramsMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_MESSAGE_TYPE] = CObjectSchemaItem::SMember(TEnumSchemaItem<messageType::eType>::create(MessageTypeItems), true);
+
+paramsMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_CORRELATION_ID] = CObjectSchemaItem::SMember(TNumberSchemaItem<int>::create(), true);
+
+paramsMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_PROTOCOL_VERSION] = CObjectSchemaItem::SMember(TNumberSchemaItem<int>::create(1, 2), true);
+
+paramsMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_PROTOCOL_TYPE] = CObjectSchemaItem::SMember(TNumberSchemaItem<int>::create(), true);
+
+std::map<std::string, CObjectSchemaItem::SMember> rootMembersMap;
+
+rootMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_MSG_PARAMS] = CObjectSchemaItem::SMember(CObjectSchemaItem::create(schemaMembersMap), true);
+
+rootMembersMap[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS] = CObjectSchemaItem::SMember(CObjectSchemaItem::create(paramsMembersMap), true);
+
+
+CSmartSchema(CObjectSchemaItem::create(rootMembersMap));
+
+</pre>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Validation.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Validation.txt
new file mode 100644
index 000000000..a02f0be4b
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/Validation.txt
@@ -0,0 +1,9 @@
+/*! \page components_smartobjects_validation_use Using Schema for validation
+
+The main purpose of Schema is validation of existing Smart Object. This process includes type and value validation. The client can use results of validation to determine if given Smart Object is valid or not. Validation of specific Smart Object can be triggered by using NsSmartDeviceLink::NsSmartObjects::CSmartSchema::validate method. Internally Schema triggers respective validate method of every Schema Item in order to perform validation.
+
+Another feature of Schema is capability to be applied to the Smart Object. Applying means that Schema tries to modify object to "normalize" data. Currently this "normalization" effects on string representation of enums. Applying of the Schema can be triggered by using NsSmartDeviceLink::NsSmartObjects::CSmartSchema::applySchema method. Internally Schema triggers respective apply method of every Schema Item and at the moment only enum Schema Items try to covert string representation to enum values.
+
+To "unapply" modifications done by apply feature Schema has NsSmartDeviceLink::NsSmartObjects::CSmartSchema::unapplySchema method. It can be used to make string representations of enums.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/index.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/index.txt
new file mode 100644
index 000000000..d42579187
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Smart Objects Validation/index.txt
@@ -0,0 +1,10 @@
+/*! \page components_smartobjects_validation Smart Objects validation
+
+The mechanism of Smart Objects validation includes special Schema. This Schema is similar to the regular XML schema. In other words Schema defines structural description of desired object. After that definition is done Schema can be applied to the object in order to make validation.
+
+Every Schema is constructed from objects called SchemaItems. Every SchemaItem defines type and restriction of specific data structure.
+
+For more details please review:
+ - \subpage components_smartobjects_validation_items "Schema structure: Schema Items"
+ - \subpage components_smartobjects_validation_use "Using Schema for validation"
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/Use of Smart Objects/index.txt b/src/components/policy/doc/doxygen/components/SmartObjects/Use of Smart Objects/index.txt
new file mode 100644
index 000000000..6ad626de4
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/Use of Smart Objects/index.txt
@@ -0,0 +1,6 @@
+/*! \page components_smartobjects_usage Use Smart Objects
+
+There are lots of useful applications for the Smart Objects. They allow building complex dynamic data
+structures in runtime and can be used to store and provide almost any data. For example any array can contain an item which is other array and so on.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/SmartObjects/index.txt b/src/components/policy/doc/doxygen/components/SmartObjects/index.txt
new file mode 100644
index 000000000..3844e1ab6
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/SmartObjects/index.txt
@@ -0,0 +1,11 @@
+/*! \page components_smartobjects Smart Objects
+
+Smart Object is building block for a custom dynamic data structures with virtually unlimited complexity. Client code can use Smart Objects to create containers for simple basic types such as bools, ints, doubles, chars, strings end enums as well as arrays and maps.
+
+Smart Objects solution also includes validation/normalization mechanism of schemas witch is similar to the XML schemas. This feature allows client to validate any data structure.
+
+More detailed information is described in following chapters:
+ - \subpage components_smartobjects_types "Smart Objects Types"
+ - \subpage components_smartobjects_usage "Use of Smart Objects"
+ - \subpage components_smartobjects_validation "Smart Objects validation"
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/ConnectionManagement.txt b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/ConnectionManagement.txt
new file mode 100644
index 000000000..2ba273e9d
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/ConnectionManagement.txt
@@ -0,0 +1,11 @@
+/** @page components_transportmanager_client_connection_management Connection Management
+ *
+ * As all requests to TransportManager are asynchronous, client must implement NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener
+ * interface and add itself as a device listener with NsSmartDeviceLink::NsTransportManager::ITransportManager::addDeviceListener()
+ * in order to receive notifications.
+ * To connect remote device client must use NsSmartDeviceLink::NsTransportManager::ITransportManager::connectDevice(). It will initiate connections to all
+ * applications running on remove device. For TCP device this call has no effect as TCP connections are initiated by remote devices.
+ * Client will be notified about each connected application with NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener::onApplicationConnected().
+ * To disconnect all applications running on remote device client must use NsSmartDeviceLink::NsTransportManager::ITransportManager::disconnectDevice().
+ * Client will be notified about each disconnected application with NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener::onApplicationDisconnected().
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DataTransfer.txt b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DataTransfer.txt
new file mode 100644
index 000000000..98dd7426b
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DataTransfer.txt
@@ -0,0 +1,11 @@
+/** @page components_transportmanager_client_data_transfer Data Transfer
+ *
+ * As all requests to TransportManager are asynchronous, client must implement NsSmartDeviceLink::NsTransportManager::ITransportManagerDataListener
+ * interface and add itself as a data listener with NsSmartDeviceLink::NsTransportManager::ITransportManager::addDataListener()
+ * in order to receive notifications.
+ * To send frame to remote device client must use NsSmartDeviceLink::NsTransportManager::ITransportManager::sendFrame() poviding connection handle,
+ * frame data, data size and user data. User data is an integer that is assigned to a frame and will be sent back to client when sending of frame
+ * will be completed. Client may use this data to identify frame when send result will be reported. When sending of frame is completed
+ * client is notified via NsSmartDeviceLink::NsTransportManager::ITransportManagerDataListener::onFrameSendCompleted(). When frame is received from a remote
+ * device client is notified via NsSmartDeviceLink::NsTransportManager::ITransportManagerDataListener::onFrameReceived().
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DeviceManagement.txt b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DeviceManagement.txt
new file mode 100644
index 000000000..eb5f3e477
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/DeviceManagement.txt
@@ -0,0 +1,14 @@
+/** @page components_transportmanager_client_device_management Device Management
+ *
+ * As all requests to TransportManager are asynchronous, client must implement NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener
+ * interface and add itself as a device listener with NsSmartDeviceLink::NsTransportManager::ITransportManager::addDeviceListener()
+ * in order to receive notifications.
+ * Client of TransportManager may use NsSmartDeviceLink::NsTransportManager::ITransportManager::scanForNewDevices()
+ * to initiate device scan on all device adapters that support this feature. In order to get list of available
+ * devices client must override NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener::onDeviceListUpdated().
+ * Each device adapter will perform scan independently from other device adapters and device list might be updated
+ * several times (after each adapter that supports scanning finishes scanning operation). Device list might also be
+ * updated without device scan request, e.g. if new client connects via TCP this device will be added to device list
+ * and update notification will be sent to client. In any of these cases client will be provided with the full
+ * device list from all device adapters in every notification.
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/index.txt b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/index.txt
new file mode 100644
index 000000000..8916dbeb5
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Client Specification/index.txt
@@ -0,0 +1,18 @@
+/*! \page components_transportmanager_client Transport Manager Client Specification
+
+This chapter describes details of correct use of Transport Manager on the client side. In other words this chapter can be called "How to create effective and safe client of Transport Manager".
+Transport Manager defines set of asynchronous requests (means that operations are non-blocking in the calling thread) and provides two different interfaces to monitor asynchronous responses and notifications about data update.
+
+Clients of Transport Manager should use NsSmartDeviceLink::NsTransportManager::ITransportManager interface to initiate any request to the component.
+Also Transport Manager provides two different interfaces:
+
+1) NsSmartDeviceLink::NsTransportManager::ITransportManagerDataListener. Client can implement this interface if it needs information about data frame send/receive.
+
+2) NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener. Client can implement this interface if it needs information about updates of devices available for communication and current client applications status.
+
+For more information about typical use of Transport Manager please read the following topics:
+ - \subpage components_transportmanager_client_device_management "Device Management"
+ - \subpage components_transportmanager_client_connection_management "Connection Management"
+ - \subpage components_transportmanager_client_data_transfer "Data Transfer"
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/BluetoothAdapter.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/BluetoothAdapter.txt
new file mode 100644
index 000000000..970aeffd8
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/BluetoothAdapter.txt
@@ -0,0 +1,19 @@
+/** @page components_transportmanager_internal_design_transport_adapters_bluetooth_adapter Bluetooth Adapter
+ *
+ * Bluetooth adapter handles communication with external devices via bluetooth. It is implemented in
+ * NsSmartDeviceLink::NsTransportManager::CBluetoothAdapter.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_bluetooth_adapter_discovery Device discovery
+ *
+ * When requested by a call to NsSmartDeviceLink::NsTransportManager::CTransportAdapter::scanForNewDevices() bluetooth adapter
+ * searches for bluetooth devices. For each found device it runs SDP query for service with SmartDeviceLink UUID
+ * (936DA01F-9ABD-4D9D-80C7-02AF85C822A8). Devices that support this service are added to bluetooth adapter device list.
+ * Bluetooth device scans are performed only when explicitly requested.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_bluetooth_adapter_connecting_devices Connecting devices
+ *
+ * NsSmartDeviceLink::NsTransportManager::CBluetoothAdapter::createConnectionsListForDevice() runs SDP query for specified device
+ * and fills connection list with connections to all RFCOMM channels on remote device where SmartDeviceLink service has been discovered.
+ *
+ * @see @ref components_transportmanager_internal_design_transport_adapters_common_connecting_devices
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/TCPAdapter.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/TCPAdapter.txt
new file mode 100644
index 000000000..d81b70dfe
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/TCPAdapter.txt
@@ -0,0 +1,20 @@
+/** @page components_transportmanager_internal_design_transport_adapters_tcp_adapter TCP Adapter
+ *
+ * TCP adapter handles communication with remote devices via TCP/IP socket. It is implemented in
+ * NsSmartDeviceLink::NsTransportManager::CTCPAdapter.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_tcp_adapter_listen Listening for connections
+ *
+ * TCP adapter creates listening TCP socket (TCP port is specified in NsSmartDeviceLink::NsTransportManager::CTCPAdapter::cTCPAdapterPort)
+ * and listens for incoming connections. Devices are identified by their IP address.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_tcp_adapter_accept Accepting connection
+ *
+ * When TCP adapter accepts connection it checks if there is a device with IP address matching with IP address of accepted connection.
+ * If there is no such device, then this device is added and device list is updated.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_tcp_adapter_disconnecting Disconnecting
+ *
+ * When socket gets disconnected TCP adapter checks if there is another opened connection for IP address of disconnected application.
+ * If it was the last application from this IP address then device with this IP address is removed and devices list is updated.
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/index.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/index.txt
new file mode 100644
index 000000000..3a5d0f0e9
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Device Adapters/index.txt
@@ -0,0 +1,89 @@
+/** @page components_transportmanager_internal_design_transport_adapters Device Adapters
+ *
+ * TransportManager communicates with actual devices via device adapters.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_common Common logic
+ *
+ * Logic common to all device adapters is implemented in class NsSmartDeviceLink::NsTransportManager::CTransportAdapter.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_devices_map Devices map
+ *
+ * Devices map is a map of device handle to internal device structure NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SDevice.
+ * Devices map is stored in NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mDevices. Any access to this map must be performed
+ * with NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mDevicesMutex locked.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_connections_map Connections map
+ *
+ * Connections map is a map of connection handle to internal connection structure NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SConnection.
+ * Connections map is stored in NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mConnections. Any access to this map must be performed
+ * with NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mConnectionsMutex locked.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_main_thread Device adapter main thread
+ *
+ * Device adapter main thread is started in NsSmartDeviceLink::NsTransportManager::CTransportAdapter::run().
+ * Specific device adapter must implement virtual function NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mainThread()
+ * and implement its specific main thread logic there.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_connection_thread Device adapter connection thread
+ *
+ * Device adapter connection thread is started in NsSmartDeviceLink::NsTransportManager::CTransportAdapter::startConnection().
+ * Specific device adapter must implement virtual function NsSmartDeviceLink::NsTransportManager::CTransportAdapter::connectionThread()
+ * and implement its specific connection thread logic there. When connection is established and socket file descriptor is set
+ * in NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SConnection::mConnectionSocket specific device adapter may call
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::handleCommunication() to handle all communication through this socket
+ * until connection is terminated.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_threads_termination Termination of device adapter threads
+ *
+ * Specific device adapter implementation must call in its destructor NsSmartDeviceLink::NsTransportManager::CTransportAdapter::waitForThreadsTermination()
+ * to wait for termination of all threads (main thread and connection threads). Device adapter threads must be terminated before specific
+ * device adapter class is destructed, so it can't be called in the destructor of base class and must be called explicitly from the inherited
+ * class's destructor.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_device_scan Requesting scan for new devices
+ *
+ * Device scan is requested by setting flag NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mDeviceScanRequested
+ * and signaling conditional variable NsSmartDeviceLink::NsTransportManager::CTransportAdapter::mDeviceScanRequestedCond, which may be monitored
+ * by specific device adapter if it supports device scanning. Specific device adaptere may call for this purpose
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::waitForDeviceScanRequest() which will wait on this conditional variable
+ * until it's signaled or specified timeout expires.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_connecting_devices Connecting devices
+ *
+ * Device connection is initiated with a call to NsSmartDeviceLink::NsTransportManager::CTransportAdapter::connectDevice().
+ * This method calls virtual function NsSmartDeviceLink::NsTransportManager::CTransportAdapter::createConnectionsListForDevice()
+ * which may be implemented by specific device adapter to create a list of connections that must be established for the device.
+ * For each connection created by device adapter it calls NsSmartDeviceLink::NsTransportManager::CTransportAdapter::startConnection()
+ * which adds connection to connections map and starts connection thread.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_disconnecting_devices Disconnecting devices
+ *
+ * Device disconnection is initiated with a call to NsSmartDeviceLink::NsTransportManager::CTransportAdapter::disconnectDevice().
+ * This method finds all connections in connections map that corresponds to specified device and calls
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::stopConnection() for each of them.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_handling_communication Handling communication
+ *
+ * All frames requested to be sent via NsSmartDeviceLink::NsTransportManager::CTransportAdapter::sendFrame() are stored in
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SConnection::mFramesToSend. Pipe
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SConnection::mNotificationPipeFds is used by
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::sendFrame() to notify connection thread that data is available
+ * to be sent. NsSmartDeviceLink::NsTransportManager::CTransportAdapter::sendFrame() writes one byte to the write end of this pipe.
+ * NsSmartDeviceLink::NsTransportManager::CTransportAdapter::handleCommunication() uses poll() to wait for
+ * incoming data using connection socket file descriptor and outgoing data using file descriptor of the read end of this pipe.
+ * When either of them become available for reading or some error occurs (e.g. socket gets disconnected) connection thread
+ * wakes up and handles this event. Notification pipe is also used to notify connection thread that connection has to be
+ * terminated using NsSmartDeviceLink::NsTransportManager::CTransportAdapter::SConnection::mTerminateFlag.
+ *
+ * @subsection components_transportmanager_internal_design_transport_adapters_common_update_client_device_list Updating client device list.
+ *
+ * Specific device adapter may call NsSmartDeviceLink::NsTransportManager::CTransportAdapter::updateClientDeviceList() when its internal
+ * knowledge about available devices is updated to notify device adapter client (TransportManager) about this update.
+ *
+ * @section components_transportmanager_internal_design_transport_adapters_common_specific Specific device adapters
+ *
+ * Current TransportManager implementation contains following device adapters:
+ *
+ * - @subpage components_transportmanager_internal_design_transport_adapters_bluetooth_adapter "Bluetooth Adapter"
+ * - @subpage components_transportmanager_internal_design_transport_adapters_tcp_adapter "TCP Adapter"
+ */
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Interaction.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Interaction.txt
new file mode 100644
index 000000000..66a798ecb
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/Interaction.txt
@@ -0,0 +1,7 @@
+/*! \page components_transportmanager_internal_design_interaction Sub-Components Interaction
+
+Internally Transport Manager is a root component for Device Adapters. After running Transport Manager creates Device Adapters and runs them too.
+
+During system life cycle all messages from Device Adapter are translated via Transport Manager to the clients. In other direction – all requests from clients are re-directed to respective Device Adapters by the Transport Manager.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/MultiThreading.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/MultiThreading.txt
new file mode 100644
index 000000000..6c35f0962
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/MultiThreading.txt
@@ -0,0 +1,9 @@
+/*! \page components_transportmanager_internal_design_multithreading Multi-Threading in Component
+
+Internally Transport Manager uses different threads for different operations. This design solution was used to provide efficient asynchronous communication with clients and underlying Device Adapters.
+
+Transport Manager uses one thread to operate with all device-related callbacks. In other word all callbacks declared in NsSmartDeviceLink::NsTransportManager::ITransportManagerDeviceListener will be called from that thread.
+
+For every active connection one service thread will be created. This thread will be used for all connection-related callbacks. Therefore every implementation of NsSmartDeviceLink::NsTransportManager::ITransportManagerDataListener will be called in separated thread that allows client to support multiple connection simultaneously.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/TrasportManager.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/TrasportManager.txt
new file mode 100644
index 000000000..8c1dd4318
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/TrasportManager.txt
@@ -0,0 +1,15 @@
+/*! \page components_transportmanager_internal_design_trasport_manager Trasport Manager Implementation
+
+Actually Transport Manager component is implemented as classical manager component. It manages connections and abstract devices and provides unified information for the clients.
+
+Connection-related information encapsulated in structure NsSmartDeviceLink::NsTransportManager::CTransportManager::SConnectionInfo. Transport Manager manages these structures to store information about every active connection.
+
+Frame processing encapsulated in structure NsSmartDeviceLink::NsTransportManager::CTransportManager::SFrameDataForConnection. Transport Manager manages these structures to store information related to data for specific connection.
+
+Callback information between transport manager threads passed in form of special structures:
+NsSmartDeviceLink::NsTransportManager::CTransportManager::SDeviceListenerCallback.
+NsSmartDeviceLink::NsTransportManager::CTransportManager::SDataListenerCallback.
+
+Client calls to TM guarded by separate mutex. This allows use component from different threads without any risk.
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/index.txt b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/index.txt
new file mode 100644
index 000000000..b29ec48dd
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Internal Design/index.txt
@@ -0,0 +1,15 @@
+/*! \page components_transportmanager_internal_design Component Internal Design
+
+This chapter is focused on Transport Manager internal design and describes internal sub-components and use of multi-threading.
+
+Information regarding sub-components is described in following topics:
+ - \subpage components_transportmanager_internal_design_transport_adapters "Device Adapters"
+ - \subpage components_transportmanager_internal_design_trasport_manager "Trasport Manager Implementation"
+
+Detailed description of sub-components interaction is described here:
+ - \subpage components_transportmanager_internal_design_interaction "Sub-Components Interaction"
+
+More information about internal usage of multi-threading id described here:
+ - \subpage components_transportmanager_internal_design_multithreading "Multi-Threading in Component"
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase1.txt b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase1.txt
new file mode 100644
index 000000000..4af46e432
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase1.txt
@@ -0,0 +1,74 @@
+/*! \page components_transportmanager_use_cases_1 Scenario with 1 device and 1 application
+
+<h3>Preconditions:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>The Device is connected to SmartDeviceLink Core VIA Bluetooth or Wi-Fi</td>
+ <td>
+ <p>For BT: Devices are paired</p>
+ <p>For Wi-Fi: Devices are in the same network</p>
+ </td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Make sure that correct device is connected to SmartDeviceLink core</td>
+ <td>IP-address of connected device is relevant</td>
+ </tr>
+</table>
+
+<h3>Testcase:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Start SmartDeviceLink application on the Devices</td>
+ <td>SmartDeviceLink application is up and ready</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Initiate a Device search in HMI</td>
+ <td>HMI displays the list of found devices/applications</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Connect to desired device\application</td>
+ <td>Application is marked as connected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>Send alert message from SmartDeviceLink application</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>Disconnect device from SmartDeviceLink core</td>
+ <td>Application is marked as disconnected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>Try to send alert from disconnected device</td>
+ <td>Alert shouldn’t be delivered and displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td><strong>Repeat steps 1-4 with using another connection method (BT of Wi-Fi)</strong></td>
+ <td>Expected results should be the same</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td><h3>Stress:</h3>Send big amount of alert messages in a short period of time</td>
+ <td>All alert messages are processed correctly</td>
+ </tr>
+</table>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase2.txt b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase2.txt
new file mode 100644
index 000000000..de1d6baae
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase2.txt
@@ -0,0 +1,96 @@
+/*! \page components_transportmanager_use_cases_2 Scenario with 2 or more devices with 1 application onboard
+
+<h3>Preconditions:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Device-1 is connected to Core via Bluetooth</td>
+ <td>Devices are paired</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Device-2 is connected to SmartDeviceLink Core via Wi-Fi</td>
+ <td>Devices are in the same network</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Make sure that correct devices are connected to SmartDeviceLink core</td>
+ <td>IP-address of connected devices are relevant</td>
+ </tr>
+</table>
+
+<h3>Testcase:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Start SmartDeviceLink application on the Devices</td>
+ <td>SmartDeviceLink application is up and ready</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Initiate a Device search in HMI</td>
+ <td>HMI displays the list of found devices/applications</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Connect to application-1 on 1-st device</td>
+ <td>Application is marked as connected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>Connect to application on 2-nd device</td>
+ <td>Application is marked as connected/notification is displayed in HMI. Both applications on device-1 and device-2 are marked as connected</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>Send alert message from SmartDeviceLink application-1</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>Send alert message from SmartDeviceLink application-2</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td>Send alert messages from both application simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>Disconnect device-2 from SmartDeviceLink core</td>
+ <td>Application is marked as disconnected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>9</td>
+ <td>Try to send alert messages from both application simultaneously</td>
+ <td>Alert is delivered only from device-1</td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td>Disconnect device-1 from SmartDeviceLink core</td>
+ <td>Application is marked as disconnected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td><strong>Repeat steps 1-9 with more devices or use same connection method (BT of Wi-Fi)</strong></td>
+ <td>Expected results should be the same</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td><h3>Stress:</h3>Send big amount of alert messages in a short period of time from all devices</td>
+ <td>All alert messages are processed correctly</td>
+ </tr>
+</table>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase3.txt b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase3.txt
new file mode 100644
index 000000000..f11faadfd
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/UseCase3.txt
@@ -0,0 +1,131 @@
+/*! \page components_transportmanager_use_cases_3 Scenario with 2 or more devices with 2 or more applications onboard
+
+<h3>Preconditions:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Device-1 is connected to Core via Bluetooth</td>
+ <td>Devices are paired</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Device-2 is connected to SmartDeviceLink Core via Wi-Fi</td>
+ <td>Devices are in the same network</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Make sure that correct devices are connected to SmartDeviceLink core</td>
+ <td>IP-address of connected devices are relevant</td>
+ </tr>
+</table>
+
+<h3>Testcase:</h3>
+<table>
+ <tr>
+ <th>Steps</th>
+ <th>Actions</th>
+ <th>Expected result</th>
+ </tr>
+ <tr>
+ <td>1</td>
+ <td>Start SmartDeviceLink application on the Devices</td>
+ <td>SmartDeviceLink application is up and ready</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Initiate a Device search in HMI</td>
+ <td>HMI displays the list of found devices/applications</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>Connect to application-1 on 1-st device</td>
+ <td>Application is marked as connected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>Send alert message from SmartDeviceLink application-1 on device-1</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>Connect to application-2 on 1-st device</td>
+ <td>Application is marked as connected/notification is displayed in HMI Both applications are marked as connected</td>
+ </tr>
+ <tr>
+ <td>6</td>
+ <td>Send alert message from SmartDeviceLink application-2 on device-1</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>7</td>
+ <td>Send alert messages from application-1 and application-2 on device-1 simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>Connect to application-1 on 2-st device</td>
+ <td>Application is marked as connected/notification is displayed in HMI. All 3 applications are marked as connected</td>
+ </tr>
+ <tr>
+ <td>9</td>
+ <td>Send alert messages from application-1 on device-1 and device-2 simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>10</td>
+ <td>Send alert message from SmartDeviceLink application-1 on device-2</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td>Connect to application on 2-nd device</td>
+ <td>Application is marked as connected/notification is displayed in HMI. All 4 applications are marked as connected</td>
+ </tr>
+ <tr>
+ <td>12</td>
+ <td>Send alert message from SmartDeviceLink application-2 on device-2</td>
+ <td>Alert is displayed on HMI</td>
+ </tr>
+ <tr>
+ <td>13</td>
+ <td>Send alert messages from application-1 and application-2 on device-2 simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td>Send alert messages from application-2 on device-1 and device-2 simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>15</td>
+ <td>Send alert messages from all application simultaneously</td>
+ <td>Both alerts are displayed on HMI/Alerts are showed consequently</td>
+ </tr>
+ <tr>
+ <td>16</td>
+ <td>Disconnect device-1 from SmartDeviceLink core</td>
+ <td>Applications are marked as disconnected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>17</td>
+ <td>Disconnect device-2 from SmartDeviceLink core</td>
+ <td>All applications are marked as disconnected/notification is displayed in HMI</td>
+ </tr>
+ <tr>
+ <td>18</td>
+ <td><strong>Repeat steps 1-15 with more devices and more applications or use same connection method (BT of Wi-Fi)</strong></td>
+ <td>Expected results should be the same</td>
+ </tr>
+ <tr>
+ <td>19</td>
+ <td><h3>Stress:</h3>Send big amount of alert messages in a short period of time from all devices</td>
+ <td>All alert messages are processed correctly</td>
+ </tr>
+</table>
+
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/index.txt b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/index.txt
new file mode 100644
index 000000000..c929a16a8
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/Use Cases/index.txt
@@ -0,0 +1,11 @@
+/*! \page components_transportmanager_use_cases High-Level Use Cases to Test Component
+
+This page contains set of high-level use-cases which can be used for testing of Transport Manager functionallity.
+
+In described scenarious term “Device” means any device which is able to run SmartDeviceLink Applications and capable to connect via BT or
+Wi-Fi.
+
+- \subpage components_transportmanager_use_cases_1 Simple scenario for smoke tests of trasprot level.
+- \subpage components_transportmanager_use_cases_2 Many devices verification for transport level operations.
+- \subpage components_transportmanager_use_cases_3 Complex verification of correct transport level operations.
+*/
diff --git a/src/components/policy/doc/doxygen/components/TransportManager/index.txt b/src/components/policy/doc/doxygen/components/TransportManager/index.txt
new file mode 100644
index 000000000..73252c751
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/TransportManager/index.txt
@@ -0,0 +1,9 @@
+/*! \page components_transportmanager Transport Manager
+
+Transport Manager is a component of SmartDeviceLink application which is designed to provide transparent access to transport layer for other components. Current implementation provides unified access to connections via Bluetooth and TCP. Also this component allows run automatic device discovery and provides information about found devices which is able to connect to SmartDeviceLink.
+
+More detailed information is described in following chapters:
+ - \subpage components_transportmanager_client "Transport Manager Client Specification"
+ - \subpage components_transportmanager_internal_design "Component Internal Design"
+ - \subpage components_transportmanager_use_cases "High-Level Use Cases to Test Component"
+*/
diff --git a/src/components/policy/doc/doxygen/components/index.txt b/src/components/policy/doc/doxygen/components/index.txt
new file mode 100644
index 000000000..186de88af
--- /dev/null
+++ b/src/components/policy/doc/doxygen/components/index.txt
@@ -0,0 +1,10 @@
+/*! \page components Components
+
+Project contain following components:
+ - \subpage components_transportmanager "Transport Manager"
+ - \subpage components_protocolhandler "Protocol Handler"
+ - \subpage components_jsonhandler "JSON Handler"
+ - \subpage components_smartobjects "Smart Objects"
+ - \subpage components_appmgr "App Manager"
+ - \subpage components_hmi "HMI"
+*/
diff --git a/src/components/policy/doc/doxygen/info.txt b/src/components/policy/doc/doxygen/info.txt
new file mode 100644
index 000000000..e8afe55c1
--- /dev/null
+++ b/src/components/policy/doc/doxygen/info.txt
@@ -0,0 +1,5 @@
+/*! \page info Project information
+
+Here will be general information about project
+
+*/ \ No newline at end of file
diff --git a/src/components/policy/doc/doxygen/mainpage.txt b/src/components/policy/doc/doxygen/mainpage.txt
new file mode 100644
index 000000000..5cd05e260
--- /dev/null
+++ b/src/components/policy/doc/doxygen/mainpage.txt
@@ -0,0 +1,9 @@
+/*! \mainpage Project SmartDeviceLink
+
+This is the entry point to the documentation about project.
+
+This manual is divided in the following sections:
+- \subpage info "General project information"
+- \subpage components "Project components"
+- \subpage tools "Project specific tools"
+*/
diff --git a/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Arhitecture.txt b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Arhitecture.txt
new file mode 100644
index 000000000..4cf9e84d9
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Arhitecture.txt
@@ -0,0 +1,5 @@
+/*! \page tools_interfacegenerator_architecture InterfaceGenerator architecture
+
+InterfaceGenerator is designed as flexible and easily expendable tool that allows to implement both new parsers and generators independently. The core idea of InterfaceGenerator that it has middle-ware product - abstract model of interface that should be generated. This middle layer allows to separate collection of parsers from generators. Also it is possible to add any new validation / normalization component between them. So at the moment the root script creates actual parser and that parser produces model of interface (set of Python classes objects). After that interface model is passed to the desired generator and generator creates result source code files.
+
+*/
diff --git a/src/components/policy/doc/doxygen/tools/InterfaceGenerator/CMake Integration.txt b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/CMake Integration.txt
new file mode 100644
index 000000000..b4fb0b3df
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/CMake Integration.txt
@@ -0,0 +1,13 @@
+/*! \page tools_interfacegenerator_cmakeintegration Integration with CMake
+
+In order to organize usable build process that allows to create generated code at every workstation in accordance with local setting and ensure that code re-generated after any modification in source XML or InterfaceGenerator itself was designed custom CMake rule "GenerateInterface".
+
+This rule takes 3 arguments - name of source XML file, desired namespace for generated code and name of parser to use (name of parser is required because supported XML formats are indistinguishable and client must explicitly specify desired parser type).
+
+Example:
+
+<pre>
+GenerateInterface("test_v4_protocol_v2_0_revP.xml" "Gen::test::components::JSONHandler" "alrpcv2")
+</pre>
+
+*/
diff --git a/src/components/policy/doc/doxygen/tools/InterfaceGenerator/How To Use.txt b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/How To Use.txt
new file mode 100644
index 000000000..0f9e340bc
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/How To Use.txt
@@ -0,0 +1,31 @@
+/*! \page tools_interfacegenerator_usage How to use InterfaceGenerator
+
+To run InterfaceGenerator the Python 2.7 interpreter should be installed. As input InterfaceGenerator requires full path to the source XML file, namespace to generate result code in, full path to the output directory where result source code C++ will be created and optionally explicit specification of parser type.
+
+Example1 (Run Generator.py to display help):
+
+<pre>
+$ python Generator.py -h
+
+usage: Generator.py [-h] --parser-type {alrpcv1,alrpcv2}
+ source-xml namespace output-dir
+
+SmartSchema interface generator
+
+positional arguments:
+ source-xml
+ namespace
+ output-dir
+
+optional arguments:
+ -h, --help show this help message and exit
+ --parser-type {alrpcv1,alrpcv2}
+</pre>
+
+Example2 (Run Generator.py to generate some code)
+
+<pre>
+python Generator.py /home/user1/xml/alrpc1.xml App::Gen:: /home/user1/gen --parser-type=alrpcv2
+</pre>
+
+*/
diff --git a/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Use of Output.txt b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Use of Output.txt
new file mode 100644
index 000000000..b486fd7e3
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/Use of Output.txt
@@ -0,0 +1,11 @@
+/*! \page tools_interfacegenerator_output Use of InterfaceGenerator output
+
+As a result InterfaceGenerator produces one .cpp and one .hpp file in the output directory. Those files contain one C++ class which named in accordance with input XML file name. Class is declared and implemented in specified namespace. Also all enums form source XML file have automatically generated declarations within specified namespace.
+
+Generated class is inherited form predefined base template class CSmartFactory. Actually this inherited class defines specific set of Smart Object schema's initialization methods which are set to the base class member and can be used by the clients.
+
+Also generated code contains string mapping for enums that is used to convert string representation or enums to integer values and vice versa.
+
+Result source code should be compilable but this is not guaranteed if source XML file contains identifier names that are not correct C++ identifiers.
+
+*/
diff --git a/src/components/policy/doc/doxygen/tools/InterfaceGenerator/index.txt b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/index.txt
new file mode 100644
index 000000000..21b437f6b
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/InterfaceGenerator/index.txt
@@ -0,0 +1,12 @@
+/*! \page tools_interfacegenerator InterfaceGenerator
+
+InterfaceGenerator is a special code generation tool that allows creating of C++ source code to work with interface described as XML file.
+InterfaceGenerator is a bundle of Python scripts. Root script is a Generator.py. This script should be used by the client to run generator.
+Currently InterfaceGenerator supports generation form ALRPC v.1 and ALRPC v.2 XML formats.
+
+For more details please review:
+ - \subpage tools_interfacegenerator_usage "How to use InterfaceGenerator"
+ - \subpage tools_interfacegenerator_output "Use of InterfaceGenerator output"
+ - \subpage tools_interfacegenerator_architecture "InterfaceGenerator architecture"
+ - \subpage tools_interfacegenerator_cmakeintegration "Integration with CMake"
+*/
diff --git a/src/components/policy/doc/doxygen/tools/index.txt b/src/components/policy/doc/doxygen/tools/index.txt
new file mode 100644
index 000000000..4befa33e8
--- /dev/null
+++ b/src/components/policy/doc/doxygen/tools/index.txt
@@ -0,0 +1,5 @@
+/*! \page tools Tools
+
+Project uses following special tools:
+ - \subpage tools_interfacegenerator "InterfaceGenerator"
+*/
diff --git a/src/components/policy/doc/grc/conf.smartDeviceLinkCore b/src/components/policy/doc/grc/conf.smartDeviceLinkCore
new file mode 100644
index 000000000..11c7643c6
--- /dev/null
+++ b/src/components/policy/doc/grc/conf.smartDeviceLinkCore
@@ -0,0 +1,34 @@
+# source filename
+regexp=\w+\.(?:cpp|h)
+colours=yellow
+===
+regexp=^(ERROR|FATAL)
+colours=red on_yellow
+===
+regexp=^WARN
+colours=red
+===
+regexp=^INFO
+colours=blue
+===
+regexp=^TRACE
+colours=magenta
+===
+# component
+regexp=(?<=\])\[[^]]+\]
+colours=cyan
+===
+# something invalid
+regexp=(?i)invalid
+colours=red
+===
+# RPC message start
+regexp=^\{$
+colours=bold
+count=block
+===
+# RPC message end
+regexp=^\}$
+colours=bold
+count=unblock
+
diff --git a/src/components/policy/doc/grc/grc.conf b/src/components/policy/doc/grc/grc.conf
new file mode 100644
index 000000000..dfd3d4cbe
--- /dev/null
+++ b/src/components/policy/doc/grc/grc.conf
@@ -0,0 +1,3 @@
+# smartDeviceCore command
+(^|[/\w\.]+/)smartDeviceLinkCore\s?
+conf.smartDeviceLinkCore
diff --git a/src/components/policy/doc/install.txt b/src/components/policy/doc/install.txt
new file mode 100644
index 000000000..8076f427b
--- /dev/null
+++ b/src/components/policy/doc/install.txt
@@ -0,0 +1,91 @@
+* Introduction
+ ================
+ smartDeviceLinkCore is an application which manages the transport, connection and communication between a head unit and mobile device.
+
+* OS and Hardware
+ =========
+ Ubuntu 12.04.01 LTS 32-bit OS on the PC with USB-dongle
+ Application has been tested using 2 types of USB-dongle:
+ D-Link DBT-122
+ STLab B-121mini
+
+* External components
+ ===================
+ For build application we need:
+ libbluetooth3, the BlueZ library
+ libbluetooth-dev, the development files to link to the BluetZ library.
+ Install libraries:
+ sudo apt-get install libbluetooth3
+ sudo apt-get install libbluetooth-dev
+
+ We are using cmake to create build configurations.
+ Install cmake:
+ sudo apt-get install cmake
+
+ Also, make sure the g++ compiler is installed:
+ sudo apt-get install g++
+
+ To start web-based HMI we need web-browser with web-socket RFC6455 support.
+ For example Google Chromium. Install it using:
+ sudo apt-get install chromium-browser
+
+ To run InterfaceGenerator some python libraries are required and must be
+ installed with following command:
+ sudo pip install -r tools/InterfaceGenerator/requirements.txt
+
+ For logging Apache log4cxx library is used. Install required packages with the following command:
+ sudo apt-get install liblog4cxx10 liblog4cxx10-dev
+
+ For installing pulseaudio development files which neededfor audio management fetures run:
+ sudo apt-get install libpulse-dev
+
+ For installing gstreamer development files which needed for audio management fetures:
+ First add gstreamer repositories to your apt source list (/etc/apt/sources.list):
+ deb http://ppa.launchpad.net/gstreamer-developers/ppa/ubuntu <distributive codename> main
+ deb-src http://ppa.launchpad.net/gstreamer-developers/ppa/ubuntu <distributive codename> main
+ use code name relevant to the Ubuntu version which you use instead of <distributive codename>.
+ Run:
+ sudo apt-get update
+ and:
+ sudo apt-get install gstreamer1.0*
+
+* Build application
+ =================
+ We support "out of sources" concept for build from R3.0.0
+ It means all generated by build tools files will be stored in separate folder.
+ Temporary build of application requires two steps.
+ 1. Enter src/thirdPartyLibs/logger
+ build logger:
+
+ 1. Create directory outside of SmartDeviceLink project directory.
+ For example "build" folder in the same folder with SmartDeviceLink git repo folder which has a name "git_repo":
+ You will have folders structure like this:
+ /home/projects/smart_device_link
+ |--build
+ |--git_repo
+ |--doc
+ |--src
+ |--test
+ |--DoxyFile
+ \--CMakeLists.txt
+ Enter this folder:
+ cd build
+
+ 2. Create build configuration using cmake:
+ 2.1 For Debug configuration
+ cmake ../git_repo
+ 2.2 For Release configuration, run:
+ cmake -DCMAKE_BUILD_TYPE=Release ../git_repo
+ 2.3 For Debug configuration with tests, run:
+ cmake -DBUILD_TESTS=On ../git_repo
+
+ 3. Make project:
+ make
+
+ Ready to use release application will be in build/src/appMain/smartDeviceLinkCore
+
+ 4. If You built configuration with tests (see 2.3 above), then You can run all project tests and see overall result with:
+ make test
+
+ 5. For creating the doxygen documentation run:
+ make doxygen
diff --git a/src/components/policy/doc/qnx_build.txt b/src/components/policy/doc/qnx_build.txt
new file mode 100644
index 000000000..4f67d6eed
--- /dev/null
+++ b/src/components/policy/doc/qnx_build.txt
@@ -0,0 +1,28 @@
+Building the project
+cmake -DCMAKE_TOOLCHAIN_FILE=../applink/qnx_6.5.0_linux_x86.cmake ../applink
+or for Momentics project:
+cmake -DCMAKE_TOOLCHAIN_FILE=../applink/qnx_6.5.0_linux_x86.cmake -G "Eclipse CDT4 - Unix Makefiles" ../applink
+
+Building with support D-Bus and Qt 4.8
+Install D-Bus (see https://adc.luxoft.com/confluence/x/0AHJDw)
+Install Qt 4.8 (see https://adc.luxoft.com/confluence/x/UwfJDw)
+cmake -DHMI2=ON -DCMAKE_TOOLCHAIN_FILE=../applink/qnx_6.5.0_linux_x86.cmake ../applink
+or for Momentics project:
+cmake -DHMI2=ON -DCMAKE_TOOLCHAIN_FILE=../applink/qnx_6.5.0_linux_x86.cmake -G "Eclipse CDT4 - Unix Makefiles" ../applink
+
+make
+make install
+
+Running project:
+Change server IP in configuration file to QNX target IP.
+Copy directory bin to QNX target.
+You can copy it using scp. Example:
+scp -r user_name@linux_pc_ip:/full_path/to/dir .
+
+For Web HMI set target IP in ini file and change target IP in src/components/HMI/ffw/RPCClient.js
+! Currently we don't have any configuration file for HMI.
+
+Execute smartDeviceLinkCore on QNX qtarget.
+Execute HMI on Linux PC (only Web HMI).
+
+Have fun!
diff --git a/src/components/policy/doc/readme.txt b/src/components/policy/doc/readme.txt
new file mode 100644
index 000000000..86de7da08
--- /dev/null
+++ b/src/components/policy/doc/readme.txt
@@ -0,0 +1,67 @@
+* Introduction
+ ================
+ smartDeviceCore is an application which manages the transport, connection and communication between a head unit and mobile device.
+
+* OS and Hardware
+ =========
+ Ubuntu 12.04.1 LTS 32-bit OS on the PC with USB-dongle
+ Application has been tested using 2 types of USB-dongle:
+ D-Link DBT-122
+ STLab B-121mini
+
+ * External components
+ ===================
+ For start application we need:
+ libbluetooth3, the BlueZ library
+ Install library:
+ sudo apt-get install libbluetooth3
+ To start web-based HMI we need web-browser with web-socket RFC6455 support.
+ For example Google Chromium. Install it using:
+ sudo apt-get install chromium-browser
+ In current implementation Chromium is required for autostart HMI feature.
+ For HMI autostart please create in the executable folder file named hmi_link.
+ This file should contain one string with full path to HMI index.html file.
+ For example:
+ /home/user/projects/smart_device_link/src/components/HMI/index.html
+
+* Running application
+ ====================
+ Plug USB-dongle in.
+ Switch Bluetooth on a mobile device ON and make the device discoverable.
+ Pair mobile device with PC using Ubuntu tools.
+ Device should contain SmartDeviceLink compatible application installed.
+ Start application with command:
+ ./smartDeviceLinkCore
+ Application starts to search devices and starts HMI in cromium-browser.
+ In case HMI has not been started please start web-based HMI manually in browser opening src/components/HMI/index.html.
+ SmartDeviceLinkCore is searching Bluetooth devices with a correspondibg service.
+ Go to info menu in HMI and press App button.
+ Press change Devices button.
+ Select the device from a list.
+ Application opens all available ports on devices and starts communication.
+ Returning to the App menu all applications will be shown in a list.
+
+* Colorized logs
+ ==============
+ You can have colorized log output of smartDeviceLinkCore's messages in the terminal with the help of grc:
+
+ 1. Make sure grc is installed:
+ sudo apt-get install grc
+
+ 2. Copy the config files from the grc/ directory into ~/.grc/ directory:
+ mkdir ~/.grc
+ cp grc/* ~/.grc/
+
+ 3. Add an alias to your shell's config (usually, ~/.bashrc or ~/.zshrc):
+ alias grca='grc -es --colour=auto'
+
+ Either restart the shell session or source the edited file:
+ source ~/.bashrc
+ or
+ source ~/.zshrc
+
+ 4. Start the smartDeviceLink core with the following command:
+ grca ./smartDeviceLinkCore
+
+ 5. PROFIT
+
diff --git a/src/components/policy/src/policy/CMakeLists.txt b/src/components/policy/src/policy/CMakeLists.txt
new file mode 100644
index 000000000..33c4f50a9
--- /dev/null
+++ b/src/components/policy/src/policy/CMakeLists.txt
@@ -0,0 +1,119 @@
+# Copyright (c) 2013, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+set(target Policy)
+set(install_destination bin)
+set(copy_destination ${CMAKE_BINARY_DIR}/src/appMain)
+set(library_name ${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX})
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
+
+if (EXTENDED_POLICY_FLAG)
+ add_definitions(-DEXTENDED_POLICY)
+endif()
+
+#Generation of policy table interface...
+include(${CMAKE_SOURCE_DIR}/tools/intergen/GenerateInterfaceLibrary.cmake)
+
+if (EXTENDED_POLICY_FLAG)
+ GenerateInterfaceLibrary("policy_table_interface_ext.xml" policy_table_interface_base)
+else ()
+ GenerateInterfaceLibrary("policy_table_interface.xml" policy_table_interface_base)
+endif()
+
+include_directories (
+ ./include
+ ./usage_statistics/include
+ ${CMAKE_SOURCE_DIR}/src/components/rpc_base/include
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/src/components/utils/include/
+ ${CMAKE_SOURCE_DIR}/src/components/config_profile/include
+)
+
+set(SOURCES
+ ./src/policy_manager_impl.cc
+ ./src/policy_helper.cc
+ ./src/syncp_adapter.cc
+ ./src/policy_table.cc
+ ./src/sql_pt_queries.cc
+ ./src/sql_pt_representation.cc
+)
+
+if (EXTENDED_POLICY_FLAG)
+ list(APPEND SOURCES
+ ./src/sql_pt_ext_queries.cc
+ ./src/sql_pt_ext_representation.cc
+ )
+endif ()
+
+add_subdirectory(usage_statistics)
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ # --- QDB Wrapper
+ include_directories (qdb_wrapper/include)
+ add_subdirectory(qdb_wrapper)
+else ()
+ # --- SQLite Wrapper
+ include_directories (sqlite_wrapper/include)
+ add_subdirectory(sqlite_wrapper)
+endif ()
+
+set(LIBRARIES ConfigProfile dbms policy_table_interface_base)
+
+add_library(${target} SHARED ${SOURCES})
+target_link_libraries(${target} ${LIBRARIES})
+
+if(ENABLE_LOG)
+ add_dependencies(${target} liblog4cxx)
+ target_link_libraries(${target} log4cxx -L${LOG4CXX_LIBS_DIRECTORY})
+endif()
+
+add_custom_target(copy_library_${target} ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_BINARY_DIR}/${library_name}
+ ${copy_destination}
+ DEPENDS ${target}
+ COMMENT "Copying library ${library_name}")
+
+if (BUILD_TESTS_WITH_HMI)
+ add_custom_target(test_copy_library_${target} ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_BINARY_DIR}/${library_name}
+ ${CMAKE_BINARY_DIR}/test/
+ DEPENDS ${target}
+ COMMENT "Copying library ${library_name}")
+endif(BUILD_TESTS_WITH_HMI)
+
+install(TARGETS ${target}
+ DESTINATION ${install_destination}
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE
+)
diff --git a/src/components/policy/src/policy/Readme.txt b/src/components/policy/src/policy/Readme.txt
new file mode 100644
index 000000000..370fab238
--- /dev/null
+++ b/src/components/policy/src/policy/Readme.txt
@@ -0,0 +1,3 @@
+To use SQLite and SQLite wrapper need to install libsqlite3-0 and libsqlite3-dev packages.
+To use QDB and QDB wrapper on QNX need to install SDP QNX 6.5.0 and run qdb server.
+To start qdb server need use script qdbserver.sh from directory qdb_wrapper.
diff --git a/src/components/policy/src/policy/include/policy/policy_helper.h b/src/components/policy/src/policy/include/policy/policy_helper.h
new file mode 100644
index 000000000..d0f4317a2
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_helper.h
@@ -0,0 +1,157 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_HELPER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_HELPER_H_
+
+#include "policy_table_interface_base/functions.h"
+#include "utils/shared_ptr.h"
+#include "policy/policy_types.h"
+
+namespace policy {
+class PolicyManagerImpl;
+
+const std::string kAllowedKey = "allowed";
+const std::string kUserDisallowedKey = "userDisallowed";
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+typedef policy_table::Strings::const_iterator StringsConstItr;
+typedef policy_table::ApplicationPolicies::const_iterator AppPoliciesConstItr;
+typedef policy_table::HmiLevels::const_iterator HMILevelsConstItr;
+typedef policy_table::Parameters::const_iterator ParametersConstItr;
+typedef policy_table::FunctionalGroupings::const_iterator FuncGroupConstItr;
+
+typedef policy_table::ApplicationPolicies::value_type AppPoliciesValueType;
+typedef policy_table::Rpc::value_type RpcValueType;
+typedef policy_table::Strings::value_type StringsValueType;
+
+/*
+ * @brief Helper struct to compare functional group names
+ */
+struct CompareGroupName {
+ explicit CompareGroupName(const StringsValueType& group_name);
+ bool operator()(const StringsValueType& group_name_to_compare) const;
+ private:
+ const StringsValueType& group_name_;
+};
+
+/*
+ * @brief Used for compare of policies parameters mapped with specific
+ * application ids
+ */
+bool operator!=(const policy_table::ApplicationParams& first,
+ const policy_table::ApplicationParams& second);
+
+/*
+ * @brief Helper struct for checking changes of application policies, which
+ * come with update along with current data snapshot
+ * In case of policies changed for some application, current data will be
+ * updated and notification will be sent to application
+ */
+struct CheckAppPolicy {
+ CheckAppPolicy(PolicyManagerImpl* pm,
+ const utils::SharedPtr<policy_table::Table> update);
+ bool HasSameGroups(const AppPoliciesValueType& app_policy,
+ AppPermissions* perms) const;
+ bool IsNewAppication(const std::string& application_id) const;
+ void SendNotification(const AppPoliciesValueType& app_policy) const;
+ void SendOnPendingPermissions(const AppPoliciesValueType& app_policy,
+ AppPermissions permissions) const;
+ bool IsAppRevoked(const AppPoliciesValueType& app_policy) const;
+ bool NicknamesMatch(const std::string app_id,
+ const AppPoliciesValueType& app_policy) const;
+ bool operator()(const AppPoliciesValueType& app_policy);
+ private:
+ PolicyManagerImpl* pm_;
+ const utils::SharedPtr<policy_table::Table> update_;
+};
+
+/*
+ * @brief Fill notification data with merged rpc permissions for hmi levels and
+ * parameters
+ */
+struct FillNotificationData {
+ FillNotificationData(Permissions& data, GroupConsent group_state);
+ bool operator()(const RpcValueType& rpc);
+ void UpdateHMILevels(const policy_table::HmiLevels& in_hmi,
+ std::set<HMILevel>& out_hmi);
+ void UpdateParameters(const policy_table::Parameters& in_parameters,
+ std::set<Parameter>& out_parameter);
+ private:
+ void ExcludeDisAllowed();
+ std::string current_key_;
+ Permissions& data_;
+};
+
+/*
+ * @brief Check for functional group presence and pass it to helper struct,
+ * which gather data for notification sending
+ */
+struct ProcessFunctionalGroup {
+ ProcessFunctionalGroup(
+ const policy_table::FunctionalGroupings& fg,
+ const std::vector<FunctionalGroupPermission>& group_permissions,
+ Permissions& data);
+ bool operator()(const StringsValueType& group_name);
+ private:
+ GroupConsent GetGroupState(const std::string& group_name);
+ const policy_table::FunctionalGroupings& fg_;
+ Permissions& data_;
+ const std::vector<FunctionalGroupPermission>& group_permissions_;
+};
+
+struct FunctionalGroupInserter {
+ FunctionalGroupInserter(const policy_table::Strings& preconsented_groups,
+ PermissionsList& list);
+ void operator()(const StringsValueType& group_name);
+ private:
+ PermissionsList& list_;
+ const policy_table::Strings& preconsented_;
+};
+
+/**
+ * @brief Fills FunctionalGroupPermissions with provided params
+ * @param ids Functional group ids from DB
+ * @param names Group names and user_consent_prompt
+ * @param state User consent for group
+ * @param permissions Struct to be filled with provided params
+ */
+void FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions);
+
+}
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_HELPER_H_
diff --git a/src/components/policy/src/policy/include/policy/policy_listener.h b/src/components/policy/src/policy/include/policy/policy_listener.h
new file mode 100644
index 000000000..e2cbd86a5
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_listener.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_LISTENER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_LISTENER_H_
+
+#include "policy/policy_types.h"
+
+namespace policy {
+class PolicyListener {
+ public:
+ virtual void OnPTExchangeNeeded() = 0;
+ virtual void OnPermissionsUpdated(const std::string& policy_app_id,
+ const Permissions& permissions,
+ const policy::HMILevel& default_hmi) = 0;
+ virtual void OnPendingPermissionChange(const std::string& policy_app_id) = 0;
+ virtual void OnAppRevoked(const std::string& policy_app_id) = 0;
+ virtual void OnUpdateStatusChanged(policy::PolicyTableStatus status) = 0;
+ virtual std::string OnCurrentDeviceIdUpdateRequired(
+ const std::string& policy_app_id) = 0;
+ virtual void OnSystemInfoUpdateRequired() = 0;
+ virtual std::string GetAppName(const std::string& policy_app_id) = 0;
+};
+} // namespace policy
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_LISTENER_H_
diff --git a/src/components/policy/src/policy/include/policy/policy_manager.h b/src/components/policy/src/policy/include/policy/policy_manager.h
new file mode 100644
index 000000000..cdb81b60f
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_manager.h
@@ -0,0 +1,328 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_H_
+
+#include <vector>
+
+#include "policy/policy_types.h"
+#include "policy/policy_listener.h"
+#include "usage_statistics/statistics_manager.h"
+
+namespace policy {
+
+class PolicyManager : public usage_statistics::StatisticsManager {
+ public:
+ virtual ~PolicyManager() {
+ }
+
+ virtual void set_listener(PolicyListener* listener) = 0;
+
+ /**
+ *@brief Loads Policy Table from json file. Used for loading
+ * Preloaded Policy Table or after Master Reset of the system.
+ *@param file_name Path to preloaded PT file
+ * @return bool Success of operation
+ */
+ virtual bool LoadPTFromFile(const std::string& file_name) = 0;
+
+ /**
+ * @brief Updates Policy Table from binary message received from
+ * mobile device. Saves to Policy Table diff between Policy Table
+ * sent in snapshot and received Policy Table.
+ * @param file name of file with update policy table
+ * @param pt_content PTU as binary string
+ * @return bool Success of operation
+ */
+ virtual bool LoadPT(const std::string& file, const BinaryMessage& pt_content) = 0;
+
+ /**
+ * @brief Gets URL for sending PTS to from PT itself.
+ * @param service_type Service specifies user of URL
+ * @return string URL
+ */
+ virtual std::string GetUpdateUrl(int service_type) = 0;
+
+ /**
+ * @brief Gets all URLs for sending PTS to from PT itself.
+ * @param service_type Service specifies user of URL
+ * @return vector of urls
+ */
+ virtual EndpointUrls GetUpdateUrls(int service_type) = 0;
+
+ /**
+ * @brief PTU is needed, for this PTS has to be formed and sent.
+ * @return BinaryMessage* PTS.
+ */
+ virtual BinaryMessageSptr RequestPTUpdate() = 0;
+
+ /**
+ * @brief Check if specified RPC for specified application
+ * has permission to be executed in specified HMI Level
+ * and also its permitted params.
+ * @param app_id Id of application provided during registration
+ * @param hmi_level Current HMI Level of application
+ * @param rpc Name of RPC
+ * @return CheckPermissionResult containing flag if HMI Level is allowed
+ * and list of allowed params.
+ */
+ virtual CheckPermissionResult CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc) = 0;
+
+ /**
+ * @brief Clear all record of user consents. Used during Factory Reset.
+ * @return bool Success of operation
+ */
+ virtual bool ResetUserConsent() = 0;
+
+ /**
+ * @brief Checks, if policy update is necessary for application
+ * @param Application id assigned by Ford to the application
+ */
+ virtual void CheckAppPolicyState(const std::string& application_id) = 0;
+
+ /**
+ * @brief Returns current status of policy table for HMI
+ * @return Current status of policy table
+ */
+ virtual PolicyTableStatus GetPolicyTableStatus() = 0;
+
+ /**
+ * Checks is PT exceeded IgnitionCycles
+ * @return true if exceeded
+ */
+ virtual bool ExceededIgnitionCycles() = 0;
+
+ /**
+ * Checks is PT exceeded days
+ * @param days current day after epoch
+ * @return true if exceeded
+ */
+ virtual bool ExceededDays(int days) = 0;
+
+ /**
+ * Checks is PT exceeded kilometers
+ * @param kilometers current kilometers at odometer
+ * @return true if exceeded
+ */
+ virtual bool ExceededKilometers(int kilometers) = 0;
+
+ /**
+ * Increments counter of ignition cycles
+ */
+ virtual void IncrementIgnitionCycles() = 0;
+
+ /**
+ * Resets retry sequence
+ */
+ virtual void ResetRetrySequence() = 0;
+
+ /**
+ * Gets timeout to wait before next retry updating PT
+ * If timeout is less or equal to zero then the retry sequence is not need.
+ * @return timeout in seconds
+ */
+ virtual int NextRetryTimeout() = 0;
+
+ /**
+ * Gets timeout to wait until receive response
+ * @return timeout in seconds
+ */
+ virtual int TimeoutExchange() = 0;
+
+ /**
+ * @brief List of timeouts in seconds between retries
+ * when attempt to update PT fails
+ * @return List of delays between attempts.
+ */
+ virtual const std::vector<int> RetrySequenceDelaysSeconds() = 0;
+
+ /**
+ * Handler of exceeding timeout of exchanging policy table
+ */
+ virtual void OnExceededTimeout() = 0;
+
+ /**
+ * @brief Check user consent for mobile device data connection
+ * @param device_id Unique device identifier
+ * @return status of device consent
+ */
+ virtual DeviceConsent GetUserConsentForDevice(
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief Set user consent for mobile device data connection
+ * @param device_id Unique device identifier
+ * @param is_allowed User consent for usage device data connection
+ */
+ virtual void SetUserConsentForDevice(const std::string& device_id,
+ bool is_allowed) = 0;
+
+ /**
+ * @brief Update Application Policies as reaction
+ * on User allowing/disallowing device this app is running on.
+ */
+ virtual bool ReactOnUserDevConsentForApp(const std::string app_id,
+ bool is_device_allowed) = 0;
+ /**
+ * Sets number of kilometers and days after epoch, that passed for
+ * receiving PT UPdate.
+ */
+ virtual void PTUpdatedAt(int kilometers, int days_after_epoch) = 0;
+
+ /**
+ * @brief Retrieves data from app_policies about app on its registration:
+ * @param app_id - id of registered app
+ * @param app_types Section on HMI where app can appear (Navigation, Phone etc)
+ * @param nicknames Synonyms for application
+ */
+ virtual bool GetInitialAppData(const std::string& application_id,
+ StringArray* nicknames = NULL,
+ StringArray* app_hmi_types = NULL) = 0;
+ /**
+ * @brief Stores device parameters received during application registration
+ * to policy table
+ * @param device_id Device mac address
+ * @param device_info Received device parameters
+ */
+ virtual void SetDeviceInfo(const std::string& device_id,
+ const DeviceInfo& device_info) = 0;
+
+ /**
+ * @brief Set user consent for application functional groups
+ * @param permissions User-defined application group pemissions
+ */
+ virtual void SetUserConsentForApp(const PermissionConsent& permissions) = 0;
+
+ /**
+ * @brief Get default HMI level for application
+ * @param policy_app_id Unique application id
+ * @param default_hmi Default HMI level for application or empty, if value
+ * was not set
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool GetDefaultHmi(const std::string& policy_app_id,
+ std::string* default_hmi) = 0;
+
+ /**
+ * @brief Get priority for application
+ * @param policy_app_id Unique application id
+ * @param priority Priority for application or empty, if value was not set
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool GetPriority(const std::string& policy_app_id,
+ std::string* priority) = 0;
+
+ /**
+ * @brief Get user friendly messages for given RPC messages and language
+ * @param message_codes RPC message codes
+ * @param language Language
+ * @return Array of structs with appropriate message parameters
+ */
+ virtual std::vector<UserFriendlyMessage> GetUserFriendlyMessages(
+ const std::vector<std::string>& message_code,
+ const std::string& language) = 0;
+
+ /**
+ * Checks if the application is revoked
+ * @param app_id application id
+ * @return true if application is revoked
+ */
+ virtual bool IsApplicationRevoked(const std::string& app_id) const = 0;
+
+ /**
+ * @brief Get user permissions for application which started on specific device
+ * @param device_id Device id
+ * @param policy_app_id Unique application id
+ * @param permissions Array of functional groups permissions
+ */
+ virtual void GetUserPermissionsForApp(
+ const std::string& device_id, const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) = 0;
+ virtual AppPermissions GetAppPermissionsChanges(
+ const std::string& app_id) = 0;
+ virtual void RemovePendingPermissionChanges(const std::string& app_id) = 0;
+
+ /**
+ * @brief Return device id, which hosts specific application
+ * @param Application id, which is required to update device id
+ */
+ virtual std::string& GetCurrentDeviceId(const std::string& policy_app_id) = 0;
+
+ /**
+ * @brief Set current system language
+ * @param language Language
+ */
+ virtual void SetSystemLanguage(const std::string& language) = 0;
+
+ /**
+ * @brief Set data from GetSystemInfo response to policy table
+ * @param ccpu_version CCPU version
+ * @param wers_country_code WERS country code
+ * @param language System language
+ */
+ virtual void SetSystemInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) = 0;
+
+ /**
+ * @brief Send OnPermissionsUpdated for choosen application
+ * @param application_id
+ */
+ virtual void SendNotificationOnPermissionsUpdated(
+ const std::string& application_id) = 0;
+
+ /**
+ * @brief Removes unpaired device records and related records from DB
+ * @param device_ids List of device_id, which should be removed
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool CleanupUnpairedDevices(const DeviceIds& device_ids) = 0;
+
+ /**
+ * @brief Check if app can keep context.
+ */
+ virtual bool CanAppKeepContext(const std::string& app_id) = 0;
+
+ /**
+ * @brief Check if app can steal focus.
+ */
+ virtual bool CanAppStealFocus(const std::string& app_id) = 0;
+};
+
+} // namespace policy
+
+extern "C" policy::PolicyManager* CreateManager();
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_H_
diff --git a/src/components/policy/src/policy/include/policy/policy_manager_impl.h b/src/components/policy/src/policy/include/policy/policy_manager_impl.h
new file mode 100644
index 000000000..9b8983547
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_manager_impl.h
@@ -0,0 +1,268 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_IMPL_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_IMPL_H_
+
+#include <list>
+#include "utils/shared_ptr.h"
+#include "utils/lock.h"
+#include "policy/policy_manager.h"
+#include "policy/policy_table.h"
+#include "policy_table_interface_base/functions.h"
+#include "usage_statistics/statistics_manager.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+namespace policy {
+struct CheckAppPolicy;
+
+class PolicyManagerImpl : public PolicyManager {
+ public:
+ PolicyManagerImpl();
+ virtual ~PolicyManagerImpl();
+ void ResetDefaultPT(const PolicyTable& policy_table);
+ virtual void set_listener(PolicyListener* listener);
+ PolicyListener* listener() const {
+ return listener_;
+ }
+ virtual bool LoadPTFromFile(const std::string& file_name);
+ virtual bool LoadPT(const std::string& file, const BinaryMessage& pt_content);
+ virtual std::string GetUpdateUrl(int service_type);
+ virtual EndpointUrls GetUpdateUrls(int service_type);
+ virtual BinaryMessageSptr RequestPTUpdate();
+ virtual CheckPermissionResult CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc);
+ virtual bool ResetUserConsent();
+ virtual bool ExceededIgnitionCycles();
+ virtual bool ExceededDays(int days);
+ virtual bool ExceededKilometers(int kilometers);
+ virtual void IncrementIgnitionCycles();
+ virtual void CheckAppPolicyState(const std::string& application_id);
+ virtual PolicyTableStatus GetPolicyTableStatus();
+ virtual void ResetRetrySequence();
+ virtual int NextRetryTimeout();
+ virtual int TimeoutExchange();
+ virtual const std::vector<int> RetrySequenceDelaysSeconds();
+ virtual void OnExceededTimeout();
+ virtual void PTUpdatedAt(int kilometers, int days_after_epoch);
+
+ /**
+ * Refresh data about retry sequence from policy table
+ */
+ virtual void RefreshRetrySequence();
+ virtual DeviceConsent GetUserConsentForDevice(const std::string& device_id);
+ virtual void SetUserConsentForDevice(const std::string& device_id,
+ bool is_allowed);
+ virtual bool ReactOnUserDevConsentForApp(const std::string app_id,
+ bool is_device_allowed);
+ virtual bool GetInitialAppData(const std::string& application_id,
+ StringArray* nicknames = NULL,
+ StringArray* app_hmi_types = NULL);
+
+ virtual void SetDeviceInfo(const std::string& device_id,
+ const DeviceInfo& device_info);
+
+ virtual void SetUserConsentForApp(const PermissionConsent& permissions);
+
+ virtual bool GetDefaultHmi(const std::string& policy_app_id,
+ std::string* default_hmi);
+
+ virtual bool GetPriority(const std::string& policy_app_id,
+ std::string* priority);
+
+ virtual std::vector<UserFriendlyMessage> GetUserFriendlyMessages(
+ const std::vector<std::string>& message_code, const std::string& language);
+
+ virtual bool IsApplicationRevoked(const std::string& app_id) const;
+
+ virtual void GetUserPermissionsForApp(
+ const std::string& device_id, const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions);
+
+ virtual std::string& GetCurrentDeviceId(const std::string& policy_app_id);
+
+ virtual void SetSystemLanguage(const std::string& language);
+
+ virtual void SetSystemInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language);
+
+ // Interface StatisticsManager (begin)
+ virtual void Increment(usage_statistics::GlobalCounterId type);
+ virtual void Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type);
+ virtual void Set(const std::string& app_id, usage_statistics::AppInfoId type,
+ const std::string& value);
+ virtual void Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int32_t timespan_seconds);
+ // Interface StatisticsManager (end)
+
+ AppPermissions GetAppPermissionsChanges(const std::string& app_id);
+ void RemovePendingPermissionChanges(const std::string& app_id);
+
+ void SendNotificationOnPermissionsUpdated(const std::string& application_id);
+
+ bool CleanupUnpairedDevices(const DeviceIds& device_ids);
+
+ bool CanAppKeepContext(const std::string& app_id);
+ bool CanAppStealFocus(const std::string& app_id);
+
+ protected:
+ virtual utils::SharedPtr<policy_table::Table> Parse(
+ const BinaryMessage& pt_content);
+ // virtual bool Validate();
+ // virtual bool ValidateResponseAgainsRequest();
+
+ private:
+ /*
+ * @brief Checks policy table update along with current data for any changes
+ * in assigned functional group list of application
+ *
+ * @param Policy table update struct
+ */
+ void CheckPermissionsChanges(
+ const utils::SharedPtr<policy_table::Table> update);
+
+ /**
+ * @brief Fill structure to be sent with OnPermissionsChanged notification
+ *
+ * @param Policy table struct, which contains rpc functional groups data
+ * @param List of rpc functional group names, which should be checked
+ * @param group_permission User permissions for functional groups
+ * @param Notification struct to be filled and sent
+ */
+ void PrepareNotificationData(
+ const policy_table::FunctionalGroupings& groups,
+ const policy_table::Strings& group_names,
+ const std::vector<FunctionalGroupPermission>& group_permission,
+ Permissions& notification_data);
+ /*
+ * @brief Sets flag for update progress
+ *
+ * @param value
+ */
+ void set_exchange_in_progress(bool value);
+
+ /*
+ * @brief Sets flag for pending update
+ *
+ * @param value
+ */
+ void set_exchange_pending(bool value);
+
+ /*
+ * @brief Sets flag for update necessity
+ *
+ * @param value
+ */
+ void set_update_required(bool value);
+
+ /**
+ * @brief Add application id at the end of update permissions request list
+ * @param Application id
+ */
+ void AddAppToUpdateList(const std::string& application_id);
+
+ /**
+ * @brief Remove first application in the update permissions request list
+ */
+ void RemoveAppFromUpdateList();
+
+ int IsConsentNeeded(const std::string& app_id);
+
+ /**
+ * @brief Check update status and notify HMI on changes
+ */
+ void CheckUpdateStatus();
+
+ PolicyListener* listener_;
+ PolicyTable policy_table_;
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot_;
+ bool exchange_in_progress_;
+ bool update_required_;
+ bool exchange_pending_;
+ sync_primitives::Lock exchange_in_progress_lock_;
+ sync_primitives::Lock update_required_lock_;
+ sync_primitives::Lock exchange_pending_lock_;
+ sync_primitives::Lock update_request_list_lock_;
+ std::map<std::string, AppPermissions> app_permissions_diff_;
+
+ /**
+ * @brief List of application, which require update of permissions
+ */
+ std::list<std::string> update_requests_list_;
+
+ /**
+ * Timeout to wait response with UpdatePT
+ */
+ int retry_sequence_timeout_;
+
+ /**
+ * Seconds between retries to update PT
+ */
+ std::vector<int> retry_sequence_seconds_;
+
+ /**
+ * Current index trying of retry sequence
+ */
+ int retry_sequence_index_;
+
+ /**
+ * Lock for guarding retry sequence
+ */
+ sync_primitives::Lock retry_sequence_lock_;
+
+ /**
+ * Lock for guarding recording statistics
+ */
+ sync_primitives::Lock statistics_lock_;
+
+ /**
+ * @brief Last status of policy table update
+ */
+ policy::PolicyTableStatus last_update_status_;
+
+ /**
+ * @brief Device id, which is used during PTU handling for specific
+ * application
+ */
+ std::string last_device_id_;
+
+ friend struct CheckAppPolicy;
+};
+
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_MANAGER_IMPL_H_
diff --git a/src/components/policy/src/policy/include/policy/policy_table.h b/src/components/policy/src/policy/include/policy/policy_table.h
new file mode 100644
index 000000000..fdd4c9c2f
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_table.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TABLE_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TABLE_H_
+
+#include "utils/shared_ptr.h"
+#include "policy/pt_representation.h"
+#include "policy/pt_ext_representation.h"
+
+namespace policy {
+
+class PolicyTable {
+ public:
+ PolicyTable();
+ explicit PolicyTable(utils::SharedPtr<PTRepresentation> pt_data);
+ virtual ~PolicyTable();
+
+ /**
+ * @brief Returns current implementation of
+ * actual class storing policy table.
+ * @return PTRepresentation* Policy Table Content Handler
+ */
+ utils::SharedPtr<PTRepresentation> pt_data() const {
+ return pt_data_;
+ }
+
+ private:
+ utils::SharedPtr<PTRepresentation> pt_data_;
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TABLE_H_
diff --git a/src/components/policy/src/policy/include/policy/policy_types.h b/src/components/policy/src/policy/include/policy/policy_types.h
new file mode 100644
index 000000000..61c003604
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_types.h
@@ -0,0 +1,289 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TYPES_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TYPES_H_
+
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include "utils/shared_ptr.h"
+
+namespace policy {
+
+// TODO(PV): specify errors
+enum PolicyErrorEnum {
+};
+
+const std::string kDefaultDeviceMacAddress = "00:00:00:00:00:00";
+const std::string kDefaultDeviceName = "MyDevice";
+
+/**
+ * @brief Constants for special ids in application policies section of
+ * policy table
+ */
+const std::string kPreDataConsentId = "pre_DataConsent";
+const std::string kDefaultId = "default";
+const std::string kDeviceId = "device";
+
+/*
+ *@brief Policy Services specifies Users of Updates
+ * received from cloud through mobile device
+ */
+enum PolicyServiceTypes {
+ SERVICE_NONE = 0,
+ IVSU = 0x04,
+ POLICY = 0x07
+};
+
+/*
+ * @brief Status of policy table update
+ */
+enum PolicyTableStatus {
+ StatusUpToDate = 0,
+ StatusUpdatePending,
+ StatusUpdateRequired,
+ StatusUnknown
+};
+
+// Code generator uses String class name, so this typedef was renamed to PTSring
+typedef std::string PTString;
+typedef std::vector<uint8_t> BinaryMessage;
+typedef utils::SharedPtr<BinaryMessage> BinaryMessageSptr;
+
+typedef std::string HMILevel;
+typedef std::string Parameter;
+typedef std::string RpcName;
+
+typedef std::map<std::string, std::set<policy::HMILevel> > HMIPermissions;
+typedef std::map<std::string, std::set<policy::Parameter> > ParameterPermissions;
+
+struct RpcPermissions {
+ HMIPermissions hmi_permissions;
+ ParameterPermissions parameter_permissions;
+};
+
+typedef std::map<RpcName, RpcPermissions> Permissions;
+
+/**
+ * @brief Typedef for use with AllowApp request/notification
+ */
+typedef std::vector<std::string> PermissionsList;
+
+/**
+ * @brief Typedef for getting initial application data, e.g. nickname list
+ */
+typedef std::vector<std::string> StringArray;
+
+enum PermitResult {
+ kRpcAllowed = 0,
+ kRpcDisallowed,
+ kRpcUserDisallowed
+};
+
+/**
+ * @struct Stores result of check:
+ * if HMI Level was allowed for RPC to work in
+ * and list of parameters allowed for RPC if specified in PT.
+ */
+struct CheckPermissionResult {
+ CheckPermissionResult()
+ : hmi_level_permitted(kRpcDisallowed) {
+ }
+
+ PermitResult hmi_level_permitted;
+ utils::SharedPtr<std::vector<PTString> > list_of_allowed_params;
+};
+
+/**
+ @struct Holds Url string and optional policy app id.
+ */
+struct EndpointData {
+ explicit EndpointData(const std::string& url_string = "")
+ : url(url_string)
+ , app_id("default") {}
+ std::string url;
+ std::string app_id;
+};
+
+typedef std::vector<EndpointData> EndpointUrls;
+
+/**
+ * @brief Struct contains device data to be used for dialogs, generation of IDs
+ */
+struct DeviceParams {
+ DeviceParams()
+ : device_name(kDefaultDeviceName),
+ device_mac_address(kDefaultDeviceMacAddress),
+ device_handle(0) {
+ }
+
+ std::string device_name;
+ std::string device_mac_address;
+ uint32_t device_handle;
+};
+
+/**
+ * @brief Stores data to be sent to HMI on application permissions change
+ */
+struct AppPermissions {
+
+ AppPermissions(const std::string& app_id)
+ : application_id(app_id),
+ isAppPermissionsRevoked(false),
+ appRevoked(false),
+ appPermissionsConsentNeeded(false),
+ appUnauthorized(false) {
+ }
+
+ std::string application_id;
+ bool isAppPermissionsRevoked;
+ // TODO(AOleynik): Change type according to HMI_API spec
+ std::vector<std::string> appRevokedPermissions;
+ bool appRevoked;
+ bool appPermissionsConsentNeeded;
+ bool appUnauthorized;
+ bool isSDLAllowed;
+ std::string priority;
+ DeviceParams deviceInfo;
+};
+
+/**
+ * @brief User consent for device data usage
+ */
+enum DeviceConsent {
+ kDeviceAllowed = 0,
+ kDeviceDisallowed,
+ kDeviceHasNoConsent
+};
+
+/**
+ * @brief Struct contains parameters, which can be received during application
+ * registration and should be stored in policy table
+ */
+struct DeviceInfo {
+ DeviceInfo()
+ : max_number_rfcom_ports(0) {
+ }
+
+ std::string hardware;
+ std::string firmware_rev;
+ std::string os;
+ std::string os_ver;
+ std::string carrier;
+ uint32_t max_number_rfcom_ports;
+};
+
+/**
+ * @brief User consent for functional group
+ */
+enum GroupConsent {
+ kGroupAllowed = 0,
+ kGroupDisallowed,
+ kGroupUndefined
+};
+
+/**
+ * @brief Contains user permission for RPC functional group with specific name
+ * and id from DB
+ */
+struct FunctionalGroupPermission {
+ FunctionalGroupPermission()
+ : group_id(0),
+ state(kGroupUndefined) {
+ }
+
+ std::string group_alias;
+ std::string group_name;
+ uint32_t group_id;
+ GroupConsent state;
+};
+
+/**
+ * @brief Contains parameters for user-defined consent for appication
+ * functional groups on given device
+ */
+struct PermissionConsent {
+ std::string device_id;
+ std::string policy_app_id;
+ std::vector<FunctionalGroupPermission> group_permissions;
+ std::string consent_source;
+};
+
+/**
+ * @brief Contain data for GetUserFriendyMessage response
+ */
+struct UserFriendlyMessage {
+ std::string message_code;
+ std::string tts;
+ std::string label;
+ std::string line1;
+ std::string line2;
+ std::string text_body;
+};
+
+/**
+ * @brief Types of functional groups in policy table
+ */
+enum GroupType {
+ kTypeDefault = 0,
+ kTypeAllowed,
+ kTypeDisallowed,
+ kTypePreconsented,
+ kTypeGeneral // means, all types above
+};
+
+/**
+ * @brief Array of functional group id from DB
+ */
+typedef std::vector<uint32_t> FunctionalGroupIDs;
+
+/**
+ * @brief Array of functional group ids sorted by types
+ */
+typedef std::map<GroupType, FunctionalGroupIDs> FunctionalIdType;
+
+/**
+ * @brief Array of functional group ids binded to group name (e.g.
+ * VehicleData-4) and user_consent_prompt (e.g. VehicleData)
+ */
+typedef std::map<uint32_t, std::pair<std::string, std::string> > FunctionalGroupNames;
+
+/**
+ * @brief Array of device ids, which are an identifiers in policy table
+ */
+typedef std::set<std::string> DeviceIds;
+
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TYPES_H_
diff --git a/src/components/policy/src/policy/include/policy/pt_ext_representation.h b/src/components/policy/src/policy/include/policy/pt_ext_representation.h
new file mode 100644
index 000000000..45d3b1b4b
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/pt_ext_representation.h
@@ -0,0 +1,292 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_EXT_REPRESENTATION_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_EXT_REPRESENTATION_H_
+
+#include "policy/pt_representation.h"
+
+namespace policy {
+
+enum StatisticsType {
+ S_NONE = 0,
+ S_IAP_BUFFER_FULL,
+ S_SYNC_OUT_OF_MEMORY,
+ S_SYNC_REBOOTS,
+ S_MINS_HMI_FULL,
+ S_MINS_HMI_LIMITED,
+ S_MINS_HMI_BACKGROUND,
+ S_MINS_HMI_NONE,
+ S_RFCOM_LIMIT_REACHED,
+ S_USER_SELECTIONS,
+ S_REJECTIONS_SYNC_OUT_OF_MEMORY,
+ S_REJECTIONS_NICKNAME_MISMATCH,
+ S_REJECTIONS_DUPLICATE_NAME,
+ S_REJECTED_RPC_CALLS,
+ S_RPCS_IN_HMI_NONE,
+ S_REMOVALS_MISBEHAVED,
+ S_RUN_ATTEMPTS_WHILE_REVOKED
+};
+
+enum LanguageType {
+ L_NONE = 0,
+ L_GUI,
+ L_VUI
+};
+
+class PTExtRepresentation : public virtual PTRepresentation {
+ public:
+ virtual ~PTExtRepresentation() {
+ }
+
+ /**
+ * @brief Is application allowed to send notifications while in
+ * Backgound or limited mode.
+ * @param app_id Application id
+ * @return bool Allowed/disallowed.
+ */
+ virtual bool CanAppKeepContext(const std::string& app_id) = 0;
+
+ /**
+ * @brief Is application allowed to move foreground at will?
+ * @param app_id Application id
+ * @return bool Allowed/disallowed.
+ */
+ virtual bool CanAppStealFocus(const std::string& app_id) = 0;
+
+ /**
+ * @brief Get default_hmi for given application
+ * @param policy_app_id Unique application id
+ * @param default_hmi Default HMI level for application or empty, if value was
+ * not set
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool GetDefaultHMI(const std::string& policy_app_id,
+ std::string* default_hmi) = 0;
+
+ /**
+ * @brief Get priority for given application
+ * @param policy_app_id Unique application id
+ * @param priority Priority for application or empty, if value was not set
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool GetPriority(const std::string& policy_app_id,
+ std::string* priority) = 0;
+
+ /**
+ * @brief Reset user consent for device data and applications permissions
+ * @return
+ */
+ virtual bool ResetUserConsent() = 0;
+
+ /**
+ * @brief Get user permissions for device data usage
+ * @param device_id Generated or obtained id of device
+ * @param consented_groups Groups consented by user
+ * @param disallowed_groups Groups not consented by user
+ * @return true, if query was successfull, otherwise - false
+ */
+ virtual bool GetUserPermissionsForDevice(
+ const std::string& device_id, StringArray* consented_groups = NULL,
+ StringArray* disallowed_groups = NULL) = 0;
+
+ /**
+ * @brief GetUserPermissionsForApp
+ * @param device_id
+ * @param policy_app_id
+ * @param group_types
+ * @return
+ */
+ virtual bool GetUserPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ FunctionalIdType* group_types) = 0;
+
+ /**
+ * @brief Get device groups and preconsented groups from policies section
+ * @param groups List of groups to be consented for device usage
+ * @param preconsented_groups List of preconsented groups for device usage
+ * @return true, if query was successful, otherwise - false
+ */
+ virtual bool GetDeviceGroupsFromPolicies(
+ policy_table::Strings* groups = NULL,
+ policy_table::Strings* preconsented_groups = NULL) = 0;
+
+ /**
+ * @brief Record information about mobile device in Policy Table.
+ * @param device_id Generated or obtained id of device
+ * @return bool Success of operation
+ */
+ virtual bool SetDeviceData(const std::string& device_id,
+ const std::string& hardware = "",
+ const std::string& firmware = "",
+ const std::string& os = "",
+ const std::string& os_version = "",
+ const std::string& carrier = "",
+ const uint32_t number_of_ports = 0) = 0;
+
+ /**
+ * @brief Sets user consent for particular mobile device,
+ * i.e. to use device for exchanging of Policy Table.
+ * @return bool Success of operation
+ */
+ virtual bool SetUserPermissionsForDevice(
+ const std::string& device_id, const StringArray& consented_groups =
+ StringArray(),
+ const StringArray& disallowed_gropus = StringArray()) = 0;
+
+ /**
+ * @brief Update Application Policies as reaction
+ * on User allowing/disallowing device this app is running on.
+ */
+ virtual bool ReactOnUserDevConsentForApp(
+ const std::string& app_id,
+ bool is_device_allowed) = 0;
+
+ /**
+ * @brief Set user consent on functional groups
+ * @param permissions User consent on functional group
+ * @return true, if operation succedeed, otherwise - false
+ */
+ virtual bool SetUserPermissionsForApp(
+ const PermissionConsent& permissions) = 0;
+
+ /**
+ * @brief Counter for statistics information: adds 1 to existing number.
+ * @param type Type of statistics (errors, mins in mode etc)
+ * @return bool Success of operation
+ */
+ virtual bool IncreaseStatisticsData(StatisticsType type) = 0;
+
+ /**
+ * @brief Records information about what language
+ * application tried to register with.
+ * @param app_id Id of application
+ * @param type - language for UI/VR
+ * @param language Language
+ * @return bool Success of operation
+ */
+ virtual bool SetAppRegistrationLanguage(const std::string& app_id,
+ LanguageType type,
+ const std::string& language) = 0;
+
+ /**
+ * @brief Records information about head unit system to PT
+ * @return bool Success of operation
+ */
+ virtual bool SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) = 0;
+
+ /**
+ * @brief Kms pass since last successfull PT update
+ */
+ virtual int GetKmFromSuccessfulExchange() = 0;
+
+ /**
+ * @brief Days pass since last successfull PT update
+ */
+ virtual int GetDayFromScsExchange() = 0;
+
+ /**
+ * @brief Ignition cycles pass since last successfull PT update
+ */
+ virtual int GetIgnitionsFromScsExchange() = 0;
+
+ /**
+ * @brief Set current system language
+ * @param language System language
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool SetSystemLanguage(const std::string& language) = 0;
+
+ /**
+ * Increments global counter
+ * @param type type of counter
+ */
+ virtual void Increment(const std::string& type) const = 0;
+
+ /**
+ * Increments counter of application
+ * @param app_id id application
+ * @param type type of counter
+ */
+ virtual void Increment(const std::string& app_id,
+ const std::string& type) const = 0;
+
+ /**
+ * Sets value of application information
+ * @param app_id id application
+ * @param type type of information
+ * @param value value of information
+ */
+ virtual void Set(const std::string& app_id, const std::string& type,
+ const std::string& value) const = 0;
+
+ /**
+ * Adds value to stopwatch of application
+ * @param app_id id application
+ * @param type type of stopwatch
+ * @param seconds value for adding in seconds
+ */
+ virtual void Add(const std::string& app_id, const std::string& type,
+ int seconds) const = 0;
+
+ virtual bool CountUnconsentedGroups(const std::string& policy_app_id,
+ int* result) const = 0;
+
+ /**
+ * @brief Gets functional group names and user_consent_prompts, if any
+ * @param Array to be filled with group ids, names and functional prompts
+ * @return true, if succeeded, otherwise - false
+ */
+ // TODO(AOleynik): Possibly, we can get rid of this method. Check this.
+ virtual bool GetFunctionalGroupNames(policy::FunctionalGroupNames& names) = 0;
+
+ /**
+ * @brief Set app policy to pre_DataConsented policy
+ * @param app_id Policy ID of application to be changed
+ * @return true, if succeeded, otherwise - false
+ */
+ virtual bool SetPredataPolicy(const std::string& app_id) = 0;
+
+ /**
+ * @brief Updates application policy to either pre_DataConsented or not
+ * @param app_id Policy Id of application to be checked
+ * @param is_pre_data True of False to setting app policy to be pre_DataConsented
+ * @return true, if succeeded, otherwise - false
+ */
+ virtual bool SetIsPredata(const std::string& app_id, bool is_pre_data) = 0;
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_EXT_REPRESENTATION_H_
diff --git a/src/components/policy/src/policy/include/policy/pt_representation.h b/src/components/policy/src/policy/include/policy/pt_representation.h
new file mode 100644
index 000000000..ff6544ef2
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/pt_representation.h
@@ -0,0 +1,271 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_REPRESENTATION_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_REPRESENTATION_H_
+
+#include <vector>
+#include <string>
+#include "policy/policy_types.h"
+#include "policy_table_interface_base/types.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+namespace policy {
+
+/**
+ * @struct Data about vehicle
+ */
+struct VehicleData {
+ const std::string vehicle_make;
+ const std::string vehicle_model;
+ int vehicle_year;
+};
+
+enum InitResult {
+ NONE = 0,
+ EXISTS,
+ SUCCESS,
+ FAIL
+};
+
+class PTRepresentation {
+ public:
+ virtual ~PTRepresentation() {
+ }
+
+ /**
+ * @brief Check if specified RPC for specified application
+ * has permission to be executed in specified HMI Level
+ * and also its permitted params.
+ * @param app_id Id of application provided during registration
+ * @param hmi_level Current HMI Level of application
+ * @param rpc Name of RPC
+ * @return CheckPermissionResult containing flag if HMI Level is allowed
+ * and list of allowed params.
+ */
+ virtual CheckPermissionResult CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc) = 0;
+
+ /**
+ * @brief Returns true if Policy Table was not updated yet
+ * from preloaded pt file.
+ */
+ virtual bool IsPTPreloaded() = 0;
+
+ /**
+ * Gets number of ignition cycles before next update policy table
+ * @return number of ignition cycles
+ */
+ virtual int IgnitionCyclesBeforeExchange() = 0;
+
+ /**
+ * Gets value in kilometers before next update policy table
+ * @param current value in kilometers from the odometers
+ * @return value in kilometers
+ */
+ virtual int KilometersBeforeExchange(int current) = 0;
+
+ /**
+ * @brief Sets kilometers and days after epoch, that passed for recieved
+ * successful PT UPdate
+ */
+ virtual bool SetCountersPassedForSuccessfulUpdate(int kilometers,
+ int days_after_epoch) = 0;
+
+ /**
+ * Gets value in days before next update policy table
+ * @param current value in days after epoch
+ * @return value in days
+ */
+ virtual int DaysBeforeExchange(int current) = 0;
+
+ /**
+ * @brief Increment number of ignition cycles since last exchange by 1
+ */
+ virtual void IncrementIgnitionCycles() = 0;
+
+ /**
+ * @brief Reset number of ignition cycles since last exchange to 0
+ */
+ virtual void ResetIgnitionCycles() = 0;
+
+ /**
+ * @brief Returns timeout to wait for a response of PT update
+ * @return value in seconds
+ */
+ virtual int TimeoutResponse() = 0;
+
+ /**
+ * @brief Returns number of seconds between each try of sending PTS
+ * @param seconds Return value: array of 5 elements
+ * @return bool Success of operation
+ */
+ virtual bool SecondsBetweenRetries(std::vector<int>* seconds) = 0;
+
+ /**
+ * @brief Get information about vehicle
+ */
+ virtual VehicleData GetVehicleData() = 0;
+
+ /**
+ * @brief Get message text for displaying/pronouncing for user
+ * dependent on language and context.
+ * @param msg_codes Context of message (Driver distraction, Grant permission etc)
+ * @param language Language of the message
+ * @return Array of appropriate messages parameters
+ */
+ virtual std::vector<UserFriendlyMessage> GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) = 0;
+
+ /**
+ * @brief Get list of URL to send PTS to
+ * @param service_type If URLs for specific service are preset,
+ * return them otherwise default URLs.
+ */
+ virtual EndpointUrls GetUpdateUrls(int service_type) = 0;
+
+ /**
+ * @brief Get allowed number of notifications
+ * depending on application priority.
+ * @param priority Priority of application
+ */
+ virtual int GetNotificationsNumber(policy_table::Priority priority) = 0;
+
+ /**
+ * @brief Initialized Policy Table (load)
+ * @return bool Success of operation
+ */
+ virtual InitResult Init() = 0;
+
+ /**
+ * @brief Close policy table
+ * @return bool Success of operation
+ */
+ virtual bool Close() = 0;
+
+ /**
+ * @brief Removes policy table content.
+ * @return bool Success of operation
+ */
+ virtual bool Clear() = 0;
+
+ /**
+ * @brief Get snapshot of Policy Table
+ * including app_policies, functional_groups,
+ * device_info, statistics, excluding user messages
+ * @return Generated structure for obtaining Json string.
+ */
+ virtual utils::SharedPtr<policy_table::Table> GenerateSnapshot() const = 0;
+
+ /**
+ * Saves policy table in storage
+ * @param table policy table
+ * @return true if successfully
+ */
+ virtual bool Save(const policy_table::Table& table) = 0;
+
+ /**
+ * Gets flag updateRequired
+ * @return true if update is required
+ */
+ virtual bool UpdateRequired() const = 0;
+
+ /**
+ * Saves flag updateRequired
+ */
+ virtual void SaveUpdateRequired(bool value) = 0;
+
+ /*
+ Retrieves data from app_policies about app on its registration:
+ app_id - id of registered app; all outputs are filled in only if not null
+ output: nicknames Synonyms for application
+ output: app_types Section on HMI where app can appear (Navigation, Phone etc)
+ */
+ virtual bool GetInitialAppData(const std::string& app_id,
+ StringArray* nicknames = NULL,
+ StringArray* app_types = NULL) = 0;
+
+ /**
+ * Checks if the application is revoked
+ * @param app_id application id
+ * @return true if application is revoked
+ */
+ virtual bool IsApplicationRevoked(const std::string& app_id) const = 0;
+
+ /**
+ * @brief Get functional groupings from DB
+ * @param groups Known functional groupings
+ * @return true, if succeeded, otherwise - false
+ */
+ virtual bool GetFunctionalGroupings(policy_table::FunctionalGroupings& groups) = 0;
+
+ /**
+ * Checks if the application is represented in policy table
+ * @param app_id application id
+ * @return true if application is represented in policy table
+ */
+ virtual bool IsApplicationRepresented(const std::string& app_id) const = 0;
+
+ /**
+ * Checks if the application has default policy
+ * @param app_id application id
+ * @return true if application has default policy
+ */
+ virtual bool IsDefaultPolicy(const std::string& app_id) const = 0;
+
+ /**
+ * Checks if the application has pre_data policy
+ * @param app_id application id
+ * @return true if application has pre_data policy
+ */
+ virtual bool IsPredataPolicy(const std::string& app_id) const = 0;
+
+ /**
+ * Sets default policy for application
+ * @param app_id application id
+ * @return true if success
+ */
+ virtual bool SetDefaultPolicy(const std::string& app_id) = 0;
+
+ /**
+ * @brief Removes unpaired device records and related records from DB
+ * @param device_ids List of device_id, which should be removed
+ * @return true, if succedeed, otherwise - false
+ */
+ virtual bool CleanupUnpairedDevices(const DeviceIds& device_ids) = 0;
+};
+
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_PT_REPRESENTATION_H_
diff --git a/src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h b/src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h
new file mode 100644
index 000000000..ddcba6ae4
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h
@@ -0,0 +1,85 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_QUERIES_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_QUERIES_H_
+
+#include <string>
+
+namespace policy {
+namespace sql_pt_ext {
+
+extern const std::string kSelectKeepContext;
+extern const std::string kSelectStealFocus;
+extern const std::string kResetUserConsent;
+extern const std::string kCountDeviceConsentGroup;
+extern const std::string kCountDevice;
+extern const std::string kSelectDeviceConsentedGroup;
+extern const std::string kUpdateDeviceConsentedGroup;
+extern const std::string kUpdateDevice;
+extern const std::string kInsertDeviceConsentedGroup;
+extern const std::string kInsertDevice;
+extern const std::string kSelectDeviceData;
+extern const std::string kSelectConsentGroup;
+extern const std::string kInsertPreconsentedGroups;
+extern const std::string kSelectPreconsentedGroups;
+extern const std::string kDeletePreconsentedGroups;
+extern const std::string kSelectUsageAndErrorCount;
+extern const std::string kSelectAppLevels;
+extern const std::string kInsertDeviceData;
+extern const std::string kInsertConsentGroups;
+extern const std::string kCountUnconsentedGroups;
+extern const std::string kSelectModuleMeta;
+extern const std::string kUpdateMetaParams;
+extern const std::string kCountAppLevel;
+extern const std::string kUpdateGroupPermissions;
+extern const std::string kSelectDefaultHmi;
+extern const std::string kSelectPriority;
+extern const std::string kInsertApplication;
+extern const std::string kSelectFriendlyMsg;
+extern const std::string kSelectAppGroupsId;
+extern const std::string kSelectConsentedGroupsId;
+extern const std::string kCountAppConsents;
+extern const std::string kSelectPreconsentedGroupsId;
+extern const std::string kSelectFunctionalGroupNames;
+extern const std::string kSelectAppPolicies;
+extern const std::string kUpdateMetaLanguage;
+extern const std::string kDeleteDeviceConsent;
+extern const std::string kDeleteAppConsent;
+extern const std::string kSelectApplicationIsPreData;
+extern const std::string kUpdateIsPredata;
+extern const std::string kHasAppPreloadedGroups;
+
+} // namespace sql_pt_ext
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_QUERIES_H_
diff --git a/src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h b/src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h
new file mode 100644
index 000000000..3718d4ebb
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h
@@ -0,0 +1,164 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_REPRESENTATION_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_REPRESENTATION_H_
+
+#include <string>
+#include "policy/sql_pt_representation.h"
+#include "policy/pt_ext_representation.h"
+
+namespace policy {
+
+class SQLPTExtRepresentation : public SQLPTRepresentation,
+ public PTExtRepresentation {
+ public:
+ bool CanAppKeepContext(const std::string& app_id);
+ bool CanAppStealFocus(const std::string& app_id);
+ bool GetDefaultHMI(const std::string& policy_app_id,
+ std::string* default_hmi);
+ bool GetPriority(const std::string& policy_app_id, std::string* priority);
+ bool ResetUserConsent();
+ bool GetUserPermissionsForDevice(const std::string& device_id,
+ StringArray* consented_groups = NULL,
+ StringArray* disallowed_groups = NULL);
+
+ bool GetUserPermissionsForApp(
+ const std::string& device_id, const std::string& policy_app_id,
+ FunctionalIdType* group_types);
+
+ bool GetDeviceGroupsFromPolicies(policy_table::Strings* groups = NULL,
+ policy_table::Strings* preconsented_groups =
+ NULL);
+ bool SetDeviceData(const std::string& device_id, const std::string& hardware =
+ "",
+ const std::string& firmware = "", const std::string& os =
+ "",
+ const std::string& os_version = "",
+ const std::string& carrier = "",
+ const uint32_t number_of_ports = 0);
+ bool SetUserPermissionsForDevice(const std::string& device_id,
+ const StringArray& consented_groups =
+ StringArray(),
+ const StringArray& disallowed_groups =
+ StringArray());
+
+ bool ReactOnUserDevConsentForApp(const std::string& app_id,
+ bool is_device_allowed);
+
+ bool SetUserPermissionsForApp(const PermissionConsent& permissions);
+
+ std::vector<UserFriendlyMessage> GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language);
+
+ bool IncreaseStatisticsData(StatisticsType type) {
+ return true;
+ }
+ bool SetAppRegistrationLanguage(const std::string& app_id, LanguageType type,
+ const std::string& language) {
+ return true;
+ }
+
+ bool SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language);
+
+ bool SetSystemLanguage(const std::string& language);
+
+ int GetKmFromSuccessfulExchange() {
+ return true;
+ }
+ int GetDayFromScsExchange() {
+ return true;
+ }
+ int GetIgnitionsFromScsExchange() {
+ return true;
+ }
+
+ bool GetFunctionalGroupNames(FunctionalGroupNames& names);
+ bool CleanupUnpairedDevices(const DeviceIds& device_ids);
+
+ void Increment(const std::string& type) const;
+ void Increment(const std::string& app_id, const std::string& type) const;
+ void Set(const std::string& app_id, const std::string& type,
+ const std::string& value) const;
+ void Add(const std::string& app_id, const std::string& type,
+ int seconds) const;
+ bool SetDefaultPolicy(const std::string& app_id);
+ bool SetPredataPolicy(const std::string& app_id);
+ bool SetIsPredata(const std::string& app_id, bool is_pre_data);
+ bool IsPredataPolicy(const std::string& app_id) const;
+
+ private:
+ void GatherModuleMeta(policy_table::ModuleMeta* meta) const;
+ void GatherPreconsentedGroup(const std::string& app_id,
+ policy_table::Strings* groups) const;
+ bool GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const;
+ bool GatherAppLevels(policy_table::AppLevels* apps) const;
+ void GatherDeviceData(policy_table::DeviceData* data) const;
+ void GatherConsentGroup(const std::string& device_id,
+ policy_table::UserConsentRecords* records) const;
+ bool GatherApplicationPolicies(policy_table::ApplicationPolicies* apps) const;
+ bool SaveDeviceData(const policy_table::DeviceData& devices);
+ bool SaveConsentGroup(const std::string& device_id,
+ const policy_table::UserConsentRecords& records);
+ bool SaveApplicationPolicies(const policy_table::ApplicationPolicies& apps);
+ bool SavePreconsentedGroup(const std::string& app_id,
+ const policy_table::Strings& groups);
+ bool SaveMessageString(const std::string& type, const std::string& lang,
+ const policy_table::MessageString& strings);
+
+ bool IsExistAppLevel(const std::string& app_id) const;
+
+ bool GetAllAppGroups(const std::string& policy_app_id,
+ FunctionalGroupIDs& all_groups);
+
+ bool GetConsentedGroups(const std::string& policy_app_id,
+ const std::string& device_id,
+ FunctionalGroupIDs& allowed_groups,
+ FunctionalGroupIDs& disallowed_groups);
+
+ bool GetPreconsentedGroups(const std::string& policy_app_id,
+ FunctionalGroupIDs& preconsented_groups);
+
+ void FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids, FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions);
+ bool CountUnconsentedGroups(const std::string& policy_app_id,
+ int* result) const;
+};
+
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_EXT_REPRESENTATION_H_
diff --git a/src/components/policy/src/policy/include/policy/sql_pt_queries.h b/src/components/policy/src/policy/include/policy/sql_pt_queries.h
new file mode 100644
index 000000000..5eaea730b
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_queries.h
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_QUERIES_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_QUERIES_H_
+
+#include <string>
+
+namespace policy {
+namespace sql_pt {
+
+extern const std::string kCreateSchema;
+extern const std::string kDropSchema;
+extern const std::string kCheckPgNumber;
+extern const std::string kCheckDBIntegrity;
+extern const std::string kSelectRpc;
+extern const std::string kSelectPreloaded;
+extern const std::string kSelectEndpoint;
+extern const std::string kSelectModuleConfig;
+extern const std::string kSelectEndpoints;
+extern const std::string kSelectNotificationsPerMin;
+extern const std::string kSelectAppLevels;
+extern const std::string kSelectDeviceData;
+extern const std::string kSelectFunctionalGroups;
+extern const std::string kSelectAllRpcs;
+extern const std::string kSelectUserMsgsVersion;
+extern const std::string kSelectAppPolicies;
+extern const std::string kSelectAppGroups;
+extern const std::string kSelectNicknames;
+extern const std::string kSelectAppTypes;
+extern const std::string kSelectSecondsBetweenRetries;
+extern const std::string kSelectIgnitionCycles;
+extern const std::string kSelectKilometers;
+extern const std::string kSelectDays;
+extern const std::string kSelectTimeoutResponse;
+extern const std::string kInsertFunctionalGroup;
+extern const std::string kInsertRpc;
+extern const std::string kInsertRpcWithParameter;
+extern const std::string kInsertApplication;
+extern const std::string kInsertAppGroup;
+extern const std::string kInsertNickname;
+extern const std::string kInsertAppType;
+extern const std::string kInsertMessageType;
+extern const std::string kInsertLanguage;
+extern const std::string kInsertMessageString;
+extern const std::string kUpdateVersion;
+extern const std::string kUpdateModuleConfig;
+extern const std::string kInsertEndpoint;
+extern const std::string kInsertSecondsBetweenRetry;
+extern const std::string kInsertNotificationsByPriority;
+extern const std::string kInsertDeviceData;
+extern const std::string kInsertAppLevel;
+extern const std::string kDeleteSecondsBetweenRetries;
+extern const std::string kDeleteEndpoint;
+extern const std::string kDeleteAppLevel;
+extern const std::string kDeleteMessageString;
+extern const std::string kDeleteFunctionalGroup;
+extern const std::string kDeleteRpc;
+extern const std::string kDeleteAppGroup;
+extern const std::string kDeleteApplication;
+extern const std::string kDeleteDevice;
+extern const std::string kIncrementIgnitionCycles;
+extern const std::string kResetIgnitionCycles;
+extern const std::string kUpdateFlagUpdateRequired;
+extern const std::string kSelectFlagUpdateRequired;
+extern const std::string kUpdateCountersSuccessfulUpdate;
+extern const std::string kSelectApplicationRevoked;
+extern const std::string kSelectApplicationRepresented;
+extern const std::string kSelectApplicationIsDefault;
+extern const std::string kUpdateIsDefault;
+
+} // namespace sql_pt
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_QUERIES_H_
diff --git a/src/components/policy/src/policy/include/policy/sql_pt_representation.h b/src/components/policy/src/policy/include/policy/sql_pt_representation.h
new file mode 100644
index 000000000..2d37d53b5
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_representation.h
@@ -0,0 +1,158 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_REPRESENTATION_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_REPRESENTATION_H_
+
+#include <string>
+#include <vector>
+#include "policy/pt_representation.h"
+#include "rpc_base/rpc_base.h"
+#include "policy_table_interface_base/types.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+namespace policy {
+
+namespace dbms {
+class SQLDatabase;
+} // namespace dbms
+
+class SQLPTRepresentation : public virtual PTRepresentation {
+ public:
+ SQLPTRepresentation();
+ ~SQLPTRepresentation();
+ virtual CheckPermissionResult CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc);
+
+ virtual bool IsPTPreloaded();
+ virtual int IgnitionCyclesBeforeExchange();
+ virtual int KilometersBeforeExchange(int current);
+ virtual bool SetCountersPassedForSuccessfulUpdate(int kilometers,
+ int days_after_epoch);
+ virtual int DaysBeforeExchange(int current);
+ virtual void IncrementIgnitionCycles();
+ virtual void ResetIgnitionCycles();
+ virtual int TimeoutResponse();
+ virtual bool SecondsBetweenRetries(std::vector<int>* seconds);
+
+ virtual VehicleData GetVehicleData();
+
+ virtual std::vector<UserFriendlyMessage> GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language);
+
+ virtual EndpointUrls GetUpdateUrls(int service_type);
+
+ virtual int GetNotificationsNumber(policy_table::Priority priority);
+ InitResult Init();
+ bool Close();
+ bool Clear();
+ virtual utils::SharedPtr<policy_table::Table> GenerateSnapshot() const;
+ bool Save(const policy_table::Table& table);
+ bool GetInitialAppData(const std::string& app_id, StringArray* nicknames =
+ NULL,
+ StringArray* app_hmi_types = NULL);
+ bool GetFunctionalGroupings(policy_table::FunctionalGroupings& groups);
+
+ protected:
+ virtual void GatherModuleMeta(policy_table::ModuleMeta* meta) const;
+ virtual void GatherModuleConfig(policy_table::ModuleConfig* config) const;
+ virtual bool GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const;
+ virtual void GatherDeviceData(policy_table::DeviceData* data) const;
+ virtual bool GatherFunctionalGroupings(
+ policy_table::FunctionalGroupings* groups) const;
+ virtual bool GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const;
+ virtual bool GatherApplicationPolicies(
+ policy_table::ApplicationPolicies* apps) const;
+
+ bool GatherAppGroup(const std::string& app_id,
+ policy_table::Strings* app_groups) const;
+ bool GatherAppType(const std::string& app_id,
+ policy_table::AppHMITypes* app_types) const;
+ bool GatherNickName(const std::string& app_id,
+ policy_table::Strings* nicknames) const;
+
+ virtual bool SaveModuleMeta(const policy_table::ModuleMeta& meta);
+ virtual bool SaveModuleConfig(const policy_table::ModuleConfig& config);
+ virtual bool SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts);
+ virtual bool SaveDeviceData(const policy_table::DeviceData& devices);
+ virtual bool SaveFunctionalGroupings(
+ const policy_table::FunctionalGroupings& groups);
+ virtual bool SaveConsumerFriendlyMessages(
+ const policy_table::ConsumerFriendlyMessages& messages);
+ virtual bool SaveApplicationPolicies(
+ const policy_table::ApplicationPolicies& apps);
+
+ virtual bool SaveMessageString(const std::string& type,
+ const std::string& lang,
+ const policy_table::MessageString& strings);
+
+ bool SaveAppGroup(const std::string& app_id,
+ const policy_table::Strings& app_groups);
+ bool SaveNickname(const std::string& app_id,
+ const policy_table::Strings& nicknames);
+ bool SaveAppType(const std::string& app_id,
+ const policy_table::AppHMITypes& types);
+
+ bool UpdateRequired() const;
+ void SaveUpdateRequired(bool value);
+
+ bool IsApplicationRevoked(const std::string& app_id) const;
+ bool IsApplicationRepresented(const std::string& app_id) const;
+ virtual bool IsDefaultPolicy(const std::string& app_id) const;
+ virtual bool IsPredataPolicy(const std::string& app_id) const;
+ virtual bool SetDefaultPolicy(const std::string& app_id);
+ bool CleanupUnpairedDevices(const DeviceIds& device_ids);
+
+ dbms::SQLDatabase* db() const;
+ virtual bool SetIsDefault(const std::string& app_id, bool is_default);
+
+ private:
+ static const std::string kDatabaseName;
+ dbms::SQLDatabase* db_;
+
+ bool SaveRpcs(int64_t group_id, const policy_table::Rpc& rpcs);
+ bool SaveServiceEndpoints(const policy_table::ServiceEndpoints& endpoints);
+ bool SaveSecondsBetweenRetries(
+ const policy_table::SecondsBetweenRetries& seconds);
+ bool SaveNumberOfNotificationsPerMinute(
+ const policy_table::NumberOfNotificationsPerMinute& notifications);
+ bool SaveMessageType(const std::string& type);
+ bool SaveLanguage(const std::string& code);
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_PT_REPRESENTATION_H_
diff --git a/src/components/policy/src/policy/include/policy/sql_wrapper.h b/src/components/policy/src/policy/include/policy/sql_wrapper.h
new file mode 100644
index 000000000..29dbdd481
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_wrapper.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_WRAPPER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_WRAPPER_H_
+
+#if __QNX__
+# include "qdb_wrapper/sql_database.h"
+# include "qdb_wrapper/sql_query.h"
+#else // __QNX__
+# include "sqlite_wrapper/sql_database.h"
+# include "sqlite_wrapper/sql_query.h"
+#endif // __QNX__
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SQL_WRAPPER_H_
diff --git a/src/components/policy/src/policy/include/policy/syncp_adapter.h b/src/components/policy/src/policy/include/policy/syncp_adapter.h
new file mode 100644
index 000000000..3eb286dd4
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/syncp_adapter.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SYNCP_ADAPTER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_SYNCP_ADAPTER_H_
+
+#include "policy/policy_types.h"
+
+namespace policy {
+class SyncPAdapter {
+ public:
+ SyncPAdapter();
+ virtual ~SyncPAdapter();
+ virtual bool ParseHeader(const PTString& input);
+ virtual bool ComposeHeader();
+ virtual PTString* Decrypt(const PTString& input);
+ virtual PTString* Encrypt(const PTString& input);
+ virtual bool ValidateUpdate();
+
+ private:
+ typedef unsigned int MessageID;
+ struct Header {
+ explicit Header(MessageID id = -1)
+ : msg_id(id) {}
+ MessageID msg_id;
+ };
+
+ Header snapshot_;
+ Header update_;
+};
+} // namespace policy
+
+#endif
diff --git a/src/components/policy/src/policy/include/policy/user_consent_manager.h b/src/components/policy/src/policy/include/policy/user_consent_manager.h
new file mode 100644
index 000000000..4bf80afb1
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/user_consent_manager.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USER_CONSENT_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USER_CONSENT_MANAGER_H_
+
+namespace policy {
+class UserConsentManager {
+ public:
+ UserConsentManager() {}
+ ~UserConsentManager() {}
+};
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USER_CONSENT_MANAGER_H_
diff --git a/src/components/policy/src/policy/policy_table_interface.xml b/src/components/policy/src/policy/policy_table_interface.xml
new file mode 100644
index 000000000..576b4b203
--- /dev/null
+++ b/src/components/policy/src/policy/policy_table_interface.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" standalone="no"?>
+<?xml-stylesheet type="text/xml" href="protocol2html.xsl"?>
+
+<interface name="policy table interface base" version="0.0"
+ date="2014-01-23">
+
+ <!-- Common parameters start -->
+ <enum name="Priority">
+ <element name="EMERGENCY" />
+ <element name="NAVIGATION" />
+ <element name="VOICECOM" />
+ <element name="COMMUNICATION" />
+ <element name="NORMAL" />
+ <element name="NONE" />
+ </enum>
+
+ <enum name="HmiLevel">
+ <element name="BACKGROUND" />
+ <element name="FULL" />
+ <element name="LIMITED" />
+ <element name="NONE" />
+ </enum>
+
+ <enum name="Parameter">
+ <element name="gps" />
+ <element name="speed" />
+ <element name="engineTorque" />
+ <element name="externalTemperature" />
+ <element name="fuelLevel" />
+ <element name="fuelLevel_State" />
+ <element name="headLampStatus" />
+ <element name="instantFuelConsumption" />
+ <element name="odometer" />
+ <element name="tirePressure" />
+ <element name="wiperStatus" />
+ <element name="vin" />
+ <element name="accPedalPosition" />
+ <element name="beltStatus" />
+ <element name="driverBraking" />
+ <element name="prndl" />
+ <element name="rpm" />
+ <element name="steeringWheelAngle" />
+ <element name="myKey" />
+ <element name="airbagStatus" />
+ <element name="bodyInformation" />
+ <element name="clusterModeStatus" />
+ <element name="deviceStatus" />
+ <element name="emergencyEvent" />
+ <element name="eCallInfo" />
+ </enum>
+
+ <enum name="AppHMIType">
+ <element name="DEFAULT" />
+ <element name="COMMUNICATION" />
+ <element name="MEDIA" />
+ <element name="MESSAGING" />
+ <element name="NAVIGATION" />
+ <element name="INFORMATION" />
+ <element name="SOCIAL" />
+ <element name="BACKGROUND_PROCESS" />
+ <element name="TESTING" />
+ <element name="SYSTEM" />
+ </enum>
+ <!-- Common parameters end -->
+
+ <!-- app_policies section start -->
+
+ <typedef name="Strings" type="String" maxlength="255" array="true"
+ maxsize="255" />
+
+ <typedef name="AppHMITypes" type="AppHMIType" array="true"
+ maxsize="255" />
+
+ <struct name="ApplicationParams">
+ <param name="groups" type="Strings" />
+ <param name="nicknames" type="Strings" mandatory="false" />
+ <param name="AppHMIType" type="AppHMITypes" mandatory="false" />
+ <param name="memory_kb" type="Integer" minvalue="1" maxvalue="65225" mandatory="false"/>
+ <param name="watchdog_timer_ms" type="Integer" minvalue="1"
+ maxvalue="65225" mandatory="false"/>
+ <param name="certificate" type="String" minlength="0" maxlength="255"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="HmiLevels" type="HmiLevel" array="true"
+ maxsize="4" />
+ <typedef name="Parameters" type="Parameter" array="true"
+ maxsize="24" />
+
+ <struct name="RpcParameters">
+ <!-- maxsizes are equal to number of currently known elements of
+ given type -->
+ <param name="hmi_levels" type="HmiLevels" />
+ <param name="parameters" type="Parameters" mandatory="false" />
+ </struct>
+
+ <!-- maxsizes are equal to number of currently known elements of given
+ type -->
+ <typedef name="Rpc" type="RpcParameters" map="true" maxsize="50" />
+
+ <struct name="Rpcs">
+ <param name="user_consent_prompt" type="String" minlegth="1"
+ maxlength="255" mandatory="false"/>
+ <param name="rpcs" type="Rpc" null_values_allowed="true"/>
+ </struct>
+ <!-- app_policies section end -->
+
+ <!-- module_config section start -->
+ <!-- minlenght="10" since minimum expected is "http://a.b" -->
+ <typedef name="URL" type="String" minlength="10" maxlength="255"
+ array="true" minsize="1" maxsize="255" />
+
+ <typedef name="URLList" type="URL" map="true" minsize="1"
+ maxsize="255" />
+
+ <!-- max number of services is limited to 255 according to protocol specification -->
+ <typedef name="ServiceEndpoints" type="URLList" map="true"
+ minsize="1" maxsize="255" />
+
+ <typedef name="NumberOfNotificationsPerMinute" type="Integer"
+ map="true" maxsize="6" minvalue="0" maxvalue="255" />
+
+ <typedef name="SecondsBetweenRetries" type="Integer" array="true"
+ maxsize="10" minvalue="1" maxvalue="1000" />
+
+ <struct name="ModuleConfig">
+ <param name="device_certificates" type="String" minlength="1" maxlength="100" mandatory="false" map="true" minsize="1" maxsize="255" />
+ <param name="preloaded_pt" type="Boolean" mandatory="false" />
+ <param name="exchange_after_x_ignition_cycles" type="Integer"
+ maxvalue="255" />
+ <param name="exchange_after_x_kilometers" type="Integer"
+ maxvalue="4294967296" />
+ <param name="exchange_after_x_days" type="Integer"
+ maxvalue="255" />
+ <param name="timeout_after_x_seconds" type="Integer"
+ maxvalue="65535" />
+ <param name="seconds_between_retries" type="SecondsBetweenRetries" />
+ <param name="endpoints" type="ServiceEndpoints" />
+ <param name="notifications_per_minute_by_priority" type="NumberOfNotificationsPerMinute" />
+ <param name="vehicle_make" type="String" maxlength="100"
+ mandatory="false" />
+ <param name="vehicle_model" type="String" maxlength="100"
+ mandatory="false" />
+ <param name="vehicle_year" type="Integer" minvalue="1900" maxvalue="2020"
+ mandatory="false" />
+ </struct>
+ <!-- module_config section end -->
+
+ <!-- consumer_friendly_messages section start -->
+ <struct name="MessageString">
+ <param name="line1" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="line2" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="tts" type="String" maxlength="65535" mandatory="false" />
+ <param name="label" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="textBody" type="String" maxlength="500"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="Languages" map="true" type="MessageString"
+ maxsize="500" mandatory="false" />
+
+ <struct name="MessageLanguages">
+ <param name="languages" type="Languages" />
+ </struct>
+
+ <typedef name="Messages" map="true" type="MessageLanguages"
+ maxsize="255" />
+
+ <struct name="ConsumerFriendlyMessages">
+ <param name="version" type="String" maxlength="100" />
+ <param name="messages" type="Messages" mandatory="false" />
+ </struct>
+ <!-- consumer_friendly_messages section end -->
+
+ <!-- module_meta section start -->
+ <struct name="ModuleMeta">
+ </struct>
+ <!-- module_meta section end -->
+
+ <!-- usage_and_error_counts section start -->
+ <struct name="AppLevel">
+ </struct>
+
+ <typedef name="AppLevels" type="AppLevel" map="true" maxsize="255" />
+
+ <struct name="UsageAndErrorCounts">
+ <param name="app_level" type="AppLevels" mandatory="false" />
+ </struct>
+ <!-- usage_and_error_counts section end -->
+
+ <!-- device_data section start -->
+ <struct name="DeviceParams">
+ </struct>
+ <!-- device_data section end -->
+
+ <!-- policy_table section start -->
+ <typedef name="ApplicationPolicies" map="true" type="ApplicationParams" null_values_allowed="true" minsize="1" maxsize="1000" />
+
+ <typedef name="FunctionalGroupings" map="true" type="Rpcs"
+ minsize="1" maxsize="255" />
+
+ <typedef name="DeviceData" map="true" type="DeviceParams"
+ maxsize="255" />
+
+ <struct name="PolicyTable">
+ <!-- maxsize for app_policies can be changed, if necessary -->
+ <param name="app_policies" type="ApplicationPolicies" />
+ <param name="functional_groupings" type="FunctionalGroupings" />
+ <param name="consumer_friendly_messages" type="ConsumerFriendlyMessages" />
+ <param name="module_config" type="ModuleConfig" />
+ <param name="module_meta" type="ModuleMeta" mandatory="false"/>
+ <param name="usage_and_error_counts" type="UsageAndErrorCounts" mandatory="false" />
+ <param name="device_data" type="DeviceData" mandatory="false" />
+ </struct>
+ <!-- policy_table section end -->
+
+ <!-- Root element -->
+ <struct name="Table">
+ <param name="policy_table" type="PolicyTable" />
+ </struct>
+
+</interface>
diff --git a/src/components/policy/src/policy/policy_table_interface_ext.xml b/src/components/policy/src/policy/policy_table_interface_ext.xml
new file mode 100644
index 000000000..1f126a7df
--- /dev/null
+++ b/src/components/policy/src/policy/policy_table_interface_ext.xml
@@ -0,0 +1,279 @@
+<?xml version="1.0" standalone="no"?>
+<?xml-stylesheet type="text/xml" href="protocol2html.xsl"?>
+
+<interface name="policy table interface base" version="0.0"
+ date="2014-01-23">
+
+ <!-- Common parameters start -->
+ <enum name="Priority">
+ <element name="EMERGENCY" />
+ <element name="NAVIGATION" />
+ <element name="VOICECOM" />
+ <element name="COMMUNICATION" />
+ <element name="NORMAL" />
+ <element name="NONE" />
+ </enum>
+
+ <enum name="HmiLevel">
+ <element name="BACKGROUND" />
+ <element name="FULL" />
+ <element name="LIMITED" />
+ <element name="NONE" />
+ </enum>
+
+ <enum name="Parameter">
+ <element name="gps" />
+ <element name="speed" />
+ <element name="engineTorque" />
+ <element name="externalTemperature" />
+ <element name="fuelLevel" />
+ <element name="fuelLevel_State" />
+ <element name="headLampStatus" />
+ <element name="instantFuelConsumption" />
+ <element name="odometer" />
+ <element name="tirePressure" />
+ <element name="wiperStatus" />
+ <element name="vin" />
+ <element name="accPedalPosition" />
+ <element name="beltStatus" />
+ <element name="driverBraking" />
+ <element name="prndl" />
+ <element name="rpm" />
+ <element name="steeringWheelAngle" />
+ <element name="myKey" />
+ <element name="airbagStatus" />
+ <element name="bodyInformation" />
+ <element name="clusterModeStatus" />
+ <element name="deviceStatus" />
+ <element name="emergencyEvent" />
+ <element name="eCallInfo" />
+ </enum>
+
+ <enum name="AppHMIType">
+ <element name="DEFAULT" />
+ <element name="COMMUNICATION" />
+ <element name="MEDIA" />
+ <element name="MESSAGING" />
+ <element name="NAVIGATION" />
+ <element name="INFORMATION" />
+ <element name="SOCIAL" />
+ <element name="BACKGROUND_PROCESS" />
+ <element name="TESTING" />
+ <element name="SYSTEM" />
+ </enum>
+ <!-- Common parameters end -->
+
+ <!-- app_policies section start -->
+
+ <typedef name="Strings" type="String" maxlength="255" array="true"
+ maxsize="255" />
+
+ <typedef name="AppHMITypes" type="AppHMIType" array="true"
+ maxsize="255" />
+
+ <struct name="ApplicationParams">
+ <param name="groups" type="Strings" />
+ <param name="nicknames" type="Strings" mandatory="false" />
+ <param name="preconsented_groups" type="Strings" mandatory="false" />
+ <param name="AppHMIType" type="AppHMITypes" mandatory="false" />
+ <param name="priority" type="Priority" />
+ <param name="default_hmi" type="HmiLevel" />
+ <param name="keep_context" type="Boolean" />
+ <param name="steal_focus" type="Boolean" />
+ <param name="memory_kb" type="Integer" minvalue="1" maxvalue="65225" mandatory="false"/>
+ <param name="watchdog_timer_ms" type="Integer" minvalue="1"
+ maxvalue="65225" mandatory="false"/>
+ <param name="certificate" type="String" minlength="0" maxlength="255"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="HmiLevels" type="HmiLevel" array="true"
+ maxsize="4" />
+ <typedef name="Parameters" type="Parameter" array="true"
+ maxsize="24" />
+
+ <struct name="RpcParameters">
+ <!-- maxsizes are equal to number of currently known elements of
+ given type -->
+ <param name="hmi_levels" type="HmiLevels" />
+ <param name="parameters" type="Parameters" mandatory="false" />
+ </struct>
+
+ <!-- maxsizes are equal to number of currently known elements of given
+ type -->
+ <typedef name="Rpc" type="RpcParameters" map="true" maxsize="50" null_values_allowed="true" />
+
+ <struct name="Rpcs">
+ <param name="user_consent_prompt" type="String" minlegth="1"
+ maxlength="255" mandatory="false"/>
+ <param name="rpcs" type="Rpc" />
+ </struct>
+ <!-- app_policies section end -->
+
+ <!-- module_config section start -->
+ <!-- minlenght="10" since minimum expected is "http://a.b" -->
+ <typedef name="URL" type="String" minlength="10" maxlength="255"
+ array="true" minsize="1" maxsize="255" />
+
+ <typedef name="URLList" type="URL" map="true" minsize="1"
+ maxsize="255" />
+
+ <!-- max number of services is limited to 255 according to protocol specification -->
+ <typedef name="ServiceEndpoints" type="URLList" map="true"
+ minsize="1" maxsize="255" />
+
+ <typedef name="NumberOfNotificationsPerMinute" type="Integer"
+ map="true" maxsize="6" minvalue="0" maxvalue="255" />
+
+ <typedef name="SecondsBetweenRetries" type="Integer" array="true"
+ maxsize="10" minvalue="1" maxvalue="1000" />
+
+ <struct name="ModuleConfig">
+ <param name="device_certificates" type="String" minlength="1" maxlength="100" mandatory="false" map="true" minsize="1" maxsize="255" />
+ <param name="preloaded_pt" type="Boolean" mandatory="false" />
+ <param name="exchange_after_x_ignition_cycles" type="Integer"
+ maxvalue="255" />
+ <param name="exchange_after_x_kilometers" type="Integer"
+ maxvalue="4294967296" />
+ <param name="exchange_after_x_days" type="Integer"
+ maxvalue="255" />
+ <param name="timeout_after_x_seconds" type="Integer"
+ maxvalue="65535" />
+ <param name="seconds_between_retries" type="SecondsBetweenRetries" />
+ <param name="endpoints" type="ServiceEndpoints" />
+ <param name="notifications_per_minute_by_priority" type="NumberOfNotificationsPerMinute" />
+ <param name="vehicle_make" type="String" maxlength="100"
+ mandatory="false" />
+ <param name="vehicle_model" type="String" maxlength="100"
+ mandatory="false" />
+ <param name="vehicle_year" type="Integer" minvalue="1900" maxvalue="2020"
+ mandatory="false" />
+ </struct>
+ <!-- module_config section end -->
+
+ <!-- consumer_friendly_messages section start -->
+ <struct name="MessageString">
+ <param name="line1" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="line2" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="tts" type="String" maxlength="65535" mandatory="false" />
+ <param name="label" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="textBody" type="String" maxlength="500"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="Languages" map="true" type="MessageString"
+ maxsize="500" mandatory="false" />
+
+ <struct name="MessageLanguages">
+ <param name="languages" type="Languages" />
+ </struct>
+
+ <typedef name="Messages" map="true" type="MessageLanguages"
+ maxsize="255" />
+
+ <struct name="ConsumerFriendlyMessages">
+ <param name="version" type="String" maxlength="100" />
+ <param name="messages" type="Messages" mandatory="false" />
+ </struct>
+ <!-- consumer_friendly_messages section end -->
+
+ <!-- module_meta section start -->
+ <struct name="ModuleMeta">
+ <param name="ccpu_version" type="String" maxlength="250" mandatory="false"/>
+ <param name="language" type="String" maxlength="250" mandatory="false"/>
+ <param name="wers_country_code" type="String" maxlength="250" mandatory="false"/>
+ <param name="pt_exchanged_at_odometer_x" type="Integer" minvalue="0" maxvalue="65535" mandatory="false"/>
+ <param name="pt_exchanged_x_days_after_epoch" type="Integer" minvalue="0" maxvalue="65535" mandatory="false"/>
+ <param name="ignition_cycles_since_last_exchange" type="Integer" minvalue="0" maxvalue="65535" mandatory="false"/>
+ <param name="vin" type="String" maxlength="250" mandatory="false"/>
+ </struct>
+ <!-- module_meta section end -->
+
+ <!-- usage_and_error_counts section start -->
+ <struct name="AppLevel">
+ <param name="minutes_in_hmi_full" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="app_registration_language_gui" type="String" minlength="1" maxlength="10" />
+ <param name="app_registration_language_vui" type="String" minlength="1" maxlength="10" />
+ <param name="count_of_rfcom_limit_reached" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="minutes_in_hmi_limited" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="minutes_in_hmi_background" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="minutes_in_hmi_none" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_user_selections" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_rejections_sync_out_of_memory" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_rejections_nickname_mismatch" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_rejections_duplicate_name" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_rejected_rpc_calls" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_rpcs_sent_in_hmi_none" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_removals_for_bad_behavior" type="Integer" minvalue="0" maxvalue="65535" />
+ <param name="count_of_run_attempts_while_revoked" type="Integer" minvalue="0" maxvalue="65535" />
+ </struct>
+
+ <typedef name="AppLevels" type="AppLevel" map="true"
+ maxsize="255" />
+
+ <struct name="UsageAndErrorCounts">
+ <param name="count_of_iap_buffer_full" type="Integer" minvalue="0" maxvalue="65535" mandatory="false" />
+ <param name="count_sync_out_of_memory" type="Integer" minvalue="0" maxvalue="65535" mandatory="false" />
+ <param name="count_of_sync_reboots" type="Integer" minvalue="0" maxvalue="65535" mandatory="false" />
+ <param name="app_level" type="AppLevels" mandatory="false" />
+ </struct>
+ <!-- usage_and_error_counts section end -->
+
+ <!-- device_data section start -->
+ <enum name="Input" scope="internal">
+ <element name="GUI" />
+ <element name="VUI" />
+ </enum>
+
+ <typedef name="ConsentGroups" scope="internal" type="Boolean" map="true" maxsize="255" mandatory="false"/>
+
+ <struct name="ConsentRecords" scope="internal">
+ <param name="consent_groups" type="ConsentGroups" mandatory="false"/>
+ <param name="input" type="Input" mandatory="false" />
+ <param name="time_stamp" type="String" maxlength="255" mandatory="false" />
+ </struct>
+
+ <typedef name="UserConsentRecords" scope="internal" map="true" type="ConsentRecords" minsize="0" maxsize="1000"/>
+
+ <struct name="DeviceParams" scope="internal">
+ <param name="hardware" type="String" maxlength="255" mandatory="false"/>
+ <param name="firmware_rev" type="String" maxlength="255" nullable="true" mandatory="false"/>
+ <param name="os" type="String" maxlength="255" mandatory="false"/>
+ <param name="os_version" type="String" maxlength="255" mandatory="false"/>
+ <param name="carrier" type="String" maxlength="255" nullable="true" mandatory="false"/>
+ <param name="user_consent_records" type="UserConsentRecords" mandatory="false"/>
+ <param name="max_number_rfcom_ports" type="Integer" maxvalue="255" mandatory="false"/>
+ </struct>
+ <!-- device_data section end -->
+
+ <!-- policy_table section start -->
+ <typedef name="ApplicationPolicies" map="true" type="ApplicationParams"
+ null_values_allowed="true" minsize="1" maxsize="1000" />
+
+ <typedef name="FunctionalGroupings" map="true" type="Rpcs"
+ minsize="1" maxsize="255" />
+
+ <typedef name="DeviceData" map="true" type="DeviceParams"
+ maxsize="255" />
+
+ <struct name="PolicyTable">
+ <!-- maxsize for app_policies can be changed, if necessary -->
+ <param name="app_policies" type="ApplicationPolicies" />
+ <param name="functional_groupings" type="FunctionalGroupings" />
+ <param name="consumer_friendly_messages" type="ConsumerFriendlyMessages" />
+ <param name="module_config" type="ModuleConfig" />
+ <param name="module_meta" type="ModuleMeta" mandatory="false"/>
+ <param name="usage_and_error_counts" type="UsageAndErrorCounts" mandatory="false" />
+ <param name="device_data" type="DeviceData" mandatory="false" />
+ </struct>
+ <!-- policy_table section end -->
+
+ <!-- Root element -->
+ <struct name="Table">
+ <param name="policy_table" type="PolicyTable" />
+ </struct>
+
+</interface>
diff --git a/src/components/policy/src/policy/qdb_wrapper/CMakeLists.txt b/src/components/policy/src/policy/qdb_wrapper/CMakeLists.txt
new file mode 100644
index 000000000..8b06351e2
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (c) 2013, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+set(target dbms)
+
+include_directories(include)
+
+set(SOURCES
+ src/sql_database.cc
+ src/sql_query.cc
+ src/sql_error.cc
+)
+
+add_library(${target} ${SOURCES})
+target_link_libraries(${target} qdb Utils)
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/policy.ini DESTINATION ${CMAKE_BINARY_DIR}/src/appMain)
+ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/qdbserver.sh DESTINATION ${CMAKE_BINARY_DIR}/src/appMain)
+endif ()
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ install(FILES policy.ini DESTINATION bin)
+ install(FILES qdbserver.sh DESTINATION bin
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
+ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+endif () \ No newline at end of file
diff --git a/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_database.h b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_database.h
new file mode 100644
index 000000000..90df8f0b6
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_database.h
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_DATABASE_H_
+#define SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_DATABASE_H_
+
+#include <qdb/qdb.h>
+#include <string>
+#include "qdb_wrapper/sql_error.h"
+#include "utils/lock.h"
+
+namespace policy {
+namespace dbms {
+
+class SQLQuery;
+
+/**
+ * Represents a connection to a database.
+ */
+class SQLDatabase {
+ public:
+ explicit SQLDatabase(const std::string& db_name);
+ ~SQLDatabase();
+
+ /**
+ * Opens connection to the temporary in-memory database
+ * @return true if successfully
+ */
+ bool Open();
+
+ /**
+ * Closes connection to the database
+ */
+ void Close();
+
+ /**
+ * Begins a transaction on the database
+ * @return true if successfully
+ */
+ bool BeginTransaction();
+
+ /**
+ * Commits a transaction to the database
+ * @return true if successfully
+ */
+ bool CommitTransaction();
+
+ /**
+ * Rolls back a transaction on the database
+ * @return true if successfully
+ */
+ bool RollbackTransaction();
+
+ /**
+ * Gets information about the last error that occurred on the database
+ * @return last error
+ */
+ SQLError LastError() const;
+
+ protected:
+ /**
+ * Gets connection to the SQLite database
+ * @return pointer to connection
+ */
+ qdb_hdl_t* conn() const;
+
+ private:
+ /**
+ * The connection to the SQLite database
+ */
+ qdb_hdl_t* conn_;
+
+ /**
+ * Lock for guarding connection to database
+ */
+ sync_primitives::Lock conn_lock_;
+
+ /**
+ * The database name
+ */
+ std::string db_name_;
+
+ /**
+ * The last error that occurred on the database
+ */
+ Error error_;
+
+ /**
+ * Execs query for internal using in this class
+ * @param query sql query without return results
+ * @return true if query was executed successfully
+ */
+ inline bool Exec(const std::string& query);
+
+ friend class SQLQuery;
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_DATABASE_H_
diff --git a/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_error.h b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_error.h
new file mode 100644
index 000000000..0f5bd36b4
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_error.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_ERROR_H_
+#define SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_ERROR_H_
+
+#include <string>
+
+namespace policy {
+namespace dbms {
+
+typedef enum Error {
+ OK = 0, /* Successful result */
+ ERROR /* Error */
+} Error;
+
+/**
+ * Provides SQL database error information
+ */
+class SQLError {
+ public:
+ SQLError(Error number, const std::string& text = "");
+
+ /**
+ * Gets number of error
+ * @return error number
+ */
+ Error number() const;
+
+ /**
+ * Gets text description of the error
+ * @return text
+ */
+ std::string text() const;
+
+ private:
+ /**
+ * Number of the error
+ */
+ Error number_;
+
+ /**
+ * Description of the error
+ */
+ mutable std::string text_;
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_ERROR_H_
diff --git a/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_query.h b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_query.h
new file mode 100644
index 000000000..f0b014e47
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/include/qdb_wrapper/sql_query.h
@@ -0,0 +1,251 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_QUERY_H_
+#define SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_QUERY_H_
+
+#include <stdint.h>
+#include <qdb/qdb.h>
+#include <string>
+#include <vector>
+#include <utility>
+#include "qdb_wrapper/sql_error.h"
+#include "utils/lock.h"
+
+namespace policy {
+namespace dbms {
+
+class SQLDatabase;
+
+/**
+ * Provides a means of executing and manipulating SQL statements
+ */
+class SQLQuery {
+ public:
+ explicit SQLQuery(SQLDatabase* db);
+ ~SQLQuery();
+
+ /**
+ * Prepares the SQL query for executing
+ * @param query the utf-8 string of SQL query
+ * @return true if successfully
+ */
+ bool Prepare(const std::string& query);
+
+ /**
+ * Resets the binds of query for re-executing
+ * @return true if successfully
+ */
+ bool Reset();
+
+ /**
+ * Deletes prepared SQL query
+ */
+ void Finalize();
+
+ /**
+ * Executes SQL query without make binds
+ * @param query the utf-8 string of SQL query
+ * @return true if successfull
+ */
+ bool Exec(const std::string& query);
+
+ /**
+ * Executes prepared SQL query and positions the query on the first record
+ * @return true if successfull
+ */
+ bool Exec();
+
+ /**
+ * Retrieves the next record in the result, if available,
+ * and positions the query on the retrieved record
+ * @return true if record was retrieved successfully, false if a error was
+ * or the result is empty or was retrieves last record
+ */
+ bool Next();
+
+ /**
+ * Binds null in the prepared query
+ * @param pos position of param in the query
+ */
+ void Bind(int pos);
+
+ /**
+ * Binds int value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, int value);
+
+ /**
+ * Binds int64_t value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, int64_t value);
+
+ /**
+ * Binds double value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, double value);
+
+ /**
+ * Binds bool value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, bool value);
+
+ /**
+ * Binds string in the prepared query.
+ * @param pos position of param in the query
+ * @param value utf-8 string
+ */
+ void Bind(int pos, const std::string& value);
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return boolean value
+ */
+ bool GetBoolean(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return integer value
+ */
+ int GetInteger(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return double value
+ */
+ double GetDouble(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return string value
+ */
+ std::string GetString(int pos) const;
+
+ /**
+ * Checks if value is null
+ * @param pos position of value
+ * @return true if value is null
+ */
+ bool IsNull(int pos) const;
+
+ /**
+ * Gets last id of insert row
+ * @return id of insert row
+ */
+ int64_t LastInsertId() const;
+
+ /**
+ * Gets string of the query
+ * @return string of the query
+ */
+ const std::string& query() const;
+
+ /**
+ * Gets information about the last error that occurred on the database
+ * @return last error
+ */
+ SQLError LastError() const;
+
+ private:
+ /**
+ * The instantiation of database
+ */
+ SQLDatabase* db_;
+
+ /**
+ * The string of query
+ */
+ std::string query_;
+
+ /**
+ * The id of SQL statement in QDB
+ */
+ int statement_;
+
+ /**
+ * Containers for keeping bind data
+ */
+ std::vector<std::pair<int, int64_t> > int_binds_;
+ std::vector<std::pair<int, double> > double_binds_;
+ std::vector<std::pair<int, std::string> > string_binds_;
+ std::vector<int> null_binds_;
+
+ /**
+ * The array for binging data to the prepare query
+ */
+ qdb_binding_t* bindings_;
+
+ /**
+ * Lock for guarding bindings
+ */
+ sync_primitives::Lock bindings_lock_;
+
+ /**
+ * The result of query
+ */
+ qdb_result_t *result_;
+
+ /**
+ * The current row in result for select
+ */
+ int current_row_;
+
+ /**
+ * The number of rows in a result
+ */
+ int rows_;
+
+ /**
+ * The last error that occurred with this query
+ */
+ Error error_;
+
+ int SetBinds();
+ bool Result();
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_QDB_WRAPPER_INCLUDE_QDB_WRAPPER_SQL_QUERY_H_
diff --git a/src/components/policy/src/policy/qdb_wrapper/policy.ini b/src/components/policy/src/policy/qdb_wrapper/policy.ini
new file mode 100644
index 000000000..e22a07e81
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/policy.ini
@@ -0,0 +1,4 @@
+# This config file for QDB
+# Format see in manual of QNX
+[policy]
+Filename=policy.sqlite \ No newline at end of file
diff --git a/src/components/policy/src/policy/qdb_wrapper/qdbserver.sh b/src/components/policy/src/policy/qdb_wrapper/qdbserver.sh
new file mode 100755
index 000000000..40ecbea51
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/qdbserver.sh
@@ -0,0 +1,6 @@
+# This script star QDB server for SDL
+# Need superuser to start qdb
+
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/qnx650/target/qnx6/x86/usr/lib
+export LD_LIBRARY_PATH
+/usr/sbin/qdb -c policy.ini
diff --git a/src/components/policy/src/policy/qdb_wrapper/src/sql_database.cc b/src/components/policy/src/policy/qdb_wrapper/src/sql_database.cc
new file mode 100644
index 000000000..e7dc905f6
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/src/sql_database.cc
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qdb_wrapper/sql_database.h"
+
+namespace policy {
+namespace dbms {
+
+SQLDatabase::SQLDatabase(const std::string& db_name)
+ : conn_(NULL),
+ db_name_(db_name),
+ error_(Error::OK) {
+}
+
+SQLDatabase::~SQLDatabase() {
+ Close();
+}
+
+bool SQLDatabase::Open() {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ if (conn_) return true;
+ conn_ = qdb_connect(db_name_.c_str(), 0);
+ if (conn_ == NULL) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ return true;
+}
+
+void SQLDatabase::Close() {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ if (conn_) {
+ if (qdb_disconnect(conn_) != -1) {
+ conn_ = NULL;
+ } else {
+ error_ = Error::ERROR;
+ }
+ }
+}
+
+bool SQLDatabase::BeginTransaction() {
+ return Exec("BEGIN TRANSACTION");
+}
+
+bool SQLDatabase::CommitTransaction() {
+ return Exec("COMMIT TRANSACTION");
+}
+
+bool SQLDatabase::RollbackTransaction() {
+ return Exec("ROLLBACK TRANSACTION");
+}
+
+bool SQLDatabase::Exec(const std::string& query) {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ if (qdb_statement(conn_, query.c_str()) == -1) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ return true;
+}
+
+SQLError SQLDatabase::LastError() const {
+ return SQLError(error_, qdb_geterrmsg(conn_));
+}
+
+qdb_hdl_t* SQLDatabase::conn() const {
+ return conn_;
+}
+
+} // namespace dbms
+} // namespace policy
diff --git a/src/components/policy/src/policy/qdb_wrapper/src/sql_error.cc b/src/components/policy/src/policy/qdb_wrapper/src/sql_error.cc
new file mode 100644
index 000000000..7dc31c2c2
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/src/sql_error.cc
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qdb_wrapper/sql_error.h"
+
+namespace policy {
+namespace dbms {
+
+SQLError::SQLError(Error number, const std::string& text)
+ : number_(number),
+ text_(text) {
+}
+
+Error SQLError::number() const {
+ return number_;
+}
+
+std::string SQLError::text() const {
+ if (!text_.empty()) {
+ return text_;
+ }
+ switch (number_) {
+ case OK:
+ text_ = "Successful result";
+ break;
+ case ERROR:
+ text_ = "Error";
+ break;
+ default:
+ text_ = "Unknown error";
+ }
+ return text_;
+}
+
+} // namespace dbms
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/qdb_wrapper/src/sql_query.cc b/src/components/policy/src/policy/qdb_wrapper/src/sql_query.cc
new file mode 100644
index 000000000..0bd709ed8
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/src/sql_query.cc
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qdb_wrapper/sql_query.h"
+#include <string.h>
+#include <cassert>
+#include <algorithm>
+#include "qdb_wrapper/sql_database.h"
+
+namespace policy {
+namespace dbms {
+
+class SetBindInteger {
+ public:
+ explicit SetBindInteger(qdb_binding_t* array)
+ : array_(array) {
+ }
+ void operator()(const std::pair<int, int64_t>& x) {
+ // In QDB the number of position for binding starts since 1.
+ QDB_SETARRAYBIND_INT(array_, x.first + 1, x.second);
+ }
+ private:
+ qdb_binding_t* array_;
+};
+
+class SetBindReal {
+ public:
+ explicit SetBindReal(qdb_binding_t* array)
+ : array_(array) {
+ }
+ void operator()(const std::pair<int, double>& x) {
+ // In QDB the number of position for binding starts since 1.
+ QDB_SETBIND(&(array_[x.first + 1]), x.first + 1, QDB_REAL,
+ (sizeof(x.second)), &(x.second));
+ }
+ private:
+ qdb_binding_t* array_;
+};
+
+class SetBindText {
+ public:
+ explicit SetBindText(qdb_binding_t* array)
+ : array_(array) {
+ }
+ void operator()(const std::pair<int, std::string>& x) {
+ // In QDB the number of position for binding starts since 1.
+ QDB_SETARRAYBIND_TEXT(array_, x.first + 1, x.second.c_str());
+ }
+ private:
+ qdb_binding_t* array_;
+};
+
+class SetBindNull {
+ public:
+ explicit SetBindNull(qdb_binding_t* array)
+ : array_(array) {
+ }
+ void operator()(int x) {
+ // In QDB the number of position for binding starts since 1.
+ QDB_SETARRAYBIND_NULL(array_, x + 1);
+ }
+ private:
+ qdb_binding_t* array_;
+};
+
+SQLQuery::SQLQuery(SQLDatabase* db)
+ : db_(db),
+ query_(""),
+ statement_(-1),
+ bindings_(NULL),
+ result_(NULL),
+ current_row_(0),
+ rows_(0),
+ error_(Error::OK) {
+}
+
+SQLQuery::~SQLQuery() {
+ Finalize();
+ db_->Close();
+ delete db_;
+}
+
+bool SQLQuery::Prepare(const std::string& query) {
+ query_ = query;
+ statement_ = qdb_stmt_init(db_->conn(), query.c_str(), query.length() + 1);
+ if (statement_ == -1) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ return true;
+}
+
+int SQLQuery::SetBinds() {
+ int binding_count = int_binds_.size() + double_binds_.size()
+ + string_binds_.size() + null_binds_.size();
+
+ bindings_ = new qdb_binding_t[binding_count];
+
+ std::for_each(int_binds_.begin(), int_binds_.end(),
+ SetBindInteger(bindings_));
+ std::for_each(double_binds_.begin(), double_binds_.end(),
+ SetBindReal(bindings_));
+ std::for_each(string_binds_.begin(), string_binds_.end(),
+ SetBindText(bindings_));
+ std::for_each(null_binds_.begin(), null_binds_.end(), SetBindNull(bindings_));
+
+ return binding_count;
+}
+
+bool SQLQuery::Result() {
+ result_ = qdb_getresult(db_->conn());
+ if (!result_) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ rows_ = qdb_rows(result_);
+ if (rows_ == -1) {
+ rows_ = 0;
+ error_ = Error::ERROR;
+ return false;
+ }
+ return true;
+}
+
+bool SQLQuery::Exec() {
+ sync_primitives::AutoLock auto_lock(bindings_lock_);
+ if (result_)
+ return true;
+
+ current_row_ = 0;
+ int binding_count = SetBinds();
+ if (qdb_stmt_exec(db_->conn(), statement_, bindings_, binding_count) == -1) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ return Result();
+}
+
+bool SQLQuery::Next() {
+ ++current_row_;
+ return Exec() && current_row_ < rows_;
+}
+
+bool SQLQuery::Reset() {
+ sync_primitives::AutoLock auto_lock(bindings_lock_);
+ int_binds_.clear();
+ double_binds_.clear();
+ string_binds_.clear();
+ null_binds_.clear();
+ delete[] bindings_;
+ bindings_ = NULL;
+ rows_ = 0;
+ current_row_ = 0;
+ if (result_ && qdb_freeresult(result_) == -1) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ result_ = NULL;
+ return true;
+}
+
+void SQLQuery::Finalize() {
+ if (Reset() && qdb_stmt_free(db_->conn(), statement_) != -1) {
+ statement_ = 0;
+ } else {
+ error_ = Error::ERROR;
+ }
+}
+
+bool SQLQuery::Exec(const std::string& query) {
+ query_ = query;
+ if (qdb_statement(db_->conn(), query.c_str()) == -1) {
+ error_ = Error::ERROR;
+ return false;
+ }
+ return true;
+}
+
+void SQLQuery::Bind(int pos, int value) {
+ int_binds_.push_back(std::make_pair(pos, value));
+}
+
+void SQLQuery::Bind(int pos, int64_t value) {
+ int_binds_.push_back(std::make_pair(pos, value));
+}
+
+void SQLQuery::Bind(int pos, double value) {
+ double_binds_.push_back(std::make_pair(pos, value));
+}
+
+void SQLQuery::Bind(int pos, bool value) {
+ Bind(pos, static_cast<int>(value));
+}
+
+void SQLQuery::Bind(int pos, const std::string& value) {
+ string_binds_.push_back(std::make_pair(pos, value));
+}
+
+void SQLQuery::Bind(int pos) {
+ null_binds_.push_back(pos);
+}
+
+bool SQLQuery::GetBoolean(int pos) const {
+ return static_cast<bool>(GetInteger(pos));
+}
+
+int SQLQuery::GetInteger(int pos) const {
+ return *static_cast<int*>(qdb_cell(result_, current_row_, pos));
+}
+
+double SQLQuery::GetDouble(int pos) const {
+ return *static_cast<double*>(qdb_cell(result_, current_row_, pos));
+}
+
+std::string SQLQuery::GetString(int pos) const {
+ void* str = qdb_cell(result_, current_row_, pos);
+ return str ? static_cast<const char*>(str) : "";
+}
+
+bool SQLQuery::IsNull(int pos) const {
+ return qdb_cell_type(result_, current_row_, pos) == QDB_NULL;
+}
+
+const std::string& SQLQuery::query() const {
+ // TODO(KKolodiy): may return string query with value of arguments
+ return query_;
+}
+
+SQLError SQLQuery::LastError() const {
+ return SQLError(error_, qdb_geterrmsg(db_->conn()));
+}
+
+int64_t SQLQuery::LastInsertId() const {
+ return qdb_last_insert_rowid(db_->conn(), result_);
+}
+
+} // namespace dbms
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/specification.txt b/src/components/policy/src/policy/specification.txt
new file mode 100644
index 000000000..b00a2932e
--- /dev/null
+++ b/src/components/policy/src/policy/specification.txt
@@ -0,0 +1 @@
+https://adc.luxoft.com/confluence/display/APPLINK/Policy+Manager+Specification
diff --git a/src/components/policy/src/policy/sqlite_wrapper/CMakeLists.txt b/src/components/policy/src/policy/sqlite_wrapper/CMakeLists.txt
new file mode 100644
index 000000000..a541ca8cd
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (c) 2013, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+set(target dbms)
+
+find_package(Sqlite3 REQUIRED)
+
+include_directories(include)
+
+set(SOURCES
+ src/sql_database.cc
+ src/sql_query.cc
+ src/sql_error.cc
+)
+
+add_library(${target} ${SOURCES})
+target_link_libraries(${target} sqlite3 Utils) \ No newline at end of file
diff --git a/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_database.h b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_database.h
new file mode 100644
index 000000000..bd4f22db9
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_database.h
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_DATABASE_H_
+#define SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_DATABASE_H_
+
+#include <string>
+#include "sqlite_wrapper/sql_error.h"
+#include "utils/lock.h"
+
+struct sqlite3;
+
+namespace policy {
+namespace dbms {
+
+class SQLQuery;
+
+/**
+ * Represents a connection to a database.
+ */
+class SQLDatabase {
+ public:
+ SQLDatabase();
+ explicit SQLDatabase(const std::string& filename);
+ ~SQLDatabase();
+
+ /**
+ * Opens connection to the temporary in-memory database
+ * @return true if successfully
+ */
+ bool Open();
+
+ /**
+ * Closes connection to the database
+ */
+ void Close();
+
+ /**
+ * Begins a transaction on the database
+ * @return true if successfully
+ */
+ bool BeginTransaction();
+
+ /**
+ * Commits a transaction to the database
+ * @return true if successfully
+ */
+ bool CommitTransaction();
+
+ /**
+ * Rolls back a transaction on the database
+ * @return true if successfully
+ */
+ bool RollbackTransaction();
+
+ /**
+ * Gets information about the last error that occurred on the database
+ * @return last error
+ */
+ SQLError LastError() const;
+
+ /**
+ * Sets path to database
+ * If the database is already opened then need reopen it
+ */
+ void set_path(const std::string& path);
+
+ protected:
+ /**
+ * Gets connection to the SQLite database
+ * @return pointer to connection
+ */
+ sqlite3* conn() const;
+
+ private:
+ /**
+ * The connection to the SQLite database
+ */
+ sqlite3* conn_;
+
+ /**
+ * Lock for guarding connection to database
+ */
+ sync_primitives::Lock conn_lock_;
+
+ /**
+ * The filename of database
+ */
+ std::string databasename_;
+
+ /**
+ * The last error that occurred on the database
+ */
+ int error_;
+
+ /**
+ * The temporary in-memory database
+ * @see SQLite manual
+ */
+ static const std::string kInMemory;
+
+ /**
+ * The extension of filename of database
+ */
+ static const std::string kExtension;
+
+ /**
+ * Execs query for internal using in this class
+ * @param query sql query without return results
+ * @return true if query was executed successfully
+ */
+ inline bool Exec(const std::string& query);
+
+ friend class SQLQuery;
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_DATABASE_H_
diff --git a/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_error.h b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_error.h
new file mode 100644
index 000000000..3b5fff3c1
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_error.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_ERROR_H_
+#define SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_ERROR_H_
+
+#include <string>
+
+namespace policy {
+namespace dbms {
+
+typedef enum Error {
+ OK = 0, /* Successful result */
+ ERROR, /* SQL error or missing database */
+ INTERNAL, /* Internal logic error in SQLite */
+ PERM, /* Access permission denied */
+ ABORT, /* Callback routine requested an abort */
+ BUSY, /* The database file is locked */
+ LOCKED, /* A table in the database is locked */
+ NOMEM, /* A malloc() failed */
+ READONLY, /* Attempt to write a readonly database */
+ INTERRUPT, /* Operation terminated by sqlite3_interrupt()*/
+ IOERR, /* Some kind of disk I/O error occurred */
+ CORRUPT, /* The database disk image is malformed */
+ NOTFOUND, /* Unknown opcode in sqlite3_file_control() */
+ FULL, /* Insertion failed because database is full */
+ CANTOPEN, /* Unable to open the database file */
+ PROTOCOL, /* Database lock protocol error */
+ EMPTY, /* Database is empty */
+ SCHEMA, /* The database schema changed */
+ TOOBIG, /* String or BLOB exceeds size limit */
+ CONSTRAINT, /* Abort due to constraint violation */
+ MISMATCH, /* Data type mismatch */
+ MISUSE, /* Library used incorrectly */
+ NOLFS, /* Uses OS features not supported on host */
+ AUTH, /* Authorization denied */
+ FORMAT, /* Auxiliary database format error */
+ RANGE, /* 2nd parameter to sqlite3_bind out of range */
+ NOTADB, /* File opened that is not a database file */
+ NOTICE, /* Notifications from sqlite3_log() */
+ WARNING, /* Warnings from sqlite3_log() */
+ ROW = 100, /* sqlite3_step() has another row ready */
+ DONE = 101 /* sqlite3_step() has finished executing */
+} Error;
+
+/**
+ * Provides SQL database error information
+ */
+class SQLError {
+ public:
+ SQLError(Error number, const std::string& text = "");
+
+ /**
+ * Gets number of error
+ * @return error number
+ */
+ Error number() const;
+
+ /**
+ * Gets text description of the error
+ * @return text
+ */
+ std::string text() const;
+
+ private:
+ /**
+ * Number of the error
+ */
+ Error number_;
+
+ /**
+ * Description of the error
+ */
+ mutable std::string text_;
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_ERROR_H_
diff --git a/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_query.h b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_query.h
new file mode 100644
index 000000000..939cd1341
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_query.h
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_QUERY_H_
+#define SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_QUERY_H_
+
+#include <stdint.h>
+#include <string>
+#include "sqlite_wrapper/sql_error.h"
+#include "utils/lock.h"
+
+struct sqlite3_stmt;
+
+namespace policy {
+namespace dbms {
+
+class SQLDatabase;
+
+/**
+ * Provides a means of executing and manipulating SQL statements
+ */
+class SQLQuery {
+ public:
+ explicit SQLQuery(SQLDatabase* db);
+ ~SQLQuery();
+
+ /**
+ * Prepares the SQL query for executing
+ * @param query the utf-8 string of SQL query
+ * @return true if successfully
+ */
+ bool Prepare(const std::string& query);
+
+ /**
+ * Resets the binds of query for re-executing
+ * @return true if successfully
+ */
+ bool Reset();
+
+ /**
+ * Deletes prepared SQL query
+ */
+ void Finalize();
+
+ /**
+ * Executes SQL query without make binds
+ * @param query the utf-8 string of SQL query
+ * @return true if successfull
+ */
+ bool Exec(const std::string& query);
+
+ /**
+ * Executes prepared SQL query and positions the query on the first record
+ * @return true if successfull
+ */
+ bool Exec();
+
+ /**
+ * Retrieves the next record in the result, if available,
+ * and positions the query on the retrieved record
+ * @return true if record was retrieved successfully, false if a error was
+ * or the result is empty or was retrieves last record
+ */
+ bool Next();
+
+ /**
+ * Binds null in the prepared query
+ * @param pos position of param in the query
+ */
+ void Bind(int pos);
+
+ /**
+ * Binds int value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, int value);
+
+ /**
+ * Binds int64_t value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, int64_t value);
+
+ /**
+ * Binds double value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, double value);
+
+ /**
+ * Binds bool value in the prepared query.
+ * @param pos position of param in the query
+ * @param value value of param
+ */
+ void Bind(int pos, bool value);
+
+ /**
+ * Binds string in the prepared query.
+ * @param pos position of param in the query
+ * @param value utf-8 string
+ */
+ void Bind(int pos, const std::string& value);
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return boolean value
+ */
+ bool GetBoolean(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return integer value
+ */
+ int GetInteger(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return double value
+ */
+ double GetDouble(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
+ * @return string value
+ */
+ std::string GetString(int pos) const;
+
+ /**
+ * Checks if value is null
+ * @param pos position of value
+ * @return true if value is null
+ */
+ bool IsNull(int pos) const;
+
+ /**
+ * Gets last id of insert row
+ * @return id of insert row
+ */
+ int64_t LastInsertId() const;
+
+ /**
+ * Gets string of the query
+ * @return string of the query
+ */
+ const std::string& query() const;
+
+ /**
+ * Gets information about the last error that occurred on the database
+ * @return last error
+ */
+ SQLError LastError() const;
+
+ private:
+ /**
+ * The instantiation of database
+ */
+ SQLDatabase& db_;
+
+ /**
+ * The string of query
+ */
+ std::string query_;
+
+ /**
+ * The SQL statement in SQLite
+ */
+ sqlite3_stmt* statement_;
+
+ /**
+ * Lock for guarding statement
+ */
+ sync_primitives::Lock statement_lock_;
+
+ /**
+ * The last error that occurred with this query
+ */
+ int error_;
+};
+
+} // namespace dbms
+} // namespace policy
+
+#endif // SRC_COMPONENTS_POLICY_SQLITE_WRAPPER_INCLUDE_SQLITE_WRAPPER_SQL_QUERY_H_
diff --git a/src/components/policy/src/policy/sqlite_wrapper/src/sql_database.cc b/src/components/policy/src/policy/sqlite_wrapper/src/sql_database.cc
new file mode 100644
index 000000000..95a1aaa6f
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/src/sql_database.cc
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sqlite_wrapper/sql_database.h"
+#include <sqlite3.h>
+
+namespace policy {
+namespace dbms {
+
+const std::string SQLDatabase::kInMemory = ":memory:";
+const std::string SQLDatabase::kExtension = ".sqlite";
+
+SQLDatabase::SQLDatabase()
+ : conn_(NULL),
+ databasename_(kInMemory),
+ error_(SQLITE_OK) {}
+
+SQLDatabase::SQLDatabase(const std::string& db_name)
+ : conn_(NULL),
+ databasename_(db_name + kExtension),
+ error_(SQLITE_OK) {}
+
+SQLDatabase::~SQLDatabase() {
+ Close();
+}
+
+bool SQLDatabase::Open() {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ if (conn_) return true;
+ error_ = sqlite3_open(databasename_.c_str(), &conn_);
+ return error_ == SQLITE_OK;
+}
+
+void SQLDatabase::Close() {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ error_ = sqlite3_close(conn_);
+ if (error_ == SQLITE_OK) {
+ conn_ = NULL;
+ }
+}
+
+bool SQLDatabase::BeginTransaction() {
+ return Exec("BEGIN TRANSACTION");
+}
+
+bool SQLDatabase::CommitTransaction() {
+ return Exec("COMMIT TRANSACTION");
+}
+
+bool SQLDatabase::RollbackTransaction() {
+ return Exec("ROLLBACK TRANSACTION");
+}
+
+bool SQLDatabase::Exec(const std::string& query) {
+ sync_primitives::AutoLock auto_lock(conn_lock_);
+ error_ = sqlite3_exec(conn_, query.c_str(), NULL, NULL, NULL);
+ return error_ == SQLITE_OK;
+}
+
+SQLError SQLDatabase::LastError() const {
+ return SQLError(Error(error_));
+}
+
+sqlite3* SQLDatabase::conn() const {
+ return conn_;
+}
+
+void SQLDatabase::set_path(const std::string& path) {
+ databasename_ = path + databasename_;
+}
+
+} // namespace dbms
+} // namespace policy
diff --git a/src/components/policy/src/policy/sqlite_wrapper/src/sql_error.cc b/src/components/policy/src/policy/sqlite_wrapper/src/sql_error.cc
new file mode 100644
index 000000000..0f87ef2cc
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/src/sql_error.cc
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sqlite_wrapper/sql_error.h"
+
+namespace policy {
+namespace dbms {
+
+SQLError::SQLError(Error number, const std::string& text)
+ : number_(number),
+ text_(text) {
+}
+
+Error SQLError::number() const {
+ return number_;
+}
+
+std::string SQLError::text() const {
+ if (!text_.empty()) {
+ return text_;
+ }
+ switch (number_) {
+ case OK:
+ text_ = "Successful result";
+ break;
+ case ERROR:
+ text_ = "SQL error or missing database";
+ break;
+ case INTERNAL:
+ text_ = "Internal logic error in SQLite";
+ break;
+ case PERM:
+ text_ = "Access permission denied";
+ break;
+ case ABORT:
+ text_ = "Callback routine requested an abort";
+ break;
+ case BUSY:
+ text_ = "The database file is locked";
+ break;
+ case LOCKED:
+ text_ = "A table in the database is locked";
+ break;
+ case NOMEM:
+ text_ = "A malloc() failed";
+ break;
+ case READONLY:
+ text_ = "Attempt to write a readonly database";
+ break;
+ case INTERRUPT:
+ text_ = "Operation terminated by sqlite3_interrupt()";
+ break;
+ case IOERR:
+ text_ = "Some kind of disk I/O error occurred";
+ break;
+ case CORRUPT:
+ text_ = "The database disk image is malformed";
+ break;
+ case NOTFOUND:
+ text_ = "Unknown opcode in sqlite3_file_control()";
+ break;
+ case FULL:
+ text_ = "Insertion failed because database is full";
+ break;
+ case CANTOPEN:
+ text_ = "Unable to open the database file";
+ break;
+ case PROTOCOL:
+ text_ = "Database lock protocol error";
+ break;
+ case EMPTY:
+ text_ = "Database is empty";
+ break;
+ case SCHEMA:
+ text_ = "The database schema changed";
+ break;
+ case TOOBIG:
+ text_ = "String or BLOB exceeds size limit";
+ break;
+ case CONSTRAINT:
+ text_ = "Abort due to constraint violation";
+ break;
+ case MISMATCH:
+ text_ = "Data type mismatch";
+ break;
+ case MISUSE:
+ text_ = "Library used incorrectly";
+ break;
+ case NOLFS:
+ text_ = "Uses OS features not supported on host";
+ break;
+ case AUTH:
+ text_ = "Authorization denied";
+ break;
+ case FORMAT:
+ text_ = "Auxiliary database format error";
+ break;
+ case RANGE:
+ text_ = "2nd parameter to sqlite3_bind out of range";
+ break;
+ case NOTADB:
+ text_ = "File opened that is not a database file";
+ break;
+ case NOTICE:
+ text_ = "Notifications from sqlite3_log()";
+ break;
+ case WARNING:
+ text_ = "Warnings from sqlite3_log()";
+ break;
+ case ROW:
+ text_ = "sqlite3_step() has another row ready";
+ break;
+ case DONE:
+ text_ = "sqlite3_step() has finished executing";
+ break;
+ default:
+ text_ = "Unknown error";
+ }
+ return text_;
+}
+
+} // namespace dbms
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/sqlite_wrapper/src/sql_query.cc b/src/components/policy/src/policy/sqlite_wrapper/src/sql_query.cc
new file mode 100644
index 000000000..c8afdfcdb
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/src/sql_query.cc
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sqlite_wrapper/sql_query.h"
+#include <sqlite3.h>
+#include <cassert>
+#include "sqlite_wrapper/sql_database.h"
+
+namespace policy {
+namespace dbms {
+
+SQLQuery::SQLQuery(SQLDatabase* db)
+ : db_(*db),
+ query_(""),
+ statement_(NULL),
+ error_(SQLITE_OK) {
+}
+
+SQLQuery::~SQLQuery() {
+ Finalize();
+}
+
+bool SQLQuery::Prepare(const std::string& query) {
+ Finalize();
+ sync_primitives::AutoLock auto_lock(statement_lock_);
+ if (statement_) return false;
+ error_ = sqlite3_prepare(db_.conn(), query.c_str(), query.length(),
+ &statement_, NULL);
+ query_ = query;
+ return error_ == SQLITE_OK;
+}
+
+bool SQLQuery::Exec() {
+ error_ = sqlite3_step(statement_);
+ return error_ == SQLITE_ROW || error_ == SQLITE_DONE;
+}
+
+bool SQLQuery::Next() {
+ error_ = sqlite3_step(statement_);
+ return error_ == SQLITE_ROW;
+}
+
+bool SQLQuery::Reset() {
+ error_ = sqlite3_reset(statement_);
+ return error_ == SQLITE_OK;
+}
+
+void SQLQuery::Finalize() {
+ sync_primitives::AutoLock auto_lock(statement_lock_);
+ error_ = sqlite3_finalize(statement_);
+ if (error_ == SQLITE_OK) {
+ statement_ = NULL;
+ }
+}
+
+bool SQLQuery::Exec(const std::string& query) {
+ query_ = query;
+ error_ = sqlite3_exec(db_.conn(), query.c_str(), NULL, NULL, NULL);
+ return error_ == SQLITE_OK;
+}
+
+void SQLQuery::Bind(int pos, int value) {
+ // In SQLite the number of position for binding starts since 1.
+ error_ = sqlite3_bind_int(statement_, pos + 1, value);
+}
+
+void SQLQuery::Bind(int pos, int64_t value) {
+ // In SQLite the number of position for binding starts since 1.
+ error_ = sqlite3_bind_int64(statement_, pos + 1, value);
+}
+
+void SQLQuery::Bind(int pos, double value) {
+ // In SQLite the number of position for binding starts since 1.
+ error_ = sqlite3_bind_double(statement_, pos + 1, value);
+}
+
+void SQLQuery::Bind(int pos, bool value) {
+ Bind(pos, static_cast<int>(value));
+}
+
+void SQLQuery::Bind(int pos, const std::string& value) {
+ // In SQLite the number of position for binding starts since 1.
+ error_ = sqlite3_bind_text(statement_, pos + 1, value.c_str(), value.length(),
+ SQLITE_TRANSIENT);
+}
+
+bool SQLQuery::GetBoolean(int pos) const {
+ return static_cast<bool>(GetInteger(pos));
+}
+
+int SQLQuery::GetInteger(int pos) const {
+ return sqlite3_column_int(statement_, pos);
+}
+
+double SQLQuery::GetDouble(int pos) const {
+ return sqlite3_column_double(statement_, pos);
+}
+
+std::string SQLQuery::GetString(int pos) const {
+ const unsigned char* str = sqlite3_column_text(statement_, pos);
+ return str ? reinterpret_cast<const char*>(str) : "";
+}
+
+const std::string& SQLQuery::query() const {
+ // TODO(KKolodiy): may return string query with value of arguments
+ return query_;
+}
+
+bool SQLQuery::IsNull(int pos) const {
+ return sqlite3_column_type(statement_, pos) == SQLITE_NULL;
+}
+
+void SQLQuery::Bind(int pos) {
+ // In SQLite the number of position for binding starts since 1.
+ error_ = sqlite3_bind_null(statement_, pos + 1);
+}
+
+SQLError SQLQuery::LastError() const {
+ return SQLError(Error(error_));
+}
+
+int64_t SQLQuery::LastInsertId() const {
+ return sqlite3_last_insert_rowid(db_.conn());
+}
+
+} // namespace dbms
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/src/policy_helper.cc b/src/components/policy/src/policy/src/policy_helper.cc
new file mode 100644
index 000000000..09362e6a7
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_helper.cc
@@ -0,0 +1,485 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include "utils/logger.h"
+#include "policy/policy_helper.h"
+#include "policy/policy_manager_impl.h"
+
+namespace policy {
+
+namespace {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyManagerImpl")
+
+bool Match(const StringsValueType& first_name,
+ const StringsValueType& second_name) {
+ const std::string& first = first_name;
+ const std::string& second = second_name;
+ return (strcasecmp(first.c_str(), second.c_str()) == 0);
+}
+
+bool Compare(const StringsValueType& first, const StringsValueType& second) {
+ const std::string& first_str = first;
+ const std::string& second_str = second;
+ return (strcasecmp(first_str.c_str(), second_str.c_str()) < 0);
+}
+
+}
+
+CompareGroupName::CompareGroupName(const StringsValueType& group_name)
+ : group_name_(group_name) {
+}
+
+bool CompareGroupName::operator()(
+ const StringsValueType& group_name_to_compare) const {
+ const std::string gn_ = group_name_;
+ const std::string gn_compare = group_name_to_compare;
+ return !(strcasecmp(gn_.c_str(), gn_compare.c_str()));
+}
+
+bool operator!=(const policy_table::ApplicationParams& first,
+ const policy_table::ApplicationParams& second) {
+ // TODO(AOleynik): Add comparing of Ford-specific and other parameters
+ if (first.groups.size() != second.groups.size()) {
+ return true;
+ }
+ StringsConstItr it_first = first.groups.begin();
+ StringsConstItr it_first_end = first.groups.end();
+ StringsConstItr it_second = second.groups.begin();
+ StringsConstItr it_second_end = second.groups.end();
+ for (; it_first != it_first_end; ++it_first) {
+ CompareGroupName gp(*it_first);
+ StringsConstItr it = std::find_if(it_second, it_second_end, gp);
+ if (it_first_end == it) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CheckAppPolicy::CheckAppPolicy(
+ PolicyManagerImpl* pm, const utils::SharedPtr<policy_table::Table> update)
+ : pm_(pm),
+ update_(update) {
+}
+
+bool CheckAppPolicy::HasSameGroups(const AppPoliciesValueType& app_policy,
+ AppPermissions* perms) const {
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+ const std::string app_id = app_policy.first;
+ AppPoliciesConstItr it = pm_->policy_table_snapshot_->policy_table
+ .app_policies.find(app_id);
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ StringsConstItr new_it = it_groups_new;
+ StringsConstItr old_it = it_groups_curr;
+
+ std::pair<StringsConstItr, StringsConstItr> diff;
+
+ while (it_groups_new_end != new_it && it_groups_curr_end != old_it) {
+ size_t size = ((it_groups_new_end - new_it) > (it_groups_curr_end - old_it)) ? it_groups_curr_end - old_it : it_groups_new_end - new_it;
+ diff = std::mismatch(old_it, old_it + size, new_it, Match);
+ if (it_groups_curr_end == diff.first || it_groups_new_end == diff.second) {
+ new_it = diff.second;
+ old_it = diff.first;
+ break;
+ }
+ if (Compare(*diff.first, *diff.second)) {
+ perms->isAppPermissionsRevoked = true;
+ perms->appRevokedPermissions.push_back(*(diff.first));
+ old_it = ++diff.first;
+ new_it = diff.second;
+ } else {
+ perms->appPermissionsConsentNeeded = true;
+ old_it = diff.first;
+ new_it = ++diff.second;
+ }
+ }
+
+ for (StringsConstItr it = old_it; it != it_groups_curr_end; ++it) {
+ perms->isAppPermissionsRevoked = true;
+ perms->appRevokedPermissions.push_back(*it);
+ }
+
+ if (it_groups_new_end != new_it) {
+ perms->appPermissionsConsentNeeded = true;
+ }
+
+ return !(perms->appRevokedPermissions.size() > 0
+ || perms->appPermissionsConsentNeeded);
+}
+
+bool CheckAppPolicy::IsNewAppication(const std::string& application_id) const {
+ const policy_table::ApplicationPolicies& current_policies = pm_
+ ->policy_table_snapshot_->policy_table.app_policies;
+ AppPoliciesConstItr it_app_policies_curr = current_policies.begin();
+ AppPoliciesConstItr it_app_policies_curr_end = current_policies.end();
+
+ for (; it_app_policies_curr != it_app_policies_curr_end;
+ ++it_app_policies_curr) {
+
+ // Find necessary application in current snapshot
+ const std::string application_id_curr = (*it_app_policies_curr).first;
+ if (application_id == application_id_curr) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void CheckAppPolicy::SendNotification(
+ const AppPoliciesValueType& app_policy) const {
+ // Collecting all available rpcs and their parameters from updated
+ // policies and fill notification data struct
+ Permissions notification_data;
+
+ // Get current user permissions for groups from DB
+ std::vector<FunctionalGroupPermission> group_permissons;
+ // Get current device_id from application id
+ const std::string device_id = pm_->GetCurrentDeviceId(app_policy.first);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_, "Couldn't find device info for application id "
+ "'" << app_policy.first << "'");
+ return;
+ }
+ pm_->GetUserPermissionsForApp(device_id, app_policy.first, group_permissons);
+
+ pm_->PrepareNotificationData(update_->policy_table.functional_groupings,
+ app_policy.second.groups,
+ group_permissons, notification_data);
+
+ const std::string app_id = app_policy.first;
+ LOG4CXX_INFO(logger_, "Send notification for application_id:" << app_id);
+#if defined (EXTENDED_POLICY)
+ pm_->listener()->OnPermissionsUpdated(app_id, notification_data,
+ policy_table::EnumToJsonString(app_policy.second.default_hmi));
+#else
+ // Default_hmi is Ford-specific and should not be used with basic policy
+ const std::string default_hmi;
+ pm_->listener()->OnPermissionsUpdated(app_id, notification_data, default_hmi);
+#endif
+}
+
+void CheckAppPolicy::SendOnPendingPermissions(
+ const AppPoliciesValueType& app_policy, AppPermissions permissions) const {
+ // TODO(AOleynik): Exclude default group(s)
+ if (permissions.appPermissionsConsentNeeded) {
+#if defined(EXTENDED_POLICY)
+ const policy_table::Strings& groups = app_policy.second.groups;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ const policy_table::Strings& preconsented_groups = *app_policy.second
+ .preconsented_groups;
+
+ // TODO(KKolodiy): Use consent_groups to filtrate groups
+ PermissionsList list_of_permissions;
+ std::for_each(
+ groups.begin(), groups.end(),
+ FunctionalGroupInserter(preconsented_groups, list_of_permissions));
+ // TODO(PV): logic has changed.
+ if (!list_of_permissions.empty()) {
+ pm_->app_permissions_diff_.insert(
+ std::make_pair(app_policy.first, permissions));
+ pm_->listener()->OnPendingPermissionChange(app_policy.first);
+ return;
+ }
+#endif
+ }
+ if (permissions.isAppPermissionsRevoked) {
+ pm_->app_permissions_diff_.insert(
+ std::make_pair(app_policy.first, permissions));
+ pm_->listener()->OnPendingPermissionChange(app_policy.first);
+ }
+}
+
+bool CheckAppPolicy::IsAppRevoked(
+ const AppPoliciesValueType& app_policy) const {
+ // Application params are not initialized = application revoked
+ // i.e. "123":null
+ return app_policy.second.is_null();
+}
+
+bool CheckAppPolicy::NicknamesMatch(const std::string app_id,
+ const AppPoliciesValueType& app_policy) const {
+ std::string app_name = pm_->listener()->GetAppName(app_id);
+ if (!app_name.empty() && app_policy.second.nicknames && !app_policy.second.nicknames->empty()) {
+ for (policy_table::Strings::const_iterator it = app_policy.second.nicknames->begin();
+ app_policy.second.nicknames->end() != it; ++it) {
+ std::string temp = *it;
+ if (temp.compare(app_name) == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) {
+ policy_table::ApplicationPolicies& current_policies = pm_
+ ->policy_table_snapshot_->policy_table.app_policies;
+
+ const std::string app_id = app_policy.first;
+
+ AppPermissions permissions_diff(app_id);
+#if defined (EXTENDED_POLICY)
+ permissions_diff.priority = policy_table::EnumToJsonString(
+ app_policy.second.priority);
+#endif
+
+ // Check revocation for any numeric application ids
+ if (atoi(app_id.c_str()) && IsAppRevoked(app_policy)) {
+ permissions_diff.appRevoked = true;
+ pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
+ pm_->listener()->OnAppRevoked(app_id);
+ policy_table::ApplicationPolicies::iterator it = current_policies.find(
+ app_id);
+ // Update snapshot with new policies for application
+ if (it != current_policies.end()) {
+ (*it).second = app_policy.second;
+ it->second.set_to_null();
+ }
+ return true;
+ }
+
+ // TODO(PV): do we really need this check?
+ if (IsNewAppication(app_id)) {
+ // Update snapshot with policies for new application
+ current_policies[app_id] = app_policy.second;
+ SendNotification(app_policy);
+ SendOnPendingPermissions(app_policy, permissions_diff);
+ return true;
+ }
+
+ if (!NicknamesMatch(app_id, app_policy)) {
+ permissions_diff.appUnauthorized = true;
+ pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
+ pm_->listener()->OnPendingPermissionChange(app_policy.first);
+ policy_table::ApplicationPolicies::iterator it = current_policies.find(
+ app_id);
+ // Update snapshot with new policies for application
+ if (it != current_policies.end()) {
+ (*it).second = app_policy.second;
+ it->second.set_to_null();
+ }
+ return true;
+ }
+
+ if (HasSameGroups(app_policy, &permissions_diff)) {
+ LOG4CXX_INFO(
+ logger_,
+ "Permissions for application:" << app_id << " wasn't changed.");
+ return true;
+ }
+
+ policy_table::ApplicationPolicies::iterator it = current_policies.find(
+ app_id);
+ // Update snapshot with new policies for application
+ (*it).second = app_policy.second;
+
+ // Don't sent notification for "default"
+ if (kDefaultId != app_id && kDeviceId != app_id) {
+ SendNotification(app_policy);
+ SendOnPendingPermissions(app_policy, permissions_diff);
+ }
+
+ // TODO(PV): if 'device' was update with new/other func groups => user consent for device should be cleared.
+
+ return true;
+}
+
+FillNotificationData::FillNotificationData(Permissions& data,
+ GroupConsent group_state)
+ : data_(data) {
+ switch (group_state) {
+ case kGroupAllowed:
+ current_key_ = kAllowedKey;
+ break;
+ default:
+ current_key_ = kUserDisallowedKey;
+ break;
+ }
+}
+
+bool FillNotificationData::operator()(const RpcValueType& rpc) {
+ Permissions::iterator it = data_.find(rpc.first);
+ // If rpc is present already - update its permissions
+ if (data_.end() != it) {
+ UpdateHMILevels(rpc.second.hmi_levels,
+ (*it).second.hmi_permissions[current_key_]);
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ UpdateParameters(*rpc.second.parameters,
+ (*it).second.parameter_permissions[current_key_]);
+ ExcludeDisAllowed();
+ } else {
+ // If rpc is not present - add its permissions
+ UpdateHMILevels(rpc.second.hmi_levels,
+ data_[rpc.first].hmi_permissions[current_key_]);
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ UpdateParameters(*rpc.second.parameters,
+ data_[rpc.first].parameter_permissions[current_key_]);
+ ExcludeDisAllowed();
+ }
+ return true;
+}
+
+void FillNotificationData::UpdateHMILevels(
+ const policy_table::HmiLevels& in_hmi, std::set<HMILevel>& out_hmi) {
+ HMILevelsConstItr it_hmi_levels = in_hmi.begin();
+ HMILevelsConstItr it_hmi_levels_end = in_hmi.end();
+
+ for (; it_hmi_levels != it_hmi_levels_end; ++it_hmi_levels) {
+ out_hmi.insert(policy_table::EnumToJsonString(*it_hmi_levels));
+ }
+}
+
+void FillNotificationData::UpdateParameters(
+ const policy_table::Parameters& in_parameters,
+ std::set<Parameter>& out_parameter) {
+ ParametersConstItr it_parameters = in_parameters.begin();
+ ParametersConstItr it_parameters_end = in_parameters.end();
+
+ for (; it_parameters != it_parameters_end; ++it_parameters) {
+ out_parameter.insert(policy_table::EnumToJsonString(*it_parameters));
+ }
+}
+
+void FillNotificationData::ExcludeDisAllowed() {
+ // Search through filled data and remove permission from allowed, if it was
+ // found in disallowed section
+ Permissions::iterator it = data_.begin();
+ Permissions::const_iterator it_end = data_.end();
+ // Groups
+ for (; it != it_end; ++it) {
+ std::set<HMILevel>& allowed_hmi_level = (*it).second.hmi_permissions[kAllowedKey];
+ std::set<HMILevel>& disallowed_hmi_level =
+ (*it).second.hmi_permissions[kUserDisallowedKey];
+ std::set<HMILevel> diff_hmi;
+
+ std::set_difference(allowed_hmi_level.begin(), allowed_hmi_level.end(),
+ disallowed_hmi_level.begin(), disallowed_hmi_level.end(),
+ std::inserter(diff_hmi, diff_hmi.begin()));
+ // Leave levels, which are not present in disallowed
+ allowed_hmi_level = diff_hmi;
+
+ std::set<Parameter>& allowed_parameters =
+ (*it).second.parameter_permissions[kAllowedKey];
+ std::set<Parameter>& disallowed_parameters =
+ (*it).second.parameter_permissions[kUserDisallowedKey];
+
+ std::set<Parameter> diff_params;
+
+ std::set_difference(allowed_parameters.begin(), allowed_parameters.end(),
+ disallowed_parameters.begin(), disallowed_parameters.end(),
+ std::inserter(diff_params, diff_params.begin()));
+
+ // Leave parameters, which are not present in disallowed
+ allowed_parameters = diff_params;
+ }
+}
+
+ProcessFunctionalGroup::ProcessFunctionalGroup(
+ const policy_table::FunctionalGroupings& fg,
+ const std::vector<FunctionalGroupPermission>& group_permissions,
+ Permissions& data)
+ : fg_(fg),
+ group_permissions_(group_permissions),
+ data_(data) {
+}
+
+bool ProcessFunctionalGroup::operator()(const StringsValueType& group_name) {
+ const std::string group_name_str = group_name;
+ FuncGroupConstItr it = fg_.find(group_name_str);
+
+ if (fg_.end() != it) {
+ const policy_table::Rpc& rpcs = (*it).second.rpcs;
+ FillNotificationData filler(data_, GetGroupState(group_name_str));
+ std::for_each(rpcs.begin(), rpcs.end(), filler);
+ }
+ return true;
+}
+
+GroupConsent ProcessFunctionalGroup::GetGroupState(
+ const std::string& group_name) {
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ group_permissions_.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ group_permissions_.end();
+ for (; it != it_end; ++it) {
+ if (group_name == (*it).group_name) {
+ return (*it).state;
+ }
+ }
+ return kGroupUndefined;
+}
+
+FunctionalGroupInserter::FunctionalGroupInserter(
+ const policy_table::Strings& preconsented_groups, PermissionsList& list)
+ : list_(list),
+ preconsented_(preconsented_groups) {
+}
+
+void FunctionalGroupInserter::operator()(const StringsValueType& group_name) {
+ CompareGroupName name(group_name);
+ if (std::find_if(preconsented_.begin(), preconsented_.end(), name)
+ == preconsented_.end()) {
+ list_.push_back(group_name);
+ }
+}
+
+void FillFunctionalGroupPermissions(FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+}
diff --git a/src/components/policy/src/policy/src/policy_manager_impl.cc b/src/components/policy/src/policy/src/policy_manager_impl.cc
new file mode 100644
index 000000000..74e9c0e55
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_manager_impl.cc
@@ -0,0 +1,1224 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <set>
+#include "json/reader.h"
+#include "json/writer.h"
+#include "policy/policy_table.h"
+#include "policy/pt_representation.h"
+#include "policy/policy_manager_impl.h"
+#include "policy/policy_helper.h"
+#include "utils/file_system.h"
+#include "utils/logger.h"
+
+policy::PolicyManager* CreateManager() {
+ return new policy::PolicyManagerImpl();
+}
+
+namespace {
+void CheckPreloadedGroups(policy_table::ApplicationParams& app_param) {
+
+}
+}
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyManagerImpl")
+
+#if defined(__QNXNTO__) and defined(GCOV_ENABLED)
+bool CheckGcov() {
+ LOG4CXX_ERROR(log4cxx::Logger::getLogger("appMain"),
+ "Attention! This application was built with unsupported "
+ "configuration (gcov + QNX). Use it at your own risk.");
+ return true;
+}
+bool check_gcov = CheckGcov();
+#endif
+
+PolicyManagerImpl::PolicyManagerImpl()
+ : PolicyManager(),
+ listener_(NULL),
+ exchange_in_progress_(false),
+ update_required_(policy_table_.pt_data()->UpdateRequired()),
+ exchange_pending_(false),
+ retry_sequence_index_(0),
+ last_update_status_(policy::StatusUnknown) {
+ RefreshRetrySequence();
+}
+
+void PolicyManagerImpl::ResetDefaultPT(const PolicyTable& policy_table) {
+ policy_table_ = policy_table;
+ exchange_in_progress_ = false;
+ update_required_ = policy_table_.pt_data()->UpdateRequired();
+ exchange_pending_ = false;
+ retry_sequence_index_ = 0;
+ last_update_status_ = policy::StatusUnknown;
+ RefreshRetrySequence();
+}
+
+void PolicyManagerImpl::set_listener(PolicyListener* listener) {
+ listener_ = listener;
+}
+
+PolicyManagerImpl::~PolicyManagerImpl() {
+ LOG4CXX_INFO(logger_, "Destroying policy manager.");
+ policy_table_.pt_data()->SaveUpdateRequired(update_required_);
+}
+
+bool PolicyManagerImpl::LoadPTFromFile(const std::string& file_name) {
+ LOG4CXX_INFO(logger_, "LoadPTFromFile: " << file_name);
+ bool final_result = false;
+ InitResult init_result = policy_table_.pt_data()->Init();
+ switch (init_result) {
+ case InitResult::EXISTS: {
+ LOG4CXX_INFO(logger_, "Policy Table exists, was loaded correctly.");
+ final_result = true;
+ break;
+ }
+ case InitResult::SUCCESS: {
+ BinaryMessage json_string;
+ final_result = file_system::ReadBinaryFile(file_name, json_string);
+ if (!final_result) {
+ LOG4CXX_WARN(logger_, "Failed to read pt file.");
+ utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
+ return final_result;
+ }
+ utils::SharedPtr<policy_table::Table> table = Parse(json_string);
+ if (!table) {
+ LOG4CXX_WARN(logger_, "Failed to parse policy table");
+ utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
+ return false;
+ }
+ final_result = final_result && policy_table_.pt_data()->Save(*table);
+ LOG4CXX_INFO(
+ logger_,
+ "Loading from file was " << (final_result ? "successful" : "unsuccessful"));
+ }
+ break;
+ case InitResult::FAIL:
+ default: {
+ LOG4CXX_WARN(logger_, "Failed to init policy table.");
+ return final_result;
+ }
+ }
+
+ // Initial setting of snapshot data
+ if (!policy_table_snapshot_.valid()) {
+ policy_table_snapshot_ = policy_table_.pt_data()->GenerateSnapshot();
+ if (!policy_table_snapshot_.valid()) {
+ LOG4CXX_WARN(logger_,
+ "Failed to create initial snapshot of policy table");
+ return final_result;
+ }
+ }
+
+ RefreshRetrySequence();
+ return final_result;
+}
+
+utils::SharedPtr<policy_table::Table> PolicyManagerImpl::Parse(
+ const BinaryMessage& pt_content) {
+ std::string json(pt_content.begin(), pt_content.end());
+ Json::Value value;
+ Json::Reader reader;
+ if (reader.parse(json.c_str(), value)) {
+ return new policy_table::Table(&value);
+ } else {
+ return 0;
+ }
+}
+
+bool PolicyManagerImpl::LoadPT(const std::string& file,
+ const BinaryMessage& pt_content) {
+ LOG4CXX_INFO(logger_, "LoadPTFromString of size " << pt_content.size());
+
+ // Parse message into table struct
+ utils::SharedPtr<policy_table::Table> pt_update = Parse(pt_content);
+
+ if (!pt_update) {
+ LOG4CXX_WARN(logger_, "Parsed table pointer is 0.");
+ return false;
+ }
+
+#if defined (EXTENDED_POLICY)
+ file_system::DeleteFile(file);
+#endif
+
+ set_exchange_in_progress(false);
+
+ if (!pt_update->is_valid()) {
+ rpc::ValidationReport report("policy_table");
+ pt_update->ReportErrors(&report);
+ LOG4CXX_WARN(logger_, "Parsed table is not valid " << rpc::PrettyFormat(report));
+ return false;
+ }
+
+ // Check and update permissions for applications, send notifications
+ CheckPermissionsChanges(pt_update);
+
+ // Replace current data with updated
+ policy_table_snapshot_->policy_table.functional_groupings = pt_update
+ ->policy_table.functional_groupings;
+
+ policy_table_snapshot_->policy_table.module_config = pt_update->policy_table
+ .module_config;
+
+ bool is_message_part_updated = pt_update->policy_table
+ .consumer_friendly_messages.messages.is_initialized();
+
+ if (is_message_part_updated) {
+ policy_table_snapshot_->policy_table.consumer_friendly_messages.messages =
+ pt_update->policy_table.consumer_friendly_messages.messages;
+ }
+
+ //policy_table.module_meta
+
+ // Save data to DB
+ if (!policy_table_.pt_data()->Save(*policy_table_snapshot_)) {
+ LOG4CXX_WARN(logger_, "Unsuccessful save of updated policy table.");
+ return false;
+ }
+
+ // Removing last app request from update requests
+ RemoveAppFromUpdateList();
+
+ // TODO(AOleynik): Check, if there is updated info present for apps in list
+ // and skip update in this case for given app
+ if (!update_requests_list_.empty()) {
+ if (listener_) {
+ listener_->OnPTExchangeNeeded();
+ }
+ } else {
+ LOG4CXX_INFO(logger_, "Update request queue is empty.");
+ }
+
+ RefreshRetrySequence();
+ return true;
+}
+
+void PolicyManagerImpl::CheckPermissionsChanges(
+ const utils::SharedPtr<policy_table::Table> pt_update) {
+ LOG4CXX_INFO(logger_, "Checking incoming permissions.");
+
+ std::for_each(pt_update->policy_table.app_policies.begin(),
+ pt_update->policy_table.app_policies.end(),
+ CheckAppPolicy(this, pt_update));
+}
+
+void PolicyManagerImpl::PrepareNotificationData(
+ const policy_table::FunctionalGroupings& groups,
+ const policy_table::Strings& group_names,
+ const std::vector<FunctionalGroupPermission>& group_permission,
+ Permissions& notification_data) {
+
+ LOG4CXX_INFO(logger_, "Preparing data for notification.");
+ ProcessFunctionalGroup processor(groups, group_permission, notification_data);
+ std::for_each(group_names.begin(), group_names.end(), processor);
+}
+
+void PolicyManagerImpl::set_exchange_in_progress(bool value) {
+ sync_primitives::AutoLock lock(exchange_in_progress_lock_);
+ LOG4CXX_INFO(logger_,
+ "Exchange in progress value is:" << std::boolalpha << value);
+ exchange_in_progress_ = value;
+ CheckUpdateStatus();
+}
+
+void PolicyManagerImpl::set_exchange_pending(bool value) {
+ sync_primitives::AutoLock lock(exchange_pending_lock_);
+ LOG4CXX_INFO(logger_,
+ "Exchange pending value is:" << std::boolalpha << value);
+ exchange_pending_ = value;
+ CheckUpdateStatus();
+}
+
+void PolicyManagerImpl::set_update_required(bool value) {
+ sync_primitives::AutoLock lock(update_required_lock_);
+ LOG4CXX_INFO(logger_, "Update required value is:" << std::boolalpha << value);
+ update_required_ = value;
+ CheckUpdateStatus();
+}
+
+void PolicyManagerImpl::AddAppToUpdateList(const std::string& application_id) {
+ sync_primitives::AutoLock lock(update_request_list_lock_);
+ LOG4CXX_INFO(logger_,
+ "Adding application " << application_id << " to update list");
+ // Add application id only once
+ std::list<std::string>::const_iterator it = std::find(
+ update_requests_list_.begin(), update_requests_list_.end(),
+ application_id);
+ if (it == update_requests_list_.end()) {
+ update_requests_list_.push_back(application_id);
+ }
+}
+
+void PolicyManagerImpl::RemoveAppFromUpdateList() {
+ sync_primitives::AutoLock lock(update_request_list_lock_);
+ if (update_requests_list_.empty()) {
+ return;
+ }
+ LOG4CXX_INFO(
+ logger_,
+ "Removing application " << update_requests_list_.front() << " from update list");
+ update_requests_list_.pop_front();
+}
+
+std::string PolicyManagerImpl::GetUpdateUrl(int service_type) {
+ LOG4CXX_INFO(logger_, "PolicyManagerImpl::GetUpdateUrl");
+ EndpointUrls urls = policy_table_.pt_data()->GetUpdateUrls(service_type);
+
+ static int index = 0;
+ std::string url;
+ if (index < urls.size()) {
+ url = urls[index].url;
+ } else if (!urls.empty()) {
+ index = 0;
+ url = urls[index].url;
+ }
+ ++index;
+
+ return url;
+}
+
+EndpointUrls PolicyManagerImpl::GetUpdateUrls(int service_type) {
+ LOG4CXX_INFO(logger_, "PolicyManagerImpl::GetUpdateUrls");
+ return policy_table_.pt_data()->GetUpdateUrls(service_type);
+}
+
+BinaryMessageSptr PolicyManagerImpl::RequestPTUpdate() {
+ LOG4CXX_INFO(logger_, "Creating PT Snapshot");
+
+ // Update policy table for the first time with system information
+ if (policy_table_.pt_data()->IsPTPreloaded()) {
+ listener()->OnSystemInfoUpdateRequired();
+ }
+
+ policy_table_snapshot_ = policy_table_.pt_data()->GenerateSnapshot();
+ if (!policy_table_snapshot_) {
+ LOG4CXX_ERROR(logger_, "Failed to create snapshot of policy table");
+ return NULL;
+ }
+
+ if (!exchange_pending_) {
+ set_update_required(false);
+ }
+
+ set_exchange_in_progress(true);
+ set_exchange_pending(false);
+
+ Json::Value value = policy_table_snapshot_->ToJsonValue();
+
+ policy_table::ApplicationPolicies& apps = policy_table_snapshot_->policy_table.app_policies;
+ std::map<std::string,
+ rpc::Nullable<rpc::policy_table_interface_base::ApplicationParams>>::iterator it = apps.begin();
+ for (; apps.end() != it; ++it) {
+ if (policy_table_.pt_data()->IsDefaultPolicy(it->first)) {
+ printf("\n\t\t\t\tDefault policy of %s\n", it->first.c_str());
+ value["policy_table"]["app_policies"][it->first] = kDefaultId;
+ continue;
+ }
+ if (policy_table_.pt_data()->IsPredataPolicy(it->first)) {
+ printf("\n\t\t\t\tPredata policy of %s\n", it->first.c_str());
+ value["policy_table"]["app_policies"][it->first] = kPreDataConsentId;
+ continue;
+ }
+ Json::Value app_value = it->second.ToJsonValue();
+ value["policy_table"]["app_policies"][it->first] = app_value;
+ }
+
+ Json::FastWriter writer;
+ std::string message_string = writer.write(value);
+ LOG4CXX_INFO(logger_, "\n\n\n\nPT Snapshot " << message_string << "\n\n\n");
+ return new BinaryMessage(message_string.begin(), message_string.end());
+}
+
+CheckPermissionResult PolicyManagerImpl::CheckPermissions(
+ const PTString& app_id, const PTString& hmi_level, const PTString& rpc) {
+ LOG4CXX_INFO(
+ logger_,
+ "CheckPermissions for " << app_id << " and rpc " << rpc << " for "
+ << hmi_level << " level.");
+
+#if defined (EXTENDED_POLICY)
+ const std::string device_id = GetCurrentDeviceId(app_id);
+ // Get actual application group permission according to user consents
+ std::vector<FunctionalGroupPermission> app_group_permissions;
+ GetUserPermissionsForApp(device_id, app_id, app_group_permissions);
+
+ // Fill struct with known groups RPCs
+ policy_table::FunctionalGroupings functional_groupings;
+ policy_table_.pt_data()->GetFunctionalGroupings(functional_groupings);
+
+ policy_table::Strings app_groups;
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ app_group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ app_group_permissions.end();
+ for (; it != it_end; ++it) {
+ app_groups.push_back((*it).group_name);
+ }
+
+ Permissions rpc_permissions;
+ PrepareNotificationData(functional_groupings, app_groups,
+ app_group_permissions, rpc_permissions);
+
+ CheckPermissionResult result;
+ // If RPC is present in list, but not found in allowed and userDisallowed ==
+ // disallowed both by backend and by user, which is default value for result
+ if (rpc_permissions.end() == rpc_permissions.find(rpc)) {
+ // RPC not found in list == disallowed by backend
+ return result;
+ }
+
+ // Check HMI level
+ if (rpc_permissions[rpc].hmi_permissions[kAllowedKey].end() !=
+ rpc_permissions[rpc].hmi_permissions[kAllowedKey].find(hmi_level)) {
+ // RPC found in allowed == allowed by backend and user
+ result.hmi_level_permitted = kRpcAllowed;
+ }
+
+ if (rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].end() !=
+ rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].find(hmi_level)) {
+ // RPC found in allowed == allowed by backend, but disallowed by user
+ result.hmi_level_permitted = kRpcUserDisallowed;
+ }
+
+ // Add parameters of RPC, if any
+ result.list_of_allowed_params = new std::vector<PTString>();
+ std::copy(rpc_permissions[rpc].parameter_permissions[kAllowedKey].begin(),
+ rpc_permissions[rpc].parameter_permissions[kAllowedKey].end(),
+ result.list_of_allowed_params->begin());
+
+ return result;
+#else
+ return policy_table_.pt_data()->CheckPermissions(app_id, hmi_level, rpc);
+#endif
+}
+
+bool PolicyManagerImpl::ResetUserConsent() {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ return pt_ext->ResetUserConsent();
+ }
+ return false;
+#else
+ return true;
+#endif
+}
+
+void PolicyManagerImpl::CheckAppPolicyState(const std::string& application_id) {
+ LOG4CXX_INFO(logger_, "CheckAppPolicyState");
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ if (!policy_table_.pt_data()->IsApplicationRepresented(application_id)) {
+ LOG4CXX_INFO(
+ logger_,
+ "Setting default permissions for application id: " << application_id);
+#if defined (EXTENDED_POLICY)
+ if (kDeviceHasNoConsent == device_consent ||
+ kDeviceDisallowed == device_consent) {
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't cleanup unpaired devices.");
+ return;
+ }
+ pt_ext->SetPredataPolicy(application_id);
+ } else {
+ policy_table_.pt_data()->SetDefaultPolicy(application_id);
+ }
+#else
+ policy_table_.pt_data()->SetDefaultPolicy(application_id);
+#endif
+ SendNotificationOnPermissionsUpdated(application_id);
+ } else {
+ if (!policy_table_.pt_data()->IsDefaultPolicy(application_id)
+ || (kDeviceHasNoConsent != device_consent
+ && policy_table_.pt_data()->IsPredataPolicy(application_id))) {
+ return;
+ }
+ }
+
+ AddAppToUpdateList(application_id);
+
+ if (PolicyTableStatus::StatusUpToDate == GetPolicyTableStatus()) {
+ set_update_required(true);
+ } else {
+ set_exchange_pending(true);
+ }
+}
+
+void PolicyManagerImpl::SendNotificationOnPermissionsUpdated(
+ const std::string& application_id) {
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_, "Couldn't find device info for application id "
+ "'" << application_id << "'");
+ return;
+ }
+
+ std::vector<FunctionalGroupPermission> app_group_permissions;
+ GetUserPermissionsForApp(device_id, application_id, app_group_permissions);
+
+ policy_table::FunctionalGroupings functional_groupings;
+ policy_table_.pt_data()->GetFunctionalGroupings(functional_groupings);
+
+ policy_table::Strings app_groups;
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ app_group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ app_group_permissions.end();
+ for (; it != it_end; ++it) {
+ app_groups.push_back((*it).group_name);
+ }
+
+ Permissions notification_data;
+ PrepareNotificationData(functional_groupings, app_groups, app_group_permissions,
+ notification_data);
+
+ LOG4CXX_INFO(logger_, "Send notification for application_id:" << application_id);
+ std::string default_hmi;
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't get default hmi level for " << application_id);
+ return;
+ }
+
+ pt_ext->GetDefaultHMI(application_id, &default_hmi);
+ listener()->OnPermissionsUpdated(application_id, notification_data,
+ default_hmi);
+}
+
+bool PolicyManagerImpl::CleanupUnpairedDevices(const DeviceIds& device_ids) {
+ LOG4CXX_INFO(logger_, "CleanupUnpairedDevices");
+#if defined (EXTENDED_POLICY)
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't cleanup unpaired devices.");
+ return false;
+ }
+
+ return pt_ext->CleanupUnpairedDevices(device_ids);
+#else
+ return policy_table_.pt_data()->CleanupUnpairedDevices(device_ids);
+#endif
+}
+
+PolicyTableStatus PolicyManagerImpl::GetPolicyTableStatus() {
+ if (!exchange_in_progress_ && !exchange_pending_ && !update_required_) {
+ return PolicyTableStatus::StatusUpToDate;
+ }
+
+ if (update_required_ && !exchange_in_progress_ && !exchange_pending_) {
+ return PolicyTableStatus::StatusUpdateRequired;
+ }
+
+ return PolicyTableStatus::StatusUpdatePending;
+}
+
+DeviceConsent PolicyManagerImpl::GetUserConsentForDevice(
+ const std::string& device_id) {
+ LOG4CXX_INFO(logger_, "GetUserConsentForDevice");
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't get user consent for device");
+ return kDeviceDisallowed;
+ }
+
+ // Get device permission groups from app_policies section, which hadn't been
+ // preconsented
+ policy_table::Strings groups;
+ policy_table::Strings preconsented_groups;
+ if (!pt_ext->GetDeviceGroupsFromPolicies(&groups, &preconsented_groups)) {
+ LOG4CXX_WARN(logger_, "Can't get device groups from policies.");
+ return kDeviceDisallowed;
+ }
+
+ StringArray list_of_permissions;
+ std::for_each(
+ groups.begin(), groups.end(),
+ FunctionalGroupInserter(preconsented_groups, list_of_permissions));
+
+ // Check device permission groups for user consent in device_data section
+ if (!list_of_permissions.empty()) {
+ StringArray consented_groups;
+ StringArray disallowed_groups;
+ if (!pt_ext->GetUserPermissionsForDevice(device_id, &consented_groups,
+ &disallowed_groups)) {
+ return kDeviceDisallowed;
+ }
+
+ if (consented_groups.empty() && disallowed_groups.empty()) {
+ return kDeviceHasNoConsent;
+ }
+
+ std::sort(list_of_permissions.begin(), list_of_permissions.end());
+ std::sort(consented_groups.begin(), consented_groups.end());
+
+ StringArray to_be_consented_by_user;
+ std::set_difference(
+ list_of_permissions.begin(),
+ list_of_permissions.end(),
+ consented_groups.begin(),
+ consented_groups.end(),
+ std::back_inserter(to_be_consented_by_user));
+ if (to_be_consented_by_user.empty()) {
+ return kDeviceAllowed;
+ }
+
+ return kDeviceDisallowed;
+ }
+
+ return kDeviceAllowed;
+#else
+ return kDeviceAllowed;
+#endif
+}
+
+void PolicyManagerImpl::SetUserConsentForDevice(const std::string& device_id,
+ bool is_allowed) {
+ LOG4CXX_INFO(logger_, "SetUserConsentForDevice");
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't set user consent for device");
+ return;
+ }
+
+ // Get device permission groups from app_policies section, which hadn't been
+ // preconsented
+ policy_table::Strings groups;
+ policy_table::Strings preconsented_groups;
+ if (!pt_ext->GetDeviceGroupsFromPolicies(&groups, &preconsented_groups)) {
+ LOG4CXX_WARN(logger_, "Can't get device groups from policies.");
+ return;
+ }
+
+ StringArray list_of_permissions;
+ std::for_each(
+ groups.begin(), groups.end(),
+ FunctionalGroupInserter(preconsented_groups, list_of_permissions));
+
+ if (list_of_permissions.empty()) {
+ return;
+ }
+
+ StringArray consented_groups;
+ StringArray disallowed_groups;
+
+ // Supposed only one group for device date consent
+ if (is_allowed) {
+ consented_groups.push_back(list_of_permissions[0]);
+ } else {
+ disallowed_groups.push_back(list_of_permissions[0]);
+ }
+
+ if (!pt_ext->SetUserPermissionsForDevice(device_id, consented_groups,
+ disallowed_groups)) {
+ LOG4CXX_WARN(logger_, "Can't set user consent for device");
+ return;
+ }
+#endif
+}
+
+bool PolicyManagerImpl::ReactOnUserDevConsentForApp(const std::string app_id,
+ bool is_device_allowed) {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't set user consent for device");
+ return false;
+ }
+ return pt_ext->ReactOnUserDevConsentForApp(app_id, is_device_allowed);
+#endif
+ return true;
+}
+
+bool PolicyManagerImpl::GetInitialAppData(const std::string& application_id,
+ StringArray* nicknames,
+ StringArray* app_hmi_types) {
+ LOG4CXX_INFO(logger_, "GetInitialAppData");
+ return policy_table_.pt_data()->GetInitialAppData(application_id, nicknames,
+ app_hmi_types);
+}
+
+void PolicyManagerImpl::SetDeviceInfo(const std::string& device_id,
+ const DeviceInfo& device_info) {
+ LOG4CXX_INFO(logger_, "SetDeviceInfo");
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ if (!pt_ext->SetDeviceData(device_id, device_info.hardware,
+ device_info.firmware_rev, device_info.os,
+ device_info.os_ver, device_info.carrier,
+ device_info.max_number_rfcom_ports)) {
+ LOG4CXX_WARN(logger_, "Can't set device data.");
+ }
+ }
+#endif
+}
+
+void PolicyManagerImpl::SetUserConsentForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_INFO(logger_, "SetUserConsentForApp");
+#if defined (EXTENDED_POLICY)
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ // TODO(AOleynik): Change device id to appropriate value (MAC with SHA-256)
+ // in parameters
+ if (!pt_ext->SetUserPermissionsForApp(permissions)) {
+ LOG4CXX_WARN(logger_, "Can't set user permissions for application.");
+ }
+ // Send OnPermissionChange notification, since consents were changed
+ std::vector<FunctionalGroupPermission> app_group_permissons;
+ GetUserPermissionsForApp(permissions.device_id,
+ permissions.policy_app_id,
+ app_group_permissons);
+
+ // Get current functional groups from DB with RPC permissions
+ policy_table::FunctionalGroupings functional_groups;
+ policy_table_.pt_data()->GetFunctionalGroupings(functional_groups);
+
+ // Get list of groups assigned to application
+ policy_table::Strings app_groups;
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ app_group_permissons.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ app_group_permissons.end();
+ for (; it != it_end; ++it) {
+ app_groups.push_back((*it).group_name);
+ }
+
+ // Fill notification data according to group permissions
+ Permissions notification_data;
+ PrepareNotificationData(functional_groups, app_groups,
+ app_group_permissons, notification_data);
+
+ std::string default_hmi;
+ pt_ext->GetDefaultHMI(permissions.policy_app_id, &default_hmi);
+
+ listener()->OnPermissionsUpdated(permissions.policy_app_id,
+ notification_data,
+ default_hmi);
+ }
+#endif
+}
+
+bool PolicyManagerImpl::GetDefaultHmi(const std::string& policy_app_id,
+ std::string* default_hmi) {
+ LOG4CXX_INFO(logger_, "GetDefaultHmi");
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't get default hmi level.");
+ return false;
+ }
+
+ return pt_ext->GetDefaultHMI(policy_app_id, default_hmi);
+#else
+ return false;
+#endif
+}
+
+bool PolicyManagerImpl::GetPriority(const std::string& policy_app_id,
+ std::string* priority) {
+ LOG4CXX_INFO(logger_, "GetPriority");
+ if (!priority) {
+ LOG4CXX_WARN(logger_, "Input priority parameter is null.");
+ return false;
+ }
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (!pt_ext) {
+ LOG4CXX_WARN(logger_, "Can't get priority.");
+ return false;
+ }
+
+ return pt_ext->GetPriority(policy_app_id, priority);
+#else
+ priority->clear();
+ return true;
+#endif
+}
+
+std::vector<UserFriendlyMessage> PolicyManagerImpl::GetUserFriendlyMessages(
+ const std::vector<std::string>& message_code, const std::string& language) {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ // For extended policy
+ if (pt_ext) {
+ return pt_ext->GetUserFriendlyMsg(message_code, language);
+ }
+#endif
+ // For basic policy
+ return policy_table_.pt_data()->GetUserFriendlyMsg(message_code, language);
+}
+
+void PolicyManagerImpl::GetUserPermissionsForApp(
+ const std::string& device_id, const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_INFO(logger_, "GetUserPermissionsForApp");
+#if defined (EXTENDED_POLICY)
+ std::string app_id_to_check = policy_app_id;
+
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ // Application is limited to pre_DataConsent permission until device is
+ // allowed by user
+ if (kDeviceHasNoConsent == device_consent ||
+ kDeviceDisallowed == device_consent) {
+ app_id_to_check = kPreDataConsentId;
+ }
+
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ // For extended policy
+ if (pt_ext) {
+ FunctionalIdType group_types;
+ if (!pt_ext->GetUserPermissionsForApp(device_id, app_id_to_check,
+ &group_types)) {
+ LOG4CXX_WARN(logger_, "Can't get user permissions for app "
+ << policy_app_id);
+ return;
+ }
+
+ FunctionalGroupIDs all_groups = group_types[kTypeGeneral];
+ // If application is limited to pre_Dataconsent only related groups are
+ // allowed
+ FunctionalGroupIDs allowed_groups =
+ app_id_to_check == kPreDataConsentId ?
+ group_types[kTypeGeneral] :
+ group_types[kTypeAllowed];
+ FunctionalGroupIDs disallowed_groups = group_types[kTypeDisallowed];
+ FunctionalGroupIDs preconsented_groups = group_types[kTypePreconsented];
+ // If application is limited to pre_DataConsent - no default groups
+ // permissions should be used
+ FunctionalGroupIDs default_groups =
+ app_id_to_check == kPreDataConsentId ?
+ FunctionalGroupIDs() : group_types[kTypeDefault];
+
+ std::sort(all_groups.begin(), all_groups.end());
+ std::sort(allowed_groups.begin(), allowed_groups.end());
+ std::sort(disallowed_groups.begin(), disallowed_groups.end());
+ std::sort(preconsented_groups.begin(), preconsented_groups.end());
+ std::sort(default_groups.begin(), default_groups.end());
+
+ // Find groups with undefinded consent
+ FunctionalGroupIDs no_preconsented;
+ std::set_difference(all_groups.begin(), all_groups.end(),
+ preconsented_groups.begin(), preconsented_groups.end(),
+ std::back_inserter(no_preconsented));
+ FunctionalGroupIDs no_allowed_preconsented;
+ std::set_difference(no_preconsented.begin(), no_preconsented.end(),
+ allowed_groups.begin(), allowed_groups.end(),
+ std::back_inserter(no_allowed_preconsented));
+ FunctionalGroupIDs no_allowed_preconsented_default;
+ std::set_difference(no_allowed_preconsented.begin(),
+ no_allowed_preconsented.end(),
+ default_groups.begin(), default_groups.end(),
+ std::back_inserter(no_allowed_preconsented_default));
+ FunctionalGroupIDs undefined_consent;
+ std::set_difference(no_allowed_preconsented_default.begin(),
+ no_allowed_preconsented_default.end(),
+ disallowed_groups.begin(), disallowed_groups.end(),
+ std::back_inserter(undefined_consent));
+
+ // Find common allowed groups
+ FunctionalGroupIDs preconsented_allowed;
+ std::merge(allowed_groups.begin(), allowed_groups.end(),
+ preconsented_groups.begin(), preconsented_groups.end(),
+ std::back_inserter(preconsented_allowed));
+ FunctionalGroupIDs merged_allowed_preconsented(preconsented_allowed.begin(),
+ std::unique(preconsented_allowed.begin(),
+ preconsented_allowed.end()));
+ // Default groups are always allowed
+ FunctionalGroupIDs merged_allowed_preconsented_default;
+ std::merge(merged_allowed_preconsented.begin(),
+ merged_allowed_preconsented.end(),
+ default_groups.begin(), default_groups.end(),
+ std::back_inserter(merged_allowed_preconsented_default));
+ FunctionalGroupIDs common_allowed(
+ merged_allowed_preconsented_default.begin(),
+ std::unique(merged_allowed_preconsented_default.begin(),
+ merged_allowed_preconsented_default.end()));
+
+
+ // Find common disallowed groups
+ FunctionalGroupIDs common_disallowed;
+ std::set_difference(disallowed_groups.begin(), disallowed_groups.end(),
+ preconsented_groups.begin(), preconsented_groups.end(),
+ std::back_inserter(common_disallowed));
+
+ FunctionalGroupNames group_names;
+ if (!pt_ext->GetFunctionalGroupNames(group_names)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return;
+ }
+
+ // Fill result
+ FillFunctionalGroupPermissions(undefined_consent, group_names,
+ kGroupUndefined, permissions);
+ FillFunctionalGroupPermissions(common_allowed, group_names,
+ kGroupAllowed, permissions);
+ FillFunctionalGroupPermissions(common_disallowed, group_names,
+ kGroupDisallowed, permissions);
+
+ return;
+ }
+#else
+ // For basic policy
+ permissions = std::vector<FunctionalGroupPermission>();
+#endif
+}
+
+std::string& PolicyManagerImpl::GetCurrentDeviceId(
+ const std::string& policy_app_id) {
+ LOG4CXX_INFO(logger_, "GetDeviceInfo");
+ last_device_id_ =
+ listener()->OnCurrentDeviceIdUpdateRequired(policy_app_id);
+ return last_device_id_;
+}
+
+void PolicyManagerImpl::SetSystemLanguage(const std::string& language) {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ pt_ext->SetSystemLanguage(language);
+ return;
+ }
+#endif
+}
+
+void PolicyManagerImpl::SetSystemInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_INFO(logger_, "SetSystemInfo");
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ pt_ext->SetMetaInfo(ccpu_version, wers_country_code, language);
+ return;
+ }
+#endif
+}
+
+bool PolicyManagerImpl::ExceededIgnitionCycles() {
+ return policy_table_.pt_data()->IgnitionCyclesBeforeExchange() == 0;
+}
+
+bool PolicyManagerImpl::ExceededDays(int days) {
+ return policy_table_.pt_data()->DaysBeforeExchange(days) == 0;
+}
+
+bool PolicyManagerImpl::ExceededKilometers(int kilometers) {
+ return policy_table_.pt_data()->KilometersBeforeExchange(kilometers) == 0;
+}
+
+void PolicyManagerImpl::IncrementIgnitionCycles() {
+ policy_table_.pt_data()->IncrementIgnitionCycles();
+}
+
+int PolicyManagerImpl::NextRetryTimeout() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ LOG4CXX_DEBUG(logger_, "Index: " << retry_sequence_index_);
+ int next = 0;
+ if (!retry_sequence_seconds_.empty()
+ && retry_sequence_index_ < retry_sequence_seconds_.size()) {
+ next = retry_sequence_seconds_[retry_sequence_index_];
+ ++retry_sequence_index_;
+ }
+ return next;
+}
+
+void PolicyManagerImpl::RefreshRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_timeout_ = policy_table_.pt_data()->TimeoutResponse();
+ retry_sequence_seconds_.clear();
+ policy_table_.pt_data()->SecondsBetweenRetries(&retry_sequence_seconds_);
+}
+
+void PolicyManagerImpl::ResetRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_index_ = 0;
+
+ if (exchange_in_progress_) {
+ set_exchange_pending(true);
+ }
+ set_update_required(true);
+}
+
+int PolicyManagerImpl::TimeoutExchange() {
+ return retry_sequence_timeout_;
+}
+
+const std::vector<int> PolicyManagerImpl::RetrySequenceDelaysSeconds() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ return retry_sequence_seconds_;
+}
+
+void PolicyManagerImpl::OnExceededTimeout() {
+ set_exchange_in_progress(false);
+}
+
+void PolicyManagerImpl::PTUpdatedAt(int kilometers, int days_after_epoch) {
+ LOG4CXX_INFO(logger_, "PTUpdatedAt");
+ LOG4CXX_INFO(logger_,
+ "Kilometers: " << kilometers << " Days: " << days_after_epoch);
+ policy_table_.pt_data()->SetCountersPassedForSuccessfulUpdate(
+ kilometers, days_after_epoch);
+ policy_table_.pt_data()->ResetIgnitionCycles();
+}
+
+void PolicyManagerImpl::Increment(usage_statistics::GlobalCounterId type) {
+ std::string counter;
+ switch (type) {
+ case usage_statistics::IAP_BUFFER_FULL:
+ counter = "count_of_iap_buffer_full";
+ break;
+ case usage_statistics::SYNC_OUT_OF_MEMORY:
+ counter = "count_sync_out_of_memory";
+ break;
+ case usage_statistics::SYNC_REBOOTS:
+ counter = "count_of_sync_reboots";
+ break;
+ default:
+ LOG4CXX_INFO(logger_, "Type global counter is unknown");
+ return;
+ }
+#if defined (EXTENDED_POLICY)
+ // TODO(KKolodiy): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ pt_ext->Increment(counter);
+#endif
+}
+
+void PolicyManagerImpl::Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type) {
+ std::string counter;
+ switch (type) {
+ case usage_statistics::USER_SELECTIONS:
+ counter = "count_of_user_selections";
+ break;
+ case usage_statistics::REJECTIONS_SYNC_OUT_OF_MEMORY:
+ counter = "count_of_rejections_sync_out_of_memory";
+ break;
+ case usage_statistics::REJECTIONS_NICKNAME_MISMATCH:
+ counter = "count_of_rejections_nickname_mismatch";
+ break;
+ case usage_statistics::REJECTIONS_DUPLICATE_NAME:
+ counter = "count_of_rejections_duplicate_name";
+ break;
+ case usage_statistics::REJECTED_RPC_CALLS:
+ counter = "count_of_ejected_rpc_calls";
+ break;
+ case usage_statistics::RPCS_IN_HMI_NONE:
+ counter = "count_of_rpcs_sent_in_hmi_none";
+ break;
+ case usage_statistics::REMOVALS_MISBEHAVED:
+ counter = "count_of_removals_misbehaved";
+ break;
+ case usage_statistics::RUN_ATTEMPTS_WHILE_REVOKED:
+ counter = "count_of_run_attempts_while_revoked";
+ break;
+ default:
+ LOG4CXX_INFO(logger_, "Type app counter is unknown");
+ return;
+ }
+#if defined (EXTENDED_POLICY)
+ // TODO(KKolodiy): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ sync_primitives::AutoLock locker(statistics_lock_);
+ pt_ext->Increment(app_id, counter);
+#endif
+}
+
+void PolicyManagerImpl::Set(const std::string& app_id,
+ usage_statistics::AppInfoId type,
+ const std::string& value) {
+ std::string info;
+ switch (type) {
+ case usage_statistics::LANGUAGE_GUI:
+ info = "app_registration_language_gui";
+ break;
+ case usage_statistics::LANGUAGE_VUI:
+ info = "app_registration_language_vui";
+ break;
+ default:
+ LOG4CXX_INFO(logger_, "Type app info is unknown");
+ return;
+ }
+
+#if defined (EXTENDED_POLICY)
+ // TODO(KKolodiy): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ sync_primitives::AutoLock locker(statistics_lock_);
+ pt_ext->Set(app_id, info, value);
+#endif
+}
+
+void PolicyManagerImpl::Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int32_t timespan_seconds) {
+#if defined (EXTENDED_POLICY)
+ std::string stopwatch;
+ switch (type) {
+ // TODO(KKolodiy): rename fields in database
+ case usage_statistics::SECONDS_HMI_FULL:
+ stopwatch = "minutes_hmi_full";
+ break;
+ case usage_statistics::SECONDS_HMI_LIMITED:
+ stopwatch = "minutes_hmi_limited";
+ break;
+ case usage_statistics::SECONDS_HMI_BACKGROUND:
+ stopwatch = "minutes_hmi_background";
+ break;
+ case usage_statistics::SECONDS_HMI_NONE:
+ stopwatch = "minutes_hmi_none";
+ break;
+ default:
+ LOG4CXX_INFO(logger_, "Type app stopwatch is unknown");
+ return;
+ }
+ // TODO(KKolodiy): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ sync_primitives::AutoLock locker(statistics_lock_);
+ pt_ext->Add(app_id, stopwatch, timespan_seconds);
+#endif
+}
+
+bool PolicyManagerImpl::IsApplicationRevoked(const std::string& app_id) const {
+ return policy_table_.pt_data()->IsApplicationRevoked(app_id);
+}
+
+int PolicyManagerImpl::IsConsentNeeded(const std::string& app_id) {
+#if defined (EXTENDED_POLICY)
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ int count = 0;
+ if (pt_ext->CountUnconsentedGroups(app_id, &count)) {
+ return count;
+ } else {
+ return 0;
+ }
+#endif
+ return 0;
+}
+
+void PolicyManagerImpl::CheckUpdateStatus() {
+ LOG4CXX_INFO(logger_, "CheckUpdateStatus");
+ policy::PolicyTableStatus status = GetPolicyTableStatus();
+ if (last_update_status_ != status) {
+ listener_->OnUpdateStatusChanged(status);
+ }
+ last_update_status_ = status;
+}
+
+AppPermissions PolicyManagerImpl::GetAppPermissionsChanges(
+ const std::string& app_id) {
+ typedef std::map<std::string, AppPermissions>::const_iterator PermissionsIt;
+ PermissionsIt app_id_diff = app_permissions_diff_.find(app_id);
+ AppPermissions permissions(app_id);
+ if (app_permissions_diff_.end() != app_id_diff) {
+ permissions = app_id_diff->second;
+ } else {
+ permissions.appPermissionsConsentNeeded = IsConsentNeeded(app_id);
+ permissions.appRevoked = IsApplicationRevoked(app_id);
+ GetPriority(permissions.application_id, &permissions.priority);
+ }
+ return permissions;
+}
+
+void PolicyManagerImpl::RemovePendingPermissionChanges(
+ const std::string& app_id) {
+ app_permissions_diff_.erase(app_id);
+}
+
+bool PolicyManagerImpl::CanAppKeepContext(const std::string& app_id) {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ return pt_ext->CanAppKeepContext(app_id);
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+bool PolicyManagerImpl::CanAppStealFocus(const std::string& app_id) {
+#if defined (EXTENDED_POLICY)
+ // TODO(AOleynik): Check design for more convenient access to policy ext data
+ PTExtRepresentation* pt_ext = dynamic_cast<PTExtRepresentation*>(policy_table_
+ .pt_data().get());
+ if (pt_ext) {
+ return pt_ext->CanAppStealFocus(app_id);
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/src/policy_table.cc b/src/components/policy/src/policy/src/policy_table.cc
new file mode 100644
index 000000000..7c37a049d
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_table.cc
@@ -0,0 +1,64 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/policy_table.h"
+#ifdef EXTENDED_POLICY
+# include "policy/sql_pt_ext_representation.h"
+#else // EXTENDED_POLICY
+# include "policy/sql_pt_representation.h"
+#endif // EXTENDED_POLICY
+
+#include "utils/logger.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyTable")
+
+PolicyTable::PolicyTable()
+ : pt_data_(
+#ifdef EXTENDED_POLICY
+ new SQLPTExtRepresentation()
+#else // EXTENDED_POLICY
+ new SQLPTRepresentation()
+#endif // EXTENDED_POLICY
+ ) {
+}
+
+PolicyTable::PolicyTable(utils::SharedPtr<PTRepresentation> pt_data)
+ : pt_data_(pt_data) {
+}
+
+PolicyTable::~PolicyTable() {
+ LOG4CXX_INFO(logger_, "Destroying policy table.");
+}
+
+} // namespace policy
diff --git a/src/components/policy/src/policy/src/sql_pt_ext_queries.cc b/src/components/policy/src/policy/src/sql_pt_ext_queries.cc
new file mode 100644
index 000000000..328260fb5
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_ext_queries.cc
@@ -0,0 +1,199 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_ext_queries.h"
+
+namespace policy {
+namespace sql_pt_ext {
+
+const std::string kSelectKeepContext =
+ "SELECT `keep_context` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectStealFocus =
+ "SELECT `steal_focus` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectDefaultHmi =
+ "SELECT `default_hmi` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectPriority =
+ "SELECT `priority_value` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kResetUserConsent = "DELETE FROM `device_consent_group`";
+
+const std::string kCountDeviceConsentGroup = "SELECT COUNT (`device_id`) "
+ "FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kCountDevice = "SELECT COUNT (`id`) "
+ "FROM `device` WHERE `id` = ?";
+
+const std::string kSelectDeviceConsentedGroup =
+ "SELECT * FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kUpdateDeviceConsentedGroup =
+ "UPDATE `device_consent_group` SET `is_consented` = ? WHERE "
+ "(`device_id` = ? AND `functional_group_id` = ?)";
+
+const std::string kUpdateDevice =
+ "UPDATE `device` SET `hardware` = ?, `firmware_rev` = ?, `os` = ?, "
+ "`os_version` = ?, `carrier` = ?, `max_number_rfcom_ports` = ? "
+ "WHERE `id` = ? ";
+
+const std::string kInsertDeviceConsentedGroup =
+ "INSERT OR IGNORE INTO `device_consent_group` "
+ "(`device_id`, `functional_group_id`, `is_consented`, `input`) "
+ "VALUES (?,?,?,?)";
+
+const std::string kInsertDevice =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`, `max_number_rfcom_ports`) "
+ "VALUES (?,?,?,?,?,?,?)";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectConsentGroup =
+ "SELECT * FROM `consent_group` WHERE `device_id` = ? ";
+
+const std::string kInsertPreconsentedGroups =
+ "INSERT INTO `preconsented_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kSelectPreconsentedGroups =
+ "SELECT `f`.`name` FROM `preconsented_group` AS `p`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `p`.`functional_group_id`)"
+ " WHERE `p`.`application_id` = ?";
+
+const std::string kDeletePreconsentedGroups = "DELETE FROM `preconsented_group`";
+
+const std::string kSelectUsageAndErrorCount =
+ "SELECT `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots` "
+ "FROM `usage_and_error_count` LIMIT 1";
+
+const std::string kSelectAppLevels =
+ "SELECT `application_id`, `minutes_in_hmi_full`, `minutes_in_hmi_limited`, "
+ " `minutes_in_hmi_background`, `minutes_in_hmi_none`, "
+ " `count_of_rfcomm_limit_reached`, `count_of_user_selections`, "
+ " `count_of_rejections_sync_out_of_memory`, "
+ " `count_of_rejections_nickname_mismatch`, "
+ " `count_of_rejections_duplicate_name`, "
+ " `count_of_rejected_rpcs_calls`, "
+ " `count_of_rpcs_sent_in_hmi_none`, "
+ " `count_of_removals_for_bad_behavior`, "
+ " `count_of_run_attempts_while_revoked`, "
+ " `app_registration_language_gui`, "
+ " `app_registration_language_vui` "
+ "FROM `app_level`";
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`, `max_number_rfcom_ports`) "
+ "VALUES (?,?,?,?,?,?,?) ";
+
+const std::string kInsertConsentGroups =
+ "INSERT OR IGNORE INTO `consent_group` "
+ "(`device_id`, `application_id`, `functional_group_id`, `is_consented`, `input`) "
+ "VALUES (?,?,?,?,?)";
+
+const std::string kCountUnconsentedGroups =
+ "SELECT COUNT(`a`.`functional_group_id`) FROM `app_group` AS `a` "
+ "JOIN `consent_group` AS `f` ON (`a`.`application_id` = `f`.`application_id`) "
+ "JOIN `preconsented_group` AS `p` ON (`p`.`application_id` = `a`.`application_id`) "
+ "WHERE `a`.`application_id` = ? AND NOT (`f`.`functional_group_id` = `a`.`functional_group_id`) "
+ "AND NOT (`p`.`functional_group_id` = `a`.`functional_group_id`)";
+
+const std::string kSelectModuleMeta = "SELECT * FROM `module_meta`";
+
+const std::string kUpdateMetaParams = "UPDATE `module_meta` SET "
+ "`ccpu_version` = ?, `wers_country_code` = ?, `language` = ? ";
+
+const std::string kUpdateMetaLanguage = "UPDATE `module_meta` SET `language` = ? ";
+
+const std::string kCountAppLevel =
+ "SELECT COUNT(`application_id`) FROM `app_level`"
+ " WHERE `application_id` = ?";
+
+const std::string kUpdateGroupPermissions =
+ "UPDATE `consent_group` "
+ "SET `is_consented` = ?, `input` = ? "
+ "WHERE (`application_id` = ? AND `functional_group_id` = ? AND `device_id` = ?) ";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application` (`id`, `keep_context`, `steal_focus`,"
+ " `default_hmi`, `priority_value`, `is_revoked`, `memory_kb`,"
+ " `watchdog_timer_ms`, `certificate`) VALUES (?,?,?,?,?,?,?,?,?) ";
+
+const std::string kSelectFriendlyMsg =
+ "SELECT `tts`, `label`, `line1`, `line2`, `textBody` FROM `message` "
+ "WHERE `message_type_name` = ? AND `language_code` = ? LIMIT 1";
+
+const std::string kSelectAppGroupsId = "SELECT `functional_group_id` "
+ "FROM `app_group` WHERE `application_id` = ? ";
+
+const std::string kSelectConsentedGroupsId =
+ "SELECT `functional_group_id`, `is_consented` "
+ "FROM `consent_group` WHERE (`application_id` = ? AND `device_id` = ?) ";
+
+const std::string kCountAppConsents = "SELECT COUNT (*) from `consent_group`"
+ "WHERE (`device_id` = ? AND `application_id` = ? AND "
+ "`functional_group_id` = ?) ";
+
+const std::string kSelectPreconsentedGroupsId = "SELECT `functional_group_id` "
+ "FROM `preconsented_group` WHERE `application_id` = ? ";
+
+const std::string kSelectAppPolicies =
+ "SELECT `id`, `priority_value`, `default_hmi`, `keep_context`, `steal_focus`,"
+ " `memory_kb`, `watchdog_timer_ms`, `certificate` FROM `application`";
+
+const std::string kSelectFunctionalGroupNames = "SELECT `id`, `user_consent_prompt`, `name`"
+ " FROM `functional_group`";
+
+const std::string kDeleteDeviceConsent = "DELETE FROM `device_consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kDeleteAppConsent = "DELETE FROM `consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kSelectApplicationIsPreData =
+ "SELECT `is_predata` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateIsPredata =
+ "UPDATE `application` SET `is_predata` = ? WHERE `id` = ?";
+
+const std::string kHasAppPreloadedGroups =
+ "SELECT COUNT(`a1`.`functional_group_id`) FROM `app_group` "
+ " AS `a1` JOIN `app_group` AS `a2` "
+ " ON `a1`.`functional_group_id` = `a2`.`functional_group_id` "
+ " WHERE `a1`.`application_id` = ? AND `a2`.`application_id` = ? ";
+
+
+} // namespace sql_pt_ext
+} // namespace policy
diff --git a/src/components/policy/src/policy/src/sql_pt_ext_representation.cc b/src/components/policy/src/policy/src/sql_pt_ext_representation.cc
new file mode 100644
index 000000000..78d33812d
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_ext_representation.cc
@@ -0,0 +1,1296 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <algorithm>
+#include <utility>
+#include "utils/logger.h"
+#include "policy/sql_pt_ext_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+#include "policy/sql_pt_ext_queries.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "SQLPTRepresentation")
+
+bool SQLPTExtRepresentation::CanAppKeepContext(const std::string& app_id) {
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectKeepContext)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::CanAppStealFocus(const std::string& app_id) {
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectStealFocus)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::ResetUserConsent() {
+ return dbms::SQLQuery(db()).Exec(sql_pt_ext::kResetUserConsent);
+}
+
+bool SQLPTExtRepresentation::GetUserPermissionsForDevice(
+ const std::string& device_id, StringArray* consented_groups,
+ StringArray* disallowed_groups) {
+ LOG4CXX_INFO(logger_, "GetUserPermissionsForDevice");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from device consented groups");
+ return false;
+ }
+ query.Bind(0, device_id);
+ while (query.Next()) {
+ if (query.GetBoolean(2)) {
+ if (!consented_groups) {
+ continue;
+ }
+ consented_groups->push_back(query.GetString(1));
+ } else {
+ if (!disallowed_groups) {
+ continue;
+ }
+ disallowed_groups->push_back(query.GetString(1));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetUserPermissionsForApp(
+ const std::string& device_id, const std::string& policy_app_id,
+ FunctionalIdType* group_types) {
+ LOG4CXX_INFO(logger_, "GetUserPermissionsForApp");
+ if (!group_types) {
+ LOG4CXX_WARN(logger_, "Input parameter for group types is null.");
+ return false;
+ }
+ // Get all app groups for specified device and application
+ FunctionalGroupIDs all_groups;
+ if (!GetAllAppGroups(policy_app_id, all_groups)) {
+ return false;
+ }
+ // Get preconsented group
+ FunctionalGroupIDs preconsented_groups;
+ if (!GetPreconsentedGroups(policy_app_id, preconsented_groups)) {
+ return false;
+ }
+ // Get consented (allowed/disallowed) groups
+ FunctionalGroupIDs allowed_groups;
+ FunctionalGroupIDs disallowed_groups;
+ if (!GetConsentedGroups(policy_app_id, device_id,
+ allowed_groups, disallowed_groups)) {
+ return false;
+ }
+ // Get all default groups - they should always be allowed
+ FunctionalGroupIDs default_groups;
+ if (!GetAllAppGroups(kDefaultId, default_groups)) {
+ return false;
+ }
+
+ (*group_types)[kTypeDefault] = default_groups;
+ (*group_types)[kTypeAllowed] = allowed_groups;
+ (*group_types)[kTypeDisallowed] = disallowed_groups;
+ (*group_types)[kTypePreconsented] = preconsented_groups;
+ (*group_types)[kTypeGeneral] = all_groups;
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetDeviceGroupsFromPolicies(
+ policy_table::Strings* groups, policy_table::Strings* preconsented_groups) {
+ LOG4CXX_INFO(logger_, "GetDeviceGroupsFromPolicies");
+ if (groups) {
+ GatherAppGroup(kDeviceId, groups);
+ }
+ if (preconsented_groups) {
+ GatherPreconsentedGroup(kDeviceId, preconsented_groups);
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDeviceData(const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports) {
+ LOG4CXX_INFO(logger_, "SetDeviceData");
+ dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for count of device.");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device.");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // Update old value
+ if (update) {
+ dbms::SQLQuery update_query(db());
+ if (!update_query.Prepare(sql_pt_ext::kUpdateDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for udpate device.");
+ return false;
+ }
+
+ update_query.Bind(0, hardware);
+ update_query.Bind(1, firmware);
+ update_query.Bind(2, os);
+ update_query.Bind(3, os_version);
+ update_query.Bind(4, carrier);
+ update_query.Bind(5, static_cast<int>(number_of_ports));
+ update_query.Bind(6, device_id);
+
+ if (!update_query.Exec() || !update_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for device.");
+ return false;
+ }
+
+ return true;
+ }
+
+ // Insert new data
+ dbms::SQLQuery insert_query(db());
+ if (!insert_query.Prepare(sql_pt_ext::kInsertDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device.");
+ return false;
+ }
+
+ insert_query.Bind(0, device_id);
+ insert_query.Bind(1, hardware);
+ insert_query.Bind(2, firmware);
+ insert_query.Bind(3, os);
+ insert_query.Bind(4, os_version);
+ insert_query.Bind(5, carrier);
+ insert_query.Bind(6, static_cast<int>(number_of_ports));
+
+ if (!insert_query.Exec() || !insert_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForDevice(
+ const std::string& device_id, const StringArray& consented_groups,
+ const StringArray& disallowed_groups) {
+ LOG4CXX_INFO(logger_, "SetUserPermissionsForDevice");
+ dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDeviceConsentGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device consented groups");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device consented groups");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // TODO(AOleynik): Split to several methods?
+ dbms::SQLQuery query(db());
+ // Update old values
+ if (update) {
+ if (!query.Prepare(sql_pt_ext::kUpdateDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect update of device consented groups");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end =
+ consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, 1);
+ query.Bind(1, device_id);
+ query.Bind(2, *it_consented_groups);
+ // TODO(AOleynik): Get this info from external data
+ query.Bind(3, "GUI");
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update of device consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups =
+ disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, 0);
+ query.Bind(1, device_id);
+ query.Bind(2, *it_disallowed_groups);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update of device consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Insert new values
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device consented groups");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end = consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_consented_groups);
+ query.Bind(2, 1);
+ // TODO(AOleynik): Get this info from external data
+ query.Bind(3, std::string("GUI"));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups = disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_disallowed_groups);
+ query.Bind(2, 0);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::ReactOnUserDevConsentForApp(
+ const std::string& app_id,
+ bool is_device_allowed) {
+ bool result = true;
+ if (is_device_allowed) {
+ // If app has pre_DataConsented groups it should be 'promoted' to default
+ // If app has only pre_DataConsented flag it should be only set to false and
+ // all groups get restored automatically
+ if (IsPredataPolicy(app_id)) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kHasAppPreloadedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for has app preloaded groups");
+ return false;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, kPreDataConsentId);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select for app has predataconsted groups");
+ return false;
+ }
+ if (query.GetInteger(0) > 0) {
+ result = result && SetDefaultPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, false);
+ }
+ }
+ } else {
+ // If app has default groups change them to pre_DataConsented
+ // If app has 'normal' groups leave them as is and set
+ // pre_DataConsented flag to true.
+ if (IsDefaultPolicy(app_id)) {
+ result = result && SetPredataPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, true);
+ }
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_INFO(logger_, "SetUserPermissionsForApp");
+ // TODO(AOleynik): Handle situation, when no application was specified, i.e.
+ // general permissions were set
+ std::vector<FunctionalGroupPermission>::const_iterator it = permissions
+ .group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end = permissions
+ .group_permissions.end();
+
+ dbms::SQLQuery query(db());
+ for (; it != it_end; ++it) {
+ dbms::SQLQuery counter(db());
+ if (!counter.Prepare(sql_pt_ext::kCountAppConsents)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for consent group count.");
+ return false;
+ }
+
+ counter.Bind(0, permissions.device_id);
+ counter.Bind(1, permissions.policy_app_id);
+ counter.Bind(2, static_cast<int>((*it).group_id));
+ if (!counter.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrent count on consent groups.");
+ return false;
+ }
+
+ bool update_required = counter.GetInteger(0);
+
+ // Update already present consent record
+ if (update_required) {
+ if (!query.Prepare(sql_pt_ext::kUpdateGroupPermissions)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update consent groups.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(1, permissions.consent_source);
+ query.Bind(2, permissions.policy_app_id);
+ query.Bind(3, static_cast<int>((*it).group_id));
+ query.Bind(4, permissions.device_id);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update on user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+
+ // Insert new consent record
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for update app group permissions.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, permissions.device_id);
+ query.Bind(1, permissions.policy_app_id);
+ query.Bind(2, static_cast<int>((*it).group_id));
+ query.Bind(3, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(4, permissions.consent_source);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTExtRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ dbms::SQLQuery query(db());
+ std::vector<UserFriendlyMessage> result;
+ if (!query.Prepare(sql_pt_ext::kSelectFriendlyMsg)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ return result;
+ }
+
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ query.Bind(0, *it);
+ query.Bind(1, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from friendly messages.");
+ return result;
+ }
+
+ UserFriendlyMessage msg;
+
+ msg.message_code = *it;
+ msg.tts = query.GetString(0);
+ msg.label = query.GetString(1);
+ msg.line1 = query.GetString(2);
+ msg.line2 = query.GetString(3);
+ msg.text_body = query.GetString(4);
+
+ result.push_back(msg);
+
+ if (!query.Reset()) {
+ LOG4CXX_WARN(logger_, "Faild reset statement for selecting friendly messages.");
+ return result;
+ }
+ }
+
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_INFO(logger_, "SetMetaInfo");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaParams)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for insert to module meta.");
+ return false;
+ }
+
+ query.Bind(0, ccpu_version);
+ query.Bind(1, wers_country_code);
+ query.Bind(2, language);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to module meta.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetSystemLanguage(const std::string& language) {
+ LOG4CXX_INFO(logger_, "SetSystemLanguage");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update meta language.");
+ return false;
+ }
+
+ query.Bind(0, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for meta language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveApplicationPolicies(
+ const policy_table::ApplicationPolicies& apps) {
+ LOG4CXX_INFO(logger_, "SaveApplicationPolicies ext");
+ dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+
+ dbms::SQLQuery query_delete_preconsented(db());
+ if (!query_delete_preconsented.Exec(sql_pt_ext::kDeletePreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from preconsented_group.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator it;
+ dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt_ext::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+ for (it = apps.begin(); it != apps.end(); ++it) {
+ app_query.Bind(0, it->first);
+ app_query.Bind(1, it->second.keep_context);
+ app_query.Bind(2, it->second.steal_focus);
+ app_query.Bind(
+ 3, std::string(policy_table::EnumToJsonString(it->second.default_hmi)));
+ app_query.Bind(
+ 4, std::string(policy_table::EnumToJsonString(it->second.priority)));
+ printf("\n\t\t\t\tIs app Revoked: %s: %d\n", it->first.c_str(), it->second.is_null());
+ app_query.Bind(
+ 5, it->second.is_null());
+ app_query.Bind(6, it->second.memory_kb);
+ app_query.Bind(7, it->second.watchdog_timer_ms);
+ it->second.certificate.is_initialized() ?
+ app_query.Bind(8, *it->second.certificate) : app_query.Bind(8, std::string());
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ LOG4CXX_INFO(logger_, "Saving data for application: " << it->first);
+ if (!SaveAppGroup(it->first, it->second.groups)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveNickname(it->first, *it->second.nicknames)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveAppType(it->first, *it->second.AppHMIType)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SavePreconsentedGroup(it->first, *it->second.preconsented_groups)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GatherApplicationPolicies(
+ policy_table::ApplicationPolicies* apps) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ params.priority = priority;
+ policy_table::HmiLevel hmi;
+ policy_table::EnumFromJsonString(query.GetString(2), &hmi);
+ params.default_hmi = hmi;
+ params.keep_context = query.GetBoolean(3);
+ params.steal_focus = query.GetBoolean(4);
+ *params.memory_kb = query.GetInteger(5);
+ *params.watchdog_timer_ms = query.GetInteger(6);
+ if (!query.IsNull(7)) {
+ *params.certificate = query.GetString(7);
+ }
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ GatherPreconsentedGroup(app_id, &*params.preconsented_groups);
+ (*apps)[app_id] = params;
+ }
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherPreconsentedGroup(
+ const std::string& app_id, policy_table::Strings* groups) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from preconsented group");
+ return;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ groups->push_back(query.GetString(0));
+ }
+}
+
+bool SQLPTExtRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectUsageAndErrorCount) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed select from user_and_error_count");
+ return false;
+ }
+
+ *counts->count_of_iap_buffer_full = query.GetInteger(0);
+ *counts->count_sync_out_of_memory = query.GetInteger(1);
+ *counts->count_of_sync_reboots = query.GetInteger(2);
+
+ return GatherAppLevels(&*counts->app_level);
+}
+
+bool SQLPTExtRepresentation::GatherAppLevels(
+ policy_table::AppLevels* apps) const {
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectAppLevels)) {
+ LOG4CXX_INFO(logger_, "Failed select from app_level");
+ return false;
+ }
+ const int kSecondsInMinute = 60;
+ while (query.Next()) {
+ policy_table::AppLevel level;
+ // value of time fields database is seconds
+ level.minutes_in_hmi_full = query.GetInteger(1) / kSecondsInMinute;
+ level.minutes_in_hmi_limited = query.GetInteger(2) / kSecondsInMinute;
+ level.minutes_in_hmi_background = query.GetInteger(3) / kSecondsInMinute;
+ level.minutes_in_hmi_none = query.GetInteger(4) / kSecondsInMinute;
+ level.count_of_rfcom_limit_reached = query.GetInteger(5);
+ level.count_of_user_selections = query.GetInteger(6);
+ level.count_of_rejections_sync_out_of_memory = query.GetInteger(7);
+ level.count_of_rejections_nickname_mismatch = query.GetInteger(8);
+ level.count_of_rejections_duplicate_name = query.GetInteger(9);
+ level.count_of_rejected_rpc_calls = query.GetInteger(10);
+ level.count_of_rpcs_sent_in_hmi_none = query.GetInteger(11);
+ level.count_of_removals_for_bad_behavior = query.GetInteger(12);
+ level.count_of_run_attempts_while_revoked = query.GetInteger(13);
+ level.app_registration_language_gui = query.GetString(14);
+ level.app_registration_language_vui = query.GetString(15);
+ (*apps)[query.GetString(0)] = level;
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for device data.");
+ return;
+ }
+
+ while (query.Next()) {
+ policy_table::DeviceParams* specific_device = &(*data)[query.GetString(0)];
+ *specific_device->hardware = query.GetString(1);
+ *specific_device->firmware_rev = query.GetString(2);
+ *specific_device->os = query.GetString(3);
+ *specific_device->os_version = query.GetString(4);
+ *specific_device->carrier = query.GetString(5);
+ *specific_device->max_number_rfcom_ports = query.GetInteger(6);
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ GatherConsentGroup(query.GetString(0),
+ &(*specific_device->user_consent_records));
+ }
+}
+
+void SQLPTExtRepresentation::GatherConsentGroup(
+ const std::string& device_id,
+ policy_table::UserConsentRecords* records) const {
+ LOG4CXX_INFO(logger_, "Gather consent records.");
+ dbms::SQLQuery query(db());
+ // Fill data for device
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for device consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> "device"
+ while (query.Next()) {
+ policy_table::ConsentRecords* device_consent_records = &(*records)[kDeviceId];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups = *device_consent_records->consent_groups;
+ consent_groups[query.GetString(1)] = query.GetBoolean(2);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(3), &input);
+ *device_consent_records->input = input;
+ *device_consent_records->time_stamp = query.GetString(4);
+ }
+
+ if (!query.Reset()) {
+ return;
+ }
+
+ // Fill data for applications
+ if (!query.Prepare(sql_pt_ext::kSelectConsentGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for app consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> <app_id>
+ while (query.Next()) {
+ policy_table::ConsentRecords* app_consent_records = &(*records)[query
+ .GetString(1)];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups = *app_consent_records->consent_groups;
+
+ consent_groups[query.GetString(2)] = query.GetBoolean(3);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(4), &input);
+ *app_consent_records->input = input;
+ *app_consent_records->time_stamp = query.GetString(5);
+ }
+}
+
+bool SQLPTExtRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ LOG4CXX_INFO(logger_, "SaveDeviceData");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it = devices.begin();
+ policy_table::DeviceData::const_iterator it_end = devices.end();
+ for (; it != it_end; ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, *(it->second.hardware));
+ query.Bind(2, *(it->second.firmware_rev));
+ query.Bind(3, *(it->second.os));
+ query.Bind(4, *(it->second.os_version));
+ query.Bind(5, *(it->second.carrier));
+ query.Bind(6, *(it->second.max_number_rfcom_ports));
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveConsentGroup(it->first, *it->second.user_consent_records)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveConsentGroup(
+ const std::string& device_id,
+ const policy_table::UserConsentRecords& records) {
+ LOG4CXX_INFO(logger_, "SaveConsentGroup");
+ dbms::SQLQuery query(db());
+
+ policy_table::UserConsentRecords::const_iterator it = records.begin();
+ policy_table::UserConsentRecords::const_iterator it_end = records.end();
+ for (; it != it_end; ++it) {
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups::const_iterator it_groups = it->second
+ .consent_groups->begin();
+ policy_table::ConsentGroups::const_iterator it_groups_end = it->second
+ .consent_groups->end();
+ for (; it_groups != it_groups_end; ++it_groups) {
+ if (kDeviceId == it->first) {
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for device consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it_groups->first);
+ query.Bind(2, it_groups->second);
+ query.Bind(
+ 3,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ } else {
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it->first);
+ query.Bind(2, it_groups->first);
+ query.Bind(3, it_groups->second);
+ query.Bind(
+ 4,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ }
+
+ if (!query.Exec() && !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into consent group.");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SavePreconsentedGroup(
+ const std::string& app_id, const policy_table::Strings& groups) {
+ LOG4CXX_INFO(logger_, "SavePreconsentedGroup");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for preconsented groups");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = groups.begin(); it != groups.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into preconsented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectModuleMeta) && query.Next()) {
+ *meta->ccpu_version = query.GetString(0);
+ *meta->language = query.GetString(1);
+ *meta->wers_country_code = query.GetString(2);
+ *meta->pt_exchanged_at_odometer_x = query.GetInteger(3);
+ *meta->pt_exchanged_x_days_after_epoch = query.GetInteger(4);
+ *meta->ignition_cycles_since_last_exchange = query.GetInteger(5);
+ *meta->vin = query.GetString(6);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& type) const {
+ dbms::SQLQuery query(db());
+ std::string update_counter = "UPDATE `usage_and_error_count` SET `" + type
+ + "` = `" + type + "` + 1";
+ if (!query.Exec(update_counter)) {
+ LOG4CXX_INFO(logger_, "Failed updating global counter");
+ }
+}
+
+bool SQLPTExtRepresentation::IsExistAppLevel(const std::string& app_id) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountAppLevel)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of count app_level");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed count app_level");
+ return false;
+ }
+ return query.GetInteger(0) > 0;
+}
+
+bool SQLPTExtRepresentation::GetAllAppGroups(const std::string& policy_app_id,
+ FunctionalGroupIDs& all_groups) {
+ LOG4CXX_INFO(logger_, "GetAllAppGroups");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select app groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ all_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetConsentedGroups(
+ const std::string& policy_app_id, const std::string& device_id,
+ FunctionalGroupIDs& allowed_groups, FunctionalGroupIDs& disallowed_groups) {
+
+ LOG4CXX_INFO(logger_, "GetConsentedGroups");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectConsentedGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select consent groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, device_id);
+
+ while (query.Next()) {
+ if (query.GetBoolean(1)) {
+ allowed_groups.push_back(query.GetInteger(0));
+ } else {
+ disallowed_groups.push_back(query.GetInteger(0));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPreconsentedGroups(
+ const std::string& policy_app_id, FunctionalGroupIDs& preconsented_groups) {
+ LOG4CXX_INFO(logger_, "GetPreconsentedGroups");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroupsId)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select preconsented groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ preconsented_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetFunctionalGroupNames(
+ FunctionalGroupNames& names) {
+ LOG4CXX_INFO(logger_, "GetFunctionalGroupNames");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectFunctionalGroupNames)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select functional groups names.");
+ return false;
+ }
+
+ while (query.Next()) {
+ // Some of functional grous doesn't have filled user_consent_prompt
+ if (query.IsNull(1)) {
+ names[query.GetInteger(0)] =
+ std::make_pair<std::string, std::string>("", query.GetString(2));
+ } else {
+ names[query.GetInteger(0)] =
+ std::make_pair<std::string, std::string>(query.GetString(1), query.GetString(2));
+ }
+
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids, FunctionalGroupNames& names, GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& app_id,
+ const std::string& type) const {
+ dbms::SQLQuery query(db());
+ std::string sql_counter;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_counter = "UPDATE `app_level` SET `" + type + "` = `" + type
+ + "` + 1 WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_counter = "INSERT INTO `app_level` (`application_id`, `" + type + "`) "
+ "VALUES (?, 1)";
+ }
+ if (!query.Prepare(sql_counter)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app counter");
+ return;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app counter");
+ }
+}
+
+void SQLPTExtRepresentation::Set(const std::string& app_id,
+ const std::string& type,
+ const std::string& value) const {
+ dbms::SQLQuery query(db());
+ std::string sql_info;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_info = "UPDATE `app_level` SET `" + type + "` = ? "
+ "WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_info = "INSERT INTO `app_level` (`" + type + "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_info)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app info");
+ return;
+ }
+ query.Bind(0, value);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app info");
+ }
+}
+
+void SQLPTExtRepresentation::Add(const std::string& app_id,
+ const std::string& type, int seconds) const {
+ dbms::SQLQuery query(db());
+ std::string sql_stopwatch;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_stopwatch = "UPDATE `app_level` SET `" + type + "` = `" + type
+ + "` + ? WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_stopwatch = "INSERT INTO `app_level` (`" + type
+ + "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_stopwatch)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app stopwatch");
+ return;
+ }
+ query.Bind(0, seconds);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app stopwatch");
+ }
+}
+
+bool SQLPTExtRepresentation::GetDefaultHMI(const std::string& policy_app_id,
+ std::string* default_hmi) {
+ LOG4CXX_INFO(logger_, "GetDefaultHMI");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDefaultHmi)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for default hmi.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_INFO(logger_, "Error during default hmi getting.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ default_hmi->clear();
+ return true;
+ }
+
+ default_hmi->assign(query.GetString(0));
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPriority(const std::string& policy_app_id,
+ std::string* priority) {
+ LOG4CXX_INFO(logger_, "GetPriority");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPriority)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for priority.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during select priority.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ priority->clear();
+ return true;
+ }
+
+ priority->assign(query.GetString(0));
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CountUnconsentedGroups(
+ const std::string& policy_app_id, int* result) const {
+ LOG4CXX_INFO(logger_, "CountUnconsentedGroups");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountUnconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select for unconsented groups.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during executing unconsented groups.");
+ return false;
+ }
+ *result = query.GetInteger(0);
+ return true;
+
+}
+
+bool SQLPTExtRepresentation::SaveMessageString(
+ const std::string& type, const std::string& lang,
+ const policy_table::MessageString& strings) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message.");
+ return false;
+ }
+
+ query.Bind(0, *strings.tts);
+ query.Bind(1, *strings.label);
+ query.Bind(2, *strings.line1);
+ query.Bind(3, *strings.line2);
+ query.Bind(4, lang);
+ query.Bind(5, type);
+ query.Bind(6, *strings.textBody);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CleanupUnpairedDevices(
+ const DeviceIds& device_ids) {
+ LOG4CXX_INFO(logger_, "CleanupUnpairedDevices");
+ dbms::SQLQuery delete_device_query(db());
+ if (!delete_device_query.Prepare(sql_pt::kDeleteDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for device delete.");
+ return true;
+ }
+
+ dbms::SQLQuery delete_device_consent_query(db());
+ if (!delete_device_consent_query.Prepare(sql_pt_ext::kDeleteDeviceConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete device consent.");
+ return false;
+ }
+
+ dbms::SQLQuery delete_app_consent_query(db());
+ if (!delete_app_consent_query.Prepare(sql_pt_ext::kDeleteAppConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete app consent.");
+ return false;
+ }
+
+ DeviceIds::const_iterator it = device_ids.begin();
+ DeviceIds::const_iterator it_end = device_ids.end();
+ for (; it != it_end; ++it) {
+ delete_device_query.Bind(0, (*it));
+ if (!delete_device_query.Exec() || !delete_device_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device");
+ return false;
+ }
+
+ delete_device_consent_query.Bind(0, (*it));
+ if (!delete_device_consent_query.Exec() ||
+ !delete_device_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device consent.");
+ return false;
+ }
+
+ delete_app_consent_query.Bind(0, (*it));
+ if (!delete_app_consent_query.Exec() || !delete_app_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from app consent.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ if (SQLPTRepresentation::SetDefaultPolicy(app_id)) {
+ return SetIsPredata(app_id, false);
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::SetPredataPolicy(const std::string& app_id) {
+ LOG4CXX_INFO(logger_, "SQLPTExtRepresentation::SetPredataPolicy for " << app_id);
+ policy_table::ApplicationPolicies apps;
+ if (!GatherApplicationPolicies(&apps)) {
+ LOG4CXX_WARN(logger_, "Failed gathering application policies");
+ return false;
+ }
+ apps[app_id] = apps[kPreDataConsentId];
+ if (!SaveApplicationPolicies(apps)) {
+ LOG4CXX_WARN(logger_, "Failed saving application policies");
+ return false;
+ }
+ if (IsDefaultPolicy(app_id)) {
+ if (!SetIsDefault(app_id, false)) {
+ LOG4CXX_WARN(logger_, "Failed unsetting app policies from default.");
+ return false;
+ }
+ }
+ return SetIsPredata(app_id, true);
+}
+
+bool SQLPTExtRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectApplicationIsPreData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application is pre_dataConsented");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application is pre_dataConsented");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTExtRepresentation::SetIsPredata(const std::string& app_id,
+ bool is_pre_data) {
+ LOG4CXX_TRACE(logger_, "Set flag is_predata of application");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateIsPredata)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_predata");
+ return false;
+ }
+
+ query.Bind(0, is_pre_data);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_predata");
+ return false;
+ }
+ return true;
+}
+
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/src/sql_pt_queries.cc b/src/components/policy/src/policy/src/sql_pt_queries.cc
new file mode 100644
index 000000000..dfc9cd263
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_queries.cc
@@ -0,0 +1,577 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_queries.h"
+
+namespace policy {
+namespace sql_pt {
+
+const std::string kCreateSchema =
+ "BEGIN; "
+ "CREATE TABLE IF NOT EXISTS `device`( "
+ " `id` VARCHAR(100) PRIMARY KEY NOT NULL, "
+ " `hardware` VARCHAR(45), "
+ " `firmware_rev` VARCHAR(45), "
+ " `os` VARCHAR(45), "
+ " `os_version` VARCHAR(45), "
+ " `carrier` VARCHAR(45), "
+ " `max_number_rfcom_ports` INTEGER "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `usage_and_error_count`( "
+ " `count_of_iap_buffer_full` INTEGER, "
+ " `count_sync_out_of_memory` INTEGER, "
+ " `count_of_sync_reboots` INTEGER "
+ "); "
+ "INSERT OR IGNORE INTO `usage_and_error_count` ( "
+ " `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots`) VALUES (0, 0, 0); "
+ "CREATE TABLE IF NOT EXISTS `module_meta`( "
+ " `ccpu_version` VARCHAR(45), "
+ " `language` VARCHAR(45), "
+ " `wers_country_code` VARCHAR(45), "
+ " `pt_exchanged_at_odometer_x` INTEGER NOT NULL DEFAULT 0, "
+ " `pt_exchanged_x_days_after_epoch` INTEGER NOT NULL DEFAULT 0, "
+ " `ignition_cycles_since_last_exchange` INTEGER NOT NULL DEFAULT 0, "
+ " `vin` VARCHAR(45),"
+ " `flag_update_required` BOOL NOT NULL "
+ "); "
+ "INSERT OR IGNORE INTO `module_meta` (`pt_exchanged_at_odometer_x`, "
+ " `pt_exchanged_x_days_after_epoch`, `ignition_cycles_since_last_exchange`,"
+ " `flag_update_required`) "
+ " VALUES (0, 0, 0, 0); "
+ "CREATE TABLE IF NOT EXISTS `module_config`( "
+ " `preloaded_pt` BOOL NOT NULL, "
+ " `exchange_after_x_ignition_cycles` INTEGER NOT NULL, "
+ " `exchange_after_x_kilometers` INTEGER NOT NULL, "
+ " `exchange_after_x_days` INTEGER NOT NULL, "
+ " `timeout_after_x_seconds` INTEGER NOT NULL, "
+ " `vehicle_make` VARCHAR(45), "
+ " `vehicle_model` VARCHAR(45), "
+ " `vehicle_year` INTEGER "
+ "); "
+ "INSERT OR IGNORE INTO `module_config` (`preloaded_pt`, "
+ " `exchange_after_x_ignition_cycles`, `exchange_after_x_kilometers`, "
+ " `exchange_after_x_days`, `timeout_after_x_seconds`) "
+ " VALUES(1, 0, 0, 0, 0); "
+ "CREATE TABLE IF NOT EXISTS `functional_group`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `user_consent_prompt` TEXT UNIQUE ON CONFLICT REPLACE, "
+ " `name` VARCHAR(100) NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `priority`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('EMERGENCY');"
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NAVIGATION');"
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('VOICECOMMUNICATION');"
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('COMMUNICATION');"
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NORMAL');"
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NONE');"
+ "CREATE TABLE IF NOT EXISTS `hmi_level`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('FULL');"
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('LIMITED');"
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('BACKGROUND');"
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('NONE');"
+ "CREATE TABLE IF NOT EXISTS `notifications_by_priority`( "
+ " `priority_value` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_notifications_by_priority_priority1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`notifications_by_priority.fk_notifications_by_priority_priority1_idx` "
+ " ON `notifications_by_priority`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `language`( "
+ " `code` VARCHAR(25) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `message_type`( "
+ " `name` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `version`( "
+ " `number` VARCHAR(45) NOT NULL "
+ "); "
+ "INSERT OR IGNORE INTO `version` (`number`) VALUES('0'); "
+ "CREATE TABLE IF NOT EXISTS `rpc`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(45) NOT NULL, "
+ " `parameter` VARCHAR(45), "
+ " `hmi_level_value` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_rpc_hmi_level1` "
+ " FOREIGN KEY(`hmi_level_value`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_rpc_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_hmi_level1_idx` "
+ " ON `rpc`(`hmi_level_value`); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_functional_group1_idx` "
+ " ON `rpc`(`functional_group_id`); "
+ "CREATE INDEX `rpc.select_rpc_name_hmi_level` "
+ " ON `rpc`(`name`,`hmi_level_value`);"
+ "CREATE TABLE IF NOT EXISTS `application`( "
+ " `id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `keep_context` BOOLEAN, "
+ " `steal_focus` BOOLEAN, "
+ " `default_hmi` VARCHAR(45), "
+ " `priority_value` VARCHAR(45), "
+ " `is_revoked` BOOLEAN, "
+ " `is_default` BOOLEAN, "
+ " `is_predata` BOOLEAN, "
+ " `memory_kb` INTEGER NOT NULL, "
+ " `watchdog_timer_ms` INTEGER NOT NULL, "
+ " `certificate` VARCHAR(45), "
+ " CONSTRAINT `fk_application_hmi_level1` "
+ " FOREIGN KEY(`default_hmi`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_application_priorities1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_hmi_level1_idx` "
+ " ON `application`(`default_hmi`); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_priorities1_idx` "
+ " ON `application`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `app_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_group.fk_application_has_functional_group_functional_group1_idx` "
+ " ON `app_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS `app_group.fk_application_has_functional_group_application1_idx` "
+ " ON `app_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `preconsented_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application2` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group2` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_functional_group2_idx` "
+ " ON `preconsented_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_application2_idx` "
+ " ON `preconsented_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `seconds_between_retry`( "
+ " `index` INTEGER PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `device_consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` DATETIME DEFAULT CURRENT_TIMESTAMP, "
+ " PRIMARY KEY(`device_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_device_has_functional_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_device_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_functional_group1_idx` "
+ " ON `device_consent_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_level`( "
+ " `application_id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `minutes_in_hmi_full` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_limited` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_background` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_rfcom_limit_reached` INTEGER DEFAULT 0, "
+ " `count_of_user_selections` INTEGER DEFAULT 0, "
+ " `count_of_rejections_sync_out_of_memory` INTEGER DEFAULT 0, "
+ " `count_of_rejections_nickname_mismatch` INTEGER DEFAULT 0, "
+ " `count_of_rejections_duplicate_name` INTEGER DEFAULT 0, "
+ " `count_of_rejected_rpcs_calls` INTEGER DEFAULT 0, "
+ " `count_of_rpcs_sent_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_removals_for_bad_behavior` INTEGER DEFAULT 0, "
+ " `count_of_run_attempts_while_revoked` INTEGER DEFAULT 0, "
+ " `app_registration_language_gui` VARCHAR(25), "
+ " `app_registration_language_vui` VARCHAR(25), "
+ " CONSTRAINT `fk_app_levels_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_app_level_language1` "
+ " FOREIGN KEY(`app_registration_language_gui`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_app_level_language2` "
+ " FOREIGN KEY(`app_registration_language_vui`) "
+ " REFERENCES `language`(`code`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_levels_application1_idx` "
+ " ON `app_level`(`application_id`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language1_idx` "
+ " ON `app_level`(`app_registration_language_gui`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language2_idx` "
+ " ON `app_level`(`app_registration_language_vui`); "
+ "CREATE TABLE IF NOT EXISTS `nickname`( "
+ " `name` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_nickname_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `nickname.fk_nickname_application1_idx` "
+ " ON `nickname`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_type`( "
+ " `name` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_app_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_type.fk_app_type_application1_idx` "
+ " ON `app_type`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` DATETIME DEFAULT CURRENT_TIMESTAMP, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`,`device_id`), "
+ " CONSTRAINT `fk_consent_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_consent_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_consent_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`consent_group.fk_consent_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE INDEX IF NOT EXISTS `consent_group.fk_consent_group_functional_group1_idx` "
+ " ON `consent_group`(`functional_group_id`); "
+ "CREATE TABLE IF NOT EXISTS `endpoint`( "
+ " `service` INTEGER NOT NULL, "
+ " `url` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_endpoint_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `endpoint.fk_endpoint_application1_idx` "
+ " ON `endpoint`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `message`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `tts` TEXT, "
+ " `label` TEXT, "
+ " `line1` TEXT, "
+ " `line2` TEXT, "
+ " `textBody` TEXT, "
+ " `language_code` VARCHAR(25) NOT NULL, "
+ " `message_type_name` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_messages_languages1` "
+ " FOREIGN KEY(`language_code`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_message_consumer_friendly_messages1` "
+ " FOREIGN KEY(`message_type_name`) "
+ " REFERENCES `message_type`(`name`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `message.fk_messages_languages1_idx` "
+ " ON `message`(`language_code`);"
+ "CREATE INDEX IF NOT EXISTS `message.fk_message_consumer_friendly_messages1_idx` "
+ " ON `message`(`message_type_name`);"
+ "COMMIT;";
+
+const std::string kDropSchema =
+ "BEGIN; "
+ "DROP INDEX IF EXISTS `message.fk_messages_languages1_idx`; "
+ "DROP INDEX IF EXISTS `message.fk_message_consumer_friendly_messages1_idx`; "
+ "DROP TABLE IF EXISTS `message`; "
+ "DROP INDEX IF EXISTS `endpoint.fk_endpoint_application1_idx`; "
+ "DROP TABLE IF EXISTS `endpoint`; "
+ "DROP INDEX IF EXISTS `consent_group.fk_consent_group_device1_idx`; "
+ "DROP INDEX IF EXISTS `consent_group.fk_consent_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `consent_group`; "
+ "DROP INDEX IF EXISTS `app_type.fk_app_type_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_type`; "
+ "DROP INDEX IF EXISTS `nickname.fk_nickname_application1_idx`; "
+ "DROP TABLE IF EXISTS `nickname`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language2_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language1_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_levels_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_level`; "
+ "DROP INDEX IF EXISTS `device_consent_group.fk_device_has_functional_group_device1_idx`; "
+ "DROP INDEX IF EXISTS `device_consent_group.fk_device_has_functional_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `device_consent_group`; "
+ "DROP TABLE IF EXISTS `seconds_between_retry`; "
+ "DROP INDEX IF EXISTS `preconsented_group.fk_application_has_functional_group_application2_idx`; "
+ "DROP INDEX IF EXISTS `preconsented_group.fk_application_has_functional_group_functional_group2_idx`; "
+ "DROP TABLE IF EXISTS `preconsented_group`; "
+ "DROP INDEX IF EXISTS `app_group.fk_application_has_functional_group_application1_idx`; "
+ "DROP INDEX IF EXISTS `app_group.fk_application_has_functional_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `app_group`; "
+ "DROP INDEX IF EXISTS `application.fk_application_priorities1_idx`; "
+ "DROP INDEX IF EXISTS `application.fk_application_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `application`; "
+ "DROP INDEX IF EXISTS `rpc.select_rpc_name_hmi_level`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_functional_group1_idx`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `rpc`; "
+ "DROP TABLE IF EXISTS `version`; "
+ "DROP TABLE IF EXISTS `message_type`; "
+ "DROP TABLE IF EXISTS `language`; "
+ "DROP INDEX IF EXISTS `notifications_by_priority.fk_notifications_by_priority_priority1_idx`; "
+ "DROP TABLE IF EXISTS `notifications_by_priority`; "
+ "DROP TABLE IF EXISTS `hmi_level`; "
+ "DROP TABLE IF EXISTS `priority`; "
+ "DROP TABLE IF EXISTS `functional_group`; "
+ "DROP TABLE IF EXISTS `module_config`; "
+ "DROP TABLE IF EXISTS `module_meta`; "
+ "DROP TABLE IF EXISTS `usage_and_error_count`; "
+ "DROP TABLE IF EXISTS `device`; "
+ "COMMIT;";
+
+const std::string kCheckDBIntegrity = "PRAGMA integrity_check";
+
+const std::string kCheckPgNumber = "PRAGMA page_count";
+
+const std::string kSelectRpc =
+ "SELECT DISTINCT `rpc`.`parameter` FROM `rpc` "
+ " JOIN `app_group` AS `g` ON (`g`.`functional_group_id` = `rpc`.`functional_group_id` "
+ " AND (`g`.`application_id` = ?)) "
+ "WHERE `rpc`.`hmi_level_value` = ? AND `rpc`.`name` = ?";
+
+const std::string kSelectPreloaded =
+ "SELECT `preloaded_pt` FROM `module_config` "
+ "WHERE `preloaded_pt` = 1 LIMIT 1";
+
+const std::string kSelectEndpoint =
+ "SELECT `url`, `application_id` FROM `endpoint` WHERE `service` = ? ";
+
+const std::string kInsertFunctionalGroup =
+ "INSERT INTO `functional_group` (`name`, `user_consent_prompt`) "
+ " VALUES (?, ?)";
+
+const std::string kInsertRpc =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `functional_group_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertRpcWithParameter =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `parameter`, `functional_group_id`) "
+ " VALUES (?, ?, ?, ?)";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application` (`id`, `is_revoked`, `memory_kb`,"
+ " `watchdog_timer_ms`, `certificate`) VALUES (?,?,?,?,?)";
+
+const std::string kInsertAppGroup =
+ "INSERT INTO `app_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kInsertNickname =
+ "INSERT OR IGNORE INTO `nickname` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kInsertAppType =
+ "INSERT OR IGNORE INTO `app_type` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kUpdateVersion = "UPDATE `version` SET `number`= ?";
+
+const std::string kInsertMessageType =
+ "INSERT OR IGNORE INTO `message_type` (`name`) VALUES (?)";
+
+const std::string kInsertLanguage =
+ "INSERT OR IGNORE INTO `language` (`code`) VALUES (?)";
+
+const std::string kInsertMessageString =
+ "INSERT INTO `message` (`tts`, `label`, `line1`, `line2`, `language_code`, "
+ " `message_type_name`, `textBody`) VALUES (?, ?, ?, ?, ?, ?, ?)";
+
+const std::string kUpdateModuleConfig =
+ "UPDATE `module_config` SET `preloaded_pt` = ?, "
+ " `exchange_after_x_ignition_cycles` = ?,"
+ " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, "
+ " `timeout_after_x_seconds` = ?, `vehicle_make` = ?, "
+ " `vehicle_model` = ?, `vehicle_year` = ?";
+
+const std::string kInsertEndpoint =
+ "INSERT INTO `endpoint` (`service`, `url`, `application_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertSecondsBetweenRetry =
+ "INSERT INTO `seconds_between_retry` (`index`, `value`) VALUES (?, ?)";
+
+const std::string kInsertNotificationsByPriority =
+ "INSERT OR REPLACE INTO `notifications_by_priority` (`priority_value`, `value`) "
+ " VALUES (?, ?)";
+
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` (`id`) VALUES (?)";
+
+const std::string kInsertAppLevel =
+ "INSERT INTO `app_level` (`application_id`) VALUES (?)";
+
+const std::string kDeleteSecondsBetweenRetries =
+ "DELETE FROM `seconds_between_retry`";
+
+const std::string kDeleteEndpoint = "DELETE FROM `endpoint`";
+
+const std::string kDeleteAppLevel = "DELETE FROM `app_level`";
+
+const std::string kDeleteMessageString = "DELETE FROM `message`";
+
+const std::string kDeleteFunctionalGroup = "DELETE FROM `functional_group`";
+
+const std::string kDeleteRpc = "DELETE FROM `rpc`";
+
+const std::string kDeleteAppGroup = "DELETE FROM `app_group`";
+
+const std::string kSelectModuleConfig =
+ "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, "
+ " `exchange_after_x_kilometers`, `exchange_after_x_days`, "
+ " `timeout_after_x_seconds`, `vehicle_make`,"
+ " `vehicle_model`, `vehicle_year` "
+ " FROM `module_config`";
+
+const std::string kSelectEndpoints =
+ "SELECT `url`, `service`, `application_id` "
+ "FROM `endpoint` "
+ "GROUP BY `application_id`";
+
+const std::string kSelectNotificationsPerMin =
+ "SELECT `priority_value`, `value` FROM notifications_by_priority";
+
+const std::string kSelectAppLevels = "SELECT `application_id` FROM `app_level`";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectFunctionalGroups =
+ "SELECT `id`,`name`, `user_consent_prompt` "
+ "FROM `functional_group`";
+
+const std::string kSelectAllRpcs =
+ "SELECT `name`, `hmi_level_value`, `parameter` "
+ "FROM `rpc` WHERE `functional_group_id` = ? ";
+
+const std::string kSelectUserMsgsVersion =
+ "SELECT DISTINCT `number` FROM `version`";
+
+const std::string kSelectAppPolicies = "SELECT `id`, `memory_kb`, "
+ " `watchdog_timer_ms`, `certificate` FROM `application`";
+
+const std::string kSelectAppGroups = "SELECT `f`.`name` FROM `app_group` AS `a`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `a`.`functional_group_id`)"
+ " WHERE `a`.`application_id` = ?";
+
+const std::string kSelectNicknames = "SELECT DISTINCT `name` FROM `nickname` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectAppTypes = "SELECT DISTINCT `name` FROM `app_type` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectSecondsBetweenRetries =
+ "SELECT `value` FROM `seconds_between_retry` ORDER BY `index`";
+
+const std::string kSelectIgnitionCycles =
+ "SELECT `c`.`exchange_after_x_ignition_cycles`, "
+ " `m`.`ignition_cycles_since_last_exchange` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectKilometers =
+ "SELECT `c`.`exchange_after_x_kilometers`, "
+ " `m`.`pt_exchanged_at_odometer_x` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectDays = "SELECT `c`.`exchange_after_x_days`, "
+ " `m`.`pt_exchanged_x_days_after_epoch` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kIncrementIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 1 + "
+ " `ignition_cycles_since_last_exchange`";
+
+const std::string kResetIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 0";
+
+const std::string kSelectTimeoutResponse =
+ "SELECT `timeout_after_x_seconds` FROM `module_config` LIMIT 1";
+
+const std::string kUpdateFlagUpdateRequired =
+ "UPDATE `module_meta` SET `flag_update_required` = ?";
+
+const std::string kSelectFlagUpdateRequired =
+ "SELECT `flag_update_required` FROM `module_meta` LIMIT 1";
+
+const std::string kUpdateCountersSuccessfulUpdate =
+ "UPDATE `module_meta` SET `pt_exchanged_at_odometer_x` = ?,"
+ "`pt_exchanged_x_days_after_epoch` = ?";
+
+const std::string kDeleteApplication = "DELETE FROM `application`";
+
+const std::string kSelectApplicationRevoked =
+ "SELECT `is_revoked` FROM `application` WHERE `id` = ?";
+
+const std::string kSelectApplicationRepresented =
+ "SELECT COUNT(`id`) FROM `application` WHERE `id` = ?";
+
+const std::string kSelectApplicationIsDefault =
+ "SELECT `is_default` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateIsDefault =
+ "UPDATE `application` SET `is_default` = ? WHERE `id` = ?";
+
+const std::string kDeleteDevice = "DELETE FROM `device` WHERE `id` = ?";
+
+} // namespace sql_pt
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/src/sql_pt_representation.cc b/src/components/policy/src/policy/src/sql_pt_representation.cc
new file mode 100644
index 000000000..23322d8ab
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_representation.cc
@@ -0,0 +1,1230 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+#include "utils/logger.h"
+#include "policy/sql_pt_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+#ifndef __QNX__
+# include "config_profile/profile.h"
+#endif // __QNX__
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "SQLPTRepresentation")
+
+namespace {
+template<typename T, typename K> void InsertUnique(K value, T* array) {
+ int i = 0;
+ for (; i < array->size() && array->at(i) != value; ++i) {
+ continue;
+ }
+ if (array->size() == i) {
+ array->push_back(value);
+ }
+}
+} // namespace
+
+
+const std::string SQLPTRepresentation::kDatabaseName = "policy";
+
+SQLPTRepresentation::SQLPTRepresentation()
+ : db_(new dbms::SQLDatabase(kDatabaseName)) {
+#ifndef __QNX__
+ std::string path = profile::Profile::instance()->app_storage_folder();
+ if (!path.empty()) {
+ db_->set_path(path + "/");
+ }
+#endif // __QNX__
+}
+
+SQLPTRepresentation::~SQLPTRepresentation() {
+ db_->Close();
+ delete db_;
+}
+
+CheckPermissionResult SQLPTRepresentation::CheckPermissions(
+ const PTString& app_id, const PTString& hmi_level, const PTString& rpc) {
+ CheckPermissionResult result;
+ dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt::kSelectRpc)) {
+ LOG4CXX_WARN(
+ logger_,
+ "Incorrect select statement from rpcs" << query.LastError().text());
+ return result;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, hmi_level);
+ query.Bind(2, rpc);
+
+ bool ret = query.Next();
+ result.hmi_level_permitted = ret ? kRpcAllowed : kRpcDisallowed;
+ LOG4CXX_INFO(
+ logger_,
+ "Level is "
+ << (result.hmi_level_permitted == kRpcAllowed ? "permitted" : "not permitted"));
+ std::string parameter;
+ while (ret) {
+ if (!query.IsNull(0)) {
+ if (!result.list_of_allowed_params) {
+ result.list_of_allowed_params = new std::vector<PTString>();
+ }
+ parameter = query.GetString(0);
+ result.list_of_allowed_params->push_back(parameter);
+ }
+ ret = query.Next();
+ }
+
+ return result;
+}
+
+bool SQLPTRepresentation::IsPTPreloaded() {
+ dbms::SQLQuery query(db());
+ return query.Prepare(sql_pt::kSelectPreloaded) && query.Next();
+}
+
+int SQLPTRepresentation::IgnitionCyclesBeforeExchange() {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectIgnitionCycles) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select ignition cycles");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int current = query.GetInteger(1);
+
+ if (limit < 0 || current < 0 || current > limit) {
+ return 0;
+ }
+
+ return limit - current;
+}
+
+int SQLPTRepresentation::KilometersBeforeExchange(int current) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectKilometers) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select kilometers");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (limit < 0 || last < 0 || current < 0 || current < last
+ || limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+bool SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate(
+ int kilometers, int days_after_epoch) {
+ LOG4CXX_INFO(logger_,
+ "SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateCountersSuccessfulUpdate)) {
+ LOG4CXX_WARN(logger_,
+ "Wrong update query for counters on successful update.");
+ return false;
+ }
+ query.Bind(0, kilometers);
+ query.Bind(1, days_after_epoch);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to update counters on successful update.");
+ return false;
+ }
+ return true;
+}
+
+int SQLPTRepresentation::DaysBeforeExchange(int current) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectDays) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select days");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (0 == last) {
+ return limit;
+ }
+
+ if (limit < 0 || last < 0 || current < 0 || current < last
+ || limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+int SQLPTRepresentation::TimeoutResponse() {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectTimeoutResponse) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Can not select timeout response for retry sequence");
+ const int kDefault = 30;
+ return kDefault;
+ }
+ return query.GetInteger(0);
+}
+
+bool SQLPTRepresentation::SecondsBetweenRetries(std::vector<int>* seconds) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ return false;
+ }
+ while (query.Next()) {
+ seconds->push_back(query.GetInteger(0));
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ std::vector<UserFriendlyMessage> result;
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ UserFriendlyMessage msg;
+ msg.message_code = *it;
+ result.push_back(msg);
+ }
+ return result;
+}
+
+EndpointUrls SQLPTRepresentation::GetUpdateUrls(int service_type) {
+ LOG4CXX_INFO(logger_, "SQLPTRepresentation::GetUpdateUrls for " << service_type);
+ dbms::SQLQuery query(db());
+ EndpointUrls ret;
+ if (query.Prepare(sql_pt::kSelectEndpoint)) {
+ query.Bind(0, service_type);
+ while (query.Next()) {
+ EndpointData data;
+
+ data.url = query.GetString(0);
+ if (!query.IsNull(1)) {
+ data.app_id = query.GetString(1);
+ }
+ ret.push_back(data);
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
+ }
+ return ret;
+}
+
+int SQLPTRepresentation::GetNotificationsNumber(
+ policy_table::Priority priority) {
+ return 0;
+}
+
+InitResult SQLPTRepresentation::Init() {
+ LOG4CXX_INFO(logger_, "SQLPTRepresentation::Init");
+
+ if (!db_->Open()) {
+ LOG4CXX_ERROR(logger_, "Failed opening database");
+ return InitResult::FAIL;
+ }
+ dbms::SQLQuery check_pages(db());
+ if (!check_pages.Prepare(sql_pt::kCheckPgNumber) || !check_pages.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for page counting.");
+ } else {
+ if (0 < check_pages.GetInteger(0)) {
+ dbms::SQLQuery db_check(db());
+ if (!db_check.Prepare(sql_pt::kCheckDBIntegrity)) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for integrity check.");
+ } else {
+ while (db_check.Next()) {
+ if (db_check.GetString(0).compare("ok") == 0) {
+ return InitResult::EXISTS;
+ } else {
+ LOG4CXX_ERROR(logger_,
+ "Existing policy table representation is invlaid.");
+ // TODO(PV): add handle
+ return InitResult::FAIL;
+ }
+ }
+ }
+ }
+ }
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kCreateSchema)) {
+ LOG4CXX_INFO(
+ logger_,
+ "Failed creating schema of database: " << query.LastError().text());
+ return InitResult::FAIL;
+ }
+ return InitResult::SUCCESS;
+}
+
+bool SQLPTRepresentation::Close() {
+ db_->Close();
+ return db_->LastError().number() == dbms::OK;
+}
+
+VehicleData SQLPTRepresentation::GetVehicleData() {
+ return VehicleData();
+}
+
+bool SQLPTRepresentation::Clear() {
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDropSchema)) {
+ LOG4CXX_WARN(logger_,
+ "Failed clearing database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+utils::SharedPtr<policy_table::Table> SQLPTRepresentation::GenerateSnapshot() const {
+ LOG4CXX_INFO(logger_, "GenerateSnapshot");
+ utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
+ GatherModuleMeta(&*table->policy_table.module_meta);
+ GatherModuleConfig(&table->policy_table.module_config);
+ GatherUsageAndErrorCounts(&*table->policy_table.usage_and_error_counts);
+ GatherDeviceData(&*table->policy_table.device_data);
+ GatherFunctionalGroupings(&table->policy_table.functional_groupings);
+ GatherConsumerFriendlyMessages(
+ &table->policy_table.consumer_friendly_messages);
+ GatherApplicationPolicies(&table->policy_table.app_policies);
+ return table;
+}
+
+void SQLPTRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ meta->mark_initialized();
+ // Section Module Meta is empty for SDL specific
+}
+
+void SQLPTRepresentation::GatherModuleConfig(
+ policy_table::ModuleConfig* config) const {
+ LOG4CXX_INFO(logger_, "Gather Configuration Info");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectModuleConfig) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for module config");
+ } else {
+ *config->preloaded_pt = query.GetBoolean(0);
+ config->exchange_after_x_ignition_cycles = query.GetInteger(1);
+ config->exchange_after_x_kilometers = query.GetInteger(2);
+ config->exchange_after_x_days = query.GetInteger(3);
+ config->timeout_after_x_seconds = query.GetInteger(4);
+ *config->vehicle_make = query.GetString(5);
+ *config->vehicle_model = query.GetString(6);
+ *config->vehicle_year = query.GetInteger(7);
+ }
+
+ dbms::SQLQuery endpoints(db());
+ if (!endpoints.Prepare(sql_pt::kSelectEndpoints)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for endpoints");
+ } else {
+ while (endpoints.Next()) {
+ std::stringstream stream;
+ stream << "0x0" << endpoints.GetInteger(1);
+ config->endpoints[stream.str()][endpoints.GetString(2)]
+ .push_back(endpoints.GetString(0));
+ }
+ }
+
+ dbms::SQLQuery notifications(db());
+ if (!notifications.Prepare(sql_pt::kSelectNotificationsPerMin)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for notifications");
+ } else {
+ while (notifications.Next()) {
+ config->notifications_per_minute_by_priority[notifications.GetString(0)] =
+ notifications.GetInteger(1);
+ }
+ }
+ dbms::SQLQuery seconds(db());
+ if (!seconds.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ } else {
+ while (seconds.Next()) {
+ config->seconds_between_retries.push_back(seconds.GetInteger(0));
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectAppLevels)) {
+ policy_table::AppLevel app_level_empty;
+ app_level_empty.mark_initialized();
+ while (query.Next()) {
+ (*counts->app_level)[query.GetString(0)] = app_level_empty;
+ }
+ }
+ return true;
+}
+
+void SQLPTRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectDeviceData)) {
+ policy_table::DeviceParams device_data_empty;
+ device_data_empty.mark_initialized();
+ while (query.Next()) {
+ (*data)[query.GetString(0)] = device_data_empty;
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherFunctionalGroupings(
+ policy_table::FunctionalGroupings* groups) const {
+ LOG4CXX_INFO(logger_, "Gather Functional Groupings info");
+ dbms::SQLQuery func_group(db());
+ if (!func_group.Prepare(sql_pt::kSelectFunctionalGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from functional_groupings");
+ return false;
+ }
+ dbms::SQLQuery rpcs(db());
+ if (!rpcs.Prepare(sql_pt::kSelectAllRpcs)) {
+ LOG4CXX_WARN(logger_, "Incorrect select all from rpc");
+ return false;
+ }
+ while (func_group.Next()) {
+ policy_table::Rpcs rpcs_tbl;
+ if (!func_group.IsNull(2)) {
+ *rpcs_tbl.user_consent_prompt = func_group.GetString(2);
+ }
+ int func_id = func_group.GetInteger(0);
+ rpcs.Bind(0, func_id);
+ while (rpcs.Next()) {
+ if (!rpcs.IsNull(1)) {
+ policy_table::HmiLevel level;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(1), &level)) {
+ InsertUnique(level, &rpcs_tbl.rpcs[rpcs.GetString(0)].hmi_levels);
+ }
+ }
+ if (!rpcs.IsNull(2)) {
+ policy_table::Parameter param;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(2), &param)) {
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ InsertUnique(param, &(*rpcs_tbl.rpcs[rpcs.GetString(0)].parameters));
+ }
+ }
+ }
+ rpcs.Reset();
+ (*groups)[func_group.GetString(1)] = rpcs_tbl;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const {
+ LOG4CXX_INFO(logger_, "Gather Consumer Friendly Messages");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectUserMsgsVersion) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from consumer_friendly_messages");
+ return false;
+ }
+ messages->version = query.GetString(0);
+ return true;
+}
+
+bool SQLPTRepresentation::GatherApplicationPolicies(
+ policy_table::ApplicationPolicies* apps) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ if (IsApplicationRevoked(app_id)) {
+ params.set_to_null();
+ (*apps)[app_id] = params;
+ continue;
+ }
+ *params.memory_kb = query.GetInteger(1);
+ *params.watchdog_timer_ms = query.GetInteger(2);
+ if (!query.IsNull(3)) {
+ *params.certificate = query.GetString(3);
+ }
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ (*apps)[app_id] = params;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::Save(const policy_table::Table& table) {
+ LOG4CXX_INFO(logger_, "SQLPTRepresentation::Save");
+ db_->BeginTransaction();
+ if (!SaveFunctionalGroupings(table.policy_table.functional_groupings)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveApplicationPolicies(table.policy_table.app_policies)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleConfig(table.policy_table.module_config)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveConsumerFriendlyMessages(
+ table.policy_table.consumer_friendly_messages)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveDeviceData(*table.policy_table.device_data)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveUsageAndErrorCounts(*table.policy_table.usage_and_error_counts)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleMeta(*table.policy_table.module_meta)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ db_->CommitTransaction();
+ return true;
+}
+
+bool SQLPTRepresentation::SaveFunctionalGroupings(
+ const policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_INFO(logger_, "SaveFunctionalGroupings");
+ dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteRpc)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from rpc.");
+ return false;
+ }
+
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for functional groups");
+ return false;
+ }
+
+ policy_table::FunctionalGroupings::const_iterator it;
+ for (it = groups.begin(); it != groups.end(); ++it) {
+ query.Bind(0, it->first);
+ it->second.user_consent_prompt.is_initialized() ?
+ query.Bind(1, *(it->second.user_consent_prompt)) : query.Bind(1);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into functional groups");
+ return false;
+ }
+
+ if (!SaveRpcs(query.LastInsertId(), it->second.rpcs)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SaveRpcs(int64_t group_id,
+ const policy_table::Rpc& rpcs) {
+ dbms::SQLQuery query(db());
+ dbms::SQLQuery query_parameter(db());
+ if (!query.Prepare(sql_pt::kInsertRpc)
+ || !query_parameter.Prepare(sql_pt::kInsertRpcWithParameter)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for rpc");
+ return false;
+ }
+
+ policy_table::Rpc::const_iterator it;
+ for (it = rpcs.begin(); it != rpcs.end(); ++it) {
+ const policy_table::HmiLevels& hmi_levels = it->second.hmi_levels;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ const policy_table::Parameters& parameters = *it->second.parameters;
+ policy_table::HmiLevels::const_iterator hmi_it;
+ policy_table::Parameters::const_iterator ps_it;
+ for (hmi_it = hmi_levels.begin(); hmi_it != hmi_levels.end(); ++hmi_it) {
+ if (!parameters.empty()) {
+ for (ps_it = parameters.begin(); ps_it != parameters.end(); ++ps_it) {
+ query_parameter.Bind(0, it->first);
+ query_parameter.Bind(
+ 1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query_parameter.Bind(
+ 2, std::string(policy_table::EnumToJsonString(*ps_it)));
+ query_parameter.Bind(3, group_id);
+ if (!query_parameter.Exec() || !query_parameter.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc with parameter");
+ return false;
+ }
+ }
+ } else {
+ query.Bind(0, it->first);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query.Bind(2, group_id);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveApplicationPolicies(
+ const policy_table::ApplicationPolicies& apps) {
+ LOG4CXX_INFO(logger_, "SaveApplicationPolicies");
+ dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+ policy_table::ApplicationPolicies::const_iterator it;
+ dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+ for (it = apps.begin(); it != apps.end(); ++it) {
+ app_query.Bind(0, it->first);
+ app_query.Bind(1, it->second.is_null());
+ app_query.Bind(2, it->second.memory_kb);
+ app_query.Bind(3, it->second.watchdog_timer_ms);
+ it->second.certificate.is_initialized() ?
+ app_query.Bind(4, *it->second.certificate) : app_query.Bind(4);
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ LOG4CXX_INFO(logger_, "Saving data for application: " << it->first);
+ if (!SaveAppGroup(it->first, it->second.groups)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveNickname(it->first, *it->second.nicknames)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveAppType(it->first, *it->second.AppHMIType)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppGroup(
+ const std::string& app_id, const policy_table::Strings& app_groups) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app group");
+ return false;
+ }
+ LOG4CXX_INFO(logger_, "SaveAppGroup");
+ policy_table::Strings::const_iterator it;
+ for (it = app_groups.begin(); it != app_groups.end(); ++it) {
+ std::string ssss = *it;
+ LOG4CXX_INFO(logger_, "Group: " << ssss);
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(
+ logger_,
+ "Incorrect insert into app group." << query.LastError().text());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNickname(const std::string& app_id,
+ const policy_table::Strings& nicknames) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNickname)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for nickname");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = nicknames.begin(); it != nicknames.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into nickname.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppType(const std::string& app_id,
+ const policy_table::AppHMITypes& types) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app type");
+ return false;
+ }
+
+ policy_table::AppHMITypes::const_iterator it;
+ for (it = types.begin(); it != types.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app type.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleMeta(const policy_table::ModuleMeta& meta) {
+ LOG4CXX_INFO(logger_, "SaveModuleMeta");
+ // Section Module Meta is empty for SDL specific
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleConfig(
+ const policy_table::ModuleConfig& config) {
+ LOG4CXX_INFO(logger_, "SaveModuleConfig");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateModuleConfig)) {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for module config");
+ return false;
+ }
+
+ config.preloaded_pt.is_initialized() ?
+ query.Bind(0, config.preloaded_pt) : query.Bind(0, false);
+ query.Bind(1, config.exchange_after_x_ignition_cycles);
+ query.Bind(2, config.exchange_after_x_kilometers);
+ query.Bind(3, config.exchange_after_x_days);
+ query.Bind(4, config.timeout_after_x_seconds);
+ config.vehicle_make.is_initialized() ?
+ query.Bind(5, *(config.vehicle_make)) : query.Bind(5);
+ config.vehicle_model.is_initialized() ?
+ query.Bind(6, *(config.vehicle_model)) : query.Bind(6);
+ config.vehicle_year.is_initialized() ?
+ query.Bind(7, *(config.vehicle_year)) : query.Bind(7);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update module config");
+ return false;
+ }
+
+ if (!SaveSecondsBetweenRetries(config.seconds_between_retries)) {
+ return false;
+ }
+
+ if (!SaveNumberOfNotificationsPerMinute(
+ config.notifications_per_minute_by_priority)) {
+ return false;
+ }
+
+ if (!SaveServiceEndpoints(config.endpoints)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveServiceEndpoints(
+ const policy_table::ServiceEndpoints& endpoints) {
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from endpoint.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt::kInsertEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for endpoint");
+ return false;
+ }
+
+ policy_table::ServiceEndpoints::const_iterator it;
+ for (it = endpoints.begin(); it != endpoints.end(); ++it) {
+ const policy_table::URLList& apps = it->second;
+ policy_table::URLList::const_iterator app_it;
+ for (app_it = apps.begin(); app_it != apps.end(); ++app_it) {
+ const policy_table::URL& urls = app_it->second;
+ policy_table::URL::const_iterator url_it;
+ for (url_it = urls.begin(); url_it != urls.end(); ++url_it) {
+ std::stringstream temp_stream(it->first);
+ int service;
+ temp_stream.seekg(3);
+ temp_stream >> service;
+ query.Bind(0, service);
+ query.Bind(1, *url_it);
+ query.Bind(2, app_it->first);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into endpoint");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveConsumerFriendlyMessages(
+ const policy_table::ConsumerFriendlyMessages& messages) {
+ LOG4CXX_INFO(logger_, "SaveConsumerFriendlyMessages");
+
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from message.");
+ return false;
+ }
+
+ if (query.Prepare(sql_pt::kUpdateVersion)) {
+ query.Bind(0, messages.version);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update into version.");
+ return false;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for version.");
+ return false;
+ }
+
+ policy_table::Messages::const_iterator it;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ for (it = messages.messages->begin(); it != messages.messages->end(); ++it) {
+ if (!SaveMessageType(it->first)) {
+ return false;
+ }
+ const policy_table::Languages& langs = it->second.languages;
+ policy_table::Languages::const_iterator lang_it;
+ for (lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) {
+ if (!SaveLanguage(lang_it->first)) {
+ return false;
+ }
+ if (!SaveMessageString(it->first, lang_it->first, lang_it->second)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageType(const std::string& type) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message type.");
+ return false;
+ }
+
+ query.Bind(0, type);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message type.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveLanguage(const std::string& code) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for language.");
+ return false;
+ }
+
+ query.Bind(0, code);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageString(
+ const std::string& type, const std::string& lang,
+ const policy_table::MessageString& strings) {
+ // Section is empty for SDL specific
+ return true;
+}
+
+bool SQLPTRepresentation::SaveSecondsBetweenRetries(
+ const policy_table::SecondsBetweenRetries& seconds) {
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteSecondsBetweenRetries)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertSecondsBetweenRetry)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for seconds between retries.");
+ return false;
+ }
+
+ for (int i = 0; i < seconds.size(); ++i) {
+ query.Bind(0, i);
+ query.Bind(1, seconds[i]);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into seconds between retries.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNumberOfNotificationsPerMinute(
+ const policy_table::NumberOfNotificationsPerMinute& notifications) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNotificationsByPriority)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for notifications by priority.");
+ return false;
+ }
+
+ policy_table::NumberOfNotificationsPerMinute::const_iterator it;
+ for (it = notifications.begin(); it != notifications.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into notifications by priority.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ LOG4CXX_INFO(logger_, "SaveDeviceData");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it;
+ for (it = devices.begin(); it != devices.end(); ++it) {
+ query.Bind(0, it->first);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts) {
+ LOG4CXX_INFO(logger_, "SaveUsageAndErrorCounts");
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
+ return false;
+ }
+
+ policy_table::AppLevels::const_iterator it;
+ const policy_table::AppLevels& app_levels = *counts.app_level;
+ for (it = app_levels.begin(); it != app_levels.end(); ++it) {
+ query.Bind(0, it->first);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void SQLPTRepresentation::IncrementIgnitionCycles() {
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kIncrementIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed incrementing ignition cycles");
+ }
+}
+
+void SQLPTRepresentation::ResetIgnitionCycles() {
+ LOG4CXX_INFO(logger_, "ResetIgnitionCycles");
+ dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kResetIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed to reset ignition cycles number.");
+ }
+}
+
+bool SQLPTRepresentation::UpdateRequired() const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectFlagUpdateRequired) || !query.Exec()) {
+ LOG4CXX_WARN(logger_,
+ "Failed select update required flag from module meta");
+ return false;
+ }
+ return query.GetBoolean(0);
+}
+
+void SQLPTRepresentation::SaveUpdateRequired(bool value) {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateFlagUpdateRequired)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect update into module meta (update_required)");
+ return;
+ }
+ query.Bind(0, value);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update module meta (update_required)");
+ }
+}
+
+bool SQLPTRepresentation::GetInitialAppData(const std::string& app_id,
+ StringArray* nicknames,
+ StringArray* app_types) {
+ LOG4CXX_INFO(logger_, "Getting initial application data.");
+ dbms::SQLQuery app_names(db());
+ if (!app_names.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+ dbms::SQLQuery app_hmi_types(db());
+ if (!app_hmi_types.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+ app_names.Bind(0, app_id);
+ while (app_names.Next()) {
+ nicknames->push_back(app_names.GetString(0));
+ }
+ app_names.Reset();
+ app_hmi_types.Bind(0, app_id);
+ while (app_hmi_types.Next()) {
+ app_types->push_back(app_names.GetString(0));
+ }
+ app_hmi_types.Reset();
+ return true;
+}
+
+bool SQLPTRepresentation::GetFunctionalGroupings(
+ policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_INFO(logger_, "GetFunctionalGroupings");
+ return GatherFunctionalGroupings(&groups);
+}
+
+bool SQLPTRepresentation::GatherAppType(
+ const std::string& app_id, policy_table::AppHMITypes* app_types) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ policy_table::AppHMIType type;
+ if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
+ return false;
+ }
+ app_types->push_back(type);
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherNickName(
+ const std::string& app_id, policy_table::Strings* nicknames) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ nicknames->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherAppGroup(
+ const std::string& app_id, policy_table::Strings* app_groups) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app groups");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ app_groups->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::IsApplicationRevoked(
+ const std::string& app_id) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRevoked)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from is_revoked of application");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select is_revoked of application");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTRepresentation::IsApplicationRepresented(
+ const std::string& app_id) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRepresented)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.GetInteger(0) != 0;
+}
+
+bool SQLPTRepresentation::IsDefaultPolicy(const std::string& app_id) const {
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ return false;
+}
+
+bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ policy_table::ApplicationPolicies apps;
+ if (!GatherApplicationPolicies(&apps)) {
+ LOG4CXX_WARN(logger_, "Failed gathering application policies");
+ return false;
+ }
+ apps[app_id] = apps[kDefaultId];
+ if (!SaveApplicationPolicies(apps)) {
+ LOG4CXX_WARN(logger_, "Failed saving application policies");
+ return false;
+ }
+
+ return SetIsDefault(app_id, true);
+}
+
+bool SQLPTRepresentation::CleanupUnpairedDevices(const DeviceIds& device_ids) {
+ LOG4CXX_INFO(logger_, "CleanupUnpairedDevices");
+ dbms::SQLQuery delete_device_query(db());
+ if (!delete_device_query.Prepare(sql_pt::kDeleteDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for device delete.");
+ return true;
+ }
+
+ DeviceIds::const_iterator it = device_ids.begin();
+ DeviceIds::const_iterator it_end = device_ids.end();
+ for (; it != it_end; ++it) {
+ delete_device_query.Bind(0, (*it));
+ if (!delete_device_query.Exec() || !delete_device_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SetIsDefault(const std::string& app_id,
+ bool is_default) {
+ LOG4CXX_TRACE(logger_, "Set flag is_default of application");
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_default");
+ return false;
+ }
+
+ query.Bind(0, is_default);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_default");
+ return false;
+ }
+ return true;
+}
+
+dbms::SQLDatabase* SQLPTRepresentation::db() const {
+#ifdef __QNX__
+ dbms::SQLDatabase* db = new dbms::SQLDatabase(kDatabaseName);
+ db->Open();
+ return db;
+#else
+ return db_;
+#endif
+}
+
+} // namespace policy
+
diff --git a/src/components/policy/src/policy/src/syncp_adapter.cc b/src/components/policy/src/policy/src/syncp_adapter.cc
new file mode 100644
index 000000000..07128bb05
--- /dev/null
+++ b/src/components/policy/src/policy/src/syncp_adapter.cc
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "./policy/syncp_adapter.h"
+
+namespace policy {
+SyncPAdapter::SyncPAdapter() {
+}
+
+SyncPAdapter::~SyncPAdapter() {
+}
+
+bool SyncPAdapter::ParseHeader(const PTString& input) {
+ // TODO(PV): add implementation
+ update_.msg_id = 10;
+ return true;
+}
+
+bool SyncPAdapter::ComposeHeader() {
+ // TODO(PV): add implementation
+ snapshot_.msg_id = 9;
+ return true;
+}
+
+PTString* SyncPAdapter::Decrypt(const PTString& input) {
+ // TODO(PV): add implementation
+ return new PTString("policy_table_string");
+}
+
+PTString* SyncPAdapter::Encrypt(const PTString& input) {
+ // TODO(PV): add implementation
+ return new PTString("policy_table_encrypted_string");
+}
+bool SyncPAdapter::ValidateUpdate() {
+ return true;
+}
+
+} // namespace policy
diff --git a/src/components/policy/src/policy/usage_statistics/CMakeLists.txt b/src/components/policy/src/policy/usage_statistics/CMakeLists.txt
new file mode 100644
index 000000000..b57431b8f
--- /dev/null
+++ b/src/components/policy/src/policy/usage_statistics/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (c) 2014, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+include_directories(include)
+
+set(SOURCES
+ src/counter.cc
+)
+
+add_library(UsageStatistics ${SOURCES})
diff --git a/src/components/policy/src/policy/usage_statistics/include/usage_statistics/counter.h b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/counter.h
new file mode 100644
index 000000000..e767aaafa
--- /dev/null
+++ b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/counter.h
@@ -0,0 +1,93 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_COUNTER_H
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_COUNTER_H
+
+#include <ctime>
+#include "usage_statistics/statistics_manager.h"
+
+namespace usage_statistics {
+
+class GlobalCounter {
+ public:
+ GlobalCounter(StatisticsManager* statistics_manager,
+ GlobalCounterId counter_type);
+ void operator++() const;
+ private:
+ GlobalCounterId counter_type_;
+ StatisticsManager* statistics_manager_;
+};
+
+class AppCounter {
+ public:
+ AppCounter(StatisticsManager* statistics_manager,
+ const std::string& app_id,
+ AppCounterId counter_type);
+ void operator++() const;
+ private:
+ std::string app_id_;
+ AppCounterId counter_type_;
+ StatisticsManager* statistics_manager_;
+};
+
+class AppInfo {
+ public:
+ AppInfo(StatisticsManager* statistics_manager,
+ const std::string& app_id,
+ AppInfoId info_type);
+ void Update(const std::string& new_info) const;
+ private:
+ std::string app_id_;
+ AppInfoId info_type_;
+ StatisticsManager* statistics_manager_;
+};
+
+class AppStopwatch {
+ public:
+ AppStopwatch(StatisticsManager* statistics_manager,
+ const std::string& app_id);
+ ~AppStopwatch();
+ void Start(AppStopwatchId stopwatch_type);
+ void Switch(AppStopwatchId stopwatch_type);
+ void Stop();
+ private:
+ // Fields
+ std::string app_id_;
+ AppStopwatchId stopwatch_type_;
+ StatisticsManager* statistics_manager_;
+ time_t start_time_;
+};
+
+} // namespace usage_statistics
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_COUNTER_H
diff --git a/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h
new file mode 100644
index 000000000..49a0274d5
--- /dev/null
+++ b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_STATISTICS_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_STATISTICS_MANAGER_H_
+
+#include <stdint.h>
+#include <string>
+
+namespace usage_statistics {
+
+enum GlobalCounterId {
+ IAP_BUFFER_FULL,
+ SYNC_OUT_OF_MEMORY,
+ SYNC_REBOOTS
+};
+
+enum AppInfoId {
+ LANGUAGE_GUI,
+ LANGUAGE_VUI
+};
+
+enum AppStopwatchId {
+ SECONDS_HMI_FULL,
+ SECONDS_HMI_LIMITED,
+ SECONDS_HMI_BACKGROUND,
+ SECONDS_HMI_NONE
+};
+
+enum AppCounterId {
+ USER_SELECTIONS,
+ REJECTIONS_SYNC_OUT_OF_MEMORY,
+ REJECTIONS_NICKNAME_MISMATCH,
+ REJECTIONS_DUPLICATE_NAME,
+ REJECTED_RPC_CALLS,
+ RPCS_IN_HMI_NONE,
+ REMOVALS_MISBEHAVED,
+ RUN_ATTEMPTS_WHILE_REVOKED
+};
+
+class StatisticsManager {
+ public:
+ virtual ~StatisticsManager() {}
+ virtual void Increment(GlobalCounterId type) = 0;
+ virtual void Increment(const std::string& app_id, AppCounterId type) = 0;
+ virtual void Set(const std::string& app_id, AppInfoId type,
+ const std::string& value) = 0;
+ virtual void Add(const std::string& app_id,
+ AppStopwatchId type,
+ int32_t timespan_seconds) = 0;
+};
+
+} // namespace usage_statistics
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_USAGE_STATISTICS_STATISTICS_MANAGER_H_
diff --git a/src/components/policy/src/policy/usage_statistics/src/counter.cc b/src/components/policy/src/policy/usage_statistics/src/counter.cc
new file mode 100644
index 000000000..8ed19148d
--- /dev/null
+++ b/src/components/policy/src/policy/usage_statistics/src/counter.cc
@@ -0,0 +1,117 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+
+#include "usage_statistics/counter.h"
+#include <cassert>
+
+namespace usage_statistics {
+
+GlobalCounter::GlobalCounter(StatisticsManager* statistics_manager,
+ GlobalCounterId counter_type)
+ : counter_type_(counter_type),
+ statistics_manager_(statistics_manager) {
+}
+
+void GlobalCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(counter_type_);
+ }
+}
+
+AppCounter::AppCounter(StatisticsManager* statistics_manager,
+ const std::string& app_id,
+ AppCounterId counter_type)
+ : app_id_(app_id),
+ counter_type_(counter_type),
+ statistics_manager_(statistics_manager) {
+}
+
+void AppCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(app_id_, counter_type_);
+ }
+}
+
+AppInfo::AppInfo(StatisticsManager* statistics_manager,
+ const std::string& app_id,
+ AppInfoId info_type)
+ : app_id_(app_id),
+ info_type_(info_type),
+ statistics_manager_(statistics_manager) {
+}
+
+void AppInfo::Update(const std::string& new_info) const {
+ if (statistics_manager_) {
+ statistics_manager_->Set(app_id_, info_type_, new_info);
+ }
+}
+
+AppStopwatch::AppStopwatch(StatisticsManager* statistics_manager,
+ const std::string& app_id)
+ : app_id_(app_id),
+ stopwatch_type_(SECONDS_HMI_NONE),
+ statistics_manager_(statistics_manager),
+ start_time_() {
+}
+
+AppStopwatch::~AppStopwatch() {
+ if (start_time_) {
+ Stop();
+ }
+}
+
+void AppStopwatch::Start(AppStopwatchId stopwatch_type) {
+ assert(0 == start_time_);
+ stopwatch_type_ = stopwatch_type;
+ start_time_ = time(NULL);
+}
+
+void AppStopwatch::Switch(AppStopwatchId stopwatch_type) {
+ Stop();
+ Start(stopwatch_type);
+}
+
+void AppStopwatch::Stop() {
+ assert(start_time_ != 0);
+ double difference = difftime(time(NULL), start_time_);
+ if (statistics_manager_) {
+ statistics_manager_->Add(app_id_, stopwatch_type_, int32_t(difference));
+ }
+ start_time_ = 0;
+}
+
+} // namespace usage_statistics
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
diff --git a/src/components/policy/test/policy/CMakeLists.txt b/src/components/policy/test/policy/CMakeLists.txt
new file mode 100644
index 000000000..7d19dc213
--- /dev/null
+++ b/src/components/policy/test/policy/CMakeLists.txt
@@ -0,0 +1,95 @@
+include_directories(
+ ./
+ ./include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/gtest/include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/jsoncpp/include/
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/include/
+ ${CMAKE_BINARY_DIR}/src/components/policy/src/policy/
+ ${CMAKE_SOURCE_DIR}/src/components/rpc_base/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/sqlite_wrapper/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/qdb_wrapper/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/usage_statistics/include
+ ${CMAKE_SOURCE_DIR}/src/components/utils/include/
+)
+
+set(LIBRARIES
+ gtest
+ gtest_main
+ gmock
+ gmock_main
+ Policy
+ ConfigProfile
+)
+
+set(SHARED_LIBRARY_LIBRARIES
+ gtest
+ gtest_main
+ gmock
+ gmock_main
+ dl
+)
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ list(REMOVE_ITEM SHARED_LIBRARY_LIBRARIES dl)
+endif()
+
+set(SHARED_LIBRARY_SOURCES
+ ./src/test_shared_library.cc
+)
+
+set(SQL_PT_REPRESENTATION_SOURCES
+ ./src/test_sql_pt_representation.cc
+)
+
+set(GENERATED_CODE_SOURCES
+ ./src/generated_code_test.cc
+)
+
+set(GENERATED_CODE_WITH_SQLITE_SOURCES
+ ./src/generated_code_with_sqlite_test.cc
+)
+
+set(POLICY_MANAGER_IMPL_SOURCES
+ ./src/test_policy_manager_impl.cc
+)
+
+set(STRESS_POLICY_MANAGER_IMPL_SOURCES
+ ./src/test_stress_policy_manager_impl.cc
+)
+
+add_subdirectory(usage_statistics)
+
+
+if (EXTENDED_POLICY_FLAG)
+ add_definitions(-DEXTENDED_POLICY)
+endif()
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ # --- Tests for QDB Wrapper
+ add_subdirectory(qdb_wrapper)
+ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/qdbserver.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test-qdb.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+else ()
+ # --- Tests for SQLite Wrapper
+ add_subdirectory(sqlite_wrapper)
+ create_test("test_generated_code_with_sqlite" "${GENERATED_CODE_WITH_SQLITE_SOURCES}" "${LIBRARIES}")
+
+ if (EXTENDED_POLICY_FLAG)
+ set(SQL_PT_EXT_REPRESENTATION_SOURCES
+ ./src/test_sql_pt_ext_representation.cc
+ )
+ create_test("test_SQLPTExtRepresentation" "${SQL_PT_EXT_REPRESENTATION_SOURCES}" "${LIBRARIES}")
+ else ()
+ # TODO(KKolodiy): test crashes in QNX and failed for extended policy
+ create_test("test_stress_PolicyManagerImpl" "${STRESS_POLICY_MANAGER_IMPL_SOURCES}" "${LIBRARIES}")
+ endif ()
+endif()
+
+create_test("test_generated_policy_code" "${GENERATED_CODE_SOURCES}" "${LIBRARIES}")
+create_test("test_SharedLibrary" "${SHARED_LIBRARY_SOURCES}" "${SHARED_LIBRARY_LIBRARIES}")
+create_test("test_SQLPTRepresentation" "${SQL_PT_REPRESENTATION_SOURCES}" "${LIBRARIES}")
+create_test("test_PolicyManagerImpl" "${POLICY_MANAGER_IMPL_SOURCES}" "${LIBRARIES}")
+
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/valid_sdl_pt_update.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/src/components/policy/test/policy/include/generated_code_with_sqlite_test.h b/src/components/policy/test/policy/include/generated_code_with_sqlite_test.h
new file mode 100644
index 000000000..62641f32e
--- /dev/null
+++ b/src/components/policy/test/policy/include/generated_code_with_sqlite_test.h
@@ -0,0 +1,400 @@
+/* Copyright (c) 2013, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef GENERATED_CODE_WITH_SQLITE_TEST_H_
+#define GENERATED_CODE_WITH_SQLITE_TEST_H_
+
+#include "policy_table_interface_base/types.h"
+#include "rpc_base/rpc_base.h"
+#include "sqlite_wrapper/sql_query.h"
+#include "sqlite_wrapper/sql_database.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+namespace dbms = policy::dbms;
+
+namespace rpc {
+namespace policy_table_interface_base {
+
+bool FindSection(dbms::SQLDatabase* db,
+ policy_table::ServiceEndpoints& ep) {
+ /*
+ * Following table structure is assumed:
+ *
+ * table Endpoints
+ * index, service_type, application_id, url, is_default
+ *
+ * If url belongs to default section, application_id should be null and is_defaut = true
+ * Otherwise application_id should be set and is_default = false
+ */
+
+ std::string query = "select * from Endpoints";
+
+ dbms::SQLQuery sqlquery(db);
+ sqlquery.Prepare(query);
+ if (!sqlquery.Exec()) {
+ return false;
+ }
+
+ /*
+ * Following query result is assumed (data from wp1_policy_table.json):
+ * 1, 0x07, null, http://applinkqa.trafficmanager.net/api/policies, true
+ */
+
+ policy_table::URL urls;
+ urls.push_back(sqlquery.GetString(3));
+
+ policy_table::URLList urllist;
+ if (sqlquery.GetBoolean(4)) {
+ urllist["default"] = urls;
+ } else {
+ urllist[sqlquery.GetString(2)] = urls;
+ }
+
+ policy_table::ServiceEndpoints new_ep;
+ new_ep[sqlquery.GetString(1)] = urllist;
+
+ ep = new_ep;
+
+ return true;
+}
+
+bool FindSection(dbms::SQLDatabase* db,
+ policy_table::ModuleConfig& mc) {
+ policy_table::ModuleConfig new_mc;
+ FindSection(db, new_mc.endpoints);
+ mc = new_mc;
+
+ return true;
+}
+
+bool RemoveSection(dbms::SQLDatabase* db,
+ const policy_table::ApplicationPolicies& ap) {
+ dbms::SQLQuery sqlquery(db);
+ bool is_policies_removed = sqlquery.Exec("delete from AppPolicies");
+ // bool is_nicknames_removed = sqlquery.Exec("delete from Nicknames");
+ bool is_groups_removed = sqlquery.Exec("delete from Groups");
+
+ return is_policies_removed /*&& is_nicknames_removed*/ && is_groups_removed;
+}
+
+bool RemoveSection(dbms::SQLDatabase* db,
+ const policy_table::ServiceEndpoints& ep) {
+ std::string query = "delete from Endpoints";
+ dbms::SQLQuery sqlquery(db);
+ return sqlquery.Exec(query);
+}
+
+bool RemoveSection(dbms::SQLDatabase* db,
+ const policy_table::ModuleConfig& mc) {
+ // std::string query = "delete * from ModuleConfig";
+ // sqlite::SQLQuery sqlquery(db);
+ // sqlquery.Exec(query);
+
+ return RemoveSection(db, mc.endpoints);
+}
+
+bool RemoveSection(dbms::SQLDatabase* db,
+ const policy_table::FunctionalGroupings& fg) {
+ std::string query = "delete from FunctionalGroups";
+ dbms::SQLQuery sqlquery(db);
+ return sqlquery.Exec(query);
+}
+
+bool UpdateSection(dbms::SQLDatabase* db,
+ const policy_table::ServiceEndpoints& ep) {
+ /*
+ * Following table structure is assumed:
+ *
+ * table Endpoints
+ * index, service_type, application_id, url, is_default
+ *
+ * If url belongs to default section, application_id should be null and is_defaut = true
+ * Otherwise application_id should be set and is_default = false
+ */
+
+ // According to documentation, we have to REPLACE this part on update coming,
+ // so we delete all data first;
+ if (!RemoveSection(db, ep)) {
+ return false;
+ }
+
+ std::string query = "insert into Endpoints values(?,?,?,?,?)";
+ dbms::SQLQuery sqlquery(db);
+ sqlquery.Prepare(query);
+
+ policy_table::ServiceEndpoints::const_iterator it_ep = ep.begin();
+ policy_table::ServiceEndpoints::const_iterator it_ep_end = ep.end();
+
+ // TODO: use define for int from stdint.h
+ for (int index = 1; it_ep != it_ep_end; ++it_ep, ++index) {
+
+ policy_table::URLList::const_iterator it_urllist = (*it_ep).second.begin();
+ policy_table::URLList::const_iterator it_urllist_end = (*it_ep).second.end();
+
+ for (; it_urllist != it_urllist_end; ++it_urllist) {
+
+ policy_table::URL::const_iterator it_url = (*it_urllist).second.begin();
+ policy_table::URL::const_iterator it_url_end = (*it_urllist).second.end();
+
+ for (; it_url != it_url_end; ++it_url) {
+ // Index binding
+ sqlquery.Bind(0, index);
+
+ // Service type binding
+ sqlquery.Bind(1, (*it_ep).first);
+
+ // Application_id and is_default binding
+ std::string url_list_name = (*it_urllist).first;
+ if ("default" == url_list_name) {
+ sqlquery.Bind(2, "null");
+ sqlquery.Bind(4, true);
+ } else {
+ sqlquery.Bind(2, url_list_name);
+ sqlquery.Bind(4, false);
+ }
+
+ // URL binding
+ sqlquery.Bind(3, (*it_url));
+
+ if (sqlquery.Exec()) {
+ sqlquery.Reset();
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool UpdateSection(dbms::SQLDatabase* db,
+ const policy_table::ModuleConfig& mc) {
+ UpdateSection(db, mc.endpoints);
+ return true;
+}
+
+bool UpdateSection(dbms::SQLDatabase* db,
+ const policy_table::FunctionalGroupings& fg) {
+ /*
+ * Following table structure is assumed:
+ *
+ * table Rpcs - list of all available RPC commands
+ * index, rpc
+ *
+ * table HmiLevels -list of all available hmi levels
+ * index, hmi_level
+ *
+ * table Groups - list of functional group names
+ * index, group_name
+ *
+ * table FunctionalGroups - list of functional groups
+ * index, group_name_id, rpc_id, hmi_level_id
+ *
+ */
+
+ // According to documentation, we have to REPLACE this part on update coming,
+ // so we delete all data first;
+ if (!RemoveSection(db, fg)) {
+ return false;
+ }
+
+ std::string query = "insert into FunctionalGroups values("
+ "?,"
+ "(select index from Groups where group_name=?),"
+ "(select index from Rpcs where rpc=?),"
+ "(select index from HmiLevels where hmi_levels=?)";
+
+ dbms::SQLQuery sqlquery(db);
+ sqlquery.Prepare(query);
+
+ policy_table::FunctionalGroupings::const_iterator it_fg = fg.begin();
+ policy_table::FunctionalGroupings::const_iterator it_fg_end = fg.end();
+
+ for (int index = 1; it_fg != it_fg_end; ++it_fg, ++index) {
+
+ policy_table::Rpcs rpcs = (*it_fg).second;
+ policy_table::Rpc::const_iterator it_rpcs = rpcs.rpcs.begin();
+ policy_table::Rpc::const_iterator it_rpcs_end = rpcs.rpcs.end();
+
+ for (; it_rpcs != it_rpcs_end; ++it_rpcs) {
+
+ policy_table::RpcParameters rpc_params = (*it_rpcs).second;
+
+ policy_table::HmiLevels::const_iterator it_hmi_levels = rpc_params.hmi_levels.begin();
+ policy_table::HmiLevels::const_iterator it_hmi_levels_end = rpc_params.hmi_levels.end();
+
+ for (; it_hmi_levels != it_hmi_levels_end; ++it_hmi_levels) {
+
+ // Index binding
+ sqlquery.Bind(0, index);
+
+ // Group name binding
+ sqlquery.Bind(1, (*it_fg).first);
+
+ // RPC name binding
+ sqlquery.Bind(2, (*it_rpcs).first);
+
+ // Hmi levels binding
+ sqlquery.Bind(3, (*it_hmi_levels));
+ if (sqlquery.Exec()) {
+ sqlquery.Reset();
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool UpdateSection(dbms::SQLDatabase* db,
+ const policy_table::Table& pt) {
+ UpdateSection(db, pt.policy_table.module_config);
+ UpdateSection(db, pt.policy_table.functional_groupings);
+ return true;
+}
+
+bool UpdateSection(dbms::SQLDatabase* db,
+ const policy_table::ApplicationPolicies& ap) {
+ /*
+ * Following structure is assumed:
+ *
+ * table Groups - list of functional groups for application
+ * index, application_id, functional_group_id
+ *
+ * table Nicknames - list of nickname for application
+ * index, application_id, nickname
+ *
+ * table AppPolicies - policies for applications
+ * index, application_id, priority, is_default
+ *
+ */
+
+ // According to documentation, we have to REPLACE this part on update coming,
+ // so we delete all data first;
+ if (!RemoveSection(db, ap)) {
+ return false;
+ }
+
+ std::string groups_query = "insert into Groups values ("
+ "?,"
+ "?,"
+ "?)";
+ dbms::SQLQuery groups_sqlquery(db);
+ groups_sqlquery.Prepare(groups_query);
+
+ std::string nicknames_query = "insert into Nicknames values(?,?,?)";
+ dbms::SQLQuery nicknames_sqlquery(db);
+ nicknames_sqlquery.Prepare(nicknames_query);
+
+ std::string app_policies_query = "insert into AppPolicies values(?,?,?,?)";
+ dbms::SQLQuery app_policies_sqlquery(db);
+ app_policies_sqlquery.Prepare(app_policies_query);
+
+ policy_table::ApplicationPolicies::const_iterator it_ap = ap.begin();
+ policy_table::ApplicationPolicies::const_iterator it_ap_end = ap.end();
+
+ for (int index = 0; it_ap != it_ap_end; ++it_ap, ++index) {
+ // Index binding for AppPolicies table
+ app_policies_sqlquery.Bind(0, index);
+
+ std::string app_policy_name = (*it_ap).first;
+ bool is_default_policy = "default" == app_policy_name ? true : false;
+ if (is_default_policy) {
+ app_policies_sqlquery.Bind(1, "null");
+ app_policies_sqlquery.Bind(3, true);
+ } else {
+ app_policies_sqlquery.Bind(1, app_policy_name);
+ app_policies_sqlquery.Bind(3, false);
+ }
+
+ // Struct contains groups, nicknames, priority for application/default section
+ policy_table::ApplicationParams app_params = (*it_ap).second;
+
+ // Priority binding
+ // This param is present in extended policy table interface only
+ //app_policies_sqlquery.Bind(2, app_params.priority);
+ app_policies_sqlquery.Bind(2, "Dummy priority parameter");
+
+ // Add record to AppPolicies table
+ if (app_policies_sqlquery.Exec()) {
+ app_policies_sqlquery.Reset();
+ } else {
+ return false;
+ }
+
+ if (!is_default_policy) {
+ // Seems, there is generator issue with Optional type inheritance
+ // It should have pubic inheritance from type T to have array
+ // begin/end methods in its interface
+ // To be discussed with I.Kozyrenko
+
+ // policy_table::StringArray::const_iterator it_nicknames = app_params.nicknames.begin();
+ // policy_table::StringArray::const_iterator it_nicknames_end = app_params.nicknames.end();
+ //
+ // for (int nick_index = 0;it_nicknames != it_nicknames_end; ++ it_nicknames, ++nick_index) {
+ // nicknames_sqlquery.Bind(0, nick_index);
+ // nicknames_sqlquery.Bind(1, app_policy_name);
+ //
+ // nicknames_sqlquery.Bind(2, (*it_nicknames));
+ //
+ // if (nicknames_sqlquery.Exec()) {
+ // nicknames_sqlquery.Reset();
+ // } else {
+ // return false;
+ // }
+ // }
+
+ policy_table::Strings::const_iterator it_groups = app_params.groups.begin();
+ policy_table::Strings::const_iterator it_groups_end = app_params.groups.end();
+
+ for (int group_index = 0; it_groups != it_groups_end; ++it_groups, ++group_index) {
+ groups_sqlquery.Bind(0, group_index);
+ groups_sqlquery.Bind(1, app_policy_name);
+ groups_sqlquery.Bind(2, (*it_groups));
+
+ if (groups_sqlquery.Exec()) {
+ groups_sqlquery.Reset();
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+}
+}
+
+#endif /* GENERATED_CODE_WITH_SQLITE_TEST_H_ */
diff --git a/src/components/policy/test/policy/include/mock_policy_listener.h b/src/components/policy/test/policy/include/mock_policy_listener.h
new file mode 100644
index 000000000..4a84bc2e4
--- /dev/null
+++ b/src/components/policy/test/policy/include/mock_policy_listener.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_COMPONENTS_POLICY_INCLUDE_MOCK_POLICY_LISTENER_H_
+#define TEST_COMPONENTS_POLICY_INCLUDE_MOCK_POLICY_LISTENER_H_
+
+#include "gmock/gmock.h"
+#include "policy/policy_listener.h"
+#include "rpc_base/rpc_base.h"
+#include "policy_table_interface_base/types.h"
+
+namespace policy_table = ::rpc::policy_table_interface_base;
+
+namespace policy {
+
+class MockPolicyListener : public PolicyListener {
+ public:
+ MOCK_METHOD0(OnPTExchangeNeeded,
+ void());
+ MOCK_METHOD3(OnPermissionsUpdated,
+ void(const std::string& policy_app_id, const Permissions& permissions,
+ const policy::HMILevel& default_hmi));
+ MOCK_METHOD1(OnPendingPermissionChange,
+ void(const std::string& policy_app_id));
+ MOCK_METHOD1(OnAppRevoked,
+ void(const std::string& policy_app_id));
+ MOCK_METHOD1(OnUpdateStatusChanged,
+ void(policy::PolicyTableStatus status));
+ MOCK_METHOD1(OnCurrentDeviceIdUpdateRequired,
+ std::string(const std::string& policy_app_id));
+ MOCK_METHOD0(OnSystemInfoUpdateRequired,
+ void());
+ MOCK_METHOD1(GetAppName,
+ std::string(const std::string& policy_app_id));
+};
+
+}
+// namespace policy
+
+#endif // TEST_COMPONENTS_POLICY_INCLUDE_MOCK_POLICY_LISTENER_H_
diff --git a/src/components/policy/test/policy/include/mock_pt_ext_representation.h b/src/components/policy/test/policy/include/mock_pt_ext_representation.h
new file mode 100644
index 000000000..f8b2958ca
--- /dev/null
+++ b/src/components/policy/test/policy/include/mock_pt_ext_representation.h
@@ -0,0 +1,119 @@
+/* Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_EXT_REPRESENTATION_H_
+#define TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_EXT_REPRESENTATION_H_
+
+#include "gmock/gmock.h"
+#include "policy/pt_ext_representation.h"
+#include "rpc_base/rpc_base.h"
+#include "policy_table_interface_base/types.h"
+#include "mock_pt_representation.h"
+
+namespace policy_table = ::rpc::policy_table_interface_base;
+
+namespace policy {
+
+class MockPTExtRepresentation : public MockPTRepresentation,
+ public PTExtRepresentation {
+ public:
+ MOCK_METHOD1(CanAppKeepContext,
+ bool(const std::string& app_id));
+ MOCK_METHOD1(CanAppStealFocus,
+ bool(const std::string& app_id));
+ MOCK_METHOD2(GetDefaultHMI,
+ bool(const std::string& app_id, std::string* default_hmi));
+ MOCK_METHOD2(GetPriority,
+ bool(const std::string& app_id, std::string* priority));
+ MOCK_METHOD0(ResetUserConsent,
+ bool());
+ MOCK_METHOD3(GetUserPermissionsForDevice,
+ bool(const std::string&, StringArray*, StringArray*));
+ MOCK_METHOD3(GetUserPermissionsForApp,
+ bool(const std::string&, const std::string&,
+ FunctionalIdType* group_types));
+ MOCK_METHOD2(GetDeviceGroupsFromPolicies,
+ bool(policy_table::Strings*, policy_table::Strings*));
+ MOCK_METHOD2(GetUserFriendlyMsg,
+ std::vector<UserFriendlyMessage>(const std::vector<std::string>& msg_code,
+ const std::string& language));
+ MOCK_METHOD7(SetDeviceData, bool (const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports));
+ MOCK_METHOD6(SetDeviceData,
+ bool(const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&));
+ MOCK_METHOD2(SetMaxNumberPorts,
+ bool(const std::string& device_id, unsigned int number_of_ports));
+ MOCK_METHOD3(SetUserPermissionsForDevice,
+ bool(const std::string&, const StringArray&, const StringArray&));
+ MOCK_METHOD1(SetUserPermissionsForApp,
+ bool(const PermissionConsent&));
+ MOCK_METHOD1(IncreaseStatisticsData,
+ bool(StatisticsType type));
+ MOCK_METHOD3(SetAppRegistrationLanguage,
+ bool(const std::string& app_id, LanguageType type, const std::string& language));
+ MOCK_METHOD3(SetMetaInfo,
+ bool(const std::string& ccpu_version, const std::string& wers_country_code, const std::string& vin));
+ MOCK_METHOD1(SetSystemLanguage,
+ bool(const std::string& language));
+ MOCK_METHOD0(GetKmFromSuccessfulExchange,
+ int());
+ MOCK_METHOD0(GetDayFromScsExchange,
+ int());
+ MOCK_METHOD0(GetIgnitionsFromScsExchange,
+ int());
+ MOCK_CONST_METHOD1(Increment,
+ void(const std::string& type));
+ MOCK_CONST_METHOD2(Increment,
+ void(const std::string& app_id, const std::string& type));
+ MOCK_CONST_METHOD3(Set,
+ void(const std::string& app_id, const std::string& type, const std::string& value));
+ MOCK_CONST_METHOD3(Add,
+ void(const std::string& app_id, const std::string& type, int seconds));
+ MOCK_CONST_METHOD2(CountUnconsentedGroups,
+ bool(const std::string& app_id, int* count));
+ MOCK_METHOD1(GetFunctionalGroupNames,
+ bool(FunctionalGroupNames& names));
+ MOCK_METHOD1(CleanupUnpairedDevices,
+ bool(const DeviceIds& device_ids));
+ MOCK_METHOD2(ReactOnUserDevConsentForApp,
+ bool(const std::string& app_id, bool is_device_allowed));
+ MOCK_METHOD1(SetPredataPolicy, bool(const std::string& app_id));
+ MOCK_METHOD2(SetIsPredata, bool(const std::string& app_id, bool is_predata));
+};
+
+} // namespace policy
+
+#endif // TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_EXT_REPRESENTATION_H_
diff --git a/src/components/policy/test/policy/include/mock_pt_representation.h b/src/components/policy/test/policy/include/mock_pt_representation.h
new file mode 100644
index 000000000..41ce49030
--- /dev/null
+++ b/src/components/policy/test/policy/include/mock_pt_representation.h
@@ -0,0 +1,106 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_REPRESENTATION_H_
+#define TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_REPRESENTATION_H_
+
+#include "gmock/gmock.h"
+#include "policy/pt_representation.h"
+#include "rpc_base/rpc_base.h"
+#include "policy_table_interface_base/types.h"
+
+namespace policy_table = ::rpc::policy_table_interface_base;
+
+namespace policy {
+
+class MockPTRepresentation : virtual public PTRepresentation {
+ public:
+ MOCK_METHOD3(CheckPermissions,
+ CheckPermissionResult(const PTString& app_id, const PTString& hmi_level,
+ const PTString& rpc));
+ MOCK_METHOD0(IsPTPreloaded,
+ bool());
+ MOCK_METHOD0(IgnitionCyclesBeforeExchange,
+ int());
+ MOCK_METHOD1(KilometersBeforeExchange,
+ int(int current));
+ MOCK_METHOD2(SetCountersPassedForSuccessfulUpdate,
+ bool(int kilometers, int days_after_epoch));
+ MOCK_METHOD1(DaysBeforeExchange,
+ int(int current));
+ MOCK_METHOD0(IncrementIgnitionCycles,
+ void());
+ MOCK_METHOD0(ResetIgnitionCycles,
+ void());
+ MOCK_METHOD0(TimeoutResponse,
+ int());
+ MOCK_METHOD1(SecondsBetweenRetries,
+ bool(std::vector<int>* seconds));
+ MOCK_METHOD0(GetVehicleData,
+ VehicleData());
+ MOCK_METHOD2(GetUserFriendlyMsg,
+ std::vector<UserFriendlyMessage>(const std::vector<std::string>& msg_code,
+ const std::string& language));
+ MOCK_METHOD1(GetUpdateUrls,
+ EndpointUrls(int service_type));
+ MOCK_METHOD1(GetNotificationsNumber,
+ int(policy_table::Priority priority));
+ MOCK_METHOD0(Init,
+ InitResult());
+ MOCK_METHOD0(Close,
+ bool());
+ MOCK_METHOD0(Clear,
+ bool());
+ MOCK_CONST_METHOD0(GenerateSnapshot,
+ utils::SharedPtr<policy_table::Table>());
+ MOCK_METHOD1(Save,
+ bool(const policy_table::Table& table));
+ MOCK_CONST_METHOD0(UpdateRequired,
+ bool());
+ MOCK_METHOD1(SaveUpdateRequired,
+ void(bool value));
+ MOCK_METHOD3(GetInitialAppData,
+ bool(const std::string& app_id, StringArray* nicknames, StringArray* app_types));
+ MOCK_CONST_METHOD1(IsApplicationRevoked, bool(const std::string& app_id));
+ MOCK_METHOD1(GetFunctionalGroupings,
+ bool(policy_table::FunctionalGroupings& groups));
+ MOCK_CONST_METHOD1(IsApplicationRepresented, bool(const std::string& app_id));
+ MOCK_CONST_METHOD1(IsDefaultPolicy, bool(const std::string& app_id));
+ MOCK_METHOD1(SetDefaultPolicy, bool(const std::string& app_id));
+ MOCK_METHOD1(CleanupUnpairedDevices,
+ bool(const DeviceIds& device_ids));
+ MOCK_CONST_METHOD1(IsPredataPolicy, bool(const std::string& app_id));
+};
+
+}
+// namespace policy
+
+#endif // TEST_COMPONENTS_POLICY_INCLUDE_MOCK_PT_REPRESENTATION_H_
diff --git a/src/components/policy/test/policy/log4cxx.properties b/src/components/policy/test/policy/log4cxx.properties
new file mode 100644
index 000000000..632ab540c
--- /dev/null
+++ b/src/components/policy/test/policy/log4cxx.properties
@@ -0,0 +1,21 @@
+# Only ERROR and FATAL messages are logged to console
+log4j.appender.Console=org.apache.log4j.ConsoleAppender
+log4j.appender.Console.ImmediateFlush=true
+log4j.appender.Console.layout=org.apache.log4j.PatternLayout
+log4j.appender.Console.layout.ConversionPattern=%-5p [%d{dd MMM yyyy HH:mm:ss,SSS}][%c] %m%n
+log4j.appender.Console.Threshold=ERROR
+
+# Log for all SQLPTRepresentation messages
+log4j.appender.SQLPTRepresentationLogFile=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.SQLPTRepresentationLogFile.File=SQLRepresentation.log
+log4j.appender.SQLPTRepresentationLogFile.ImmediateFlush=true
+log4j.appender.SQLPTRepresentationLogFile.layout=org.apache.log4j.PatternLayout
+log4j.appender.SQLPTRepresentationLogFile.layout.ConversionPattern=%-5p [%d{dd MMM yyyy HH:mm:ss,SSS}] :%L %M: %m%n
+log4j.appender.SQLPTRepresentationLogFile.Schedule=DAILY
+log4j.appender.SQLPTRepresentationLogFile.DatePattern='.' yyyy-MM-dd
+
+# All SmartDeviceLinkCore logs
+log4j.rootLogger=ALL, Console
+
+# SQLPTRepresentation logs
+log4j.logger.SQLPTRepresentation=ALL, SQLPTRepresentationLogFile \ No newline at end of file
diff --git a/src/components/policy/test/policy/qdb_wrapper/CMakeLists.txt b/src/components/policy/test/policy/qdb_wrapper/CMakeLists.txt
new file mode 100644
index 000000000..06ec91f28
--- /dev/null
+++ b/src/components/policy/test/policy/qdb_wrapper/CMakeLists.txt
@@ -0,0 +1,29 @@
+find_package(Sqlite3 REQUIRED)
+
+include_directories(
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/gtest/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/qdb_wrapper/include
+)
+
+set(LIBRARIES
+ gtest
+ gtest_main
+ gmock
+ gmock_main
+ dbms
+)
+
+set(DATABASE_SOURCES
+ ./src/test_sql_database.cc
+)
+
+set(QUERY_SOURCES
+ ./src/test_sql_query.cc
+)
+
+create_test("test_SQLDatabase" "${DATABASE_SOURCES}" "${LIBRARIES}")
+create_test("test_SQLQuery" "${QUERY_SOURCES}" "${LIBRARIES}")
+
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../qdbserver.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test-qdb.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file
diff --git a/src/components/policy/test/policy/qdb_wrapper/src/test_sql_database.cc b/src/components/policy/test/policy/qdb_wrapper/src/test_sql_database.cc
new file mode 100644
index 000000000..103fbc7f4
--- /dev/null
+++ b/src/components/policy/test/policy/qdb_wrapper/src/test_sql_database.cc
@@ -0,0 +1,142 @@
+/* Copyright (c) 2013, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <gtest/gtest.h>
+#include <cstdlib>
+#include "qdb_wrapper/sql_error.h"
+#include "qdb_wrapper/sql_database.h"
+
+using ::policy::dbms::SQLError;
+using ::policy::dbms::SQLDatabase;
+
+namespace test {
+namespace components {
+namespace policy {
+namespace dbms {
+
+::testing::AssertionResult IsError(SQLError error) {
+ if (error.number() != ::policy::dbms::OK) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+TEST(SQLDatabaseTest, OpenClose) {
+ SQLDatabase db("test-database");
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+
+TEST(SQLDatabaseTest, DoubleOpen) {
+ SQLDatabase db("test-database");
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+ ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, DoubleClose) {
+ SQLDatabase db("test-database");
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+
+TEST(SQLDatabaseTest, CloseWithoutOpen) {
+ SQLDatabase db("test-database");
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+
+TEST(SQLDatabaseTest, CommitTransaction) {
+ SQLDatabase db("test-database");
+ ASSERT_TRUE(db.Open());
+ EXPECT_TRUE(db.BeginTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ EXPECT_TRUE(db.CommitTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, RollbackTransaction) {
+ SQLDatabase db("test-database");
+ ASSERT_TRUE(db.Open());
+ EXPECT_TRUE(db.BeginTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ EXPECT_TRUE(db.RollbackTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, FailedCommitTransaction) {
+ SQLDatabase db("test-database");
+ ASSERT_TRUE(db.Open());
+ EXPECT_FALSE(db.CommitTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, FailedRollbackTransaction) {
+ SQLDatabase db("test-database");
+ ASSERT_TRUE(db.Open());
+ EXPECT_FALSE(db.RollbackTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, BadTransaction) {
+ SQLDatabase db("test-database");
+ EXPECT_FALSE(db.BeginTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+}
+
+} // namespace dbms
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/qdb_wrapper/src/test_sql_query.cc b/src/components/policy/test/policy/qdb_wrapper/src/test_sql_query.cc
new file mode 100644
index 000000000..fbe502d45
--- /dev/null
+++ b/src/components/policy/test/policy/qdb_wrapper/src/test_sql_query.cc
@@ -0,0 +1,284 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <qdb/qdb.h>
+#include <string>
+#include "qdb_wrapper/sql_error.h"
+#include "qdb_wrapper/sql_database.h"
+#include "qdb_wrapper/sql_query.h"
+
+using ::policy::dbms::SQLError;
+using ::policy::dbms::SQLDatabase;
+using ::policy::dbms::SQLQuery;
+
+namespace test {
+namespace components {
+namespace policy {
+namespace dbms {
+
+class SQLQueryTest : public ::testing::Test {
+ protected:
+ static qdb_hdl_t* conn;
+ static const std::string kDatabaseName;
+
+ static void SetUpTestCase() {
+ conn = qdb_connect(kDatabaseName.c_str(), 0);
+ ASSERT_TRUE(conn);
+ int ret = qdb_statement(conn, "CREATE TABLE testTable (integerValue INTEGER,"
+ " doubleValue REAL, stringValue TEXT)");
+ ASSERT_NE(-1, ret);
+ }
+
+ static void TearDownTestCase() {
+ qdb_statement(conn, "DROP TABLE IF EXISTS testTable");
+ qdb_disconnect(conn);
+ }
+
+ void SetUp() {
+ qdb_statement(conn, "DELETE FROM testTable");
+ }
+};
+
+qdb_hdl_t* SQLQueryTest::conn = 0;
+const std::string SQLQueryTest::kDatabaseName = "test-query";
+
+::testing::AssertionResult IsError(SQLError error) {
+ if (error.number() != ::policy::dbms::OK) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+TEST_F(SQLQueryTest, Query) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_NE(-1, qdb_statement(conn, insert));
+
+ const std::string kSelect("SELECT * FROM testTable WHERE integerValue = ?");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+ SQLQuery query(&db);
+ query.Prepare(kSelect);
+ EXPECT_STREQ(kSelect.c_str(), query.query().c_str());
+}
+
+TEST_F(SQLQueryTest, ExecString) {
+ const std::string kInsert("INSERT INTO testTable"
+ " (integerValue, doubleValue, stringValue)"
+ " VALUES(2, 3.4, 'five-пять')");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Exec(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, Bind) {
+ const std::string kInsert1("INSERT INTO testTable (integerValue) VALUES (?)");
+ const std::string kInsert2("INSERT INTO testTable (doubleValue) VALUES (?)");
+ const std::string kInsert3("INSERT INTO testTable (stringValue) VALUES (?)");
+ const std::string kInsert4("INSERT INTO testTable (integerValue, doubleValue,"
+ " stringValue) VALUES (?, ?, ?)");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query1(&db);
+ EXPECT_TRUE(query1.Prepare(kInsert1));
+ EXPECT_FALSE(IsError(query1.LastError()));
+ query1.Bind(0, kIntegerValue);
+ EXPECT_FALSE(IsError(query1.LastError()));
+ EXPECT_TRUE(query1.Exec());
+ EXPECT_FALSE(IsError(query1.LastError()));
+
+ SQLQuery query2(&db);
+ EXPECT_TRUE(query2.Prepare(kInsert2));
+ EXPECT_FALSE(IsError(query2.LastError()));
+ query2.Bind(0, kDoubleValue);
+ EXPECT_FALSE(IsError(query2.LastError()));
+ EXPECT_TRUE(query2.Exec());
+ EXPECT_FALSE(IsError(query2.LastError()));
+
+ SQLQuery query3(&db);
+ EXPECT_TRUE(query3.Prepare(kInsert3));
+ EXPECT_FALSE(IsError(query3.LastError()));
+ query3.Bind(0, kStringValue);
+ EXPECT_FALSE(IsError(query3.LastError()));
+ EXPECT_TRUE(query3.Exec());
+ EXPECT_FALSE(IsError(query3.LastError()));
+
+ SQLQuery query4(&db);
+ EXPECT_TRUE(query4.Prepare(kInsert4));
+ EXPECT_FALSE(IsError(query4.LastError()));
+ query4.Bind(0, kIntegerValue);
+ query4.Bind(1, kDoubleValue);
+ query4.Bind(2, kStringValue);
+ EXPECT_FALSE(IsError(query4.LastError()));
+ // TODO(KKolodiy): EXPECT -> ASSERT because test crashes in IsError
+ ASSERT_TRUE(query4.Exec());
+ EXPECT_FALSE(IsError(query4.LastError()));
+}
+
+TEST_F(SQLQueryTest, Value) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_NE(-1, qdb_statement(conn, insert));
+
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_EQ(kIntegerValue, query.GetInteger(0));
+ EXPECT_EQ(kDoubleValue, query.GetDouble(1));
+ EXPECT_EQ(kStringValue, query.GetString(2));
+ EXPECT_FALSE(query.Next());
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, EmptySelect) {
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable WHERE 0");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, NextAndBind) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_NE(-1, qdb_statement(conn, insert));
+
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable WHERE stringValue = ?");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0, kStringValue);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_FALSE(IsError(query.LastError()));
+ EXPECT_EQ(kIntegerValue, query.GetInteger(0));
+ EXPECT_EQ(kDoubleValue, query.GetDouble(1));
+ EXPECT_EQ(kStringValue, query.GetString(2));
+ EXPECT_FALSE(query.Next());
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, LastInsertId) {
+ const char* create = "CREATE TABLE idTable ( "
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "value TEXT)";
+ ASSERT_NE(-1, qdb_statement(conn, create));
+
+ const int64_t kExpectId = 1;
+ const std::string kValue("Test last id of insert row");
+ const std::string kInsert("INSERT INTO idTable (value) VALUES(?)");
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0, kValue);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_FALSE(IsError(query.LastError()));
+ EXPECT_EQ(kExpectId, query.LastInsertId());
+
+ ASSERT_NE(-1, qdb_statement(conn, "DROP TABLE idTable"));
+}
+
+TEST_F(SQLQueryTest, BindNull) {
+ const std::string kInsert("INSERT INTO testTable (`integerValue`)"
+ " VALUES (?)");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, DoublePrepare) {
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare("SELECT * FROM testTable"));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Prepare("SELECT * FROM testTable"));
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+} // namespace dbms
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/qdbserver.sh b/src/components/policy/test/policy/qdbserver.sh
new file mode 100755
index 000000000..3f0144106
--- /dev/null
+++ b/src/components/policy/test/policy/qdbserver.sh
@@ -0,0 +1,6 @@
+# This script star QDB server for SDL
+# Need superuser to start qdb
+
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/qnx650/target/qnx6/x86/usr/lib
+export LD_LIBRARY_PATH
+/usr/sbin/qdb -c test-qdb.ini
diff --git a/src/components/policy/test/policy/sqlite_wrapper/CMakeLists.txt b/src/components/policy/test/policy/sqlite_wrapper/CMakeLists.txt
new file mode 100644
index 000000000..9d5a3fceb
--- /dev/null
+++ b/src/components/policy/test/policy/sqlite_wrapper/CMakeLists.txt
@@ -0,0 +1,26 @@
+find_package(Sqlite3 REQUIRED)
+
+include_directories(
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/gtest/include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/sqlite_wrapper/include
+)
+
+set(LIBRARIES
+ gtest
+ gtest_main
+ gmock
+ gmock_main
+ dbms
+)
+
+set(DATABASE_SOURCES
+ ./src/test_sql_database.cc
+)
+
+set(QUERY_SOURCES
+ ./src/test_sql_query.cc
+)
+
+create_test("test_SQLDatabase" "${DATABASE_SOURCES}" "${LIBRARIES}")
+create_test("test_SQLQuery" "${QUERY_SOURCES}" "${LIBRARIES}") \ No newline at end of file
diff --git a/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_database.cc b/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_database.cc
new file mode 100644
index 000000000..4cd75a702
--- /dev/null
+++ b/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_database.cc
@@ -0,0 +1,151 @@
+/* Copyright (c) 2013, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <gtest/gtest.h>
+#include "sqlite_wrapper/sql_error.h"
+#include "sqlite_wrapper/sql_database.h"
+
+using ::policy::dbms::SQLError;
+using ::policy::dbms::SQLDatabase;
+
+namespace test {
+namespace components {
+namespace policy {
+namespace dbms {
+
+::testing::AssertionResult IsError(SQLError error) {
+ if (error.number() != ::policy::dbms::OK) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+TEST(SQLDatabaseTest, OpenCloseMemory) {
+ SQLDatabase db;
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+TEST(SQLDatabaseTest, OpenCloseFile) {
+ SQLDatabase db("test-database");
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+ remove("test-database.sqlite");
+}
+
+TEST(SQLDatabaseTest, DoubleOpen) {
+ SQLDatabase db;
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+ ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, DoubleClose) {
+ SQLDatabase db;
+ bool ret = db.Open();
+ EXPECT_FALSE(IsError(db.LastError()));
+ ASSERT_TRUE(ret);
+
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+
+TEST(SQLDatabaseTest, CloseWithoutOpen) {
+ SQLDatabase db;
+ db.Close();
+ EXPECT_FALSE(IsError(db.LastError()));
+}
+
+TEST(SQLDatabaseTest, CommitTransaction) {
+ SQLDatabase db;
+ ASSERT_TRUE(db.Open());
+ EXPECT_TRUE(db.BeginTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ EXPECT_TRUE(db.CommitTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, RollbackTransaction) {
+ SQLDatabase db;
+ ASSERT_TRUE(db.Open());
+ EXPECT_TRUE(db.BeginTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ EXPECT_TRUE(db.RollbackTransaction());
+ EXPECT_FALSE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, FailedCommitTransaction) {
+ SQLDatabase db;
+ ASSERT_TRUE(db.Open());
+ EXPECT_FALSE(db.CommitTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, FailedRollbackTransaction) {
+ SQLDatabase db;
+ ASSERT_TRUE(db.Open());
+ EXPECT_FALSE(db.RollbackTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+ db.Close();
+}
+
+TEST(SQLDatabaseTest, BadTransaction) {
+ SQLDatabase db;
+ EXPECT_FALSE(db.BeginTransaction());
+ EXPECT_TRUE(IsError(db.LastError()));
+}
+
+} // namespace dbms
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_query.cc b/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_query.cc
new file mode 100644
index 000000000..68560f3c6
--- /dev/null
+++ b/src/components/policy/test/policy/sqlite_wrapper/src/test_sql_query.cc
@@ -0,0 +1,299 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <sqlite3.h>
+#include <string>
+#include "sqlite_wrapper/sql_error.h"
+#include "sqlite_wrapper/sql_database.h"
+#include "sqlite_wrapper/sql_query.h"
+
+using ::policy::dbms::SQLError;
+using ::policy::dbms::SQLDatabase;
+using ::policy::dbms::SQLQuery;
+
+namespace test {
+namespace components {
+namespace policy {
+namespace dbms {
+
+class SQLQueryTest : public ::testing::Test {
+ protected:
+ static sqlite3* conn;
+ static const std::string kDatabaseName;
+
+ static void SetUpTestCase() {
+ sqlite3_open((kDatabaseName + ".sqlite").c_str(), &conn);
+ sqlite3_exec(conn, "CREATE TABLE testTable (integerValue INTEGER,"
+ " doubleValue REAL, stringValue TEXT)",
+ NULL, NULL, NULL);
+ }
+
+ static void TearDownTestCase() {
+ sqlite3_close(conn);
+ remove((kDatabaseName + ".sqlite").c_str());
+ }
+
+ void SetUp() {
+ sqlite3_exec(conn, "DELETE FROM testTable", NULL, NULL, NULL);
+ }
+};
+
+sqlite3* SQLQueryTest::conn = 0;
+const std::string SQLQueryTest::kDatabaseName = "test-query";
+
+::testing::AssertionResult IsError(SQLError error) {
+ if (error.number() != ::policy::dbms::OK) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+::testing::AssertionResult IsDone(SQLError error) {
+ if (error.number() == ::policy::dbms::DONE) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+::testing::AssertionResult IsRow(SQLError error) {
+ if (error.number() == ::policy::dbms::ROW) {
+ return ::testing::AssertionSuccess() << error.text();
+ } else {
+ return ::testing::AssertionFailure() << error.text();
+ }
+}
+
+TEST_F(SQLQueryTest, Query) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, insert, NULL, NULL, NULL));
+
+ const std::string kSelect("SELECT * FROM testTable WHERE integerValue = ?");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+ SQLQuery query(&db);
+ query.Prepare(kSelect);
+ EXPECT_STREQ(kSelect.c_str(), query.query().c_str());
+}
+
+TEST_F(SQLQueryTest, ExecString) {
+ const std::string kInsert("INSERT INTO testTable"
+ " (integerValue, doubleValue, stringValue)"
+ " VALUES(2, 3.4, 'five-пять')");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Exec(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, Bind) {
+ const std::string kInsert1("INSERT INTO testTable (integerValue) VALUES (?)");
+ const std::string kInsert2("INSERT INTO testTable (doubleValue) VALUES (?)");
+ const std::string kInsert3("INSERT INTO testTable (stringValue) VALUES (?)");
+ const std::string kInsert4("INSERT INTO testTable (integerValue, doubleValue,"
+ " stringValue) VALUES (?, ?, ?)");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query1(&db);
+ EXPECT_TRUE(query1.Prepare(kInsert1));
+ EXPECT_FALSE(IsError(query1.LastError()));
+ query1.Bind(0, kIntegerValue);
+ EXPECT_FALSE(IsError(query1.LastError()));
+ EXPECT_TRUE(query1.Exec());
+ EXPECT_TRUE(IsDone(query1.LastError()));
+
+ SQLQuery query2(&db);
+ EXPECT_TRUE(query2.Prepare(kInsert2));
+ EXPECT_FALSE(IsError(query2.LastError()));
+ query2.Bind(0, kDoubleValue);
+ EXPECT_FALSE(IsError(query2.LastError()));
+ EXPECT_TRUE(query2.Exec());
+ EXPECT_TRUE(IsDone(query2.LastError()));
+
+ SQLQuery query3(&db);
+ EXPECT_TRUE(query3.Prepare(kInsert3));
+ EXPECT_FALSE(IsError(query3.LastError()));
+ query3.Bind(0, kStringValue);
+ EXPECT_FALSE(IsError(query3.LastError()));
+ EXPECT_TRUE(query3.Exec());
+ EXPECT_TRUE(IsDone(query3.LastError()));
+
+ SQLQuery query4(&db);
+ EXPECT_TRUE(query4.Prepare(kInsert4));
+ EXPECT_FALSE(IsError(query4.LastError()));
+ query4.Bind(0, kIntegerValue);
+ query4.Bind(1, kDoubleValue);
+ query4.Bind(2, kStringValue);
+ EXPECT_FALSE(IsError(query4.LastError()));
+ EXPECT_TRUE(query4.Exec());
+ EXPECT_TRUE(IsDone(query4.LastError()));
+}
+
+TEST_F(SQLQueryTest, Value) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, insert, NULL, NULL, NULL));
+
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ EXPECT_TRUE(IsRow(query.LastError()));
+ EXPECT_EQ(kIntegerValue, query.GetInteger(0));
+ EXPECT_EQ(kDoubleValue, query.GetDouble(1));
+ EXPECT_EQ(kStringValue, query.GetString(2));
+ EXPECT_FALSE(query.Next());
+ EXPECT_TRUE(IsDone(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, EmptySelect) {
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable WHERE 0");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ EXPECT_TRUE(IsDone(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, NextAndBind) {
+ const char* insert = "INSERT INTO testTable "
+ "(integerValue, doubleValue, stringValue) "
+ "VALUES (1, 2.3, 'four');";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, insert, NULL, NULL, NULL));
+
+ const std::string kSelect("SELECT integerValue, doubleValue, stringValue"
+ " FROM testTable WHERE stringValue = ?");
+ const int kIntegerValue = 1;
+ const double kDoubleValue = 2.3;
+ const std::string kStringValue = "four";
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kSelect));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0, kStringValue);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_TRUE(IsRow(query.LastError()));
+ EXPECT_EQ(kIntegerValue, query.GetInteger(0));
+ EXPECT_EQ(kDoubleValue, query.GetDouble(1));
+ EXPECT_EQ(kStringValue, query.GetString(2));
+ EXPECT_FALSE(query.Next());
+ EXPECT_TRUE(IsDone(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, LastInsertId) {
+ const char* create = "CREATE TABLE idTable ( "
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "value TEXT)";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, create, NULL, NULL, NULL));
+
+ const int64_t kExpectId = 1;
+ const std::string kValue("Test last id of insert row");
+ const std::string kInsert("INSERT INTO idTable (value) VALUES(?)");
+
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0, kValue);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_TRUE(IsDone(query.LastError()));
+ EXPECT_EQ(kExpectId, query.LastInsertId());
+
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_exec(conn, "DROP TABLE idTable", NULL, NULL, NULL));
+}
+
+TEST_F(SQLQueryTest, BindNull) {
+ const std::string kInsert("INSERT INTO testTable (`integerValue`)"
+ " VALUES (?)");
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ ASSERT_TRUE(query.Prepare(kInsert));
+ EXPECT_FALSE(IsError(query.LastError()));
+ query.Bind(0);
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Exec());
+ ASSERT_TRUE(IsDone(query.LastError()));
+}
+
+TEST_F(SQLQueryTest, DoublePrepare) {
+ SQLDatabase db(kDatabaseName);
+ ASSERT_TRUE(db.Open());
+
+ SQLQuery query(&db);
+ EXPECT_TRUE(query.Prepare("SELECT * FROM testTable"));
+ EXPECT_FALSE(IsError(query.LastError()));
+ EXPECT_TRUE(query.Prepare("SELECT * FROM testTable"));
+ EXPECT_FALSE(IsError(query.LastError()));
+}
+
+} // namespace dbms
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/src/generated_code_test.cc b/src/components/policy/test/policy/src/generated_code_test.cc
new file mode 100644
index 000000000..312b06a89
--- /dev/null
+++ b/src/components/policy/test/policy/src/generated_code_test.cc
@@ -0,0 +1,60 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fstream>
+
+#include <gtest/gtest.h>
+#include "json/reader.h"
+#include "json/value.h"
+#include "policy_table_interface_base/enums.h"
+#include "policy_table_interface_base/types.h"
+#include "rpc_base/gtest_support.h"
+
+using namespace rpc::policy_table_interface_base;
+
+namespace test {
+namespace components {
+namespace policy {
+
+TEST(PolicyGeneratedCodeTest, TestValidPTUpdateJsonIsValid) {
+ std::ifstream json_file("valid_sdl_pt_update.json");
+ ASSERT_TRUE(json_file.is_open());
+ Json::Value valid_table;
+ Json::Reader reader;
+ ASSERT_TRUE(reader.parse(json_file, valid_table));
+ Table table(&valid_table);
+ ASSERT_RPCTYPE_VALID(table);
+}
+
+
+} // namespace policy
+} // namespace components
+} // namespace test
diff --git a/src/components/policy/test/policy/src/generated_code_with_sqlite_test.cc b/src/components/policy/test/policy/src/generated_code_with_sqlite_test.cc
new file mode 100644
index 000000000..885f79b8b
--- /dev/null
+++ b/src/components/policy/test/policy/src/generated_code_with_sqlite_test.cc
@@ -0,0 +1,172 @@
+/* Copyright (c) 2013, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <gtest/gtest.h>
+#include <sqlite3.h>
+#include "include/generated_code_with_sqlite_test.h"
+
+namespace rpc {
+
+class GeneratedCodeTest : public ::testing::Test {
+ public:
+ static void SetUpTestCase() {
+ sqlite3* conn;
+ sqlite3_open((kDatabaseName + ".sqlite").c_str(), &conn);
+ sqlite3_exec(conn, kEndpointsCreation.c_str(),NULL, NULL, NULL);
+ sqlite3_exec(conn, kEndpointsContent.c_str(),NULL, NULL, NULL);
+ sqlite3_exec(conn, kAppPoliciesCreation.c_str(),NULL, NULL, NULL);
+ sqlite3_exec(conn, kGroupsCreation.c_str(),NULL, NULL, NULL);
+ sqlite3_close(conn);
+ }
+
+ static void TearDownTestCase() {
+ remove((kDatabaseName + ".sqlite").c_str());
+ }
+
+ static const std::string kDatabaseName;
+ static const std::string kEndpointsCreation;
+ static const std::string kEndpointsContent;
+ static const std::string kAppPoliciesCreation;
+ static const std::string kGroupsCreation;
+};
+
+const std::string GeneratedCodeTest::kDatabaseName = "test_db";
+
+const std::string GeneratedCodeTest::kEndpointsCreation = "CREATE TABLE Endpoints ("
+ "endpoint_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "service_id VARCHAR(45) NOT NULL,"
+ "application_id VARCHAR(45),"
+ "url VARCHAR(45) NOT NULL,"
+ "is_default INTEGER NOT NULL CHECK(is_default>=0))";
+
+const std::string GeneratedCodeTest::kEndpointsContent = "INSERT INTO Endpoints "
+ "VALUES (1, '0x07', null, 'http://test.example.com', 1)";
+
+const std::string GeneratedCodeTest::kAppPoliciesCreation = "CREATE TABLE AppPolicies ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "application_id VARCHAR(45),"
+ "priority VARCHAR(45),"
+ "is_default INTEGER NOT NULL CHECK(is_default>=0))";
+
+const std::string GeneratedCodeTest::kGroupsCreation = "CREATE TABLE Groups ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "application_id VARCHAR(45) NOT NULL,"
+ "group_name VARCHAR(45) NOT NULL )";
+
+
+TEST_F(GeneratedCodeTest, FindSectionEndpoints) {
+ dbms::SQLDatabase db(GeneratedCodeTest::kDatabaseName);
+ EXPECT_TRUE(db.Open());
+ policy_table::ServiceEndpoints ep;
+ EXPECT_TRUE(policy_table::FindSection(&db, ep));
+ EXPECT_EQ(1, ep.size());
+ std::string url = ep["0x07"]["default"].front();
+ EXPECT_EQ("http://test.example.com", url);
+}
+
+TEST_F(GeneratedCodeTest, RemoveSectionEndpoints) {
+ dbms::SQLDatabase db(GeneratedCodeTest::kDatabaseName);
+ EXPECT_TRUE(db.Open());
+ policy_table::ServiceEndpoints ep;
+ EXPECT_TRUE(policy_table::RemoveSection(&db, ep));
+ dbms::SQLQuery sqlquery(&db);
+ std::string check_query = "select count (*) from endpoints";
+ EXPECT_TRUE(sqlquery.Prepare(check_query));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(0, sqlquery.GetInteger(0));
+}
+
+TEST_F(GeneratedCodeTest, UpdateSectionEndpoints) {
+ dbms::SQLDatabase db(GeneratedCodeTest::kDatabaseName);
+ EXPECT_TRUE(db.Open());
+
+ std::string test_url = "http://url.example.com";
+
+ policy_table::URL urls;
+ urls.push_back(test_url);
+
+ policy_table::URLList urllist;
+ urllist["default"] = urls;
+
+ policy_table::ServiceEndpoints ep;
+ ep["0x07"] = urllist;
+
+ EXPECT_TRUE(policy_table::UpdateSection(&db, ep));
+
+ dbms::SQLQuery sqlquery(&db);
+ std::string num_of_records_check = "select count (*) from endpoints";
+ EXPECT_TRUE(sqlquery.Prepare(num_of_records_check));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(1, sqlquery.GetInteger(0));
+ EXPECT_TRUE(sqlquery.Reset());
+
+ std::string url_check_query = "select * from endpoints";
+ EXPECT_TRUE(sqlquery.Prepare(url_check_query));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(test_url, sqlquery.GetString(3));
+}
+
+TEST_F(GeneratedCodeTest, UpdateSectionAppPolicies) {
+ dbms::SQLDatabase db(GeneratedCodeTest::kDatabaseName);
+ EXPECT_TRUE(db.Open());
+
+ policy_table::ApplicationPolicies ap;
+ const std::string application_id = "12345678";
+ ap[application_id].groups.push_back("Base-4");
+ // This param is present in extended policy table interface only
+ //ap[application_id].priority = policy_table::P_NORMAL;
+
+ EXPECT_TRUE(policy_table::UpdateSection(&db, ap));
+
+ dbms::SQLQuery sqlquery(&db);
+ EXPECT_TRUE(sqlquery.Prepare("select count (*) from AppPolicies"));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(1, sqlquery.GetInteger(0));
+ EXPECT_TRUE(sqlquery.Reset());
+
+ EXPECT_TRUE(sqlquery.Prepare("select count (*) from Groups"));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(1, sqlquery.GetInteger(0));
+ EXPECT_TRUE(sqlquery.Reset());
+
+ EXPECT_TRUE(sqlquery.Prepare("select application_id from Groups where group_name='Base-4'"));
+ EXPECT_TRUE(sqlquery.Exec());
+ // Index for binding starts from 1, index for results starts from 0
+ EXPECT_EQ(application_id, sqlquery.GetString(0));
+ EXPECT_TRUE(sqlquery.Reset());
+
+}
+} // end namespace
diff --git a/src/components/policy/test/policy/src/test_policy_manager_impl.cc b/src/components/policy/test/policy/src/test_policy_manager_impl.cc
new file mode 100644
index 000000000..0301b486e
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_policy_manager_impl.cc
@@ -0,0 +1,437 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <vector>
+#include "mock_policy_listener.h"
+#include "mock_pt_representation.h"
+#include "mock_pt_ext_representation.h"
+#include "policy/policy_manager_impl.h"
+#include "json/value.h"
+
+using ::testing::_;
+using ::testing::Return;
+using ::testing::DoAll;
+using ::testing::SetArgPointee;
+
+using ::policy::PTRepresentation;
+using ::policy::MockPolicyListener;
+using ::policy::MockPTRepresentation;
+using ::policy::MockPTExtRepresentation;
+using ::policy::PolicyManagerImpl;
+using ::policy::PolicyTable;
+using ::policy::EndpointUrls;
+
+namespace test {
+namespace components {
+namespace policy {
+
+class PolicyManagerImplTest : public ::testing::Test {
+ protected:
+ static void SetUpTestCase() {
+ }
+
+ static void TearDownTestCase() {
+ }
+};
+
+TEST_F(PolicyManagerImplTest, ExceededIgnitionCycles) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, IgnitionCyclesBeforeExchange()).Times(2).WillOnce(
+ Return(5)).WillOnce(Return(0));
+ EXPECT_CALL(
+ mock_pt, IncrementIgnitionCycles()).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_FALSE(manager->ExceededIgnitionCycles());
+ manager->IncrementIgnitionCycles();
+ EXPECT_TRUE(manager->ExceededIgnitionCycles());
+}
+
+TEST_F(PolicyManagerImplTest, ExceededDays) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, DaysBeforeExchange(_)).Times(2).WillOnce(Return(5))
+ .WillOnce(Return(0));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_FALSE(manager->ExceededDays(5));
+ EXPECT_TRUE(manager->ExceededDays(15));
+}
+
+TEST_F(PolicyManagerImplTest, ExceededKilometers) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, KilometersBeforeExchange(_)).Times(2).WillOnce(
+ Return(50)).WillOnce(Return(0));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_FALSE(manager->ExceededKilometers(50));
+ EXPECT_TRUE(manager->ExceededKilometers(150));
+}
+
+TEST_F(PolicyManagerImplTest, NextRetryTimeout) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ std::vector<int> seconds;
+ seconds.push_back(50);
+ seconds.push_back(100);
+ seconds.push_back(200);
+
+ EXPECT_CALL(mock_pt, TimeoutResponse()).Times(1).WillOnce(Return(60));
+ EXPECT_CALL(mock_pt,
+ SecondsBetweenRetries(_)).Times(1).WillOnce(
+ DoAll(SetArgPointee<0>(seconds), Return(true)));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_EQ(50, manager->NextRetryTimeout());
+ EXPECT_EQ(100, manager->NextRetryTimeout());
+ EXPECT_EQ(200, manager->NextRetryTimeout());
+ EXPECT_EQ(0, manager->NextRetryTimeout());
+}
+
+TEST_F(PolicyManagerImplTest, GetUpdateUrl) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ EndpointUrls urls_1234, urls_4321;
+ urls_1234.push_back(::policy::EndpointData("http://ford.com/cloud/1"));
+ urls_1234.push_back(::policy::EndpointData("http://ford.com/cloud/2"));
+ urls_1234.push_back(::policy::EndpointData("http://ford.com/cloud/3"));
+ urls_4321.push_back(::policy::EndpointData("http://panasonic.com/cloud/1"));
+ urls_4321.push_back(::policy::EndpointData("http://panasonic.com/cloud/2"));
+ urls_4321.push_back(::policy::EndpointData("http://panasonic.com/cloud/3"));
+
+ EXPECT_CALL(mock_pt, GetUpdateUrls(7)).Times(4).WillRepeatedly(
+ Return(urls_1234));
+ EXPECT_CALL(mock_pt,
+ GetUpdateUrls(4)).Times(2).WillRepeatedly(Return(urls_4321));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_EQ("http://ford.com/cloud/1", manager->GetUpdateUrl(7));
+ EXPECT_EQ("http://ford.com/cloud/2", manager->GetUpdateUrl(7));
+ EXPECT_EQ("http://ford.com/cloud/3", manager->GetUpdateUrl(7));
+ EXPECT_EQ("http://panasonic.com/cloud/1", manager->GetUpdateUrl(4));
+ EXPECT_EQ("http://ford.com/cloud/2", manager->GetUpdateUrl(7));
+ EXPECT_EQ("http://panasonic.com/cloud/3", manager->GetUpdateUrl(4));
+}
+
+TEST_F(PolicyManagerImplTest, RefreshRetrySequence) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ std::vector<int> seconds, seconds_empty;
+ seconds.push_back(50);
+ seconds.push_back(100);
+ seconds.push_back(200);
+
+ EXPECT_CALL(mock_pt, TimeoutResponse()).Times(2).WillOnce(Return(0)).WillOnce(
+ Return(60));
+ EXPECT_CALL(mock_pt, SecondsBetweenRetries(_)).Times(2).WillOnce(
+ DoAll(SetArgPointee<0>(seconds_empty), Return(true))).WillOnce(
+ DoAll(SetArgPointee<0>(seconds), Return(true)));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->RefreshRetrySequence();
+ EXPECT_EQ(60, manager->TimeoutExchange());
+ EXPECT_EQ(50, manager->NextRetryTimeout());
+ EXPECT_EQ(100, manager->NextRetryTimeout());
+ EXPECT_EQ(200, manager->NextRetryTimeout());
+}
+
+#ifdef EXTENDED_POLICY
+TEST_F(PolicyManagerImplTest, IncrementGlobalCounter) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, Increment("count_of_sync_reboots")).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->Increment(usage_statistics::SYNC_REBOOTS);
+}
+
+TEST_F(PolicyManagerImplTest, IncrementAppCounter) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, Increment("12345", "count_of_user_selections")).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->Increment("12345", usage_statistics::USER_SELECTIONS);
+}
+
+TEST_F(PolicyManagerImplTest, SetAppInfo) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, Set("12345", "app_registration_language_gui", "de-de")).
+ Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->Set("12345", usage_statistics::LANGUAGE_GUI, "de-de");
+}
+
+TEST_F(PolicyManagerImplTest, AddAppStopwatch) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, Add("12345", "minutes_hmi_full", 30)).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->Add("12345", usage_statistics::SECONDS_HMI_FULL, 30);
+}
+#endif // EXTENDED_POLICY
+
+TEST_F(PolicyManagerImplTest, LoadPTFromFile) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, Init()).WillOnce(Return(::policy::NONE))
+ //.WillOnce(Return(::policy::EXISTS));
+ //.WillOnce(Return(::policy::SUCCESS))
+ .WillOnce(Return(::policy::FAIL));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_FALSE(manager->LoadPTFromFile("filename"));
+ // TODO(AOleynik): Sometimes fails, check this
+ // EXPECT_TRUE(manager->LoadPTFromFile("filename"));
+ // EXPECT_TRUE(manager->LoadPTFromFile("filename"));
+ EXPECT_FALSE(manager->LoadPTFromFile("filename"));
+}
+
+TEST_F(PolicyManagerImplTest, CheckPermissions) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ MockPolicyListener mock_listener;
+
+ ::policy::CheckPermissionResult result;
+ result.hmi_level_permitted = ::policy::kRpcAllowed;
+ result.list_of_allowed_params = new std::vector< ::policy::PTString>();
+ result.list_of_allowed_params->push_back("speed");
+ result.list_of_allowed_params->push_back("gps");
+
+#ifdef EXTENDED_POLICY
+ EXPECT_CALL(mock_pt, CheckPermissions("pre_DataConsent", "FULL", "Alert")).WillOnce(
+ Return(result));
+#else // EXTENDED_POLICY
+ EXPECT_CALL(mock_pt, CheckPermissions("12345678", "FULL", "Alert")).WillOnce(
+ Return(result));
+#endif // EXTENDED_POLICY
+ EXPECT_CALL(mock_listener, OnCurrentDeviceIdUpdateRequired("12345678")).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->set_listener(&mock_listener);
+ ::policy::CheckPermissionResult out_result = manager->CheckPermissions(
+ "12345678", "FULL", "Alert");
+ EXPECT_EQ(::policy::kRpcAllowed, out_result.hmi_level_permitted);
+ ASSERT_TRUE(out_result.list_of_allowed_params);
+ ASSERT_EQ(2, out_result.list_of_allowed_params->size());
+ EXPECT_EQ("speed", (*out_result.list_of_allowed_params)[0]);
+ EXPECT_EQ("gps", (*out_result.list_of_allowed_params)[1]);
+}
+
+TEST_F(PolicyManagerImplTest, DISABLED_LoadPT) {
+ // TODO(KKolodiy): PolicyManagerImpl is hard for testing
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ MockPolicyListener mock_listener;
+
+ Json::Value table(Json::objectValue);
+ table["policy_table"] = Json::Value(Json::objectValue);
+
+ Json::Value& policy_table = table["policy_table"];
+ policy_table["module_meta"] = Json::Value(Json::objectValue);
+ policy_table["module_config"] = Json::Value(Json::objectValue);
+ policy_table["usage_and_error_counts"] = Json::Value(Json::objectValue);
+ policy_table["device_data"] = Json::Value(Json::objectValue);
+ policy_table["functional_groupings"] = Json::Value(Json::objectValue);
+ policy_table["consumer_friendly_messages"] = Json::Value(Json::objectValue);
+ policy_table["app_policies"] = Json::Value(Json::objectValue);
+ policy_table["app_policies"]["1234"] = Json::Value(Json::objectValue);
+
+ Json::Value& module_meta = policy_table["module_meta"];
+ module_meta["ccpu_version"] = Json::Value("ccpu version");
+ module_meta["language"] = Json::Value("ru");
+ module_meta["wers_country_code"] = Json::Value("ru");
+ module_meta["pt_exchanged_at_odometer_x"] = Json::Value(0);
+ module_meta["pt_exchanged_x_days_after_epoch"] = Json::Value(0);
+ module_meta["ignition_cycles_since_last_exchange"] = Json::Value(0);
+ module_meta["vin"] = Json::Value("vin");
+
+ Json::Value& module_config = policy_table["module_config"];
+ module_config["preloaded_pt"] = Json::Value(true);
+ module_config["exchange_after_x_ignition_cycles"] = Json::Value(10);
+ module_config["exchange_after_x_kilometers"] = Json::Value(100);
+ module_config["exchange_after_x_days"] = Json::Value(5);
+ module_config["timeout_after_x_seconds"] = Json::Value(500);
+ module_config["seconds_between_retries"] = Json::Value(Json::arrayValue);
+ module_config["seconds_between_retries"][0] = Json::Value(10);
+ module_config["seconds_between_retries"][1] = Json::Value(20);
+ module_config["seconds_between_retries"][2] = Json::Value(30);
+ module_config["endpoints"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"]["default"] = Json::Value(Json::arrayValue);
+ module_config["endpoints"]["0x00"]["default"][0] = Json::Value(
+ "http://ford.com/cloud/default");
+ module_config["notifications_per_minute_by_priority"] = Json::Value(
+ Json::objectValue);
+ module_config["notifications_per_minute_by_priority"]["emergency"] =
+ Json::Value(1);
+ module_config["notifications_per_minute_by_priority"]["navigation"] =
+ Json::Value(2);
+ module_config["notifications_per_minute_by_priority"]["voiceCommunication"] =
+ Json::Value(3);
+ module_config["notifications_per_minute_by_priority"]["communication"] =
+ Json::Value(4);
+ module_config["notifications_per_minute_by_priority"]["normal"] = Json::Value(
+ 5);
+ module_config["notifications_per_minute_by_priority"]["none"] = Json::Value(
+ 6);
+ module_config["vehicle_make"] = Json::Value("MakeT");
+ module_config["vehicle_model"] = Json::Value("ModelT");
+ module_config["vehicle_year"] = Json::Value(2014);
+
+ Json::Value& usage_and_error_counts = policy_table["usage_and_error_counts"];
+ usage_and_error_counts["count_of_iap_buffer_full"] = Json::Value(0);
+ usage_and_error_counts["count_sync_out_of_memory"] = Json::Value(0);
+ usage_and_error_counts["count_of_sync_reboots"] = Json::Value(0);
+
+ Json::Value& device_data = policy_table["device_data"];
+ device_data["DEVICEHASH"] = Json::Value(Json::objectValue);
+ device_data["DEVICEHASH"]["hardware"] = Json::Value("hardware");
+ device_data["DEVICEHASH"]["firmware_rev"] = Json::Value("firmware_rev");
+ device_data["DEVICEHASH"]["os"] = Json::Value("os");
+ device_data["DEVICEHASH"]["os_version"] = Json::Value("os_version");
+ device_data["DEVICEHASH"]["carrier"] = Json::Value("carrier");
+ device_data["DEVICEHASH"]["max_number_rfcom_ports"] = Json::Value(10);
+
+ Json::Value& functional_groupings = policy_table["functional_groupings"];
+ functional_groupings["default"] = Json::Value(Json::objectValue);
+ Json::Value& default_group = functional_groupings["default"];
+ default_group["rpcs"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"]["hmi_levels"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["hmi_levels"][0] = Json::Value("FULL");
+ default_group["rpcs"]["Update"]["parameters"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["parameters"][0] = Json::Value("speed");
+
+ Json::Value& consumer_friendly_messages =
+ policy_table["consumer_friendly_messages"];
+ consumer_friendly_messages["version"] = Json::Value("1.2");
+
+ Json::Value& app_policies = policy_table["app_policies"];
+ app_policies["default"] = Json::Value(Json::objectValue);
+ app_policies["default"]["memory_kb"] = Json::Value(50);
+ app_policies["default"]["watchdog_timer_ms"] = Json::Value(100);
+ app_policies["default"]["groups"] = Json::Value(Json::arrayValue);
+ app_policies["default"]["groups"][0] = Json::Value("default");
+ app_policies["default"]["priority"] = Json::Value("EMERGENCY");
+ app_policies["default"]["default_hmi"] = Json::Value("FULL");
+ app_policies["default"]["keep_context"] = Json::Value(true);
+ app_policies["default"]["steal_focus"] = Json::Value(true);
+ app_policies["default"]["certificate"] = Json::Value("sign");
+
+ std::string json = table.toStyledString();
+ ::policy::BinaryMessage msg(json.begin(), json.end());
+
+ EXPECT_CALL(mock_pt, Save(_)).Times(1).WillOnce(Return(true));
+ EXPECT_CALL(mock_listener, OnUpdateStatusChanged(_)).Times(1);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->set_listener(&mock_listener);
+
+ EXPECT_TRUE(manager->LoadPT("file_pt_update.json", msg));
+}
+
+TEST_F(PolicyManagerImplTest, RequestPTUpdate) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+ MockPolicyListener mock_listener;
+
+ ::utils::SharedPtr< ::policy_table::Table> p_table =
+ new ::policy_table::Table();
+ std::string json = p_table->ToJsonValue().toStyledString();
+ ::policy::BinaryMessageSptr expect = new ::policy::BinaryMessage(json.begin(),
+ json.end());
+
+ EXPECT_CALL(mock_pt, GenerateSnapshot()).WillOnce(Return(p_table));
+ EXPECT_CALL(mock_listener, OnUpdateStatusChanged(_)).Times(2);
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ manager->set_listener(&mock_listener);
+ ::policy::BinaryMessageSptr output = manager->RequestPTUpdate();
+ EXPECT_EQ(*expect, *output);
+}
+
+#ifdef EXTENDED_POLICY
+TEST_F(PolicyManagerImplTest, ResetUserConsent) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ EXPECT_CALL(mock_pt, ResetUserConsent()).WillOnce(Return(true)).WillOnce(
+ Return(false));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ EXPECT_TRUE(manager->ResetUserConsent());
+ EXPECT_FALSE(manager->ResetUserConsent());
+}
+#endif // EXTENDED_POLICY
+
+TEST_F(PolicyManagerImplTest, CheckAppPolicyState) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ // TODO(AOleynik): Implementation of method should be changed to avoid
+ // using of snapshot
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ //manager->CheckAppPolicyState("12345678");
+}
+
+TEST_F(PolicyManagerImplTest, GetPolicyTableStatus) {
+ ::testing::NiceMock<MockPTExtRepresentation> mock_pt;
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ // TODO(AOleynik): Test is not finished, to be continued
+ //manager->GetPolicyTableStatus();
+}
+
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/src/test_shared_library.cc b/src/components/policy/test/policy/src/test_shared_library.cc
new file mode 100644
index 000000000..9ec2ea479
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_shared_library.cc
@@ -0,0 +1,71 @@
+/* Copyright (c) 2013, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <gtest/gtest.h>
+#include <dlfcn.h>
+
+namespace test {
+namespace components {
+namespace policy {
+
+::testing::AssertionResult IsError(void* error) {
+ if (error) {
+ return ::testing::AssertionSuccess() << static_cast<const char*>(error);
+ } else {
+ return ::testing::AssertionFailure() << error;
+ }
+}
+
+TEST(SharedLibraryTest, Full) {
+ const std::string kLib = "../../src/components/policy/src/policy/libPolicy.so";
+ void* handle = dlopen(kLib.c_str(), RTLD_LAZY);
+ EXPECT_FALSE(IsError(dlerror()));
+ ASSERT_TRUE(handle);
+
+ const std::string kSymbol = "CreateManager";
+ void* symbol = dlsym(handle, kSymbol.c_str());
+ EXPECT_FALSE(IsError(dlerror()));
+ EXPECT_TRUE(symbol);
+
+ int ret = dlclose(handle);
+ EXPECT_FALSE(ret);
+ EXPECT_FALSE(IsError(dlerror()));
+}
+
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/src/components/policy/test/policy/src/test_sql_pt_ext_representation.cc b/src/components/policy/test/policy/src/test_sql_pt_ext_representation.cc
new file mode 100644
index 000000000..ae19b0b15
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_sql_pt_ext_representation.cc
@@ -0,0 +1,299 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <sqlite3.h>
+#include <vector>
+#include "json/value.h"
+#include "policy/sql_pt_ext_representation.h"
+#include "policy/policy_types.h"
+#include "policy_table_interface_base/types.h"
+#include "policy_table_interface_base/enums.h"
+
+using policy::SQLPTExtRepresentation;
+
+namespace test {
+namespace components {
+namespace policy {
+
+class SQLPTExtRepresentationTest : public ::testing::Test {
+ protected:
+ static sqlite3* conn;
+ static SQLPTExtRepresentation* reps;
+ static const std::string kFileName;
+
+ static void SetUpTestCase() {
+ reps = new SQLPTExtRepresentation;
+ EXPECT_EQ(::policy::SUCCESS, reps->Init());
+ EXPECT_EQ(SQLITE_OK, sqlite3_open(kFileName.c_str(), &conn));
+ }
+
+ static void TearDownTestCase() {
+ EXPECT_TRUE(reps->Clear());
+ EXPECT_TRUE(reps->Close());
+ delete reps;
+ sqlite3_close(conn);
+ remove(kFileName.c_str());
+ }
+};
+
+sqlite3* SQLPTExtRepresentationTest::conn = 0;
+SQLPTExtRepresentation* SQLPTExtRepresentationTest::reps = 0;
+const std::string SQLPTExtRepresentationTest::kFileName = "policy.sqlite";
+
+::testing::AssertionResult IsValid(const policy_table::Table &table) {
+ if (table.is_valid()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ ::rpc::ValidationReport report(" - table");
+ table.ReportErrors(&report);
+ return ::testing::AssertionFailure() << ::rpc::PrettyFormat(report);
+ }
+}
+
+TEST_F(SQLPTExtRepresentationTest, SaveGenerateSnapshot) {
+ Json::Value expect(Json::objectValue);
+ expect["policy_table"] = Json::Value(Json::objectValue);
+
+ Json::Value& policy_table = expect["policy_table"];
+ policy_table["module_meta"] = Json::Value(Json::objectValue);
+ policy_table["module_config"] = Json::Value(Json::objectValue);
+ policy_table["usage_and_error_counts"] = Json::Value(Json::objectValue);
+ policy_table["device_data"] = Json::Value(Json::objectValue);
+ policy_table["functional_groupings"] = Json::Value(Json::objectValue);
+ policy_table["consumer_friendly_messages"] = Json::Value(Json::objectValue);
+ policy_table["app_policies"] = Json::Value(Json::objectValue);
+
+ Json::Value& module_meta = policy_table["module_meta"];
+ module_meta["ccpu_version"] = Json::Value("ccpu version");
+ module_meta["language"] = Json::Value("ru");
+ module_meta["wers_country_code"] = Json::Value("ru");
+ module_meta["pt_exchanged_at_odometer_x"] = Json::Value(0);
+ module_meta["pt_exchanged_x_days_after_epoch"] = Json::Value(0);
+ module_meta["ignition_cycles_since_last_exchange"] = Json::Value(0);
+ module_meta["vin"] = Json::Value("vin");
+
+ Json::Value& module_config = policy_table["module_config"];
+ module_config["preloaded_pt"] = Json::Value(true);
+ module_config["exchange_after_x_ignition_cycles"] = Json::Value(10);
+ module_config["exchange_after_x_kilometers"] = Json::Value(100);
+ module_config["exchange_after_x_days"] = Json::Value(5);
+ module_config["timeout_after_x_seconds"] = Json::Value(500);
+ module_config["seconds_between_retries"] = Json::Value(Json::arrayValue);
+ module_config["seconds_between_retries"][0] = Json::Value(10);
+ module_config["seconds_between_retries"][1] = Json::Value(20);
+ module_config["seconds_between_retries"][2] = Json::Value(30);
+ module_config["endpoints"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"]["default"] = Json::Value(Json::arrayValue);
+ module_config["endpoints"]["0x00"]["default"][0] = Json::Value(
+ "http://ford.com/cloud/default");
+ module_config["notifications_per_minute_by_priority"] = Json::Value(
+ Json::objectValue);
+ module_config["notifications_per_minute_by_priority"]["emergency"] =
+ Json::Value(1);
+ module_config["notifications_per_minute_by_priority"]["navigation"] =
+ Json::Value(2);
+ module_config["notifications_per_minute_by_priority"]["voiceCommunication"] =
+ Json::Value(3);
+ module_config["notifications_per_minute_by_priority"]["communication"] =
+ Json::Value(4);
+ module_config["notifications_per_minute_by_priority"]["normal"] = Json::Value(
+ 5);
+ module_config["notifications_per_minute_by_priority"]["none"] = Json::Value(
+ 6);
+ module_config["vehicle_make"] = Json::Value("MakeT");
+ module_config["vehicle_model"] = Json::Value("ModelT");
+ module_config["vehicle_year"] = Json::Value(2014);
+
+ Json::Value& usage_and_error_counts = policy_table["usage_and_error_counts"];
+ usage_and_error_counts["count_of_iap_buffer_full"] = Json::Value(0);
+ usage_and_error_counts["count_sync_out_of_memory"] = Json::Value(0);
+ usage_and_error_counts["count_of_sync_reboots"] = Json::Value(0);
+
+ Json::Value& device_data = policy_table["device_data"];
+ device_data["DEVICEHASH"] = Json::Value(Json::objectValue);
+ device_data["DEVICEHASH"]["hardware"] = Json::Value("hardware");
+ device_data["DEVICEHASH"]["firmware_rev"] = Json::Value("firmware_rev");
+ device_data["DEVICEHASH"]["os"] = Json::Value("os");
+ device_data["DEVICEHASH"]["os_version"] = Json::Value("os_version");
+ device_data["DEVICEHASH"]["carrier"] = Json::Value("carrier");
+ device_data["DEVICEHASH"]["max_number_rfcom_ports"] = Json::Value(10);
+
+ Json::Value& functional_groupings = policy_table["functional_groupings"];
+ functional_groupings["default"] = Json::Value(Json::objectValue);
+ Json::Value& default_group = functional_groupings["default"];
+ default_group["rpcs"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"]["hmi_levels"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["hmi_levels"][0] = Json::Value("FULL");
+ default_group["rpcs"]["Update"]["parameters"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["parameters"][0] = Json::Value("speed");
+
+ Json::Value& consumer_friendly_messages =
+ policy_table["consumer_friendly_messages"];
+ consumer_friendly_messages["version"] = Json::Value("1.2");
+
+ Json::Value& app_policies = policy_table["app_policies"];
+ app_policies["default"] = Json::Value(Json::objectValue);
+ app_policies["default"]["memory_kb"] = Json::Value(50);
+ app_policies["default"]["watchdog_timer_ms"] = Json::Value(100);
+ app_policies["default"]["groups"] = Json::Value(Json::arrayValue);
+ app_policies["default"]["groups"][0] = Json::Value("default");
+ app_policies["default"]["priority"] = Json::Value("EMERGENCY");
+ app_policies["default"]["default_hmi"] = Json::Value("FULL");
+ app_policies["default"]["keep_context"] = Json::Value(true);
+ app_policies["default"]["steal_focus"] = Json::Value(true);
+ app_policies["default"]["certificate"] = Json::Value("sign");
+
+ policy_table::Table table(&expect);
+
+ ASSERT_TRUE(IsValid(table));
+ ASSERT_TRUE(reps->Save(table));
+ ASSERT_TRUE(reps->SetMetaInfo("ccpu version", "ru", "ru"));
+ const char* query_vin = "UPDATE `module_meta` SET `vin` = 'vin'; ";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_vin, NULL, NULL, NULL));
+ utils::SharedPtr<policy_table::Table> snapshot = reps->GenerateSnapshot();
+ EXPECT_TRUE(IsValid(*snapshot));
+ EXPECT_EQ(table.ToJsonValue().toStyledString(),
+ snapshot->ToJsonValue().toStyledString());
+}
+
+TEST_F(SQLPTExtRepresentationTest, CanAppKeepContext) {
+ const char* query_delete = "DELETE FROM `application`; ";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+ const char* query_insert = "INSERT INTO `application` (`id`, `memory_kb`,"
+ " `watchdog_timer_ms`, `keep_context`) VALUES ('12345', 5, 10, 1)";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_insert, NULL, NULL, NULL));
+ EXPECT_FALSE(reps->CanAppKeepContext("0"));
+ EXPECT_TRUE(reps->CanAppKeepContext("12345"));
+}
+
+TEST_F(SQLPTExtRepresentationTest, CanAppStealFocus) {
+ const char* query_delete = "DELETE FROM `application`; ";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+ const char* query_insert = "INSERT INTO `application` (`id`, `memory_kb`,"
+ " `watchdog_timer_ms`, `steal_focus`) VALUES ('12345', 5, 10, 1)";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_insert, NULL, NULL, NULL));
+ EXPECT_TRUE(reps->CanAppStealFocus("12345"));
+ EXPECT_FALSE(reps->CanAppStealFocus("0"));
+}
+
+TEST_F(SQLPTExtRepresentationTest, IncrementGlobalCounter) {
+ const char* query_update = "UPDATE `usage_and_error_count` SET"
+ " `count_of_sync_reboots` = 0";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_update, NULL, NULL, NULL));
+
+ reps->Increment("count_of_sync_reboots");
+ reps->Increment("count_of_sync_reboots");
+ reps->Increment("count_of_sync_reboots");
+
+ const char* query_select =
+ "SELECT `count_of_sync_reboots` FROM `usage_and_error_count`";
+ sqlite3_stmt* statement;
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_prepare(conn, query_select, -1, &statement, NULL));
+ ASSERT_EQ(SQLITE_ROW, sqlite3_step(statement));
+ EXPECT_EQ(3, sqlite3_column_int(statement, 0));
+ EXPECT_EQ(SQLITE_DONE, sqlite3_step(statement));
+}
+
+TEST_F(SQLPTExtRepresentationTest, IncrementAppCounter) {
+ const char* query_delete =
+ "DELETE FROM `app_level` WHERE `application_id` = '12345'";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+
+ reps->Increment("12345", "count_of_user_selections");
+ reps->Increment("12345", "count_of_user_selections");
+ reps->Increment("12345", "count_of_user_selections");
+
+ const char* query_select =
+ "SELECT `count_of_user_selections` FROM `app_level`"
+ " WHERE `application_id` = '12345'";
+ sqlite3_stmt* statement;
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_prepare(conn, query_select, -1, &statement, NULL));
+ ASSERT_EQ(SQLITE_ROW, sqlite3_step(statement));
+ EXPECT_EQ(3, sqlite3_column_int(statement, 0));
+ EXPECT_EQ(SQLITE_DONE, sqlite3_step(statement));
+}
+
+TEST_F(SQLPTExtRepresentationTest, SetAppInfo) {
+ const char* query_delete =
+ "DELETE FROM `app_level` WHERE `application_id` = '12345'";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+
+ reps->Set("12345", "app_registration_language_gui", "ru-ru");
+ reps->Set("12345", "app_registration_language_vui", "en-en");
+
+ const char* query_select = "SELECT `app_registration_language_gui`, "
+ " `app_registration_language_vui` FROM `app_level`"
+ " WHERE `application_id` = '12345'";
+ sqlite3_stmt* statement;
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_prepare(conn, query_select, -1, &statement, NULL));
+ ASSERT_EQ(SQLITE_ROW, sqlite3_step(statement));
+
+ const unsigned char* gui = sqlite3_column_text(statement, 0);
+ const unsigned char* vui = sqlite3_column_text(statement, 1);
+ ASSERT_TRUE(gui);
+ ASSERT_TRUE(vui);
+ EXPECT_EQ("ru-ru", std::string(reinterpret_cast<const char*>(gui)));
+ EXPECT_EQ("en-en", std::string(reinterpret_cast<const char*>(vui)));
+ EXPECT_EQ(SQLITE_DONE, sqlite3_step(statement));
+}
+
+TEST_F(SQLPTExtRepresentationTest, AddAppStopwatch) {
+ const char* query_delete =
+ "DELETE FROM `app_level` WHERE `application_id` = '12345'";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+
+ reps->Add("12345", "minutes_in_hmi_full", 10);
+ reps->Add("12345", "minutes_in_hmi_full", 60);
+
+ const char* query_select = "SELECT `minutes_in_hmi_full` FROM `app_level`"
+ " WHERE `application_id` = '12345'";
+ sqlite3_stmt* statement;
+ ASSERT_EQ(SQLITE_OK,
+ sqlite3_prepare(conn, query_select, -1, &statement, NULL));
+ ASSERT_EQ(SQLITE_ROW, sqlite3_step(statement));
+ EXPECT_EQ(70, sqlite3_column_int(statement, 0));
+ EXPECT_EQ(SQLITE_DONE, sqlite3_step(statement));
+}
+
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/src/test_sql_pt_representation.cc b/src/components/policy/test/policy/src/test_sql_pt_representation.cc
new file mode 100644
index 000000000..caa72bea4
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_sql_pt_representation.cc
@@ -0,0 +1,448 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#ifdef __QNX__
+# include <qdb/qdb.h>
+#else // __QNX__
+# include <sqlite3.h>
+#endif // __QNX__
+#include <vector>
+#include "json/value.h"
+#include "policy/sql_pt_representation.h"
+#include "policy/policy_types.h"
+#include "policy_table_interface_base/types.h"
+#include "policy_table_interface_base/enums.h"
+
+using policy::SQLPTRepresentation;
+using policy::CheckPermissionResult;
+using policy::EndpointUrls;
+
+namespace test {
+namespace components {
+namespace policy {
+
+#ifdef __QNX__
+class DBMS {
+ public:
+ bool Open() {
+ conn_ = qdb_connect(kDatabaseName_.c_str(), 0);
+ return conn_ != NULL;
+ }
+ void Close() {
+ qdb_disconnect(conn_);
+ }
+ bool Exec(const char* query) {
+ return -1 != qdb_statement(conn_, query);
+ }
+ private:
+ static qdb_hdl_t* conn_;
+ static const std::string kDatabaseName_;
+};
+qdb_hdl_t* DBMS::conn_ = 0;
+const std::string DBMS::kDatabaseName_ = "policy";
+#else // __QNX__
+class DBMS {
+ public:
+ bool Open() {
+ return SQLITE_OK == sqlite3_open(kFileName_.c_str(), &conn_);
+ }
+ void Close() {
+ sqlite3_close(conn_);
+ remove(kFileName_.c_str());
+ }
+ bool Exec(const char* query) {
+ return SQLITE_OK == sqlite3_exec(conn_, query, NULL, NULL, NULL);
+ }
+ private:
+ static sqlite3* conn_;
+ static const std::string kFileName_;
+};
+sqlite3* DBMS::conn_ = 0;
+const std::string DBMS::kFileName_ = "policy.sqlite";
+#endif // __QNX__
+
+class SQLPTRepresentationTest : public ::testing::Test {
+ protected:
+ static DBMS* dbms;
+ static SQLPTRepresentation* reps;
+
+ static void SetUpTestCase() {
+ reps = new SQLPTRepresentation;
+ dbms = new DBMS;
+ EXPECT_EQ(::policy::SUCCESS, reps->Init());
+ EXPECT_TRUE(dbms->Open());
+ }
+
+ static void TearDownTestCase() {
+ EXPECT_TRUE(reps->Clear());
+ EXPECT_TRUE(reps->Close());
+ delete reps;
+ dbms->Close();
+ }
+};
+
+DBMS* SQLPTRepresentationTest::dbms = 0;
+SQLPTRepresentation* SQLPTRepresentationTest::reps = 0;
+
+::testing::AssertionResult IsValid(const policy_table::Table &table) {
+ if (table.is_valid()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ ::rpc::ValidationReport report(" - table");
+ table.ReportErrors(&report);
+ return ::testing::AssertionFailure() << ::rpc::PrettyFormat(report);
+ }
+}
+
+TEST_F(SQLPTRepresentationTest, CheckPermissionsAllowed) {
+ const char* query = "INSERT OR REPLACE INTO `application` (`id`, `memory_kb`,"
+ " `watchdog_timer_ms`) VALUES ('12345', 5, 10); "
+ "INSERT OR REPLACE INTO functional_group (`id`, `name`)"
+ " VALUES (1, 'Base-4'); "
+ "INSERT OR REPLACE INTO `app_group` (`application_id`,"
+ " `functional_group_id`) VALUES ('12345', 1); "
+ "INSERT OR REPLACE INTO `rpc` (`name`, `parameter`, `hmi_level_value`,"
+ " `functional_group_id`) VALUES ('Update', 'gps', 'FULL', 1); "
+ "INSERT OR REPLACE INTO `rpc` (`name`, `parameter`, `hmi_level_value`,"
+ " `functional_group_id`) VALUES ('Update', 'speed', 'FULL', 1);";
+ ASSERT_TRUE(dbms->Exec(query));
+
+ CheckPermissionResult ret;
+ ret = reps->CheckPermissions("12345", "FULL", "Update");
+ EXPECT_TRUE(ret.hmi_level_permitted == ::policy::kRpcAllowed);
+ ASSERT_EQ(2, ret.list_of_allowed_params->size());
+ EXPECT_EQ("gps", (*ret.list_of_allowed_params)[0]);
+ EXPECT_EQ("speed", (*ret.list_of_allowed_params)[1]);
+}
+
+TEST_F(SQLPTRepresentationTest, CheckPermissionsAllowedWithoutParameters) {
+ const char* query = "INSERT OR REPLACE INTO `application` (`id`, `memory_kb`,"
+ " `watchdog_timer_ms`) VALUES ('12345', 5, 10); "
+ "INSERT OR REPLACE INTO functional_group (`id`, `name`)"
+ " VALUES (1, 'Base-4'); "
+ "INSERT OR REPLACE INTO `app_group` (`application_id`,"
+ " `functional_group_id`) VALUES ('12345', 1); "
+ "DELETE FROM `rpc`; "
+ "INSERT OR REPLACE INTO `rpc` (`name`, `hmi_level_value`,"
+ " `functional_group_id`) VALUES ('Update', 'LIMITED', 1);";
+ ASSERT_TRUE(dbms->Exec(query));
+
+ CheckPermissionResult ret;
+ ret = reps->CheckPermissions("12345", "LIMITED", "Update");
+ EXPECT_TRUE(ret.hmi_level_permitted == ::policy::kRpcAllowed);
+ EXPECT_TRUE(!ret.list_of_allowed_params);
+}
+
+TEST_F(SQLPTRepresentationTest, CheckPermissionsDisallowed) {
+ const char* query = "DELETE FROM `app_group`";
+ ASSERT_TRUE(dbms->Exec(query));
+
+ CheckPermissionResult ret;
+ ret = reps->CheckPermissions("12345", "FULL", "Update");
+ EXPECT_EQ(::policy::kRpcDisallowed, ret.hmi_level_permitted);
+ EXPECT_TRUE(!ret.list_of_allowed_params);
+}
+
+TEST_F(SQLPTRepresentationTest, IsPTPReloaded) {
+ const char* query = "UPDATE `module_config` SET `preloaded_pt` = 1";
+ ASSERT_TRUE(dbms->Exec(query));
+ EXPECT_TRUE(reps->IsPTPreloaded());
+}
+
+TEST_F(SQLPTRepresentationTest, GetUpdateUrls) {
+ const char* query_delete = "DELETE FROM `endpoint`; ";
+ ASSERT_TRUE(dbms->Exec(query_delete));
+ EndpointUrls ret = reps->GetUpdateUrls(7);
+ EXPECT_TRUE(ret.empty());
+
+ const char* query_insert =
+ "INSERT INTO `endpoint` (`application_id`, `url`, `service`) "
+ " VALUES ('12345', 'http://ford.com/cloud/1', '0x07');"
+ "INSERT INTO `endpoint` (`application_id`, `url`, `service`) "
+ " VALUES ('12345', 'http://ford.com/cloud/2', '0x07');";
+
+ ASSERT_TRUE(dbms->Exec(query_insert));
+ ret = reps->GetUpdateUrls(7);
+ ASSERT_EQ(2, ret.size());
+ EXPECT_EQ("http://ford.com/cloud/1", ret[0].url);
+ EXPECT_EQ("http://ford.com/cloud/2", ret[1].url);
+
+ ret = reps->GetUpdateUrls(0);
+ EXPECT_TRUE(ret.empty());
+}
+
+TEST_F(SQLPTRepresentationTest, IgnitionCyclesBeforeExchangeAndIncrement) {
+ const char* query_zeros = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = 0; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 0";
+ ASSERT_TRUE(dbms->Exec(query_zeros));
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+ reps->IncrementIgnitionCycles();
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+
+ const char* query_less_limit = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = 5; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
+ ASSERT_TRUE(dbms->Exec(query_less_limit));
+ EXPECT_EQ(5, reps->IgnitionCyclesBeforeExchange());
+ reps->IncrementIgnitionCycles();
+ EXPECT_EQ(4, reps->IgnitionCyclesBeforeExchange());
+
+ const char* query_limit = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = 9; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
+ ASSERT_TRUE(dbms->Exec(query_limit));
+ EXPECT_EQ(1, reps->IgnitionCyclesBeforeExchange());
+ reps->IncrementIgnitionCycles();
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+
+ const char* query_more_limit = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = 12; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
+ ASSERT_TRUE(dbms->Exec(query_more_limit));
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+
+ const char* query_negative_limit = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = 3; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = -1";
+ ASSERT_TRUE(dbms->Exec(query_negative_limit));
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+
+ const char* query_negative_current = "UPDATE `module_meta` SET "
+ " `ignition_cycles_since_last_exchange` = -1; "
+ " UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 2";
+ ASSERT_TRUE(dbms->Exec(query_negative_current));
+ EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
+}
+
+TEST_F(SQLPTRepresentationTest, KilometersBeforeExchange) {
+ const char* query_zeros = "UPDATE `module_meta` SET "
+ " `pt_exchanged_at_odometer_x` = 0; "
+ " UPDATE `module_config` SET `exchange_after_x_kilometers` = 0";
+ ASSERT_TRUE(dbms->Exec(query_zeros));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(-10));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
+
+ const char* query_negative_limit = "UPDATE `module_meta` SET "
+ " `pt_exchanged_at_odometer_x` = 10; "
+ " UPDATE `module_config` SET `exchange_after_x_kilometers` = -10";
+ ASSERT_TRUE(dbms->Exec(query_negative_limit));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
+
+ const char* query_negative_last = "UPDATE `module_meta` SET "
+ " `pt_exchanged_at_odometer_x` = -10; "
+ " UPDATE `module_config` SET `exchange_after_x_kilometers` = 20";
+ ASSERT_TRUE(dbms->Exec(query_negative_last));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
+
+ const char* query_limit = "UPDATE `module_meta` SET "
+ " `pt_exchanged_at_odometer_x` = 10; "
+ " UPDATE `module_config` SET `exchange_after_x_kilometers` = 100";
+ ASSERT_TRUE(dbms->Exec(query_limit));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(120));
+ EXPECT_EQ(60, reps->KilometersBeforeExchange(50));
+ EXPECT_EQ(0, reps->KilometersBeforeExchange(5));
+}
+
+TEST_F(SQLPTRepresentationTest, DaysBeforeExchange) {
+ const char* query_zeros = "UPDATE `module_meta` SET "
+ " `pt_exchanged_x_days_after_epoch` = 0; "
+ " UPDATE `module_config` SET `exchange_after_x_days` = 0";
+ ASSERT_TRUE(dbms->Exec(query_zeros));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(0));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(-10));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(10));
+
+ const char* query_negative_limit = "UPDATE `module_meta` SET "
+ " `pt_exchanged_x_days_after_epoch` = 10; "
+ " UPDATE `module_config` SET `exchange_after_x_days` = -10";
+ ASSERT_TRUE(dbms->Exec(query_negative_limit));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(0));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(10));
+
+ const char* query_negative_last = "UPDATE `module_meta` SET "
+ " `pt_exchanged_x_days_after_epoch` = -10; "
+ " UPDATE `module_config` SET `exchange_after_x_days` = 20";
+ ASSERT_TRUE(dbms->Exec(query_negative_last));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(0));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(10));
+
+ const char* query_limit = "UPDATE `module_meta` SET "
+ " `pt_exchanged_x_days_after_epoch` = 10; "
+ " UPDATE `module_config` SET `exchange_after_x_days` = 100";
+ ASSERT_TRUE(dbms->Exec(query_limit));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(120));
+ EXPECT_EQ(60, reps->DaysBeforeExchange(50));
+ EXPECT_EQ(0, reps->DaysBeforeExchange(5));
+}
+
+TEST_F(SQLPTRepresentationTest, SecondsBetweenRetries) {
+ std::vector<int> seconds;
+
+ const char* query_delete = "DELETE FROM `seconds_between_retry`; ";
+ ASSERT_TRUE(dbms->Exec(query_delete));
+ ASSERT_TRUE(reps->SecondsBetweenRetries(&seconds));
+ EXPECT_EQ(0, seconds.size());
+
+ const char* query_insert =
+ "INSERT INTO `seconds_between_retry` (`index`, `value`) "
+ " VALUES (0, 10); "
+ "INSERT INTO `seconds_between_retry` (`index`, `value`) "
+ " VALUES (1, 20); ";
+ ASSERT_TRUE(dbms->Exec(query_insert));
+ ASSERT_TRUE(reps->SecondsBetweenRetries(&seconds));
+ ASSERT_EQ(2, seconds.size());
+ EXPECT_EQ(10, seconds[0]);
+ EXPECT_EQ(20, seconds[1]);
+}
+
+TEST_F(SQLPTRepresentationTest, TimeoutResponse) {
+ const char* query =
+ "UPDATE `module_config` SET `timeout_after_x_seconds` = 60";
+ ASSERT_TRUE(dbms->Exec(query));
+ EXPECT_EQ(60, reps->TimeoutResponse());
+}
+
+#ifndef EXTENDED_POLICY
+TEST_F(SQLPTRepresentationTest, SaveGenerateSnapshot) {
+ Json::Value expect(Json::objectValue);
+ expect["policy_table"] = Json::Value(Json::objectValue);
+
+ Json::Value& policy_table = expect["policy_table"];
+ policy_table["module_meta"] = Json::Value(Json::objectValue);
+ policy_table["module_config"] = Json::Value(Json::objectValue);
+ policy_table["usage_and_error_counts"] = Json::Value(Json::objectValue);
+ policy_table["device_data"] = Json::Value(Json::objectValue);
+ policy_table["functional_groupings"] = Json::Value(Json::objectValue);
+ policy_table["consumer_friendly_messages"] = Json::Value(Json::objectValue);
+ policy_table["app_policies"] = Json::Value(Json::objectValue);
+
+ Json::Value& module_config = policy_table["module_config"];
+ module_config["preloaded_pt"] = Json::Value(true);
+ module_config["exchange_after_x_ignition_cycles"] = Json::Value(10);
+ module_config["exchange_after_x_kilometers"] = Json::Value(100);
+ module_config["exchange_after_x_days"] = Json::Value(5);
+ module_config["timeout_after_x_seconds"] = Json::Value(500);
+ module_config["seconds_between_retries"] = Json::Value(Json::arrayValue);
+ module_config["seconds_between_retries"][0] = Json::Value(10);
+ module_config["seconds_between_retries"][1] = Json::Value(20);
+ module_config["seconds_between_retries"][2] = Json::Value(30);
+ module_config["endpoints"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["0x00"]["default"] = Json::Value(Json::arrayValue);
+ module_config["endpoints"]["0x00"]["default"][0] = Json::Value(
+ "http://ford.com/cloud/default");
+ module_config["notifications_per_minute_by_priority"] = Json::Value(
+ Json::objectValue);
+ module_config["notifications_per_minute_by_priority"]["emergency"] =
+ Json::Value(1);
+ module_config["notifications_per_minute_by_priority"]["navigation"] =
+ Json::Value(2);
+ module_config["notifications_per_minute_by_priority"]["voiceCommunication"] =
+ Json::Value(3);
+ module_config["notifications_per_minute_by_priority"]["communication"] =
+ Json::Value(4);
+ module_config["notifications_per_minute_by_priority"]["normal"] = Json::Value(
+ 5);
+ module_config["notifications_per_minute_by_priority"]["none"] = Json::Value(
+ 6);
+ module_config["vehicle_make"] = Json::Value("MakeT");
+ module_config["vehicle_model"] = Json::Value("ModelT");
+ module_config["vehicle_year"] = Json::Value(2014);
+
+ Json::Value& usage_and_error_counts = policy_table["usage_and_error_counts"];
+ usage_and_error_counts["app_level"] = Json::Value(Json::objectValue);
+ usage_and_error_counts["app_level"]["12345"] = Json::Value(Json::objectValue);
+
+ Json::Value& device_data = policy_table["device_data"];
+ device_data["user_consent_records"] = Json::Value(Json::objectValue);
+
+ Json::Value& functional_groupings = policy_table["functional_groupings"];
+ functional_groupings["default"] = Json::Value(Json::objectValue);
+ Json::Value& default_group = functional_groupings["default"];
+ default_group["rpcs"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"] = Json::Value(Json::objectValue);
+ default_group["rpcs"]["Update"]["hmi_levels"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["hmi_levels"][0] = Json::Value("FULL");
+ default_group["rpcs"]["Update"]["parameters"] = Json::Value(Json::arrayValue);
+ default_group["rpcs"]["Update"]["parameters"][0] = Json::Value("speed");
+
+ Json::Value& consumer_friendly_messages =
+ policy_table["consumer_friendly_messages"];
+ consumer_friendly_messages["version"] = Json::Value("1.2");
+
+ Json::Value& app12345counters = usage_and_error_counts["app_level"]["12345"];
+ app12345counters["app_registration_language_gui"] = "";
+ app12345counters["app_registration_language_vui"] = "";
+ app12345counters["count_of_rejected_rpc_calls"] = 0;
+ app12345counters["count_of_rejections_duplicate_name"] = 0;
+ app12345counters["count_of_rejections_nickname_mismatch"] = 0;
+ app12345counters["count_of_rejections_sync_out_of_memory"] = 0;
+ app12345counters["count_of_removals_for_bad_behavior"] = 0;
+ app12345counters["count_of_rfcom_limit_reached"] = 0;
+ app12345counters["count_of_rpcs_sent_in_hmi_none"] = 0;
+ app12345counters["count_of_run_attempts_while_revoked"] = 0;
+ app12345counters["count_of_user_selections"] = 0;
+ app12345counters["minutes_in_hmi_background"] = 0;
+ app12345counters["minutes_in_hmi_full"] = 0;
+ app12345counters["minutes_in_hmi_limited"] = 0;
+ app12345counters["minutes_in_hmi_none"] = 0;
+
+ Json::Value& app_policies = policy_table["app_policies"];
+ app_policies["default"] = Json::Value(Json::objectValue);
+ app_policies["default"]["memory_kb"] = Json::Value(50);
+ app_policies["default"]["watchdog_timer_ms"] = Json::Value(100);
+ app_policies["default"]["groups"] = Json::Value(Json::arrayValue);
+ app_policies["default"]["groups"][0] = Json::Value("default");
+
+ policy_table::Table table(&expect);
+
+ ASSERT_TRUE(IsValid(table));
+ ASSERT_TRUE(reps->Save(table));
+ utils::SharedPtr<policy_table::Table> snapshot = reps->GenerateSnapshot();
+ EXPECT_TRUE(IsValid(*snapshot));
+ EXPECT_EQ(table.ToJsonValue().toStyledString(),
+ snapshot->ToJsonValue().toStyledString());
+}
+#endif // EXTENDED_POLICY
+
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc b/src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc
new file mode 100644
index 000000000..45607097f
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc
@@ -0,0 +1,275 @@
+/* Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <string>
+#include <set>
+#include <sstream>
+#include <fstream>
+#include "policy/policy_manager_impl.h"
+#include "mock_policy_listener.h"
+
+using ::testing::_;
+using ::policy::PolicyManagerImpl;
+using ::policy::BinaryMessage;
+using ::policy::MockPolicyListener;
+
+namespace test {
+namespace components {
+namespace policy {
+
+class PolicyManagerImplTest : public ::testing::Test {
+ protected:
+ static const std::string kNameFile;
+ static const int kNumberGroups = 100;
+ static const int kNumberFuncs = 200;
+ static const int kNumberApps = 100;
+ static const int kNumberAppGroups = 50;
+ static PolicyManagerImpl* manager;
+
+ static void SetUpTestCase() {
+ std::ofstream ofs;
+ ofs.open(kNameFile.c_str(), std::ofstream::out);
+ CreateTable(ofs);
+ ofs.close();
+
+ manager = new PolicyManagerImpl();
+ ASSERT_TRUE(manager->LoadPTFromFile(kNameFile));
+ }
+
+ static void TearDownTestCase() {
+ delete manager;
+ remove(kNameFile.c_str());
+ remove("policy.sqlite");
+ }
+
+ static void CreateTable(std::ofstream& ofs);
+ static void CreateGroups(std::ofstream& ofs);
+ static void CreateFuncs(std::ofstream& ofs);
+ static void CreateApps(std::ofstream& ofs);
+ static void CreateAppGroups(std::ofstream& ofs);
+};
+
+const std::string PolicyManagerImplTest::kNameFile = "pt.json";
+PolicyManagerImpl* PolicyManagerImplTest::manager = 0;
+
+void PolicyManagerImplTest::CreateGroups(std::ofstream& ofs) {
+ std::stringstream ss;
+ std::string number;
+ for (int i = 0; i < kNumberGroups - 1; ++i) {
+ ss << i << std::endl;
+ ss >> number;
+ ofs << "\"Group-" << number << "\":{ \"rpcs\":{";
+ CreateFuncs(ofs);
+ ofs << "} },";
+ }
+ ss << kNumberGroups - 1 << std::endl;
+ ss >> number;
+ ofs << "\"Group-" << number << "\":{ \"rpcs\":{";
+ CreateFuncs(ofs);
+ ofs << "} }";
+}
+
+void PolicyManagerImplTest::CreateFuncs(std::ofstream& ofs) {
+ std::string func = "{"
+ "\"hmi_levels\":["
+ "\"BACKGROUND\","
+ "\"FULL\","
+ "\"LIMITED\""
+ "],"
+ "\"parameters\":["
+ "\"gps\","
+ "\"speed\","
+ "\"enginetorque\","
+ "\"externaltemperature\","
+ "\"fuellevel\","
+ "\"fuellevel_state\","
+ "\"headlampstatus\","
+ "\"instantfuelconsumption\","
+ "\"odometer\","
+ "\"tirepressure\","
+ "\"wiperstatus\","
+ "\"vin\","
+ "\"accpedalposition\","
+ "\"beltstatus\","
+ "\"driverbraking\","
+ "\"prndl\","
+ "\"rpm\","
+ "\"steeringwheelangle\""
+ "]"
+ "}";
+
+ std::stringstream ss;
+ std::string number;
+ for (int i = 0; i < kNumberFuncs - 1; ++i) {
+ ss << i << std::endl;
+ ss >> number;
+ ofs << "\"Func-" << number << "\":" << func << ",";
+ }
+ ss << kNumberFuncs - 1 << std::endl;
+ ss >> number;
+ ofs << "\"Func-" << number << "\":" + func;
+}
+
+void PolicyManagerImplTest::CreateApps(std::ofstream& ofs) {
+ ofs << "\"default\":{"
+ "\"groups\":["
+ "\"Group-1\""
+ "]"
+ "},";
+
+ std::stringstream ss;
+ std::string number;
+ for (int i = 0; i < kNumberApps - 1; ++i) {
+ ss << i << std::endl;
+ ss >> number;
+ ofs << "\"" << number << "\": { \"groups\": ";
+ CreateAppGroups(ofs);
+ ofs << "},";
+ }
+ ss << kNumberApps - 1 << std::endl;
+ ss >> number;
+ ofs << "\"" << number << "\": { \"groups\": ";
+ CreateAppGroups(ofs);
+ ofs << "}";
+}
+
+void PolicyManagerImplTest::CreateAppGroups(std::ofstream& ofs) {
+ ofs << "[";
+
+ std::stringstream ss;
+ std::string number;
+ std::set<int> app_groups;
+ for (int i = 0; i < kNumberAppGroups; ++i) {
+ app_groups.insert(rand() % kNumberGroups);
+ }
+
+ std::set<int>::const_iterator i = app_groups.begin();
+ ss << *i << std::endl;
+ ss >> number;
+ ofs << "\"Group-" << number << "\"";
+ ++i;
+ for (; i != app_groups.end(); ++i) {
+ ss << *i << std::endl;
+ ss >> number;
+ ofs << ",\"Group-" << number << "\"";
+ }
+ ofs << "]";
+}
+
+void PolicyManagerImplTest::CreateTable(std::ofstream& ofs) {
+ ofs << "{"
+ "\"policy_table\":{"
+ "\"module_config\":{"
+ "\"preloaded_pt\":true,"
+ "\"endpoints\":{"
+ "\"default\": {"
+ "\"default\":["
+ "\"http://sdl.net/api\""
+ "]"
+ "}"
+ "},"
+ "\"exchange_after_x_ignition_cycles\": 40,"
+ "\"exchange_after_x_kilometers\" : 2,"
+ "\"exchange_after_x_days\" : 23,"
+ "\"timeout_after_x_seconds\" : 20,"
+ "\"seconds_between_retries\" : [10, 7, 5, 3, 1]"
+ "},"
+ "\"consumer_friendly_messages\":{"
+ "\"version\":\"001.001.001\","
+ "\"messages\":{} },"
+ "\"functional_groupings\":{";
+
+ CreateGroups(ofs);
+
+ ofs << "}, \"app_policies\":{";
+
+ CreateApps(ofs);
+
+ ofs << "}";
+}
+
+TEST_F(PolicyManagerImplTest, StressTestOneCheck) {
+ MockPolicyListener mock_listener;
+
+ EXPECT_CALL(mock_listener, OnCurrentDeviceIdUpdateRequired("2")).Times(1);
+
+ manager->set_listener(&mock_listener);
+ ::policy::CheckPermissionResult output = manager->CheckPermissions("2",
+ "FULL",
+ "Func-1");
+ EXPECT_EQ(::policy::kRpcAllowed, output.hmi_level_permitted);
+}
+
+TEST_F(PolicyManagerImplTest, StressTestNoPermission) {
+ MockPolicyListener mock_listener;
+
+ EXPECT_CALL(mock_listener, OnCurrentDeviceIdUpdateRequired("150")).Times(1);
+
+ manager->set_listener(&mock_listener);
+ ::policy::CheckPermissionResult output = manager->CheckPermissions(
+ "150", "FULL", "Func-400");
+ EXPECT_EQ(::policy::kRpcDisallowed, output.hmi_level_permitted);
+}
+
+TEST_F(PolicyManagerImplTest, StressTestFewChecks) {
+ MockPolicyListener mock_listener;
+
+ EXPECT_CALL(mock_listener, OnCurrentDeviceIdUpdateRequired(_)).Times(100);
+ manager->set_listener(&mock_listener);
+
+ const int kNumberOfCheckings = 100;
+ std::stringstream ss;
+ int app, func;
+ std::string app_number, func_number;
+ for (int i = 0; i < kNumberOfCheckings; ++i) {
+ app = rand() % kNumberApps;
+ func = rand() % kNumberFuncs;
+ ss << app << std::endl;
+ ss >> app_number;
+ ss << func << std::endl;
+ ss >> func_number;
+
+ ::policy::CheckPermissionResult output = manager->CheckPermissions(
+ app_number, "FULL", "Func-" + func_number);
+ EXPECT_EQ(::policy::kRpcAllowed, output.hmi_level_permitted);
+ }
+}
+
+} // namespace policy
+} // namespace components
+} // namespace test
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/policy/test/policy/test-qdb.ini b/src/components/policy/test/policy/test-qdb.ini
new file mode 100644
index 000000000..d54d2fce8
--- /dev/null
+++ b/src/components/policy/test/policy/test-qdb.ini
@@ -0,0 +1,10 @@
+# This config file for QDB
+# Format see in manual of QNX
+[policy]
+Filename=policy.sqlite
+
+[test-database]
+Filename=test-database.sqlite
+
+[test-query]
+Filename=test-query.sqlite \ No newline at end of file
diff --git a/src/components/policy/test/policy/usage_statistics/CMakeLists.txt b/src/components/policy/test/policy/usage_statistics/CMakeLists.txt
new file mode 100644
index 000000000..3220ce20e
--- /dev/null
+++ b/src/components/policy/test/policy/usage_statistics/CMakeLists.txt
@@ -0,0 +1,16 @@
+include_directories(
+ include
+ ${CMAKE_SOURCE_DIR}/src/components/policy/usage_statistics/include
+ ${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/gmock-1.7.0/include
+)
+
+set(LIBRARIES
+ gmock_main
+ UsageStatistics
+)
+
+set(SOURCES
+ src/test_counter.cc
+)
+
+create_test("test_counter" "${SOURCES}" "${LIBRARIES}")
diff --git a/src/components/policy/test/policy/usage_statistics/include/statistics_manager_mock.h b/src/components/policy/test/policy/usage_statistics/include/statistics_manager_mock.h
new file mode 100644
index 000000000..59b554a0b
--- /dev/null
+++ b/src/components/policy/test/policy/usage_statistics/include/statistics_manager_mock.h
@@ -0,0 +1,22 @@
+#include <gmock/gmock.h>
+
+#include "usage_statistics/statistics_manager.h"
+
+namespace usage_statistics {
+namespace test {
+
+class MockStatisticsManager: public StatisticsManager {
+ public:
+ MOCK_METHOD1(Increment, void(GlobalCounterId type));
+ MOCK_METHOD2(Increment, void(const std::string& app_id, AppCounterId type));
+ MOCK_METHOD3(Set, void(const std::string& app_id,
+ AppInfoId type,
+ const std::string& value));
+ MOCK_METHOD3(Add, void(const std::string& app_id,
+ AppStopwatchId type,
+ int32_t timespan_seconds));
+
+};
+
+} // namespace test
+} // namespace usage_statistics
diff --git a/src/components/policy/test/policy/usage_statistics/src/test_counter.cc b/src/components/policy/test/policy/usage_statistics/src/test_counter.cc
new file mode 100644
index 000000000..87a9344ea
--- /dev/null
+++ b/src/components/policy/test/policy/usage_statistics/src/test_counter.cc
@@ -0,0 +1,115 @@
+#include <gtest/gtest.h>
+
+#include "statistics_manager_mock.h"
+#include "usage_statistics/counter.h"
+
+using namespace testing;
+
+namespace usage_statistics {
+namespace test {
+
+TEST(UsageStatisticsTest, TestGlobalCounterIncrementsStatistics) {
+ StrictMock<MockStatisticsManager> msm;
+ GlobalCounter reboots_counter(&msm, SYNC_REBOOTS);
+
+ EXPECT_CALL(msm, Increment(SYNC_REBOOTS)).Times(1);
+ ++reboots_counter;
+}
+
+TEST(UsageStatisticsTest, TestGlobalCounterIncrementsStatisticsTwice) {
+ StrictMock<MockStatisticsManager> msm;
+ GlobalCounter reboots_counter(&msm, SYNC_REBOOTS);
+
+ EXPECT_CALL(msm, Increment(SYNC_REBOOTS)).Times(2);
+ ++reboots_counter;
+ ++reboots_counter;
+}
+
+TEST(UsageStatisticsTest, TestAppCounterIncrementsStatistics) {
+ StrictMock<MockStatisticsManager> msm;
+ AppCounter user_selections_counter(&msm, "HelloApp", USER_SELECTIONS);
+
+ EXPECT_CALL(msm, Increment("HelloApp", USER_SELECTIONS)).Times(1);
+ ++user_selections_counter;
+}
+
+TEST(UsageStatisticsTest, TestAppCounterIncrementsStatisticsTwice) {
+ StrictMock<MockStatisticsManager> msm;
+ AppCounter user_selections_counter(&msm, "HelloApp", USER_SELECTIONS);
+
+ EXPECT_CALL(msm, Increment("HelloApp", USER_SELECTIONS)).Times(2);
+ ++user_selections_counter;
+ ++user_selections_counter;
+}
+
+TEST(UsageStatisticsTest, TestAppInfoUpdates) {
+ StrictMock<MockStatisticsManager> msm;
+ AppInfo gui_language_info(&msm, "HelloApp", LANGUAGE_GUI);
+
+ EXPECT_CALL(msm, Set("HelloApp", LANGUAGE_GUI, "Klingon")).Times(1);
+ gui_language_info.Update("Klingon");
+}
+
+TEST(UsageStatisticsTest, TestAppInfoUpdatesTwice) {
+ StrictMock<MockStatisticsManager> msm;
+ AppInfo gui_language_info(&msm, "HelloApp", LANGUAGE_GUI);
+
+ InSequence s;
+ EXPECT_CALL(msm, Set("HelloApp", LANGUAGE_GUI, "Klingon")).Times(1);
+ EXPECT_CALL(msm, Set("HelloApp", LANGUAGE_GUI, "UA")).Times(1);
+ gui_language_info.Update("Klingon");
+ gui_language_info.Update("UA");
+}
+
+TEST(UsageStatisticsTest, TestAppStopwatchAutoStopsAndAddsZero) {
+ StrictMock<MockStatisticsManager> msm;
+ AppStopwatch hmi_full_stopwatch(&msm, "HelloApp");
+
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_FULL, 0)).Times(1);
+
+ hmi_full_stopwatch.Start(SECONDS_HMI_FULL);
+}
+
+TEST(UsageStatisticsTest, TestAppStopwatchAddsZero) {
+ StrictMock<MockStatisticsManager> msm;
+ AppStopwatch hmi_full_stopwatch(&msm, "HelloApp");
+
+ InSequence s;
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_FULL, 0)).Times(1);
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_BACKGROUND, 0)).Times(1);
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_FULL, 0)).Times(1);
+
+ hmi_full_stopwatch.Start(SECONDS_HMI_FULL);
+ hmi_full_stopwatch.Switch(SECONDS_HMI_BACKGROUND);
+ hmi_full_stopwatch.Switch(SECONDS_HMI_FULL);
+ hmi_full_stopwatch.Stop();
+}
+
+TEST(UsageStatisticsTest, TestAppStopwatchAutoStopsInASecond) {
+ StrictMock<MockStatisticsManager> msm;
+ AppStopwatch hmi_full_stopwatch(&msm, "HelloApp");
+
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_FULL, 1)).Times(1);
+
+ hmi_full_stopwatch.Start(SECONDS_HMI_FULL);
+ sleep(1);
+}
+
+TEST(UsageStatisticsTest, TestAppStopwatchStopsInTwoSeconds) {
+ StrictMock<MockStatisticsManager> msm;
+ AppStopwatch hmi_full_stopwatch(&msm, "HelloApp");
+
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_NONE, 0)).Times(1);
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_FULL, 1)).Times(1);
+ EXPECT_CALL(msm, Add("HelloApp", SECONDS_HMI_BACKGROUND, 1)).Times(1);
+
+ hmi_full_stopwatch.Start(SECONDS_HMI_NONE);
+ hmi_full_stopwatch.Switch(SECONDS_HMI_FULL);
+ sleep(1);
+ hmi_full_stopwatch.Switch(SECONDS_HMI_BACKGROUND);
+ sleep(1);
+}
+
+
+} // namespace test
+} // namespace usage_statistics
diff --git a/src/components/policy/test/policy/valid_sdl_pt_update.json b/src/components/policy/test/policy/valid_sdl_pt_update.json
new file mode 100644
index 000000000..2d85459ad
--- /dev/null
+++ b/src/components/policy/test/policy/valid_sdl_pt_update.json
@@ -0,0 +1,1817 @@
+{
+ "policy_table" : {
+ "app_policies" : {
+ "1766825573" : {
+ "AppHMIType" : [ "MEDIA" ],
+ "certificate" : "akdjfhaliuygrglurng",
+ "default_hmi" : "BACKGROUND",
+ "groups" : [
+ "Notifications",
+ "Location-1",
+ "PropriataryData-1",
+ "Navigation-1",
+ "Base-4",
+ "VehicleInfo-3",
+ "DrivingCharacteristics-3",
+ "Emergency-1"
+ ],
+ "keep_context" : true,
+ "memory_kb" : 1000,
+ "nicknames" : [ "SyncProxyTester" ],
+ "priority" : "EMERGENCY",
+ "steal_focus" : true,
+ "watchdog_timer_ms" : 20000
+ },
+ "default" : {
+ "default_hmi" : "NONE",
+ "groups" : [ "Base-4" ],
+ "keep_context" : false,
+ "memory_kb" : 1000,
+ "priority" : "NONE",
+ "steal_focus" : false,
+ "watchdog_timer_ms" : 20000
+ },
+ "device" : {
+ "default_hmi" : "NONE",
+ "groups" : [ "Base-4" ],
+ "memory_kb" : 1000,
+ "watchdog_timer_ms" : 20000,
+ "keep_context" : false,
+ "priority" : "NONE",
+ "steal_focus" : false
+ },
+ "pre_DataConsent" : {
+ "default_hmi" : "NONE",
+ "groups" : [ "pre_Base-1" ],
+ "keep_context" : false,
+ "memory_kb" : 1000,
+ "priority" : "NONE",
+ "steal_focus" : false,
+ "watchdog_timer_ms" : 20000
+ }
+ },
+ "consumer_friendly_messages" : {
+ "messages" : {
+ "AppPermissions" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Zugriffsanfrage(n)",
+ "line2" : "erlauben?",
+ "tts" : "%appName% benötigt die folgenden Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Wenn Sie Ja drücken, erklären Sie sich damit einverstanden, dass %vehicleMake% nicht für Schäden oder Verletzungen der Privatsphäre haftet, die im Zusammenhang mit der Nutzung Ihrer Benutzerdaten durch %appName% entstehen. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab."
+ },
+ "en-au" : {
+ "line1" : "Grant requested",
+ "line2" : "permission(s)?",
+ "tts" : "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny."
+ },
+ "en-gb" : {
+ "line1" : "Grant requested",
+ "line2" : "permission(s)?",
+ "tts" : "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny."
+ },
+ "en-ie" : {
+ "line1" : "Grant requested",
+ "line2" : "permission(s)?",
+ "tts" : "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny."
+ },
+ "en-us" : {
+ "line1" : "Grant Requested",
+ "line2" : "Permission(s)?",
+ "tts" : "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press yes to allow or no to deny."
+ },
+ "es-en" : {
+ "line1" : "¿Otorgar permiso(s)",
+ "line2" : "solicitado(s)?",
+ "tts" : "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar."
+ },
+ "es-es" : {
+ "line1" : "¿Conceder permisos",
+ "line2" : "solicitados?",
+ "tts" : "%appName% está solicitando el uso de los siguientes permisos e información del vehículo: %functionalGroupLabels%. Si pulsa sí, acepta que %vehicleMake% no será responsable de los daños o la pérdida de privacidad relacionados con el uso de sus datos por parte de %appName%. Pulse sí para permitir o no para denegar."
+ },
+ "es-mx" : {
+ "line1" : "¿Otorgar permiso(s)",
+ "line2" : "solicitado(s)?",
+ "tts" : "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar."
+ },
+ "fr-ca" : {
+ "line1" : "Accorder permission(s)",
+ "line2" : "demandée(s)",
+ "tts" : "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser."
+ },
+ "fr-fr" : {
+ "line1" : "Accorder permission(s)",
+ "line2" : "demandée(s)",
+ "tts" : "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser."
+ },
+ "it-it" : {
+ "line1" : "Concedi autorizzaz.",
+ "line2" : "richiesta(e)?",
+ "tts" : "%appName% richiede l'uso delle seguenti informazioni e autorizzazioni sul veicolo: %functionalGroupLabels%. Se si preme Sì, si acconsente che %vehicleMake% non sarà responsabile per danni o perdita di privacy in relazione all'impiego dei dati da parte di %appName%. Premere Sì per consentire e No per negare."
+ },
+ "nl-nl" : {
+ "line1" : "Aangevraagde",
+ "line2" : "permissie(s) verlenen?",
+ "tts" : "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. Als u op Ja drukt, gaat u ermee akkoord dat %vehicleMake% in geen geval aansprakelijk gesteld kan worden voor schade of verlies van privacy als gevolg van het feit dat %appName% gebruik maakt van uw gegevens. Druk op Ja om dit toe te staan of Nee om te weigeren."
+ },
+ "pl-pl" : {
+ "line1" : "Udzielić żądanych",
+ "line2" : "pozwoleń?",
+ "tts" : "%appName% wymaga następujących informacji o pojeździe oraz pozwoleń: %functionalGroupLabels%. Naciśnięcie TAK oznacza zgodę na fakt, iż %vehicleMake% nie będzie ponosić odpowiedzialności za szkody ani utratę prywatności w związku z wykorzystaniem przez %appName% danych, należących do użytkownika. Naciśnij TAK w celu udzielenia zgody lub NIE w celu odrzucenia żądania."
+ },
+ "pt-br" : {
+ "line1" : "Conceder permissão",
+ "line2" : "solicitada?",
+ "tts" : "%appName% está solicitando o uso das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se pressionar sim, você concorda que a %vehicleMake% não será responsável por danos ou perdas de privacidade relacionados ao uso dos seus dados por %appName%. Pressione sim para permitir ou não para negar."
+ },
+ "pt-pt" : {
+ "line1" : "Conceder permiss.",
+ "line2" : "solicitada(s)?",
+ "tts" : "%appName% está a solicitar a utilização das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se premir “Sim”, concorda que %vehicleMake% não será responsável por quaisquer danos ou perda de privacidade relacionada com a utilização dos seus dados por parte de %appName%. Prima “Sim” para permitir ou “Não” para recusar."
+ },
+ "ru-ru" : {
+ "line1" : "Предост. заправш.",
+ "line2" : "разрешения?",
+ "tts" : "%appName% запрашивает следующую информацию об автомобиле и разрешения: %functionalGroupLabels%. Нажатием \"\"да\"\", Вы соглашаетесь, что %vehicleMake% не будет нести ответственность за какие-либо убытки или потерю прайвеси, связанные с использованием Ваших данных компанией %appName%. Нажмите \"\"Да\"\", если Вы согласны, или \"\"Нет\"\" - если не согласны."
+ },
+ "sv-se" : {
+ "line1" : "Vill du ge",
+ "line2" : "tillstånd?",
+ "tts" : "%appName% begär att få tillgång till följande fordonsinformation och tillstånd: %functionalGroupLabels%. Om du trycker Ja godkänner du att %vehicleMake% ska hållas skadeslös för alla skador som kan uppstå eller eventuella integritetsintrång som uppstår när %appName% använder dina data. Tryck Ja för att godkänna eller Nej för att neka."
+ },
+ "tr-tr" : {
+ "line1" : "İstenen izinler",
+ "line2" : "verilsin mi?",
+ "tts" : "%appName%, şu araç bilgilerini ve izinleri kullanma isteğinde bulunuyor: %functionalGroupLabels%. Evet'e basarsanız, %appName%'in verilerinizi kullanması sonucunda oluşabilecek hasarlardan veya gizlilik kaybından %vehicleMake%'in sorumlu olmayacağını kabul etmiş olacaksınız. Lütfen kabul etmek için Evet'e veya reddetmek için Hayır'a basın."
+ },
+ "zh-cn" : {
+ "line1" : "是否允许请求的",
+ "line2" : "权限?",
+ "tts" : "%appName% 正在请求使用下列车辆信息和权限: %functionalGroupLabels%。如果您按“是”,则表示您同意。 %vehicleMake% 将不会对因 %appName% 使用您的数据而引起的任何损毁或隐私损失负责。 请按“是”允许或按“否”拒绝。"
+ },
+ "zh-tw" : {
+ "line1" : "允許",
+ "line2" : "授權請求?",
+ "tts" : "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許可。按「是」,表示您同意,如因 %appName% 使用您的資料導致任何損害或損失,%vehicleMake% 將不負賠償責任。同意請按「是」,拒絕請按「否」。"
+ }
+ }
+ },
+ "AppPermissionsHelp" : {
+ "languages" : {
+ "de-de" : {
+ "tts" : "%appName% fordert folgende Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Im Einstellungsmenü der mobilen Apps können Sie diese Berechtigungen ändern und sich detaillierte Beschreibungen anhören. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab."
+ },
+ "en-au" : {
+ "tts" : "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny."
+ },
+ "en-gb" : {
+ "tts" : "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny."
+ },
+ "en-ie" : {
+ "tts" : "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny."
+ },
+ "en-us" : {
+ "tts" : "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press yes to grant permissions or no to deny."
+ },
+ "es-en" : {
+ "tts" : "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar."
+ },
+ "es-es" : {
+ "tts" : "%appName% está solicitando los siguientes permisos e información del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y escuchar descripciones detalladas en el menú de configuración de la aplicación móvil. Pulse sí para conceder el permiso o no para denegarlo."
+ },
+ "es-mx" : {
+ "tts" : "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar."
+ },
+ "fr-ca" : {
+ "tts" : "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser."
+ },
+ "fr-fr" : {
+ "tts" : "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser."
+ },
+ "it-it" : {
+ "tts" : "%appName% richiede le seguenti informazioni e autorizzazioni riguardo il veicolo: %functionalGroupLabels%. È possibile modificare tali autorizzazioni e ascoltare descrizioni dettagliate nel menu impostazioni delle app mobili. Premere Sì per concedere le autorizzazioni e No per negarle."
+ },
+ "nl-nl" : {
+ "tts" : "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. U kunt deze toestemmingen wijzigen en gedetailleerde beschrijvingen beluisteren in het instellingenmenu voor mobiele apps. Druk op Ja om permissies te verlenen of op Nee om te weigeren."
+ },
+ "pl-pl" : {
+ "tts" : "%appName% wymaga następujących informacji o pojeździe oraz zezwoleń: %functionalGroupLabels%. W menu ustawień aplikacji mobilnych można zmienić owe zezwolenia i usłyszeć ich szczegółowy opis. Naciśnij TAK, aby wyrazić zgodę lub NIE w celu odrzucenia żądania."
+ },
+ "pt-br" : {
+ "tts" : "%appName% está solicitando as seguintes informações e permissões do veículo: %functionalGroupLabels%. Você pode alterar estas permissões e ouvir descrições detalhadas no menu de configurações de aplicativos móveis. Pressione sim para conceder as permissões ou não para negar."
+ },
+ "pt-pt" : {
+ "tts" : "%appName% está a solicitar as seguintes informações e permissões do veículo: %functionalGroupLabels%. Pode alterar estas permissões e ouvir descrições detalhadas no menu de definições das aplicações móveis. Prima \"\"Sim\"\" para permitir ou \"\"Não\"\" para recusar."
+ },
+ "ru-ru" : {
+ "tts" : "%appName% запрашивает следующую информацию об автомобиле и разрешения: %functionalGroupLabels%. Вы можете изменить эти разрешения и прослушать подробные их описания в меню настроек мобильного приложения. Нажмите \"\"да\"\", чтобы предоставить разрешения, или \"\"нет\"\", чтобы не предоставлять."
+ },
+ "sv-se" : {
+ "tts" : "%appName% begär tillgång till följande fordonsinformation och tillstånd: %functionalGroupLabels%. Du kan ändra tillstånden och höra detaljerade beskrivningar i menyn för mobilappsinställningar. Tryck Ja för att ge tillstånd eller Nej för att neka."
+ },
+ "tr-tr" : {
+ "tts" : "%appName%, şu araç bilgilerini ve izinleri istiyor: %functionalGroupLabels%. Bu izinleri değiştirebilir ve mobil uygulamalar ayarlar menüsünden ayrıntılı açıklamaları dinleyebilirsiniz. Lütfen izin vermek için Evet'e veya reddetmek için Hayır'a basın."
+ },
+ "zh-cn" : {
+ "tts" : "%appName% 正在请求下列车辆信息和权限: %functionalGroupLabels%。您可在移动应用程序设置菜单中更改这些权限,并听取详细说明。请按“是”允许权限或按“否”拒绝。"
+ },
+ "zh-tw" : {
+ "tts" : "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許可。您可在行動應用程式設定清單中更改這些許可,並聆聽詳細說明。給予許可請按「是」,拒絕請按「否」。"
+ }
+ }
+ },
+ "AppPermissionsRevoked" : {
+ "languages" : {
+ "de-de" : {
+ "tts" : "Die Autorisierungsdaten der App wurden geändert. %appName% hat keinen Zugriff auf %functionalGroupLabels% mehr. Installieren Sie die neueste Version der App auf Ihrem Gerät.."
+ },
+ "en-au" : {
+ "tts" : "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device."
+ },
+ "en-gb" : {
+ "tts" : "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device."
+ },
+ "en-ie" : {
+ "tts" : "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device."
+ },
+ "en-us" : {
+ "tts" : "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device."
+ },
+ "es-en" : {
+ "tts" : "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil."
+ },
+ "es-es" : {
+ "tts" : "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de que tiene la versión más reciente de la aplicación instalada en su dispositivo móvil."
+ },
+ "es-mx" : {
+ "tts" : "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil."
+ },
+ "fr-ca" : {
+ "tts" : "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile."
+ },
+ "fr-fr" : {
+ "tts" : "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile."
+ },
+ "it-it" : {
+ "tts" : "Le autorizzazioni dell'app sono cambiate. %appName% non è più in grado di accedere a %functionalGroupLabels%. Assicurarsi di avere la versione più recente dell'app installata sul dispositivo mobile."
+ },
+ "nl-nl" : {
+ "tts" : "De app-autorisaties zijn gewijzigd. %appName% heeft geen toegang meer tot %functionalGroupLabels%. Zorg ervoor dat u de meest recente app-versie op uw mobiele apparaat geïnstalleerd hebt."
+ },
+ "pl-pl" : {
+ "tts" : "Dane dostępu aplikacji zostały zmienione. %appName% nie ma już dostępu do %functionalGroupLabels%. Sprawdź, czy na telefonie komórkowym zainstalowano najnowszą wersję aplikacji."
+ },
+ "pt-br" : {
+ "tts" : "As autorizações dos aplicativos foram alteradas. %appName% não pode mais acessar %functionalGroupLabels%. Certifique-se de que a versão mais recente do aplicativo está instalada no seu dispositivo móvel."
+ },
+ "pt-pt" : {
+ "tts" : "As autorizações das aplicações mudaram. %appName% já não consegue aceder a %functionalGroupLabels%. Certifique-se de que tem a última versão da aplicação no seu dispositivo móvel."
+ },
+ "ru-ru" : {
+ "tts" : "Авторизации приложения изменены. %appName% больше не имеет доступа к %functionalGroupLabels%. Убедитесь, что на вашем мобильном устройстве установлена самая новая версия приложения."
+ },
+ "sv-se" : {
+ "tts" : "Appens behörigheter har ändrats. %appName% har inte längre åtkomst till %functionalGroupLabels%. Kontrollera att du har installerat den senaste versionen av appen på mobilenheten."
+ },
+ "tr-tr" : {
+ "tts" : "Uygulama yetkileri değişti. %appName% artık %functionalGroupLabels%'e erişemeyecek. Lütfen mobil aygıtınızda en son uygulama sürümünün yüklü olduğundan emin olun."
+ },
+ "zh-cn" : {
+ "tts" : "应用程序授权已变更。 %appName% 将不能再访问 %functionalGroupLabels%。 请确认您的移动设备上安装的应用程序是最新版本。"
+ },
+ "zh-tw" : {
+ "tts" : "應用程式授權已改變。%appName% 已無法進入 %functionalGroupLabels%。請確認您的行動裝置上安裝了最新版應用程式。"
+ }
+ }
+ },
+ "AppUnauthorized" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "nicht autorisiert",
+ "tts" : "Diese Version von %appName% ist nicht autorisiert und wird nicht mit SYNC funktionieren."
+ },
+ "en-au" : {
+ "line1" : "not authorized",
+ "tts" : "This version of %appName% is not authorized and will not work with SYNC."
+ },
+ "en-gb" : {
+ "line1" : "not authorized",
+ "tts" : "This version of %appName% is not authorized and will not work with SYNC."
+ },
+ "en-ie" : {
+ "line1" : "not authorized",
+ "tts" : "This version of %appName% is not authorized and will not work with SYNC."
+ },
+ "en-us" : {
+ "line1" : "Not Authorized",
+ "tts" : "This version of %appName% is not authorized and will not work with SYNC."
+ },
+ "es-en" : {
+ "line1" : "no autorizada",
+ "tts" : "Esta versión de %appName% no tiene autorización y no funcionará con SYNC."
+ },
+ "es-es" : {
+ "line1" : "No autorizada",
+ "tts" : "Esta versión de %appName% no está autorizada y no funcionará con SYNC."
+ },
+ "es-mx" : {
+ "line1" : "no autorizada",
+ "tts" : "Esta versión de %appName% no tiene autorización y no funcionará con SYNC."
+ },
+ "fr-ca" : {
+ "line1" : "non autorisée",
+ "tts" : "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC."
+ },
+ "fr-fr" : {
+ "line1" : "non autorisée",
+ "tts" : "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC."
+ },
+ "it-it" : {
+ "line1" : "non autorizzata",
+ "tts" : "Questa versione di %appName% non è autorizzata e non funziona con il SYNC."
+ },
+ "nl-nl" : {
+ "line1" : "niet geautoriseerd",
+ "tts" : "Deze versie van %appName% is niet geautoriseerd en werkt niet met SYNC."
+ },
+ "pl-pl" : {
+ "line1" : "brak autoryzacji",
+ "tts" : "Niniejsza wersja %appName% nie posiada autoryzacji i nie będzie działać z SYNC."
+ },
+ "pt-br" : {
+ "line1" : "não autorizado",
+ "tts" : "Esta versão do %appName% não tem autorização e não funcionará com o SYNC."
+ },
+ "pt-pt" : {
+ "line1" : "não autorizada",
+ "tts" : "Esta versão de %appName% não está autorizada e não funcionará com o SYNC."
+ },
+ "ru-ru" : {
+ "line1" : "не авторизировано",
+ "tts" : "Эта версия %appName% не авторизирована и не будет работать с SYNC."
+ },
+ "sv-se" : {
+ "line1" : "är ej godkänd",
+ "tts" : "Den här versionen av %appName% är inte godkänd och fungerar inte med SYNC."
+ },
+ "tr-tr" : {
+ "line1" : "için izin yok",
+ "tts" : "Bu %appName% sürümüne izin verilmediğinden SYNC ile çalışamaz."
+ },
+ "zh-cn" : {
+ "line1" : "未得到授权",
+ "tts" : "此版本的%appName% 未得到授权,无法在SYNC上使用。"
+ },
+ "zh-tw" : {
+ "line1" : "無授權",
+ "tts" : "%appName% 的版本未獲得授權,將無法透過 SYNC 使用。"
+ }
+ }
+ },
+ "AppUnsupported" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "nicht unterstützt",
+ "tts" : "Diese Version von %appName% wird von SYNC nicht unterstützt."
+ },
+ "en-au" : {
+ "line1" : "not supported",
+ "tts" : "This version of %appName% is not supported by SYNC."
+ },
+ "en-gb" : {
+ "line1" : "not supported",
+ "tts" : "This version of %appName% is not supported by SYNC."
+ },
+ "en-ie" : {
+ "line1" : "not supported",
+ "tts" : "This version of %appName% is not supported by SYNC."
+ },
+ "en-us" : {
+ "line1" : "Not Supported",
+ "tts" : "This version of %appName% is not supported by SYNC."
+ },
+ "es-en" : {
+ "line1" : "no compatible",
+ "tts" : "Esta versión de %appName% no es compatible con SYNC."
+ },
+ "es-es" : {
+ "line1" : "No compatible",
+ "tts" : "Esta versión de %appName% no es compatible con SYNC."
+ },
+ "es-mx" : {
+ "line1" : "no compatible",
+ "tts" : "Esta versión de %appName% no es compatible con SYNC."
+ },
+ "fr-ca" : {
+ "line1" : "incompatible",
+ "tts" : "Cette version de %appName% n’est pas prise en charge par SYNC."
+ },
+ "fr-fr" : {
+ "line1" : "incompatible",
+ "tts" : "Cette version de %appName% n’est pas prise en charge par SYNC."
+ },
+ "it-it" : {
+ "line1" : "non supportata",
+ "tts" : "Questa versione di %appName% non è supportata dal SYNC."
+ },
+ "nl-nl" : {
+ "line1" : "niet ondersteund",
+ "tts" : "Deze versie van %appName% wordt niet ondersteund door SYNC."
+ },
+ "pl-pl" : {
+ "line1" : "aplikacja nie obsług.",
+ "tts" : "Niniejsza wersja %appName% nie jest obsługiwana przez system SYNC."
+ },
+ "pt-br" : {
+ "line1" : "não suportado",
+ "tts" : "Esta versão do %appName% não é suportada pelo SYNC."
+ },
+ "pt-pt" : {
+ "line1" : "não suportada",
+ "tts" : "Esta versão de %appName% não é suportado pelo SYNC."
+ },
+ "ru-ru" : {
+ "line1" : "не поддерживается",
+ "tts" : "Эта версия %appName% не поддерживается SYNC."
+ },
+ "sv-se" : {
+ "line1" : "stöds ej",
+ "tts" : "SYNC har inte stöd för den här versionen av %appName%."
+ },
+ "tr-tr" : {
+ "line1" : "desteklenmiyor",
+ "tts" : "Bu %appName% sürümü SYNC tarafından desteklenmiyor."
+ },
+ "zh-cn" : {
+ "line1" : "不受支持",
+ "tts" : "SYNC不支持此版本的%appName%。"
+ },
+ "zh-tw" : {
+ "line1" : "不支援",
+ "tts" : "SYNC 不支援此版本的%appName% 。"
+ }
+ }
+ },
+ "DataConsent" : {
+ "languages" : {
+ "en-us" : {
+ "line1" : "Enable Mobile Apps",
+ "line2" : "on SYNC? (Uses Data)",
+ "tts" : "To use mobile apps with SYNC, SYNC will communicate with Ford at least once per month using your mobile device's data plan. Standard rates may apply. SYNC will send your VIN and SYNC module number to Ford U.S. Please press yes or no, or help for more information. "
+ }
+ }
+ },
+ "DataConsentHelp" : {
+ "languages" : {
+ "en-us" : {
+ "tts" : "Updates are about the size of an email, and the occurrence of updates depends on your vehicle usage and when a new app is found on your device. To turn on or off, visit the SYNC mobile apps settings menu. See your Owner Guide for more information. "
+ }
+ }
+ },
+ "DisableApps" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Auto-Update",
+ "line2" : "und Mobile Apps deaktivieren",
+ "tts" : "Ausschalten der automatischen Updates führt zum Ausschalten von SYNC mobile Apps. Sie können Ihre mobilen Apps dann nicht mehr mit SYNC nutzen. Bitte drücken Sie Ja zur Bestätigung oder Nein, um abzubrechen."
+ },
+ "en-au" : {
+ "line1" : "Disable auto-updates",
+ "line2" : "and Mobile Apps?",
+ "tts" : "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel."
+ },
+ "en-gb" : {
+ "line1" : "Disable auto-updates",
+ "line2" : "and Mobile Apps?",
+ "tts" : "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel."
+ },
+ "en-ie" : {
+ "line1" : "Disable auto-updates",
+ "line2" : "and Mobile Apps?",
+ "tts" : "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel."
+ },
+ "en-us" : {
+ "line1" : "Disable Auto-Updates",
+ "line2" : "and Mobile Apps?",
+ "tts" : "Disabling automatic updates will also disable sync mobile apps. You will not be able to use any mobile apps with SYNC. Please press yes to confirm or no to cancel."
+ },
+ "es-en" : {
+ "line1" : "¿Deshab. actualiz.",
+ "line2" : "autom. y aplic. móv.?",
+ "tts" : "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar."
+ },
+ "es-es" : {
+ "line1" : "¿Desact. actual. auto",
+ "line2" : "y apl. móviles?",
+ "tts" : "Si desactiva las actualizaciones automáticas, también se desactivará la sincronización de las aplicaciones móviles. No podrá utilizar ninguna aplicación móvil con SYNC. Pulse sí para confirmar o no para cancelar."
+ },
+ "es-mx" : {
+ "line1" : "¿Deshab. actualiz.",
+ "line2" : "autom. y aplic. móv.?",
+ "tts" : "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar."
+ },
+ "fr-ca" : {
+ "line1" : "Désactiver màj autom.",
+ "line2" : "et app. mobiles?",
+ "tts" : "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler."
+ },
+ "fr-fr" : {
+ "line1" : "Désactiver màj autom.",
+ "line2" : "et app. mobiles?",
+ "tts" : "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler."
+ },
+ "it-it" : {
+ "line1" : "Disabilitare agg. aut.",
+ "line2" : "e app mobili?",
+ "tts" : "Disabilitando gli aggiornamenti automatici si disattiva anche la sincronizzazione delle app mobili. Non sarà possibile usare app mobili con il SYNC. Premere Sì per confermare e No per cancellare."
+ },
+ "nl-nl" : {
+ "line1" : "Auto-updates en mob.",
+ "line2" : "apps uitschakelen?",
+ "tts" : "Door automatische updates uit te schakelen, schakelt u ook SYNC-mobiele apps uit. U kunt dan geen mobiele apps meer gebruiken met SYNC. Druk op Ja om te bevestigen of op Nee om te annuleren."
+ },
+ "pl-pl" : {
+ "line1" : "Wył. automat. aktual.",
+ "line2" : "i aplikacje mobilne?",
+ "tts" : "Wyłączenie automatycznych aktualizacji spowoduje także wyłączenie aplikacji mobilnych SYNC. Korzystanie z mobilnych aplikacji za pomocą SYNC będzie niemożliwe. Naciśnij TAK, by potwierdzić lub NIE, by anulować."
+ },
+ "pt-br" : {
+ "line1" : "Desativar atualizações",
+ "line2" : "autom. e aplicativos?",
+ "tts" : "Se as atualizações automáticas forem desativadas, os aplicativos também serão desativados. Você não poderá usar nenhum aplicativo com o SYNC. Pressione sim para confirmar ou não para cancelar."
+ },
+ "pt-pt" : {
+ "line1" : "Desact. actual. autom.",
+ "line2" : "e aplicações móveis?",
+ "tts" : "A desactivação das actualizações automáticas desactiva igualmente as aplicações móveis do SYNC. Não poderá utilizar quaisquer aplicações móveis com o SYNC. Prima \"\"Sim\"\" para confirmar ou \"\"Não\"\" para cancelar."
+ },
+ "ru-ru" : {
+ "line1" : "Откл. автообновления",
+ "line2" : "и мобил. прилож.?",
+ "tts" : "При отключении автоматических обновлений также будут отключены мобильные приложения sync. Вы не сможете использовать какие-либо мобильные приложения с SYNC. Нажмите \"\"Да\"\" для подтверждения или \"\"Нет\"\" для отмены."
+ },
+ "sv-se" : {
+ "line1" : "Avaktiverar autouppdat.",
+ "line2" : "och mobilappar?",
+ "tts" : "Om du avaktiverar automatisk uppdatering avaktiverar du även synkning av mobilappar. Du kommer inte längre att kunna använda dina mobilappar med SYNC. Tryck Ja för att bekräfta eller Nej för att avbryta."
+ },
+ "tr-tr" : {
+ "line1" : "Oto. güncelleme ve",
+ "line2" : "mobil uygul. kapat?",
+ "tts" : "Otomatik güncellemeleri devre dışı bırakırsanız sync mobil uygulamalar da devre dışı kalır. SYNC ile mobil uygulama kullanmanız mümkün olmaz. Lütfen onaylamak için Evet'e veya iptal etmek için Hayır'a basın."
+ },
+ "zh-cn" : {
+ "line1" : "是否禁用自动更新和",
+ "line2" : "移动应用程序?",
+ "tts" : "禁用自动更新同时也会禁用SYNC移动应用程序。您将无法在 SYNC 中使用任何移动应用程序。请按“是”确认或按“否”取消。"
+ },
+ "zh-tw" : {
+ "line1" : "停用自動更新",
+ "line2" : "和行動應用程式?",
+ "tts" : "停用自動更新也將停用 sync 行動應用程式。您將無法透過 SYNC 使用任何行動應用程式。確認請按「是」,取消請按「否」。"
+ }
+ }
+ },
+ "DrivingCharacteristics" : {
+ "languages" : {
+ "de-de" : {
+ "label" : "Fahreigenschaften",
+ "tts" : "Eine App hat Zugriff auf die folgenden Fahreigenschaften: Kraftstoffverbrauch, MyKey, Sicherheitsgurtstatus."
+ },
+ "en-au" : {
+ "label" : "Driving characteristics",
+ "tts" : "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status."
+ },
+ "en-gb" : {
+ "label" : "Driving characteristics",
+ "tts" : "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status."
+ },
+ "en-ie" : {
+ "label" : "Driving characteristics",
+ "tts" : "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status."
+ },
+ "en-us" : {
+ "label" : "Driving Characteristics",
+ "tts" : "An app can access the following driving characteristics: Fuel Consumption, MyKey, Seat Belt Status."
+ },
+ "es-en" : {
+ "label" : "Características del manejo",
+ "tts" : "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad."
+ },
+ "es-es" : {
+ "label" : "Características de conducción",
+ "tts" : "Una aplicación puede acceder a las siguientes características de conducción: Consumo de combustible, MyKey, Estado cinturones de seguridad."
+ },
+ "es-mx" : {
+ "label" : "Características del manejo",
+ "tts" : "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad."
+ },
+ "fr-ca" : {
+ "label" : "Caractéristiques de conduite",
+ "tts" : "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité."
+ },
+ "fr-fr" : {
+ "label" : "Caractéristiques de conduite",
+ "tts" : "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité."
+ },
+ "it-it" : {
+ "label" : "Caratteristiche di guida",
+ "tts" : "Un'app può avere accesso alle seguenti caratteristiche di guida: Consumo carburante, MyKey, Stato cinture di sicurezza."
+ },
+ "nl-nl" : {
+ "label" : "Rijkenmerken",
+ "tts" : "Een app heeft toegang tot de volgende rijkenmerken: Brandstofverbruik, MyKey, Veiligheidsgordelstatus."
+ },
+ "pl-pl" : {
+ "label" : "Informacje dotyczące stylu jazdy",
+ "tts" : "Aplikacja może uzyskać dostęp do następujących informacji dotyczących jazdy: Zużycie paliwa, MyKey, Stan pasów bezpieczeństwa."
+ },
+ "pt-br" : {
+ "label" : "Características de condução",
+ "tts" : "Um aplicativo pode acessar as seguintes características de condução: Consumo de combustível, MyKey, Estado do cinto de segurança."
+ },
+ "pt-pt" : {
+ "label" : "Características de condução",
+ "tts" : "Uma aplicação consegue aceder às seguintes informações de condução: Consumo de combustível, MyKey, Estado dos cintos de segurança."
+ },
+ "ru-ru" : {
+ "label" : "Характеристики движения",
+ "tts" : "Приложение имеет доступ к следующим характеристикам движения: Расход топлива, MyKey, Состояние ремней безопасности."
+ },
+ "sv-se" : {
+ "label" : "Köregenskaper",
+ "tts" : "Appen kan komma åt följande köregenskaper: Bränsleförbrukning, MyKey, Bältesstatus."
+ },
+ "tr-tr" : {
+ "label" : "Sürüş karakteristikleri",
+ "tts" : "Bir uygulama şu sürüş karakteristiklerine erişebilir: Yakıt tüketimi, MyKey, Emniyet kemeri durumu."
+ },
+ "zh-cn" : {
+ "label" : "行驶特性",
+ "tts" : "移动应用程序可访问下列行驶特性: 油耗, MyKey, 安全带状态"
+ },
+ "zh-tw" : {
+ "label" : "駕駛特性",
+ "tts" : "應用程式可存取以下駕駛特性: 油耗, MyKey, 安全帶狀態"
+ }
+ }
+ },
+ "Location" : {
+ "languages" : {
+ "de-de" : {
+ "label" : "GPS und Geschwindigkeit",
+ "tts" : "Eine App hat Zugriff auf die GPS-Daten und die Geschwindigkeit des Fahrzeugs."
+ },
+ "en-au" : {
+ "label" : "GPS and speed",
+ "tts" : "An app can access vehicle GPS and speed."
+ },
+ "en-gb" : {
+ "label" : "GPS and speed",
+ "tts" : "An app can access vehicle GPS and speed."
+ },
+ "en-ie" : {
+ "label" : "GPS and speed",
+ "tts" : "An app can access vehicle GPS and speed."
+ },
+ "en-us" : {
+ "label" : "GPS and speed",
+ "tts" : "An app can access vehicle GPS and speed."
+ },
+ "es-en" : {
+ "label" : "GPS y velocidad",
+ "tts" : "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo."
+ },
+ "es-es" : {
+ "label" : "GPS y velocidad",
+ "tts" : "Una aplicación puede acceder al GPS y la velocidad del vehículo."
+ },
+ "es-mx" : {
+ "label" : "GPS y velocidad",
+ "tts" : "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo."
+ },
+ "fr-ca" : {
+ "label" : "GPS et vitesse",
+ "tts" : "Une application peut accéder au GPS et à la vitesse du véhicule."
+ },
+ "fr-fr" : {
+ "label" : "GPS et vitesse",
+ "tts" : "Une application peut accéder au GPS et à la vitesse du véhicule."
+ },
+ "it-it" : {
+ "label" : "GPS e velocità",
+ "tts" : "Un'app può avere accesso a GPS e velocità del veicolo."
+ },
+ "nl-nl" : {
+ "label" : "Gps en snelheid",
+ "tts" : "Een app heeft toegang tot gps en de snelheid van het voertuig."
+ },
+ "pl-pl" : {
+ "label" : "GPS i prędkość",
+ "tts" : "Aplikacja może uzyskać dostęp do modułu GPS i prędkości pojazdu."
+ },
+ "pt-br" : {
+ "label" : "GPS e velocidade",
+ "tts" : "Um aplicativo pode acessar o GPS e a velocidade do veículo."
+ },
+ "pt-pt" : {
+ "label" : "GPS e velocidade",
+ "tts" : "Uma aplicação consegue aceder ao GPS e à velocidade do veículo."
+ },
+ "ru-ru" : {
+ "label" : "GPS и скорость",
+ "tts" : "Приложение имеет доступ к GPS и скорости автомобиля."
+ },
+ "sv-se" : {
+ "label" : "GPS och hastighet",
+ "tts" : "Appen kan komma åt fordonets GPS och hastighetsmätare."
+ },
+ "tr-tr" : {
+ "label" : "GPS ve hız",
+ "tts" : "Bu uygulama aracın GPS ve hız bilgilerine erişebilir."
+ },
+ "zh-cn" : {
+ "label" : "GPS 和车速",
+ "tts" : "移动应用程序可以访问车辆 GPS 和车速信息。"
+ },
+ "zh-tw" : {
+ "label" : "GPS和車速",
+ "tts" : "應用程式可存取車輛的GPS和速度。"
+ }
+ }
+ },
+ "Notifications" : {
+ "languages" : {
+ "de-de" : {
+ "label" : "Push-Benachrichtigungen",
+ "tts" : "Läuft die App im Hintergrund, kann Sie Benachrichtigungen senden."
+ },
+ "en-au" : {
+ "label" : "Push notifications",
+ "tts" : "An app can send notifications when running in the background."
+ },
+ "en-gb" : {
+ "label" : "Push notifications",
+ "tts" : "An app can send notifications when running in the background."
+ },
+ "en-ie" : {
+ "label" : "Push notifications",
+ "tts" : "An app can send notifications when running in the background."
+ },
+ "en-us" : {
+ "label" : "Push notifications",
+ "tts" : "An app can send notifications when running in the background."
+ },
+ "es-en" : {
+ "label" : "Notificaciones tipo Push",
+ "tts" : "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano."
+ },
+ "es-es" : {
+ "label" : "Notificaciones push",
+ "tts" : "Una aplicación puede enviar notificaciones cuando se está ejecutando en segundo plano."
+ },
+ "es-mx" : {
+ "label" : "Notificaciones tipo Push",
+ "tts" : "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano."
+ },
+ "fr-ca" : {
+ "label" : "Notifications instantanées",
+ "tts" : "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan."
+ },
+ "fr-fr" : {
+ "label" : "Notifications push",
+ "tts" : "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan."
+ },
+ "it-it" : {
+ "label" : "Notifiche push",
+ "tts" : "Un'app può inviare notifiche se eseguita in background."
+ },
+ "nl-nl" : {
+ "label" : "Push-meldingen",
+ "tts" : "Een app kan meldingen versturen als deze op de achtergrond actief is."
+ },
+ "pl-pl" : {
+ "label" : "Powiadomienia Push",
+ "tts" : "Aplikacja może wysyłać powiadomienia, działając w tle."
+ },
+ "pt-br" : {
+ "label" : "Notificações Push",
+ "tts" : "Um aplicativo pode enviar notificações quando estiver sendo executado em segundo plano."
+ },
+ "pt-pt" : {
+ "label" : "Notificações push",
+ "tts" : "Uma aplicação consegue enviar notificações quando está activa em segundo plano."
+ },
+ "ru-ru" : {
+ "label" : "Оповещения о пересылке",
+ "tts" : "Если приложение работает в фоновом режиме, оно может отправлять оповещения."
+ },
+ "sv-se" : {
+ "label" : "Push-notiser",
+ "tts" : "Appen kan skicka meddelanden när den körs i bakgrunden."
+ },
+ "tr-tr" : {
+ "label" : "Anlık bildirimleri",
+ "tts" : "Bir uygulama arka planda çalışırken bildirim gönderebilir."
+ },
+ "zh-cn" : {
+ "label" : "推送通知",
+ "tts" : "移动应用程序在后台运行时可推送通知。"
+ },
+ "zh-tw" : {
+ "label" : "傳送通知",
+ "tts" : "車輛行進時,應用程式可在背景中傳送通知。"
+ }
+ }
+ },
+ "SettingDisableUpdates" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Updates deakt."
+ },
+ "en-au" : {
+ "line1" : "Disable updates"
+ },
+ "en-gb" : {
+ "line1" : "Disable updates"
+ },
+ "en-ie" : {
+ "line1" : "Disable updates"
+ },
+ "en-us" : {
+ "line1" : "Disable Updates"
+ },
+ "es-en" : {
+ "line1" : "Deshab. actual."
+ },
+ "es-es" : {
+ "line1" : "Desact. actual."
+ },
+ "es-mx" : {
+ "line1" : "Deshab. actual."
+ },
+ "fr-ca" : {
+ "line1" : "Désactiver MAJ"
+ },
+ "fr-fr" : {
+ "line1" : "Désactiver màj"
+ },
+ "it-it" : {
+ "line1" : "Disabilita agg."
+ },
+ "nl-nl" : {
+ "line1" : "Upd. uitschak."
+ },
+ "pl-pl" : {
+ "line1" : "Wyłącz aktual."
+ },
+ "pt-br" : {
+ "line1" : "Desat. atualiz."
+ },
+ "pt-pt" : {
+ "line1" : "Desact. actualiz."
+ },
+ "ru-ru" : {
+ "line1" : "Откл. обновл."
+ },
+ "sv-se" : {
+ "line1" : "Inaktivera uppd."
+ },
+ "tr-tr" : {
+ "line1" : "Güncell. Kapat"
+ },
+ "zh-cn" : {
+ "line1" : "禁用更新"
+ },
+ "zh-tw" : {
+ "line1" : "停用更新"
+ }
+ }
+ },
+ "SettingEnableUpdates" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Apps aktivieren"
+ },
+ "en-au" : {
+ "line1" : "Enable Apps"
+ },
+ "en-gb" : {
+ "line1" : "Enable Apps"
+ },
+ "en-ie" : {
+ "line1" : "Enable Apps"
+ },
+ "en-us" : {
+ "line1" : "Enable Apps"
+ },
+ "es-en" : {
+ "line1" : "Hab. aplic."
+ },
+ "es-es" : {
+ "line1" : "Activar apl."
+ },
+ "es-mx" : {
+ "line1" : "Hab. aplic."
+ },
+ "fr-ca" : {
+ "line1" : "Activer app."
+ },
+ "fr-fr" : {
+ "line1" : "Activer app."
+ },
+ "it-it" : {
+ "line1" : "Abilita app"
+ },
+ "nl-nl" : {
+ "line1" : "Apps inschak."
+ },
+ "pl-pl" : {
+ "line1" : "Włącz aplikacje"
+ },
+ "pt-br" : {
+ "line1" : "Ativar aplic."
+ },
+ "pt-pt" : {
+ "line1" : "Activar actualiz."
+ },
+ "ru-ru" : {
+ "line1" : "Вкл. прилож."
+ },
+ "sv-se" : {
+ "line1" : "Aktivera appar"
+ },
+ "tr-tr" : {
+ "line1" : "Uygulamaları aç"
+ },
+ "zh-cn" : {
+ "line1" : "启用应用程序"
+ },
+ "zh-tw" : {
+ "line1" : "啟用應用程式"
+ }
+ }
+ },
+ "SettingUpdateAuto" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Update anford."
+ },
+ "en-au" : {
+ "line1" : "Request update"
+ },
+ "en-gb" : {
+ "line1" : "Request update"
+ },
+ "en-ie" : {
+ "line1" : "Request update"
+ },
+ "en-us" : {
+ "line1" : "Request Update"
+ },
+ "es-en" : {
+ "line1" : "Solicit. actualiz."
+ },
+ "es-es" : {
+ "line1" : "Solicitar actual."
+ },
+ "es-mx" : {
+ "line1" : "Solicit. actualiz."
+ },
+ "fr-ca" : {
+ "line1" : "Demander MAJ"
+ },
+ "fr-fr" : {
+ "line1" : "Demander màj"
+ },
+ "it-it" : {
+ "line1" : "Rich. aggiorn."
+ },
+ "nl-nl" : {
+ "line1" : "Upd. aanvragen"
+ },
+ "pl-pl" : {
+ "line1" : "Zażądaj aktual."
+ },
+ "pt-br" : {
+ "line1" : "Solicitar atualiz."
+ },
+ "pt-pt" : {
+ "line1" : "Solicit. actualiz."
+ },
+ "ru-ru" : {
+ "line1" : "Запрос на обн."
+ },
+ "sv-se" : {
+ "line1" : "Begär uppdat."
+ },
+ "tr-tr" : {
+ "line1" : "Güncelleme iste"
+ },
+ "zh-cn" : {
+ "line1" : "请求更新"
+ },
+ "zh-tw" : {
+ "line1" : "請求更新"
+ }
+ }
+ },
+ "StatusNeeded" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Update benötigt"
+ },
+ "en-au" : {
+ "line1" : "Update needed"
+ },
+ "en-gb" : {
+ "line1" : "Update needed"
+ },
+ "en-ie" : {
+ "line1" : "Update needed"
+ },
+ "en-us" : {
+ "line1" : "Update Needed"
+ },
+ "es-en" : {
+ "line1" : "Actualiz. neces."
+ },
+ "es-es" : {
+ "line1" : "Actu. necesaria"
+ },
+ "es-mx" : {
+ "line1" : "Actualiz. neces."
+ },
+ "fr-ca" : {
+ "line1" : "Màj requise"
+ },
+ "fr-fr" : {
+ "line1" : "Mise à jour requise"
+ },
+ "it-it" : {
+ "line1" : "Necess. aggiorn."
+ },
+ "nl-nl" : {
+ "line1" : "Update nodig"
+ },
+ "pl-pl" : {
+ "line1" : "Potrzeba aktual."
+ },
+ "pt-br" : {
+ "line1" : "Atualiz. necess."
+ },
+ "pt-pt" : {
+ "line1" : "Actual. necess."
+ },
+ "ru-ru" : {
+ "line1" : "Необх. обновл."
+ },
+ "sv-se" : {
+ "line1" : "Uppdat. krävs"
+ },
+ "tr-tr" : {
+ "line1" : "Güncellenmeli"
+ },
+ "zh-cn" : {
+ "line1" : "需要进行更新"
+ },
+ "zh-tw" : {
+ "line1" : "需更新"
+ }
+ }
+ },
+ "StatusPending" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Aktualisieren..."
+ },
+ "en-au" : {
+ "line1" : "Updating..."
+ },
+ "en-gb" : {
+ "line1" : "Updating..."
+ },
+ "en-ie" : {
+ "line1" : "Updating..."
+ },
+ "en-us" : {
+ "line1" : "Updating..."
+ },
+ "es-en" : {
+ "line1" : "Actualizando..."
+ },
+ "es-es" : {
+ "line1" : "Actualizando..."
+ },
+ "es-mx" : {
+ "line1" : "Actualizando..."
+ },
+ "fr-ca" : {
+ "line1" : "MAJ en cours..."
+ },
+ "fr-fr" : {
+ "line1" : "Màj en cours..."
+ },
+ "it-it" : {
+ "line1" : "Aggiornamento"
+ },
+ "nl-nl" : {
+ "line1" : "Updaten..."
+ },
+ "pl-pl" : {
+ "line1" : "Aktualizowanie"
+ },
+ "pt-br" : {
+ "line1" : "Atualizando..."
+ },
+ "pt-pt" : {
+ "line1" : "A actualizar..."
+ },
+ "ru-ru" : {
+ "line1" : "Обновление..."
+ },
+ "sv-se" : {
+ "line1" : "Uppdaterar..."
+ },
+ "tr-tr" : {
+ "line1" : "Güncelleniyor..."
+ },
+ "zh-cn" : {
+ "line1" : "正在更新......"
+ },
+ "zh-tw" : {
+ "line1" : "更新中..."
+ }
+ }
+ },
+ "StatusUpToDate" : {
+ "languages" : {
+ "de-de" : {
+ "line1" : "Aktuelle Version"
+ },
+ "en-au" : {
+ "line1" : "Up-to-date"
+ },
+ "en-gb" : {
+ "line1" : "Up-to-date"
+ },
+ "en-ie" : {
+ "line1" : "Up-to-date"
+ },
+ "en-us" : {
+ "line1" : "Up-To-Date"
+ },
+ "es-en" : {
+ "line1" : "Actualizado"
+ },
+ "es-es" : {
+ "line1" : "Actualizada"
+ },
+ "es-mx" : {
+ "line1" : "Actualizado"
+ },
+ "fr-ca" : {
+ "line1" : "Déjà à jour"
+ },
+ "fr-fr" : {
+ "line1" : "Déjà à jour"
+ },
+ "it-it" : {
+ "line1" : "più recente"
+ },
+ "nl-nl" : {
+ "line1" : "Up-to-date"
+ },
+ "pl-pl" : {
+ "line1" : "Aktualne"
+ },
+ "pt-br" : {
+ "line1" : "Atualizado"
+ },
+ "pt-pt" : {
+ "line1" : "Actualizado"
+ },
+ "ru-ru" : {
+ "line1" : "Обновлено"
+ },
+ "sv-se" : {
+ "line1" : "Uppdat. krävs ej"
+ },
+ "tr-tr" : {
+ "line1" : "Güncel"
+ },
+ "zh-cn" : {
+ "line1" : "最新更新"
+ },
+ "zh-tw" : {
+ "line1" : "更新最新"
+ }
+ }
+ },
+ "VehicleInfo" : {
+ "languages" : {
+ "de-de" : {
+ "label" : "Fahrzeuginformationen",
+ "tts" : "Eine App hat Zugriff auf die folgenden Fahrzeuginformationen: Kraftstoff-Füllstand, Kraftstoffverbrauch, Motordrehzahl, Kilometerzähler, FIN, Außentemperatur, Gangstellung, Reifenluftdruck."
+ },
+ "en-au" : {
+ "label" : "Vehicle information",
+ "tts" : "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure."
+ },
+ "en-gb" : {
+ "label" : "Vehicle information",
+ "tts" : "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure."
+ },
+ "en-ie" : {
+ "label" : "Vehicle information",
+ "tts" : "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure."
+ },
+ "en-us" : {
+ "label" : "Vehicle information",
+ "tts" : "An app can access the following vehicle information: Fuel Level, Fuel Economy, Engine RPMs, Odometer, VIN, External Temperature, Gear Position, Tire Pressure."
+ },
+ "es-en" : {
+ "label" : "Información del vehículo",
+ "tts" : "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos."
+ },
+ "es-es" : {
+ "label" : "Información del vehículo",
+ "tts" : "Una aplicación puede acceder a la siguiente información del vehículo: Nivel de combustible, Ahorro de combustible, RPM del motor, Cuentakilómetros, VIN, Temperatura aire exterior, Marcha engranada, Presión de neumáticos."
+ },
+ "es-mx" : {
+ "label" : "Información del vehículo",
+ "tts" : "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos."
+ },
+ "fr-ca" : {
+ "label" : "Renseignements du véhicule",
+ "tts" : "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Au régime du moteur, Odomètre, NIV, Température extérieure, Position d’embrayage, Pression des pneus."
+ },
+ "fr-fr" : {
+ "label" : "Renseignements du véhicule",
+ "tts" : "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Vitesse de moteur, Compteur kilométrique, NIV, Température extérieure, Position de vitesse, Pression des pneus."
+ },
+ "it-it" : {
+ "label" : "Informazioni sul veicolo",
+ "tts" : "Un'app può avere accesso alle seguenti informazioni del veicolo: Livello carburante, Consumi carburante, Numero giri motore, Contachilometri, VIN, Temperatura esterna, Posizione marcia, Pressione pneumatici."
+ },
+ "nl-nl" : {
+ "label" : "Voertuiginformatie",
+ "tts" : "Een app heeft toegang tot de volgende voertuiginformatie: Brandstofpeil, Brandstofverbruik, Motortoerental, Kilometerteller, VIN, Buitentemperatuur, Versnellingsstand, Bandenspanning."
+ },
+ "pl-pl" : {
+ "label" : "Informacje o pojeździe",
+ "tts" : "Aplikacja może uzyskać dostęp do następujących informacji o pojeździe: Poziom paliwa, Zużycie paliwa, Obroty silnika, Licznik przebiegu, Numer VIN, Temperatura zewnętrzna, Aktualny bieg, Ciśnienie opon."
+ },
+ "pt-br" : {
+ "label" : "Informações sobre o veículo",
+ "tts" : "Um aplicativo pode acessar as seguintes informações sobre o veículo: Nível de combustível, Economia de combustível, RPM do motor, Hodômetro, VIN, Temperatura externa, Posição das marchas, Pressão dos pneus."
+ },
+ "pt-pt" : {
+ "label" : "Informações do veículo",
+ "tts" : "Uma aplicação consegue aceder às seguintes informações do veículo: Nível de combustível, Poupança de combustível, RPM do motor, Conta-quilómetros, VIN, Temperatura exterior, Posição da mudança de velocidade, Pressão dos pneus."
+ },
+ "ru-ru" : {
+ "label" : "Информация об автомобиле",
+ "tts" : "Приложение имеет доступ к следующим данным автомобиля: Уровень топлива, Економия топлива, Число оборотов двигателя, Одометр, Номер VIN, Температура за бортом, Положение передачи, Давление шин."
+ },
+ "sv-se" : {
+ "label" : "Fordonsinformation",
+ "tts" : "Appen kan komma åt följande fordonsinformation: Bränslenivå, Bränsleekonomi, Motorns varvtal, Vägmätare, VIN, Utetemperatur, Växelläge, Däcktryck."
+ },
+ "tr-tr" : {
+ "label" : "Araç bilgisi",
+ "tts" : "Bir uygulama şu araç bilgilerine erişebilir: Yakıt seviyesi, Yakıt ekonomisi, Motor devirleri, Kilometre sayacı, VIN, Dış sıcaklık, Vites konumu, Lastik basıncı."
+ },
+ "zh-cn" : {
+ "label" : "车辆信息",
+ "tts" : "移动应用程序可访问下列车辆信息 : 燃油量, 燃油经济性, 发动机转速(RPM), 里程表, VIN, 车外温度, 档位, 胎压."
+ },
+ "zh-tw" : {
+ "label" : "車輛資訊",
+ "tts" : "一個應用程式可存取以下車輛資訊 : 燃油存量, 燃油經濟性, 引擎轉速, 里程表, 車輛識別號碼, 車外溫度, 檔位, 胎壓."
+ }
+ }
+ }
+ },
+ "version" : "001.001.015"
+ },
+ "device_data" : {
+ "H32L41K32JH4L1K234H3K4HUU40DAS7F970UEI17A73J" : {
+ "carrier" : null,
+ "firmware_rev" : null,
+ "hardware" : "Motorola Atrix 4G",
+ "max_number_rfcom_ports" : 15,
+ "os" : "Android",
+ "os_version" : "2.3.4",
+ "user_consent_records" : {
+ "device" : {
+ "consent_groups" : {
+ "DataConsent-1" : true
+ },
+ "input" : "VUI",
+ "time_stamp" : "4/25/2012 11:56:00 AM"
+ }
+ }
+ },
+ "HUU40DAS7F970UEI17A73JH32L41K32JH4L1K234H3K4" : {
+ "carrier" : "Verizon",
+ "firmware_rev" : null,
+ "hardware" : "HTC Incredible",
+ "max_number_rfcom_ports" : 20,
+ "os" : "Android",
+ "os_version" : "2.3.3",
+ "user_consent_records" : {
+ "device" : {
+ "consent_groups" : {
+ "DataConsent-1" : true
+ },
+ "input" : "GUI",
+ "time_stamp" : "4/11/2012 6:57:00 AM"
+ }
+ }
+ },
+ "UEI17A73JH32L41K32JH4L1K234H3K4HUU40DAS7F970" : {
+ "carrier" : "AT&T",
+ "firmware_rev" : null,
+ "hardware" : "iPhone 4S",
+ "max_number_rfcom_ports" : 25,
+ "os" : "iOS",
+ "os_version" : "5",
+ "user_consent_records" : {
+ "584421907" : {
+ "consent_groups" : {
+ "DrivingData-1" : false,
+ "Location-1" : true
+ },
+ "input" : "VUI",
+ "time_stamp" : "3/26/2012 10:41:00 AM "
+ },
+ "device" : {
+ "consent_groups" : {
+ "DataConsent-1" : true
+ },
+ "input" : "VUI",
+ "time_stamp" : "4/24/2012 12:30:00 PM"
+ }
+ }
+ }
+ },
+ "functional_groupings" : {
+ "Base-4" : {
+ "rpcs" : {
+ "AddCommand" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "AddSubMenu" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "Alert" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "ChangeRegistration" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "CreateInteractionChoiceSet" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "DeleteCommand" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "DeleteFile" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "DeleteInteractionChoiceSet" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "DeleteSubMenu" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "EncodedSyncPData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "EndAudioPassThru" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "GenericResponse" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "ListFiles" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnAppInterfaceUnregistered" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnAudioPassThru" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "OnButtonEvent" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "OnButtonPress" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "OnCommand" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "OnDriverDistraction" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "OnEncodedSyncPData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnHMIStatus" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnLanguageChange" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnPermissionsChange" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnSyncPData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnTBTClientState" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "PerformAudioPassThru" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "PerformInteraction" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "PutFile" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "RegisterAppInterface" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "ResetGlobalProperties" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "ScrollableMessage" : {
+ "hmi_levels" : [ "FULL" ]
+ },
+ "SetAppIcon" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "SetDisplayLayout" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "SetGlobalProperties" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "SetMediaClockTimer" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "Show" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "Slider" : {
+ "hmi_levels" : [ "FULL" ]
+ },
+ "Speak" : {
+ "hmi_levels" : [ "FULL", "LIMITED" ]
+ },
+ "SubscribeButton" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "SyncPData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "UnregisterAppInterface" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "UnsubscribeButton" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ }
+ }
+ },
+ "DrivingCharacteristics-3" : {
+ "rpcs" : {
+ "GetVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "accPedalPosition",
+ "beltStatus",
+ "driverBraking",
+ "myKey",
+ "prndl",
+ "rpm",
+ "steeringWheelAngle"
+ ]
+ },
+ "OnVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "accPedalPosition",
+ "beltStatus",
+ "driverBraking",
+ "myKey",
+ "prndl",
+ "rpm",
+ "steeringWheelAngle"
+ ]
+ },
+ "SubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "accPedalPosition",
+ "beltStatus",
+ "driverBraking",
+ "myKey",
+ "prndl",
+ "rpm",
+ "steeringWheelAngle"
+ ]
+ },
+ "UnsubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "accPedalPosition",
+ "beltStatus",
+ "driverBraking",
+ "myKey",
+ "prndl",
+ "rpm",
+ "steeringWheelAngle"
+ ]
+ }
+ },
+ "user_consent_prompt" : "DrivingCharacteristics"
+ },
+ "Emergency-1" : {
+ "rpcs" : {
+ "GetVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "airbagStatus",
+ "bodyInformation",
+ "clusterModeStatus",
+ "deviceStatus",
+ "eCallInfo",
+ "emergencyEvent"
+ ]
+ },
+ "OnVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "airbagStatus",
+ "bodyInformation",
+ "clusterModeStatus",
+ "deviceStatus",
+ "eCallInfo",
+ "emergencyEvent"
+ ]
+ },
+ "SubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "airbagStatus",
+ "bodyInformation",
+ "clusterModeStatus",
+ "deviceStatus",
+ "eCallInfo",
+ "emergencyEvent"
+ ]
+ },
+ "UnsubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "airbagStatus",
+ "bodyInformation",
+ "clusterModeStatus",
+ "deviceStatus",
+ "eCallInfo",
+ "emergencyEvent"
+ ]
+ }
+ }
+ },
+ "Location-1" : {
+ "rpcs" : {
+ "GetVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [ "gps", "speed" ]
+ },
+ "OnVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [ "gps", "speed" ]
+ },
+ "SubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [ "gps", "speed" ]
+ },
+ "UnsubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [ "gps", "speed" ]
+ }
+ },
+ "user_consent_prompt" : "Location"
+ },
+ "Navigation-1" : {
+ "rpcs" : {
+ "AlertManeuver" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "ShowConstantTBT" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "UpdateTurnList" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ }
+ }
+ },
+ "Notifications" : {
+ "rpcs" : {
+ "Alert" : {
+ "hmi_levels" : [ "BACKGROUND" ]
+ }
+ },
+ "user_consent_prompt" : "Notifications"
+ },
+ "PropriataryData-1" : {
+ "rpcs" : {
+ "DiagnosticMessage" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "GetDTCs" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "ReadDID" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ }
+ }
+ },
+ "VehicleInfo-3" : {
+ "rpcs" : {
+ "GetVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "engineTorque",
+ "externalTemperature",
+ "fuelLevel",
+ "fuelLevel_State",
+ "headLampStatus",
+ "instantFuelConsumption",
+ "odometer",
+ "tirePressure",
+ "vin",
+ "wiperStatus"
+ ]
+ },
+ "OnVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "engineTorque",
+ "externalTemperature",
+ "fuelLevel",
+ "fuelLevel_State",
+ "headLampStatus",
+ "instantFuelConsumption",
+ "odometer",
+ "tirePressure",
+ "vin",
+ "wiperStatus"
+ ]
+ },
+ "SubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "engineTorque",
+ "externalTemperature",
+ "fuelLevel",
+ "fuelLevel_State",
+ "headLampStatus",
+ "instantFuelConsumption",
+ "odometer",
+ "tirePressure",
+ "wiperStatus"
+ ]
+ },
+ "UnsubscribeVehicleData" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ],
+ "parameters" : [
+ "engineTorque",
+ "externalTemperature",
+ "fuelLevel",
+ "fuelLevel_State",
+ "headLampStatus",
+ "instantFuelConsumption",
+ "odometer",
+ "tirePressure",
+ "wiperStatus"
+ ]
+ }
+ },
+ "user_consent_prompt" : "VehicleInfo"
+ },
+ "pre_Base-1" : {
+ "rpcs" : {
+ "ChangeRegistration" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "DeleteFile" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "GenericResponse" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "ListFiles" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnAppInterfaceUnregistered" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnLanguageChange" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "OnPermissionsChange" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "PutFile" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "RegisterAppInterface" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "ResetGlobalProperties" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "SetAppIcon" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "SetDisplayLayout" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ },
+ "SetGlobalProperties" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED" ]
+ },
+ "UnregisterAppInterface" : {
+ "hmi_levels" : [ "BACKGROUND", "FULL", "LIMITED", "NONE" ]
+ }
+ }
+ }
+ },
+ "module_config" : {
+ "device_certificates" : {
+ "HUU40DAS7F970UEI17A73JH32L41K32JH4L1K234H3K4" : "aldhfkahfgkafrblgjr"
+ },
+ "endpoints" : {
+ "0x07" : {
+ "default" : [ "http://policies.telematics.ford.com/api/policies" ]
+ }
+ },
+ "exchange_after_x_days" : 30,
+ "exchange_after_x_ignition_cycles" : 100,
+ "exchange_after_x_kilometers" : 1800,
+ "notifications_per_minute_by_priority" : {
+ "COMMUNICATION" : 6,
+ "EMERGENCY" : 60,
+ "NAVIGATION" : 15,
+ "NONE" : 0,
+ "NORMAL" : 4,
+ "voiceCommunication" : 10
+ },
+ "preloaded_pt" : true,
+ "seconds_between_retries" : [ 1, 5, 25, 125, 625 ],
+ "timeout_after_x_seconds" : 60,
+ "vehicle_make" : "Stark Industries",
+ "vehicle_model" : "E-Tron",
+ "vehicle_year" : 1992
+ },
+ "module_meta" : {
+ "ccpu_version" : "4.1.2.B_EB355B",
+ "ignition_cycles_since_last_exchange" : 50,
+ "language" : "en-us",
+ "pt_exchanged_at_odometer_x" : 1903,
+ "pt_exchanged_x_days_after_epoch" : 46684,
+ "vin" : "1FAPP6242VH100001",
+ "wers_country_code" : "WAEGB"
+ },
+ "usage_and_error_counts" : {
+ "app_level" : {
+ "584421907" : {
+ "app_registration_language_gui" : "en-us",
+ "app_registration_language_vui" : "en-us",
+ "count_of_rejected_rpc_calls" : 9,
+ "count_of_rejections_duplicate_name" : 2,
+ "count_of_rejections_nickname_mismatch" : 1,
+ "count_of_rejections_sync_out_of_memory" : 0,
+ "count_of_removals_for_bad_behavior" : 6,
+ "count_of_rfcom_limit_reached" : 1,
+ "count_of_rpcs_sent_in_hmi_none" : 7,
+ "count_of_run_attempts_while_revoked" : 0,
+ "count_of_user_selections" : 7,
+ "minutes_in_hmi_background" : 123,
+ "minutes_in_hmi_full" : 123,
+ "minutes_in_hmi_limited" : 456,
+ "minutes_in_hmi_none" : 456
+ }
+ },
+ "count_of_iap_buffer_full" : 1,
+ "count_of_sync_reboots" : 123,
+ "count_sync_out_of_memory" : 3
+ }
+ }
+}