summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2014-07-09 15:18:39 -0400
committerJustin Dickow <jjdickow@gmail.com>2014-07-09 15:18:39 -0400
commit91a773dc2e78c25e098bca2c9b04cac69d11ba37 (patch)
tree2cac615d3f04338f086f236f723f520bb7760944
parent80d6a6d46b277edf83018193ed57022db6c473fa (diff)
downloadsmartdevicelink-91a773dc2e78c25e098bca2c9b04cac69d11ba37.tar.gz
add policy component
Signed-off-by: Justin Dickow <jjdickow@gmail.com>
-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.txt104
-rw-r--r--src/components/policy/src/policy/Readme.txt3
-rw-r--r--src/components/policy/src/policy/include/policy/policy_helper.h141
-rw-r--r--src/components/policy/src/policy/include/policy/policy_listener.h52
-rw-r--r--src/components/policy/src/policy/include/policy/policy_manager.h302
-rw-r--r--src/components/policy/src/policy/include/policy/policy_manager_impl.h264
-rw-r--r--src/components/policy/src/policy/include/policy/policy_table.h64
-rw-r--r--src/components/policy/src/policy/include/policy/policy_types.h237
-rw-r--r--src/components/policy/src/policy/include/policy/pt_ext_representation.h261
-rw-r--r--src/components/policy/src/policy/include/policy/pt_representation.h257
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h79
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h159
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_queries.h103
-rw-r--r--src/components/policy/src/policy/include/policy/sql_pt_representation.h163
-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.xml271
-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.cc266
-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.h143
-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.cc98
-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.cc422
-rw-r--r--src/components/policy/src/policy/src/policy_manager_impl.cc994
-rw-r--r--src/components/policy/src/policy/src/policy_table.cc63
-rw-r--r--src/components/policy/src/policy/src/sql_pt_ext_queries.cc178
-rw-r--r--src/components/policy/src/policy/src/sql_pt_ext_representation.cc1120
-rw-r--r--src/components/policy/src/policy/src/sql_pt_queries.cc574
-rw-r--r--src/components/policy/src/policy/src/sql_pt_representation.cc1157
-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.txt71
-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_pt_ext_representation.h111
-rw-r--r--src/components/policy/test/policy/include/mock_pt_representation.h103
-rw-r--r--src/components/policy/test/policy/log4cxx.properties21
-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_with_sqlite_test.cc172
-rw-r--r--src/components/policy/test/policy/src/test_policy_manager_impl.cc329
-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.cc269
-rw-r--r--src/components/policy/test/policy/src/test_sql_pt_representation.cc392
-rw-r--r--src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc252
-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
109 files changed, 13756 insertions, 0 deletions
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..e11422125
--- /dev/null
+++ b/src/components/policy/src/policy/CMakeLists.txt
@@ -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.
+
+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/
+)
+
+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 dbms policy_table_interface_base log4cxx )
+
+add_library(${target} SHARED ${SOURCES})
+target_link_libraries(${target} ${LIBRARIES})
+
+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}")
+
+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..f9bf0c87f
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_helper.h
@@ -0,0 +1,141 @@
+/*
+ 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;
+
+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 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, PermissionState 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_;
+ std::string allowed_key_;
+ std::string disallowed_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:
+ PermissionState 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_;
+};
+
+}
+
+#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..c62c19f3e
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_listener.h
@@ -0,0 +1,52 @@
+/*
+ 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) = 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 void OnCurrentDeviceIdUpdateRequired(
+ const std::string& policy_app_id) = 0;
+ virtual void OnSystemInfoUpdateRequired() = 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..7bc0e19af
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_manager.h
@@ -0,0 +1,302 @@
+/*
+ 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 pt_content PTU as binary string
+ * @return bool Success of operation
+ */
+ virtual bool LoadPT(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;
+ /**
+ * 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 Update current device id, which data should be proceeded
+ * @param device_id Current device id
+ */
+ virtual void UpdateCurrentDeviceId(const std::string& device_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;
+};
+
+} // 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..b510f5805
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_manager_impl.h
@@ -0,0 +1,264 @@
+/*
+ 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 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 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 void UpdateCurrentDeviceId(const std::string& device_id);
+
+ 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);
+
+ 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();
+
+ void SendNotificationOnPermissionsUpdated(const std::string& application_id);
+
+ static log4cxx::LoggerPtr logger_;
+ 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..571d160d1
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_table.h
@@ -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.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TABLE_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_POLICY_TABLE_H_
+
+#include "utils/logger.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:
+ static log4cxx::LoggerPtr logger_;
+ 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..5a89a0b2f
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/policy_types.h
@@ -0,0 +1,237 @@
+/*
+ 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 {
+};
+
+/*
+ *@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;
+
+/**
+ * @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 {
+ explicit CheckPermissionResult(bool hmi_level_ok = false)
+ : hmi_level_permitted(hmi_level_ok) {
+ }
+
+ ~CheckPermissionResult() {
+ hmi_level_permitted = false;
+ }
+
+ bool 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("MyDevice"),
+ device_mac_address("00:00:00:00:00:00"),
+ 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;
+};
+
+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;
+};
+
+enum PermissionState {
+ kAllowed = 0,
+ kDisallowed,
+ kUndefined
+};
+
+/**
+ * @brief Contains user permission for RPC functional group with specific name
+ * and id from DB
+ */
+struct FunctionalGroupPermission {
+ FunctionalGroupPermission()
+ : group_id(0),
+ state(kUndefined) {
+ }
+
+ std::string group_alias;
+ std::string group_name;
+ uint32_t group_id;
+ PermissionState 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 tts;
+ std::string label;
+ std::string line1;
+ std::string line2;
+ std::string text_body;
+};
+
+} // 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..a1f251c3e
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/pt_ext_representation.h
@@ -0,0 +1,261 @@
+/*
+ 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 Get user consent for application consent functional groups from DB
+ * @param device_id Device id of specific device, which hosts application
+ * @param policy_app_id Unique application id
+ * @param permissions User consents from DB
+ * @return true, if query was successfull, otherwise - false
+ */
+ virtual bool GetUserPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) = 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 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;
+};
+} // 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..04dfb9834
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/pt_representation.h
@@ -0,0 +1,257 @@
+/*
+ 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;
+
+ /**
+ * Sets default policy for application
+ * @param app_id application id
+ * @return true if success
+ */
+ virtual bool SetDefaultPolicy(const std::string& app_id) = 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..2227e3dc0
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_ext_queries.h
@@ -0,0 +1,79 @@
+/*
+ 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 kSelectPreconsentedGroupsId;
+extern const std::string kSelectFunctionalGroupNames;
+extern const std::string kSelectAppPolicies;
+extern const std::string kUpdateMetaLanguage;
+
+} // 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..aa171b906
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_ext_representation.h
@@ -0,0 +1,159 @@
+/*
+ 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 {
+
+typedef std::vector<uint32_t> FunctionalGroupIDs;
+typedef std::map<uint32_t, std::pair<std::string, std::string> > FunctionalGroupNames;
+
+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,
+ std::vector<FunctionalGroupPermission>& permissions);
+
+ 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 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;
+ }
+
+ 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;
+
+ private:
+ void GatherModuleMeta(policy_table::ModuleMeta* meta) const;
+ bool GatherApplicationPolicies(policy_table::ApplicationPolicies* apps) 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 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);
+
+ bool GetFunctionalGroupNames(FunctionalGroupNames& names);
+
+ void FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids, FunctionalGroupNames& names,
+ PermissionState 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..f39e11c14
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_queries.h
@@ -0,0 +1,103 @@
+/*
+ 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 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..78b7c0e21
--- /dev/null
+++ b/src/components/policy/src/policy/include/policy/sql_pt_representation.h
@@ -0,0 +1,163 @@
+/*
+ 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 "utils/logger.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;
+ bool IsDefaultPolicy(const std::string& app_id) const;
+ bool SetDefaultPolicy(const std::string& app_id);
+
+ dbms::SQLDatabase* db() const {
+ return db_;
+ }
+ static log4cxx::LoggerPtr logger() {
+ return logger_;
+ }
+
+ private:
+ static const std::string kDatabaseName;
+ static log4cxx::LoggerPtr logger_;
+ 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);
+ bool SetIsDefault(const std::string& app_id, bool is_default);
+};
+} // 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..13840a45a
--- /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" />
+ </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 -->
+ <struct name="Dummy">
+ <description>
+ Typedefs won't proceeded until first struct
+ definition
+ To be removed after typedef issue fix within
+ generator code
+ </description>
+ </struct>
+
+ <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" />
+ <param name="watchdog_timer_ms" type="Integer" minvalue="1"
+ maxvalue="65225" />
+ <param name="certificate" type="String" minlegth="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" />
+ </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="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="255" />
+ <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" maxvalue="255"
+ 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="255" mandatory="false" />
+ <param name="label" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="textBody" type="String" maxlength="255"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="Languages" map="true" type="MessageString"
+ maxsize="255" 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" />
+ <param name="usage_and_error_counts" type="UsageAndErrorCounts" />
+ <param name="device_data" type="DeviceData" />
+ </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..d971c9192
--- /dev/null
+++ b/src/components/policy/src/policy/policy_table_interface_ext.xml
@@ -0,0 +1,271 @@
+<?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" />
+ </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" />
+ <param name="watchdog_timer_ms" type="Integer" minvalue="1"
+ maxvalue="65225" />
+ <param name="certificate" type="String" minlegth="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" />
+ </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="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="255" />
+ <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" maxvalue="255"
+ 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="255" mandatory="false" />
+ <param name="label" type="String" maxlength="255"
+ mandatory="false" />
+ <param name="textBody" type="String" maxlength="255"
+ mandatory="false" />
+ </struct>
+
+ <typedef name="Languages" map="true" type="MessageString"
+ maxsize="255" 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" />
+ <param name="app_registration_language_vui" type="String" />
+ <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" />
+ </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" 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" 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" />
+ <param name="usage_and_error_counts" type="UsageAndErrorCounts" />
+ <param name="device_data" type="DeviceData" />
+ </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..051569f29
--- /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..c2792f3f2
--- /dev/null
+++ b/src/components/policy/src/policy/qdb_wrapper/src/sql_query.cc
@@ -0,0 +1,266 @@
+/**
+ * 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();
+}
+
+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..0e799c205
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/include/sqlite_wrapper/sql_database.h
@@ -0,0 +1,143 @@
+/**
+ * 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;
+
+ 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..d7a4b10bb
--- /dev/null
+++ b/src/components/policy/src/policy/sqlite_wrapper/src/sql_database.cc
@@ -0,0 +1,98 @@
+/**
+ * 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_;
+}
+
+} // 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..c41045f1a
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_helper.cc
@@ -0,0 +1,422 @@
+/*
+ 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 "policy/policy_helper.h"
+#include "policy/policy_manager_impl.h"
+
+namespace policy {
+
+namespace {
+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(pm_->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(pm_->logger_, "Send notification for application_id:" << app_id);
+ pm_->listener()->OnPermissionsUpdated(app_id, notification_data);
+}
+
+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;
+ 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::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
+ (*it).second = app_policy.second;
+ 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 (HasSameGroups(app_policy, &permissions_diff)) {
+ LOG4CXX_INFO(
+ pm_->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 ("default" != app_id && "device" != 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,
+ PermissionState group_state)
+ : data_(data),
+ allowed_key_("allowed"),
+ disallowed_key_("userDisallowed") {
+ switch (group_state) {
+ case kAllowed:
+ case kUndefined:
+ current_key_ = allowed_key_;
+ break;
+ default:
+ current_key_ = disallowed_key_;
+ 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_]);
+ 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_]);
+ 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[allowed_key_];
+ std::set<HMILevel>& disallowed_hmi_level =
+ (*it).second.hmi_permissions[disallowed_key_];
+ 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[allowed_key_];
+ std::set<Parameter>& disallowed_parameters =
+ (*it).second.parameter_permissions[disallowed_key_];
+
+ 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;
+}
+
+PermissionState 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 kUndefined;
+}
+
+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);
+ }
+}
+
+}
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..bd08694f2
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_manager_impl.cc
@@ -0,0 +1,994 @@
+/*
+ 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"
+
+policy::PolicyManager* CreateManager() {
+ return new policy::PolicyManagerImpl();
+}
+
+namespace policy {
+log4cxx::LoggerPtr PolicyManagerImpl::logger_ = log4cxx::LoggerPtr(
+ log4cxx::Logger::getLogger("PolicyManagerImpl"));
+
+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;
+ reader.parse(json.c_str(), value);
+ return new policy_table::Table(&value);
+}
+
+bool PolicyManagerImpl::LoadPT(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;
+ }
+
+ set_exchange_in_progress(false);
+
+ // Temporary disabled until correct json will be prepared
+ // if (!table->is_valid()) {
+ // LOG4CXX_WARN(logger_, "Parsed table is not valid.");
+ // 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();
+ Json::FastWriter writer;
+ std::string message_string = writer.write(value);
+ LOG4CXX_INFO(logger_, "PT Snapshot " << message_string);
+ 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.");
+
+ const std::string device_id = GetCurrentDeviceId(app_id);
+ if (kDeviceHasNoConsent == GetUserConsentForDevice(device_id)) {
+ return policy_table_.pt_data()->CheckPermissions("pre_DataConsent",
+ hmi_level, rpc);
+ }
+
+#if defined (EXTENDED_POLICY)
+ // 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_permissions.end() == rpc_permissions.find(rpc)) {
+ return result;
+ }
+
+ // Add parameters of RPC, if any
+ result.list_of_allowed_params = new std::vector<PTString>();
+ std::copy(rpc_permissions[rpc].parameter_permissions["allowed"].begin(),
+ rpc_permissions[rpc].parameter_permissions["allowed"].end(),
+ result.list_of_allowed_params->begin());
+
+ // Check HMI level
+ if (rpc_permissions[rpc].hmi_permissions["allowed"].end() !=
+ rpc_permissions[rpc].hmi_permissions["allowed"].find(hmi_level)) {
+ result.hmi_level_permitted = true;
+ }
+
+ 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");
+ if (!policy_table_.pt_data()->IsApplicationRepresented(application_id)) {
+ LOG4CXX_INFO(
+ logger_,
+ "Setting default permissions for application id: " << application_id);
+ policy_table_.pt_data()->SetDefaultPolicy(application_id);
+ SendNotificationOnPermissionsUpdated(application_id);
+ } else {
+ if (!policy_table_.pt_data()->IsDefaultPolicy(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);
+ listener()->OnPermissionsUpdated(application_id, notification_data);
+}
+
+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;
+ // TODO(AOleynik): Change id to appropriate value (MAC with SHA-256)
+ 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::inserter(to_be_consented_by_user,
+ to_be_consented_by_user.begin()));
+ 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]);
+ }
+
+ // TODO(AOleynik): Change id to appropriate value (MAC with SHA-256)
+ if (!pt_ext->SetUserPermissionsForDevice(device_id, consented_groups,
+ disallowed_groups)) {
+ LOG4CXX_WARN(logger_, "Can't set user consent for device");
+ return;
+ }
+#endif
+}
+
+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) {
+ // TODO(AOleynik): Change id to appropriate value (MAC with SHA-256)
+ 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);
+
+ listener()->OnPermissionsUpdated(permissions.policy_app_id,
+ notification_data);
+ }
+#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);
+ }
+
+ // For basic policy
+ return policy_table_.pt_data()->GetUserFriendlyMsg(message_code, language);
+#else
+ return std::vector<UserFriendlyMessage>(message_code.size());
+#endif
+}
+
+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)
+ // 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) {
+ pt_ext->GetUserPermissionsForApp(device_id, policy_app_id, permissions);
+ return;
+ }
+#else
+ // For basic policy
+ permissions = std::vector<FunctionalGroupPermission>();
+#endif
+}
+
+void PolicyManagerImpl::UpdateCurrentDeviceId(const std::string& device_id) {
+ LOG4CXX_INFO(logger_, "UpdateDeviceInfo");
+ last_device_id_ = device_id;
+}
+
+std::string& PolicyManagerImpl::GetCurrentDeviceId(
+ const std::string& policy_app_id) {
+ LOG4CXX_INFO(logger_, "GetDeviceInfo");
+ 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_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);
+}
+
+} // 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..74ac7ebb1
--- /dev/null
+++ b/src/components/policy/src/policy/src/policy_table.cc
@@ -0,0 +1,63 @@
+/*
+ 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
+
+namespace policy {
+
+log4cxx::LoggerPtr PolicyTable::logger_ = log4cxx::LoggerPtr(
+ log4cxx::Logger::getLogger("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..49955af0d
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_ext_queries.cc
@@ -0,0 +1,178 @@
+/*
+ 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 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`";
+
+
+
+} // 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..47f16b29d
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_ext_representation.cc
@@ -0,0 +1,1120 @@
+/*
+ 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 "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 {
+
+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() {
+ dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kResetUserConsent)) {
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+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,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_INFO(logger(), "GetUserPermissionsForApp");
+ // 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 group names
+ FunctionalGroupNames names;
+ if (!GetFunctionalGroupNames(names)) {
+ return false;
+ }
+
+ 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());
+
+ // 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 undefined_consent;
+ std::set_difference(no_allowed_preconsented.begin(), no_allowed_preconsented.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 common_allowed(preconsented_allowed.begin(),
+ std::unique(preconsented_allowed.begin(), preconsented_allowed.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));
+
+ // Fill result
+ FillFunctionalGroupPermissions(undefined_consent, names, kUndefined, permissions);
+ FillFunctionalGroupPermissions(common_allowed, names, kAllowed, permissions);
+ FillFunctionalGroupPermissions(common_disallowed, names, kDisallowed, permissions);
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetDeviceGroupsFromPolicies(
+ policy_table::Strings* groups, policy_table::Strings* preconsented_groups) {
+ LOG4CXX_INFO(logger(), "GetDeviceGroupsFromPolicies");
+ if (groups) {
+ GatherAppGroup("device", groups);
+ }
+ if (preconsented_groups) {
+ GatherPreconsentedGroup("device", 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::SetUserPermissionsForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_INFO(logger(), "SetUserPermissionsForApp");
+ // TODO(AOleynik): Handle situation, when no application was specified, i.e.
+ // general permissions were set
+ dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateGroupPermissions)) {
+ LOG4CXX_WARN(logger(),
+ "Incorrect statement for update app group permissions.");
+ return false;
+ }
+
+ std::vector<FunctionalGroupPermission>::const_iterator it = permissions
+ .group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end = permissions
+ .group_permissions.end();
+ for (; it != it_end; ++it) {
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, (*it).state);
+ 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;
+ }
+ }
+
+ 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.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;
+ }
+
+ 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)));
+ 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;
+ }
+ if (!SaveNickname(it->first, it->second.nicknames)) {
+ return false;
+ }
+ if (!SaveAppType(it->first, it->second.AppHMIType)) {
+ return false;
+ }
+ 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()) {
+ 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;
+ }
+ if (!GatherNickName(app_id, &params.nicknames)) {
+ return false;
+ }
+ if (!GatherAppType(app_id, &params.AppHMIType)) {
+ return false;
+ }
+ 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);
+
+ 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"
+ policy_table::ConsentRecords* device_consent_records = &(*records)["device"];
+
+ while (query.Next()) {
+ (*device_consent_records).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)];
+ (*app_consent_records).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;
+ }
+
+ 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) {
+ 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 ("device" == 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, PermissionState 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() || !query.Reset()) {
+ 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;
+}
+
+} // 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..ce81b54e6
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_queries.cc
@@ -0,0 +1,574 @@
+/*
+ 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 AUTOINCREMENT 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, "
+ " `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, "
+ " `minutes_in_hmi_limited` INTEGER, "
+ " `minutes_in_hmi_background` INTEGER, "
+ " `minutes_in_hmi_none` INTEGER, "
+ " `count_of_rfcom_limit_reached` INTEGER, "
+ " `count_of_user_selections` INTEGER, "
+ " `count_of_rejections_sync_out_of_memory` INTEGER, "
+ " `count_of_rejections_nickname_mismatch` INTEGER, "
+ " `count_of_rejections_duplicate_name` INTEGER, "
+ " `count_of_rejected_rpcs_calls` INTEGER, "
+ " `count_of_rpcs_sent_in_hmi_none` INTEGER, "
+ " `count_of_removals_for_bad_behavior` INTEGER, "
+ " `count_of_run_attempts_while_revoked` INTEGER, "
+ " `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 AUTOINCREMENT 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` = ?";
+
+} // 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..742816e09
--- /dev/null
+++ b/src/components/policy/src/policy/src/sql_pt_representation.cc
@@ -0,0 +1,1157 @@
+/*
+ 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 "policy/sql_pt_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+
+namespace policy {
+
+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
+
+log4cxx::LoggerPtr SQLPTRepresentation::logger_ = log4cxx::LoggerPtr(
+ log4cxx::Logger::getLogger("SQLPTRepresentation"));
+
+const std::string SQLPTRepresentation::kDatabaseName = "policy";
+
+SQLPTRepresentation::SQLPTRepresentation()
+ : db_(new dbms::SQLDatabase(kDatabaseName)) {
+}
+
+SQLPTRepresentation::~SQLPTRepresentation() {
+ db_->Close();
+ delete db_;
+}
+
+CheckPermissionResult SQLPTRepresentation::CheckPermissions(
+ const PTString& app_id, const PTString& hmi_level, const PTString& rpc) {
+ CheckPermissionResult result(false);
+ 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;
+ LOG4CXX_INFO(
+ logger_,
+ "Level is "
+ << (result.hmi_level_permitted ? "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) {
+ return std::vector<UserFriendlyMessage>();
+}
+
+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_INFO(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");
+ // 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[endpoints.GetString(2)][stream.str()]
+ .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)) {
+ while (query.Next()) {
+ counts->app_level[query.GetString(0)] = policy_table::AppLevel();
+ }
+ }
+ 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)) {
+ while (query.Next()) {
+ (*data)[query.GetString(0)] = policy_table::DeviceParams();
+ }
+ }
+}
+
+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;
+ 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;
+ policy_table::EnumFromJsonString(rpcs.GetString(2), &param);
+ 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()) {
+ policy_table::ApplicationParams params;
+ const std::string& app_id = query.GetString(0);
+ 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;
+ }
+ if (!GatherNickName(app_id, &params.nicknames)) {
+ return false;
+ }
+ 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;
+ 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;
+ }
+ if (!SaveNickname(it->first, it->second.nicknames)) {
+ return false;
+ }
+ 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;
+ 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;
+ for (it = counts.app_level.begin(); it != counts.app_level.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::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["default"];
+ if (!SaveApplicationPolicies(apps)) {
+ LOG4CXX_WARN(logger_, "Failed saving application policies");
+ return false;
+ }
+
+ return SetIsDefault(app_id, 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 updatign 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;
+}
+
+} // 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..bbecdd593
--- /dev/null
+++ b/src/components/policy/test/policy/CMakeLists.txt
@@ -0,0 +1,71 @@
+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/usage_statistics/include
+ ${CMAKE_SOURCE_DIR}/src/components/utils/include/
+)
+
+set(LIBRARIES
+ gtest
+ gtest_main
+ gmock
+ gmock_main
+ dl
+ Policy
+ ConfigProfile
+)
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ list(REMOVE_ITEM LIBRARIES dl)
+endif()
+
+set(SHARED_LIBRARY_SOURCES
+ ./src/test_shared_library.cc
+)
+
+set(SQL_PT_REPRESENTATION_SOURCES
+ ./src/test_sql_pt_representation.cc
+)
+
+if (EXTENDED_POLICY_FLAG)
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(SQL_PT_EXT_REPRESENTATION_SOURCES
+ ./src/test_sql_pt_ext_representation.cc
+ )
+ create_test("test_SQLPTExtRepresentation" "${SQL_PT_EXT_REPRESENTATION_SOURCES}" "${LIBRARIES}")
+ endif ()
+endif ()
+
+set(GENERATED_CODE_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 (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # --- Tests for SQLite Wrapper
+ add_subdirectory(sqlite_wrapper)
+ create_test("test_generated_code_with_sqlite" "${GENERATED_CODE_SOURCES}" "${LIBRARIES}")
+ create_test("test_SQLPTRepresentation" "${SQL_PT_REPRESENTATION_SOURCES}" "${LIBRARIES}")
+endif()
+
+create_test("test_SharedLibrary" "${SHARED_LIBRARY_SOURCES}" "${LIBRARIES}")
+create_test("test_PolicyManagerImpl" "${POLICY_MANAGER_IMPL_SOURCES}" "${LIBRARIES}")
+create_test("test_stress_PolicyManagerImpl" "${STRESS_POLICY_MANAGER_IMPL_SOURCES}" "${LIBRARIES}")
+
+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_pt_ext_representation.h b/src/components/policy/test/policy/include/mock_pt_ext_representation.h
new file mode 100644
index 000000000..ede173dc9
--- /dev/null
+++ b/src/components/policy/test/policy/include/mock_pt_ext_representation.h
@@ -0,0 +1,111 @@
+/* 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&,
+ std::vector<FunctionalGroupPermission>&));
+ 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));
+};
+
+} // 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..69616f6f8
--- /dev/null
+++ b/src/components/policy/test/policy/include/mock_pt_representation.h
@@ -0,0 +1,103 @@
+/* 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));
+};
+
+}
+// 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/sqlite_wrapper/CMakeLists.txt b/src/components/policy/test/policy/sqlite_wrapper/CMakeLists.txt
new file mode 100644
index 000000000..e95ce95b4
--- /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_impl/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_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..d52af67ab
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_policy_manager_impl.cc
@@ -0,0 +1,329 @@
+/* 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_pt_representation.h"
+#include "mock_pt_ext_representation.h"
+#include "policy/policy_table.h"
+#include "policy/policy_manager_impl.h"
+#include "json/writer.h"
+
+using ::testing::_;
+using ::testing::Return;
+using ::testing::DoAll;
+using ::testing::SetArgPointee;
+
+using ::policy::PTRepresentation;
+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(7));
+}
+
+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());
+}
+
+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);
+}
+
+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;
+
+ ::policy::CheckPermissionResult result;
+ result.hmi_level_permitted = true;
+ result.list_of_allowed_params = new std::vector< ::policy::PTString>();
+ result.list_of_allowed_params->push_back("FULL");
+ result.list_of_allowed_params->push_back("NONE");
+ result.list_of_allowed_params->push_back("LIMITED");
+ result.list_of_allowed_params->push_back("BACKGROUND");
+
+ ::policy::PTString app_id = "12345678";
+ ::policy::PTString hmi_level = "FULL";
+ ::policy::PTString rpc = "Alert";
+
+ EXPECT_CALL(mock_pt, CheckPermissions(app_id, hmi_level, rpc)).WillOnce(
+ Return(result));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ ::policy::CheckPermissionResult out_result = manager->CheckPermissions(
+ app_id, hmi_level, rpc);
+ EXPECT_TRUE(out_result.hmi_level_permitted == true);
+}
+
+TEST_F(PolicyManagerImplTest, LoadPT) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ ::policy_table::Table table;
+ Json::Value value = table.ToJsonValue();
+ Json::FastWriter writer;
+ std::string json = writer.write(value);
+ ::policy::BinaryMessage msg(json.begin(), json.end());
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+
+ // TODO(AOleynik): Validation is not enabled yet, so test fails
+ // TODO(AOleynik): Segfault occurs, check
+ //EXPECT_FALSE(manager->LoadPT(msg));
+}
+
+TEST_F(PolicyManagerImplTest, RequestPTUpdate) {
+ ::testing::NiceMock<MockPTRepresentation> mock_pt;
+
+ ::utils::SharedPtr< ::policy_table::Table> p_table =
+ new ::policy_table::Table();
+ Json::Value value = p_table.get()->ToJsonValue();
+ Json::FastWriter writer;
+ std::string json(writer.write(value));
+ ::policy::BinaryMessageSptr p_msg = new ::policy::BinaryMessage(json.begin(),
+ json.end());
+
+ EXPECT_CALL(mock_pt, GenerateSnapshot()).WillOnce(Return(p_table));
+
+ PolicyManagerImpl* manager = new PolicyManagerImpl();
+ manager->ResetDefaultPT(::policy::PolicyTable(&mock_pt));
+ ::policy::BinaryMessageSptr p_result = manager->RequestPTUpdate();
+ EXPECT_TRUE(*p_msg.get() == *p_result.get());
+}
+
+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());
+}
+
+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..178fdb749
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_sql_pt_ext_representation.cc
@@ -0,0 +1,269 @@
+/* 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() {
+ sqlite3_open(kFileName.c_str(), &conn);
+ reps = new SQLPTExtRepresentation;
+ EXPECT_TRUE(reps->Init());
+ 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";
+
+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("");
+ module_meta["language"] = Json::Value("");
+ module_meta["wers_country_code"] = Json::Value("");
+ 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("");
+
+ 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"]["default"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["default"]["default"] = Json::Value(
+ Json::arrayValue);
+ module_config["endpoints"]["default"]["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(14);
+
+ 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);
+// usage_and_error_counts["app_level"] = Json::Value(Json::objectValue);
+ // this map is not mandatory but is_valid returns false if map is empty
+// 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& 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);
+
+ policy_table::Table table(&expect);
+
+ //TODO(KKolodiy): temporarily validation is turned off
+// EXPECT_TRUE(table.is_valid());
+ ASSERT_TRUE(reps->Save(table));
+ utils::SharedPtr<policy_table::Table> snapshot = reps->GenerateSnapshot();
+// EXPECT_TRUE(snapshot->is_valid());
+ EXPECT_EQ(expect.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`, `keep_context`) VALUES ('12345', 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`, `steal_focus`) VALUES ('12345', 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..869b111f5
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_sql_pt_representation.cc
@@ -0,0 +1,392 @@
+/* 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_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 {
+
+class SQLPTRepresentationTest : public ::testing::Test {
+ protected:
+ static sqlite3* conn;
+ static SQLPTRepresentation* reps;
+ static const std::string kFileName;
+
+ static void SetUpTestCase() {
+ sqlite3_open(kFileName.c_str(), &conn);
+ reps = new SQLPTRepresentation;
+ EXPECT_TRUE(reps->Init());
+ 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* SQLPTRepresentationTest::conn = 0;
+SQLPTRepresentation* SQLPTRepresentationTest::reps = 0;
+const std::string SQLPTRepresentationTest::kFileName = "policy.sqlite";
+
+TEST_F(SQLPTRepresentationTest, CheckPermissionsAllowed) {
+ const char* query =
+ "INSERT OR REPLACE INTO `application` (`id`) VALUES ('12345'); "
+ "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_EQ(SQLITE_OK, sqlite3_exec(conn, query, NULL, NULL, NULL));
+
+ CheckPermissionResult ret(false);
+ ret = reps->CheckPermissions("12345", "FULL", "Update");
+ ASSERT_TRUE(ret.hmi_level_permitted);
+ 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`) VALUES ('12345'); "
+ "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_EQ(SQLITE_OK, sqlite3_exec(conn, query, NULL, NULL, NULL));
+
+ CheckPermissionResult ret(false);
+ ret = reps->CheckPermissions("12345", "LIMITED", "Update");
+ EXPECT_TRUE(ret.hmi_level_permitted);
+ EXPECT_TRUE(!ret.list_of_allowed_params);
+}
+
+TEST_F(SQLPTRepresentationTest, CheckPermissionsDisallowed) {
+ const char* query = "DELETE FROM `app_group`";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query, NULL, NULL, NULL));
+
+ CheckPermissionResult ret;
+ ret = reps->CheckPermissions("12345", "FULL", "Update");
+ EXPECT_FALSE(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_EQ(SQLITE_OK, sqlite3_exec(conn, query, NULL, NULL, NULL));
+ EXPECT_TRUE(reps->IsPTPreloaded());
+}
+
+TEST_F(SQLPTRepresentationTest, GetUpdateUrls) {
+ const char* query_delete = "DELETE FROM `endpoint`; ";
+ ASSERT_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_insert, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_zeros, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_less_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_more_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_current, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_zeros, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_last, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_zeros, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK,
+ sqlite3_exec(conn, query_negative_last, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_limit, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_delete, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query_insert, NULL, NULL, NULL));
+ 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_EQ(SQLITE_OK, sqlite3_exec(conn, query, NULL, NULL, NULL));
+ EXPECT_EQ(60, reps->TimeoutResponse());
+}
+
+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);
+
+ 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"]["default"] = Json::Value(Json::objectValue);
+ module_config["endpoints"]["default"]["default"] = Json::Value(Json::arrayValue);
+ module_config["endpoints"]["default"]["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(14);
+
+ Json::Value& usage_and_error_counts = policy_table["usage_and_error_counts"];
+ usage_and_error_counts["app_level"] = Json::Value(Json::objectValue);
+ // this map is not mandatory but is_valid returns false if map is empty
+ 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& consumer_friendly_messages = policy_table["consumer_friendly_messages"];
+ consumer_friendly_messages["version"] = Json::Value("1.2");
+
+ Json::Value& default_policies = policy_table["app_policies"]["default"];
+ default_policies["default_hmi"] = "BACKGROUND";
+ default_policies["keep_context"] = false;
+ default_policies["priority"] = "EMERGENCY";
+ default_policies["steal_focus"] = false;
+
+ 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;
+
+ policy_table::Table table(&expect);
+
+ //TODO(KKolodiy): temporarily validation is turned off
+ // EXPECT_TRUE(table.is_valid());
+ ASSERT_TRUE(reps->Save(table));
+ utils::SharedPtr<policy_table::Table> snapshot = reps->GenerateSnapshot();
+ // EXPECT_TRUE(snapshot->is_valid());
+ EXPECT_EQ(expect.toStyledString(), snapshot->ToJsonValue().toStyledString());
+}
+
+} // 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..c63a45356
--- /dev/null
+++ b/src/components/policy/test/policy/src/test_stress_policy_manager_impl.cc
@@ -0,0 +1,252 @@
+/* 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 <string>
+#include <set>
+#include <sstream>
+#include <fstream>
+#include "policy/policy_manager_impl.h"
+
+using policy::PolicyManagerImpl;
+using policy::BinaryMessage;
+
+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) {
+ EXPECT_TRUE(
+ manager->CheckPermissions("2", "FULL", "Func-1").hmi_level_permitted);
+}
+
+TEST_F(PolicyManagerImplTest, StressTestNoPermission) {
+ EXPECT_FALSE(
+ manager->CheckPermissions("150", "FULL", "Func-400").hmi_level_permitted);
+}
+
+TEST_F(PolicyManagerImplTest, StressTestFewChecks) {
+ 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;
+ EXPECT_TRUE(
+ manager->CheckPermissions(app_number, "FULL", "Func-" + func_number)
+ .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/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