Add APIs to wait the mount of storage 00/120100/4
authorSungbae Yoo <sungbae.yoo@samsung.com>
Tue, 21 Mar 2017 10:36:46 +0000 (19:36 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 22 Mar 2017 05:02:19 +0000 (14:02 +0900)
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
Change-Id: I15ba0826caaa601bdbb0894e8cb5d2b306b3bfad

lib/client.cpp
lib/client.h
lib/ode/external-encryption.cpp
lib/ode/external-encryption.h
lib/ode/internal-encryption.cpp
lib/ode/internal-encryption.h
server/external-encryption.cpp
server/internal-encryption.cpp
server/server.cpp
server/server.h
tools/cli/ode-admin-cli.cpp

index b9fbd1e..25d8cb2 100644 (file)
 
 namespace {
 
+const std::string SUBSCRIBER_REGISTER = "Server::registerNotificationSubscriber";
+const std::string SUBSCRIBER_UNREGISTER = "Server::unregisterNotificationSubscriber";
+
+
 const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
 
 } // namespace
@@ -53,3 +57,25 @@ void ODEContext::disconnect() noexcept
 {
        client.reset();
 }
+
+int ODEContext::subscribeSignal(const std::string& name,
+                                                                       const SignalListener& listener,
+                                                                       void* data)
+{
+       auto listenerDispatcher = [listener, data](std::string name) {
+               listener(data);
+       };
+
+       try {
+               return client->subscribe<std::string>
+                                                       (SUBSCRIBER_REGISTER, name, listenerDispatcher);
+       } catch (runtime::Exception& e) {
+               std::cout << e.what() << std::endl;
+               return -1;
+       }
+}
+
+int ODEContext::unsubscribeSignal(int subscriberId)
+{
+       return client->unsubscribe(SUBSCRIBER_UNREGISTER, subscriberId);
+}
index a512821..70d7369 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <klay/rmi/client.h>
 
+typedef std::function<void(void*)> SignalListener;
+
 class ODEContext final {
 public:
        typedef std::unique_ptr<rmi::Client> ODEControlContext;
@@ -34,6 +36,9 @@ public:
        int connect(const std::string& address) noexcept;
        void disconnect() noexcept;
 
+       int subscribeSignal(const std::string& name, const SignalListener& listener, void* data);
+       int unsubscribeSignal(int subscriberId);
+
        template<typename Interface, typename... Args>
        Interface createInterface(Args&&... args) noexcept
        {
index e578c65..35fe505 100644 (file)
@@ -164,3 +164,24 @@ int ode_external_encryption_get_supported_options(unsigned int* options)
        *options = external.getSupportedOptions();
        return ODE_ERROR_NONE;
 }
+
+static void _ode_external_event_listener(void *user_data) {
+       std::mutex *pMtx = (std::mutex*)user_data;
+       pMtx->unlock();
+}
+
+int ode_external_encryption_wait_for_mount()
+{
+       ODEContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+
+       std::mutex mtx;
+       mtx.lock();
+
+       int ret = client.subscribeSignal("ExternalEncryption::mount", _ode_external_event_listener, &mtx);
+       RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+       mtx.lock();
+
+       return ODE_ERROR_NONE;
+}
index 5ab67c3..b156f74 100644 (file)
@@ -267,6 +267,20 @@ typedef enum {
 ODE_API int ode_external_encryption_get_supported_options(unsigned int* options);
 
 /**
+ * @brief       Wait for mount of external storage
+ * @details     Services can use this API to wait for mount of external storage.
+ * @since_tizen 3.0
+ * @return      #ODE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ODE_ERROR_NONE Successful
+ * @retval      #ODE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ODE_ERROR_TIMED_OUT Time out
+ * @retval      #ODE_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @see         ode_external_encryption_mount()
+ */
+ODE_API int ode_external_encryption_wait_for_mount();
+
+/**
  * @}
  */
 
index 9c8aee8..527174d 100644 (file)
@@ -164,3 +164,24 @@ int ode_internal_encryption_get_supported_options(unsigned int* options)
        *options = internal.getSupportedOptions();
        return ODE_ERROR_NONE;
 }
+
+static void _ode_internal_event_listener(void *user_data) {
+       std::mutex *pMtx = (std::mutex*)user_data;
+       pMtx->unlock();
+}
+
+int ode_internal_encryption_wait_for_mount()
+{
+    ODEContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+
+       std::mutex mtx;
+       mtx.lock();
+
+    int ret = client.subscribeSignal("InternalEncryption::mount", _ode_internal_event_listener, &mtx);
+       RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+       mtx.lock();
+
+    return ODE_ERROR_NONE;
+}
index 45b7bbd..94eb681 100644 (file)
@@ -267,6 +267,19 @@ typedef enum {
  */
 ODE_API int ode_internal_encryption_get_supported_options(unsigned int* options);
 
+/**
+ * @brief       Wait for mount of internal storage
+ * @details     Services can use this API to wait for mount of internal storage.
+ * @since_tizen 3.0
+ * @return      #ODE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ODE_ERROR_NONE Successful
+ * @retval      #ODE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ODE_ERROR_TIMED_OUT Time out
+ * @retval      #ODE_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @see         ode_internal_encryption_mount()
+ */
+ODE_API int ode_internal_encryption_wait_for_mount();
 /*
  * @}
  */
index 932b83e..82d2690 100644 (file)
@@ -171,6 +171,8 @@ ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
        context.expose(this, "", (int)(ExternalEncryption::getState)());
        context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
 
+       context.createNotification("ExternalEncryption::mount");
+
        engine.reset(new EXTERNAL_ENGINE(
                EXTERNAL_PATH, EXTERNAL_PATH,
                ProgressBar([](int v) {
@@ -200,6 +202,8 @@ int ExternalEncryption::mount(const std::string &password)
        }
 
        engine->mount(keyManager.getMasterKey(data), getOptions());
+       context.notify("ExternalEncryption::mount");
+
        return 0;
 }
 
index a5059ca..f1a1a0d 100644 (file)
@@ -206,6 +206,8 @@ InternalEncryption::InternalEncryption(ODEControlContext& ctx) :
        context.expose(this, "", (int)(InternalEncryption::getState)());
        context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)());
 
+       context.createNotification("InternalEncryption::mount");
+
        engine.reset(new INTERNAL_ENGINE(
                INTERNAL_DEV, INTERNAL_PATH,
                ProgressBar([](int v) {
@@ -233,6 +235,8 @@ int InternalEncryption::mount(const std::string& password)
        }
 
        engine->mount(keyManager.getMasterKey(pwData), getOptions());
+       context.notify("InternalEncryption::mount");
+
        return 0;
 }
 
index e948ebb..521826c 100644 (file)
@@ -41,6 +41,9 @@ Server::Server()
 
        service->setPrivilegeChecker(std::bind(&Server::checkPeerPrivilege, this, _1, _2));
 
+       service->expose(this, "", (runtime::FileDescriptor)(Server::registerNotificationSubscriber)(std::string));
+       service->expose(this, "", (int)(Server::unregisterNotificationSubscriber)(std::string, int));
+
        secureErase.reset(new ode::SecureErase(*this));
        internalEncryption.reset(new ode::InternalEncryption(*this));
        externalEncryption.reset(new ode::ExternalEncryption(*this));
@@ -89,3 +92,15 @@ bool Server::checkPeerPrivilege(const rmi::Credentials& cred, const std::string&
 
        return true;
 }
+
+runtime::FileDescriptor Server::registerNotificationSubscriber(const std::string& name)
+{
+       INFO("registerNotificationSubscriber");
+       INFO(name);
+       return runtime::FileDescriptor(service->subscribeNotification(name), true);
+}
+
+int Server::unregisterNotificationSubscriber(const std::string& name, int id)
+{
+       return service->unsubscribeNotification(name, id);
+}
index 9b21e68..d7a439d 100644 (file)
@@ -39,6 +39,12 @@ public:
                service->setMethodHandler<Type, Args...>(privilege, method, handler);
        }
 
+       template <typename... Args>
+       void notify(const std::string& name, Args&&... args)
+       {
+               service->notify<Args...>(name, std::forward<Args>(args)...);
+       }
+
        uid_t getPeerUid() const
        {
                return service->getPeerUid();
@@ -56,6 +62,15 @@ public:
 
        bool checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege);
 
+
+       void createNotification(const std::string& name)
+       {
+               service->createNotification(name);
+       }
+
+       runtime::FileDescriptor registerNotificationSubscriber(const std::string& name);
+       int unregisterNotificationSubscriber(const std::string& name, int id);
+
 private:
        std::string securityLabel;
        std::unique_ptr<rmi::Service> service;
index 7d6f0d2..0b412a8 100644 (file)
@@ -44,6 +44,7 @@ static inline int usage(const std::string name)
                          << "   -d, --decrypt=internal|external  decrypt" << std::endl
                          << "   -p, --changepw=internal|external change password" << std::endl
                          << "   -s, --state=internal|external    get state" << std::endl
+                         << "   -w, --waitmnt=internal|external  wait for mount"<< std::endl
                          << "   -r, --erase=FILE|DIRECTORY       secure-erase" << std::endl
                          << "   -c, --clean=DIRECTORY            secure-clean" << std::endl
                          << "   -h, --help                       show this" << std::endl
@@ -296,6 +297,29 @@ static inline int get_state(const std::string name)
        return ret;
 }
 
+static inline int wait_for_mount(const std::string name)
+{
+       int ret;
+
+       if (name == "internal") {
+               std::cout << "Wait for internal storage mount..." << std::endl;
+               ret = ode_internal_encryption_wait_for_mount();
+       } else if (name == "external") {
+               std::cout << "Wait for external storage mount..." << std::endl;
+               ret = ode_external_encryption_wait_for_mount();
+       } else {
+               printSelectableStorage();
+               return -1;
+       }
+
+       if (ret != 0) {
+               std::cerr << "Error : " << ret <<std::endl;
+               return -1;
+       }
+       std::cout << "Mount is completed"<< std::endl;
+
+       return ret;
+}
 static inline int erase(const std::string name)
 {
        int ret;
@@ -331,6 +355,7 @@ int main(int argc, char* argv[])
                {"encrypt", required_argument, 0, 'e'},
                {"decrypt", required_argument, 0, 'd'},
                {"state", required_argument, 0, 's'},
+               {"waitmnt", required_argument, 0, 'w'},
                {"erase", required_argument, 0, 'r'},
                {"clean", required_argument, 0, 'c'},
                {0, 0, 0, 0}
@@ -341,7 +366,7 @@ int main(int argc, char* argv[])
                return EXIT_SUCCESS;
        }
 
-       while ((opt = getopt_long(argc, argv, "m:u:e:d:p:s:r:c:h", options, &index)) != -1) {
+       while ((opt = getopt_long(argc, argv, "m:u:e:d:p:s:w:r:c:h", options, &index)) != -1) {
                switch (opt) {
                case 'm':
                        ret = mount(optarg);
@@ -358,6 +383,9 @@ int main(int argc, char* argv[])
                case 'p':
                        ret = change_password(optarg);
                        break;
+               case 'w':
+                       ret = wait_for_mount(optarg);
+                       break;
                case 's':
                        ret = get_state(optarg);
                        break;