[SecureElement] Improvement of initialization and error handling.
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>
Mon, 27 Apr 2015 08:20:32 +0000 (10:20 +0200)
committerPawel Andruszkiewicz <p.andruszkie@samsung.com>
Tue, 28 Apr 2015 10:05:40 +0000 (19:05 +0900)
Change-Id: Iad0b767e85d87ab8ec07bfd3b3ce332fa6b62bde

src/secureelement/secureelement_instance.cc
src/secureelement/secureelement_seservice.cc
src/secureelement/secureelement_seservice.h

index 16a5bfe..14fc760 100644 (file)
@@ -64,7 +64,14 @@ void SecureElementInstance::GetReaders(const picojson::value& args, picojson::ob
   LoggerD("Entered");
 
   CHECK_PRIVILEGE_ACCESS(kPrivilegeSecureElement, &out);
-  service_.GetReaders(args);
+
+  double callback_id = 0.0;
+  if (args.contains("callbackId")) {
+    callback_id = args.get("callbackId").get<double>();
+  }
+
+  service_.GetReaders(callback_id);
+  ReportSuccess(out);
 }
 
 void SecureElementInstance::RegisterSEListener(const picojson::value& args, picojson::object& out) {
index a4aa18b..adbef37 100644 (file)
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "secureelement_seservice.h"
+#include "secureelement/secureelement_seservice.h"
 
-#include "secureelement_instance.h"
 #include "common/logger.h"
 #include "common/task-queue.h"
 #include "common/platform_result.h"
 
+
+#include "secureelement/secureelement_instance.h"
+
 using namespace smartcard_service_api;
 using namespace common;
 using namespace tools;
@@ -42,6 +44,11 @@ class SEServiceEventHandler : public SEServiceListener {
 
   void errorHandler(SEServiceHelper *service, int error, void *context) {
     LoggerE("Error handler called, code: %d", error);
+    if (context) {
+      (static_cast<SEService*>(context))->ErrorHandler(error);
+    } else {
+      LoggerE("Context is null");
+    }
   }
 };
 
@@ -50,6 +57,7 @@ static SEServiceEventHandler se_event_handler;
 SEService::SEService(SecureElementInstance& instance)
     : is_initialized_(false),
       is_listener_set_(false),
+      is_error_(false),
       instance_(instance) {
   LoggerD("Entered");
 
@@ -68,23 +76,11 @@ SEService::~SEService() {
   se_service_ = nullptr;
 }
 
-void SEService::GetReaders(const picojson::value& args) {
+void SEService::GetReaders(double callback_id) {
   LoggerD("Entered");
 
-  double callback_id = 0.0;
-  if (args.contains("callbackId")) {
-    callback_id = args.get("callbackId").get<double>();
-  }
-
   auto get_readers = [this](
       const std::shared_ptr<picojson::value>& response) -> void {
-
-    if (!is_initialized_) {
-      ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "SE service not initialized."),
-                  &response->get<picojson::object>());
-      return;
-    }
-
     picojson::value result = picojson::value(picojson::array());
     picojson::array& result_array = result.get<picojson::array>();
 
@@ -105,6 +101,24 @@ void SEService::GetReaders(const picojson::value& args) {
     instance_.PostMessage(response->serialize().c_str());
   };
 
+  if (is_error_) {
+    // there has been an error, report it asynchronously
+    std::shared_ptr<picojson::value> response{new picojson::value{picojson::object{}}};
+    ReportError(
+        PlatformResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR,
+                       "Unable to connect to service."),
+        &response->get<picojson::object>());
+    TaskQueue::GetInstance().Async<picojson::value>(get_readers_response, response);
+    return;
+  }
+
+  if (!is_initialized_) {
+    // not yet ready, wait for the platform callback, send the response then
+    get_readers_callbacks_.push_back(callback_id);
+    return;
+  }
+
+  // everything's fine, get the readers, send the response
   TaskQueue::GetInstance().Queue<picojson::value>(
       get_readers,
       get_readers_response,
@@ -136,6 +150,14 @@ void SEService::ServiceConnected() {
   LoggerD("Entered");
 
   is_initialized_ = true;
+
+  // send the response to pending GetReaders callbacks
+  for (const auto& callback_id : get_readers_callbacks_) {
+    GetReaders(callback_id);
+  }
+  get_readers_callbacks_.clear();
+
+  // notify the listeners
   if (!is_listener_set_) {
     LoggerW("SE listener is not set.");
     return;
@@ -187,5 +209,15 @@ void SEService::EventHandler(char *se_name, int event) {
   }
 }
 
+void SEService::ErrorHandler(int error) {
+  LoggerD("Entered");
+  is_error_ = true;
+
+  for (const auto& callback_id : get_readers_callbacks_) {
+    GetReaders(callback_id);
+  }
+  get_readers_callbacks_.clear();
+}
+
 } // secureelement
 } // extension
index bb13988..dadc37e 100644 (file)
@@ -8,8 +8,6 @@
 #include <SEService.h>
 #include <SEServiceHelper.h>
 
-#include "common/picojson.h"
-
 namespace extension {
 namespace secureelement {
 
@@ -20,13 +18,14 @@ class SEService {
   explicit SEService(SecureElementInstance& instance);
   ~SEService();
 
-  void GetReaders(const picojson::value& args);
+  void GetReaders(double callback_id);
   void RegisterSEListener();
   void UnregisterSEListener();
   void Shutdown();
 
   void ServiceConnected();
   void EventHandler(char *se_name, int event);
+  void ErrorHandler(int error);
  private:
   SEService(const SEService&) = delete;
   SEService& operator=(const SEService&) = delete;
@@ -34,6 +33,8 @@ class SEService {
   smartcard_service_api::SEService *se_service_;
   bool is_initialized_;
   bool is_listener_set_;
+  bool is_error_;
+  std::vector<double> get_readers_callbacks_;
   SecureElementInstance& instance_;
 };