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 b9fbd1e9136b56ff9e39c384707c6a598c5ce5b8..25d8cb29e1c748ebd7c6828e411d139c73892d4f 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 a5128218e34069a5b57cd2fdafac04a1b191d0dc..70d73690d151e5d432b14848faa9e8e4bc3eceae 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 e578c65227651bcdcc5559dba8ecfcf4c64f8569..35fe505d24f250c27f702978ce1bd7820c1f8433 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 5ab67c3316a43f67841db3193a485f6803ad6dcd..b156f74bef451f2d80d545fca82746d546c42989 100644 (file)
@@ -266,6 +266,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 9c8aee88e77682258fb2a3f0067980e1b22f1962..527174df9374f0f87fe76be0b8a5a58afeec351d 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 45b7bbd5f81849706031eb6b22e0f7b450ae0f63..94eb681b8c37e1835d5c609bd1992737209950f9 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 932b83edc1da2ba336e1ab4d091d97dacfe73559..82d2690117efb42d99ac6d4ebb110e67370f075a 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 a5059ca9c218977e5dafbbc9779693191c991558..f1a1a0d73be64926ae803c1fe919cc355e61287a 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 e948ebbc0e29f785f7ee804cc83f0f6b2c572f14..521826c957ef75f889f0dd83a0da27c1fafaef0d 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 9b21e689c351e37d7e402b8fba8db0d9da443017..d7a439dec3ebcaf52418bd94c6139a5346a1e2d7 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 7d6f0d2086d51791de411c82b7cfb07649c846f5..0b412a877f9e86573aee606feda88032237eab11 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;