From: Ossama Othman Date: Fri, 8 Nov 2013 23:05:41 +0000 (-0800) Subject: Incremental commit. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4db15cfd553463dc86314fe93a4f145027c1873c;p=profile%2Fivi%2Fsettings-daemon.git Incremental commit. Change-Id: I35f92e98d1ecda31999c7ca23c8f53c7f6a85d15 Signed-off-by: Ossama Othman --- diff --git a/plugins/connman/agent.cpp b/plugins/connman/agent.cpp index 6bccc37..61e99cd 100644 --- a/plugins/connman/agent.cpp +++ b/plugins/connman/agent.cpp @@ -81,6 +81,76 @@ namespace // -------------------------------------------------------------- // Connman Agent Handlers // -------------------------------------------------------------- + /** + * @class agent_operation_handler + * + * @brief Handle agent operations through given callback. + * + * This class factors out common connection data retrieval code, and + * performs Agent operations through the given callback. + */ + class agent_operation_handler + { + typedef ivi::settings::agent agent; + typedef agent::user_data data_type; + + // Prevent copying. + agent_operation_handler(agent_operation_handler const &) = delete; + void operator=(agent_operation_handler const &) = delete; + + public: + + /** + * Constructor + * + * @param[in] service D-Bus object path for connman service + * @param[in] user_data User/connection data + * @param[in] callback Callback that implements Agent operation + */ + agent_operation_handler( + gchar const * service, + gpointer user_data, + std::function + callback) + : data_(static_cast(user_data)) + , guard_(data_->lock) + , iterator_(data_->info.find(service)) + { + // data_ should never be null! + + if (iterator_ != data_->info.end()) + callback(iterator_->second); + } + + /// Destructor + ~agent_operation_handler() + { + // Done with the connection data. Remove it from the map. + if (iterator_ != data_->info.end()) + data_->info.erase(iterator_); + } + + private: + /// User/connection data. + data_type * const data_; + + /** + * Synchronize access to the user/connection data map. + * + * @note This lock will be held for the life of the + * @c agent_operation_handler object, i.e. for the duration + * of the operation. This is needed to synchronize the map + * @c erase() operation in the destructor. The erase() + * operation is performed in the destructor to ensure + * element removal occurs if an exception is thrown by the + * callback. + */ + std::lock_guard guard_; + + /// Map iterator that points to the connection data. + agent::user_data::map_type::iterator const iterator_; + }; + bool on_handle_release(Agent * object, GDBusMethodInvocation * invocation, @@ -97,27 +167,13 @@ namespace gchar const * error, gpointer user_data) { - using namespace ivi::settings; - typedef agent::user_data data_type; + using ivi::settings::agent; - data_type * const data = static_cast(user_data); - - { - std::lock_guard guard(data->lock); - - auto const i = data->info.find(service); - if (i != data->info.end()) { - auto & response = i->second.response; - response.send_error(error); - - /** - * @todo Make sure map element removal occurs if exception is - * thrown above. - */ - // Done with the connection data. - data->info.erase(i); - } - } + agent_operation_handler(service, + user_data, + [error](agent::connect_data const & d){ + d.response.send_error(std::string(error)); + }); agent_complete_report_error(object, invocation); @@ -142,16 +198,14 @@ namespace GVariant * fields, gpointer user_data) { - using namespace ivi::settings; - typedef agent::user_data data_type; + using ivi::settings::agent; - data_type * const data = static_cast(user_data); + agent_operation_handler( + service, + user_data, + [fields](agent::connect_data const & /* d */){ + using ivi::settings::unique_ptr; - { - std::lock_guard guard(data->lock); - - auto const i = data->info.find(service); - if (i != data->info.end()) { // Extract requested mandatory and alternate fields. GVariantIter * vi = nullptr; g_variant_get(fields, "(a{sv})", &vi); @@ -166,29 +220,10 @@ namespace } - - - auto & response = i->second.response; - - // Nothing to add to successful response. - response.send_response( - [](JsonBuilder * /* builder */) {}); - - /** - * @todo Make sure map element removal occurs if exception is - * thrown above. - */ - // Done with the connection data. - data->info.erase(i); - } - } - - + }); GVariant * dictionary = nullptr; - - // The method return value will contain a dictionary of the // requested input fields. agent_complete_request_input(object, invocation, dictionary); @@ -283,11 +318,13 @@ ivi::settings::agent::register_connect_data( JsonReader * reader, response_callback const & response) { + connect_data data(reader, response); + std::lock_guard guard(data_.lock); auto const result = - data_.info.emplace(std::make_pair(service_path, - connect_data(reader, response))); + data_.info.insert( + std::make_pair(service_path, std::move(data))); return result.second; } diff --git a/plugins/connman/agent.hpp b/plugins/connman/agent.hpp index 32c35dd..9b8cf17 100644 --- a/plugins/connman/agent.hpp +++ b/plugins/connman/agent.hpp @@ -33,7 +33,6 @@ #include - #include #include #include @@ -108,8 +107,9 @@ namespace ivi // Nothing to do with response field. } - /// Disallow copy construction. + /// Disallow copy construction and assignment. connect_data(connect_data const &) = delete; + void operator=(connect_data const &) = delete; /** * Pointer to the @c JsonReader object containing the request @@ -135,11 +135,13 @@ namespace ivi /// Synchronize access to the response/request data map. std::mutex lock; + typedef std::map map_type; + /** * Map of service D-Bus object path to request/response * data. */ - std::map info; + map_type info; }; private: diff --git a/plugins/connman/technology.cpp b/plugins/connman/technology.cpp index 15c0f1f..b370e34 100644 --- a/plugins/connman/technology.cpp +++ b/plugins/connman/technology.cpp @@ -183,6 +183,41 @@ ivi::settings::technology::scan(JsonReader * reader, } } +void +ivi::settings::technology::connect(JsonReader * reader, + response_callback response) +{ + char const * service_path = nullptr; + if (json_reader_read_member(reader, "value")) { + service_path = json_reader_get_string_value(reader); + } + json_reader_end_member(reader); + + /// @todo Refactor malformed JSON request handling code. + if (service_path != nullptr) { + // This call must bump the ref count on the reader! + // The response_callback should be copied, too! + if (manager_.register_connect_data(service_path, + reader, + response)) { + service s(service_path, + connman_.connection(), + event_callback_); + + // This connect() method call should not return until the + // service is fully connected. + s.connect(response); + } else { + response.send_error(std::string("Connection already pending: ") + + service_path); + } + } else { + response.send_error( + "Malformed " + technology_ + " connect request value."); +>>>>>>> Incremental commit. + } +} + GVariant * ivi::settings::technology::get_property(char const * name, GVariantType const * type,