summaryrefslogtreecommitdiff
path: root/src/components/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/utils')
-rw-r--r--src/components/utils/CMakeLists.txt1
-rw-r--r--src/components/utils/include/utils/optional.h83
-rw-r--r--src/components/utils/include/utils/system_time_handler.h151
-rw-r--r--src/components/utils/include/utils/timer.h2
-rw-r--r--src/components/utils/src/lock_posix.cc13
-rw-r--r--src/components/utils/src/system_time_handler.cc (renamed from src/components/utils/test/atomic_object_test.cc)41
-rw-r--r--src/components/utils/test/conditional_variable_test.cc2
-rw-r--r--src/components/utils/test/data_accessor_test.cc36
8 files changed, 289 insertions, 40 deletions
diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt
index 46acf76e89..6449f123a4 100644
--- a/src/components/utils/CMakeLists.txt
+++ b/src/components/utils/CMakeLists.txt
@@ -38,6 +38,7 @@ include_directories (
${COMPONENTS_DIR}/config_profile/include
${COMPONENTS_DIR}/media_manager/include
${COMPONENTS_DIR}/protocol_handler/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
${LOG4CXX_INCLUDE_DIRECTORY}
)
diff --git a/src/components/utils/include/utils/optional.h b/src/components/utils/include/utils/optional.h
new file mode 100644
index 0000000000..0395945de0
--- /dev/null
+++ b/src/components/utils/include/utils/optional.h
@@ -0,0 +1,83 @@
+#ifndef ERROR_OR_H
+#define ERROR_OR_H
+#include <string>
+#include "utils/macro.h"
+
+namespace utils {
+
+/**
+ * @brief The Optional class is able to keep value, manage it it is empty and
+ * specify error code.
+ * Can be used as return value of function that is not guarantee that vaue will
+ * be returned
+ *
+ */
+template <typename ObjectType, typename ErrorType = std::string>
+class Optional {
+ public:
+ /**
+ * @brief The OptionalEmpty enum enum with one value to specify that Optional
+ * is not initialized
+ */
+ enum OptionalEmpty { EMPTY };
+
+ /**
+ * @brief Optional constructor with object initialization
+ * @param object object to initialize Optional
+ */
+ Optional(ObjectType& object)
+ : object_(&object), error_(), is_initialized_(true) {}
+
+ /**
+ * @brief Optional constructor with object and error initialization
+ * @param object object to initialize Optional
+ * @param error error code initialization
+ */
+ Optional(ObjectType& object, ErrorType error)
+ : object_(&object), error_(error), is_initialized_(true) {}
+
+ /**
+ * @brief Optional constructir without object initialization
+ * @param empty manadatory parameter for explicit specifying that Optional is
+ * empty
+ * @param error error code initialization
+ */
+ Optional(OptionalEmpty empty, ErrorType error)
+ : object_(nullptr), error_(error), is_initialized_(false) {}
+
+ /**
+ * @brief Optional empty optional initialization without specifying error code
+ * @param empty manadatory parameter for explicit specifying that Optional is
+ * empty
+ */
+ Optional(OptionalEmpty empty)
+ : object_(nullptr), error_(), is_initialized_(false) {}
+
+ /**
+ * @brief operator bool operator for checking if optional is initialized
+ */
+ operator bool() const {
+ return is_initialized_;
+ }
+
+ /**
+ * @brief operator * access to object
+ * @return
+ */
+ ObjectType& operator*() const {
+ DCHECK(is_initialized_);
+ return *object_;
+ }
+
+ ErrorType error() const {
+ return error_;
+ }
+
+ private:
+ ObjectType* object_;
+ ErrorType error_;
+ bool is_initialized_;
+};
+
+} // utils utils
+#endif // ERROR_OR_H
diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h
new file mode 100644
index 0000000000..15b2dd0cca
--- /dev/null
+++ b/src/components/utils/include/utils/system_time_handler.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018, 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_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
+
+#include <time.h>
+
+namespace utils {
+
+/**
+ * @brief The SystemTimeListener interface.
+ * This interface allows to get notifications whenever
+ * system time appears or fails to appear.
+ */
+class SystemTimeListener {
+ public:
+ /**
+ * @brief OnSystemTimeArrived Notify about system time
+ * in utc format
+ * @param utc_time current system time.
+ */
+ virtual void OnSystemTimeArrived(const time_t utc_time) = 0;
+};
+
+/**
+ * @brief SystemTimeHandler the interface which provides the necessary
+ * public API to work with system time. The class does not implement
+ * any logic it's public api forwards call to the private virtual
+ * methods which are suppose to be defined within specific implementation.
+ */
+class SystemTimeHandler {
+ public:
+ /**
+ * @brief SystemTimeHandler creates an instance
+ * for this class.
+ */
+ SystemTimeHandler();
+
+ /**
+ * @brief QuerySystemTime provides the public interface
+ * to retrieve the system time. Interface uses private implementation
+ * hence the logic will be defined within descendant class.
+ */
+ void QuerySystemTime();
+
+ /**
+ * @brief SubscribeOnSystemTime allows to subscribe listener
+ * to the certain event. This class does not provide such storage.
+ * It rather uses private pure virtual function. So the final behaviour
+ * should be defined within the descendant class
+ */
+ void SubscribeOnSystemTime(SystemTimeListener* listener);
+
+ /**
+ * @brief UnsubscribeFromSystemTime allows to unsubscribe listener
+ * from the certain event. This class does not manipulate with storage.
+ * It rather uses private pure virtual function. So the final behaviour
+ * should be defined within the descendant class
+ */
+ void UnsubscribeFromSystemTime(SystemTimeListener* listener);
+
+ /**
+ * @brief GetUTCTime allows to obtain cached result for the
+ * GetSystemTime request
+ * @return utc time.
+ */
+ time_t GetUTCTime();
+
+ /**
+ * @brief Checks if system time is ready
+ * and can be requested by GetSystemTime request
+ * @return True if HMI is ready to provide UTC time
+ * otherwise False
+ */
+ bool system_time_can_be_received() const;
+
+ /**
+ * @brief ~SystemTimeHandler destroys the object
+ */
+ virtual ~SystemTimeHandler();
+
+ private:
+ /**
+ * @brief DoSystemTimeQuery responsible for the system time querying.
+ * It is up to implementator how exactly system is going to receive this time.
+ */
+ virtual void DoSystemTimeQuery() = 0;
+
+ /**
+ * @brief DoSubscribe implements the logic which allows to handle
+ * subscription process. The handling logic should be defined within
+ * descendant class.
+ */
+ virtual void DoSubscribe(SystemTimeListener* listener) = 0;
+
+ /**
+ * @brief DoUnsubscribe implements the logic which allows to handle
+ * unsubscription process. The handling logic should be defined within
+ * descendant class.
+ */
+ virtual void DoUnsubscribe(SystemTimeListener* listener) = 0;
+
+ /**
+ * @brief FetchSystemTime allows to obtain the cached result
+ * for the GetSystemTime request.
+ * @return utc time.
+ */
+ virtual time_t FetchSystemTime() = 0;
+
+ /**
+ * @brief Checks if UTC time is ready to provided by HMI
+ * and can be requested by GetSystemTime request
+ * @return True if HMI is ready to provide UTC time
+ * otherwise False
+ */
+ virtual bool utc_time_can_be_received() const = 0;
+};
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
diff --git a/src/components/utils/include/utils/timer.h b/src/components/utils/include/utils/timer.h
index ab3d48ef6f..e391db992c 100644
--- a/src/components/utils/include/utils/timer.h
+++ b/src/components/utils/include/utils/timer.h
@@ -218,7 +218,7 @@ class Timer {
mutable sync_primitives::Lock state_lock_;
- mutable std::auto_ptr<TimerDelegate> delegate_;
+ mutable std::unique_ptr<TimerDelegate> delegate_;
threads::Thread* thread_;
/**
diff --git a/src/components/utils/src/lock_posix.cc b/src/components/utils/src/lock_posix.cc
index 0f795bb669..2807de1d0a 100644
--- a/src/components/utils/src/lock_posix.cc
+++ b/src/components/utils/src/lock_posix.cc
@@ -63,14 +63,16 @@ Lock::Lock(bool is_recursive)
Lock::~Lock() {
#ifndef NDEBUG
if (lock_taken_ > 0) {
- LOG4CXX_ERROR(logger_, "Destroying non-released mutex " << &mutex_);
+ LOG4CXX_FATAL(logger_, "Destroying non-released mutex " << &mutex_);
+ NOTREACHED();
}
#endif
int32_t status = pthread_mutex_destroy(&mutex_);
if (status != 0) {
- LOG4CXX_ERROR(logger_,
+ LOG4CXX_FATAL(logger_,
"Failed to destroy mutex " << &mutex_ << ": "
<< strerror(status));
+ NOTREACHED();
}
}
@@ -90,9 +92,10 @@ void Lock::Release() {
AssertTakenAndMarkFree();
const int32_t status = pthread_mutex_unlock(&mutex_);
if (status != 0) {
- LOG4CXX_ERROR(logger_,
+ LOG4CXX_FATAL(logger_,
"Failed to unlock mutex" << &mutex_ << ": "
<< strerror(status));
+ NOTREACHED();
}
}
@@ -110,14 +113,14 @@ bool Lock::Try() {
#ifndef NDEBUG
void Lock::AssertFreeAndMarkTaken() {
if ((lock_taken_ > 0) && !is_mutex_recursive_) {
- LOG4CXX_ERROR(logger_, "Locking already taken not recursive mutex");
+ LOG4CXX_FATAL(logger_, "Locking already taken not recursive mutex");
NOTREACHED();
}
lock_taken_++;
}
void Lock::AssertTakenAndMarkFree() {
if (lock_taken_ == 0) {
- LOG4CXX_ERROR(logger_, "Unlocking a mutex that is not taken");
+ LOG4CXX_FATAL(logger_, "Unlocking a mutex that is not taken");
NOTREACHED();
}
lock_taken_--;
diff --git a/src/components/utils/test/atomic_object_test.cc b/src/components/utils/src/system_time_handler.cc
index 44975fd004..0c3c62cc53 100644
--- a/src/components/utils/test/atomic_object_test.cc
+++ b/src/components/utils/src/system_time_handler.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Ford Motor Company
+ * Copyright (c) 2018, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,28 +30,33 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "utils/atomic_object.h"
-#include "gtest/gtest.h"
+#include "utils/system_time_handler.h"
-namespace test {
-namespace components {
-namespace utils_test {
+namespace utils {
-TEST(AtomicObjectTest, Construct) {
- sync_primitives::atomic_int var(5);
- EXPECT_EQ(5, var);
+SystemTimeHandler::SystemTimeHandler() {}
- var = 8;
- EXPECT_EQ(8, var);
+SystemTimeHandler::~SystemTimeHandler() {}
- sync_primitives::atomic_bool flag = true;
+void SystemTimeHandler::QuerySystemTime() {
+ DoSystemTimeQuery();
+}
+
+void SystemTimeHandler::SubscribeOnSystemTime(SystemTimeListener* listener) {
+ DoSubscribe(listener);
+}
- EXPECT_TRUE(flag == true);
+void SystemTimeHandler::UnsubscribeFromSystemTime(
+ SystemTimeListener* listener) {
+ DoUnsubscribe(listener);
+}
+
+time_t SystemTimeHandler::GetUTCTime() {
+ return FetchSystemTime();
+}
- flag = false;
- EXPECT_FALSE(flag == true);
+bool SystemTimeHandler::system_time_can_be_received() const {
+ return utc_time_can_be_received();
}
-} // namespace utils_test
-} // namespace components
-} // namespace test
+} // namespace utils
diff --git a/src/components/utils/test/conditional_variable_test.cc b/src/components/utils/test/conditional_variable_test.cc
index 290ff3434f..1ef29685e6 100644
--- a/src/components/utils/test/conditional_variable_test.cc
+++ b/src/components/utils/test/conditional_variable_test.cc
@@ -61,8 +61,8 @@ class ConditionalVariableTest : public ::testing::Test {
protected:
std::string test_value_;
- sync_primitives::ConditionalVariable cond_var_;
sync_primitives::Lock test_mutex_;
+ sync_primitives::ConditionalVariable cond_var_;
unsigned counter_;
};
diff --git a/src/components/utils/test/data_accessor_test.cc b/src/components/utils/test/data_accessor_test.cc
index c7c728b676..24b7bab282 100644
--- a/src/components/utils/test/data_accessor_test.cc
+++ b/src/components/utils/test/data_accessor_test.cc
@@ -41,7 +41,8 @@ namespace utils_test {
TEST(DataAccessorTest, CreateDataAccessor) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
DataAccessor<int> testdata(test_value, testSet_lock_);
int data_from_testdata = testdata.GetData();
@@ -52,17 +53,19 @@ TEST(DataAccessorTest, CreateDataAccessor) {
TEST(DataAccessorTest, CreateDataAccessor_MutexIsLocked_CannotLockItAgain) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
DataAccessor<int> testdata(test_value, testSet_lock_);
// assert
- EXPECT_FALSE(testSet_lock_.Try());
+ EXPECT_FALSE(testSet_lock_->Try());
}
TEST(DataAccessorTest, CopyDataAccessor_GetDataFromDataAccessors) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
DataAccessor<int> testdata(test_value, testSet_lock_);
DataAccessor<int> testdata_copy(testdata);
@@ -72,14 +75,15 @@ TEST(DataAccessorTest, CopyDataAccessor_GetDataFromDataAccessors) {
// assert
EXPECT_EQ(data_from_testdata, data_from_testdata_copy);
- EXPECT_FALSE(testSet_lock_.Try());
+ EXPECT_FALSE(testSet_lock_->Try());
}
TEST(DataAccessorTest,
ChangedDataInDataAccessor_ChangeData_DataInDataAccessorIsChanged) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
DataAccessor<int> testdata(test_value, testSet_lock_);
test_value = 0;
@@ -93,40 +97,42 @@ TEST(DataAccessorTest,
DeleteDataAccessor_CreatedOneDeleteOneThread_MutexIsUnlocked) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
{
DataAccessor<int> testdata(test_value, testSet_lock_);
// assert
- EXPECT_FALSE(testSet_lock_.Try());
+ EXPECT_FALSE(testSet_lock_->Try());
}
// assert
- EXPECT_TRUE(testSet_lock_.Try());
+ EXPECT_TRUE(testSet_lock_->Try());
- testSet_lock_.Release();
+ testSet_lock_->Release();
}
TEST(DataAccessorTest,
DeleteDataAccessor_CreatedThreadAndCopyDeleteBothThreads_MutexIsUnlocked) {
// arrange
int test_value = 10;
- sync_primitives::Lock testSet_lock_;
+ std::shared_ptr<sync_primitives::Lock> testSet_lock_ =
+ std::make_shared<sync_primitives::Lock>();
{
DataAccessor<int> testdata(test_value, testSet_lock_);
{
DataAccessor<int> testdata_copy(testdata);
// assert
- EXPECT_FALSE(testSet_lock_.Try());
+ EXPECT_FALSE(testSet_lock_->Try());
}
// assert
- EXPECT_FALSE(testSet_lock_.Try());
+ EXPECT_FALSE(testSet_lock_->Try());
}
// assert
- EXPECT_TRUE(testSet_lock_.Try());
- testSet_lock_.Release();
+ EXPECT_TRUE(testSet_lock_->Try());
+ testSet_lock_->Release();
}
} // namespace utils_test