Add ProgressBar 22/109522/8
authorSeok Hong <seok85.hong@samsung.com>
Tue, 10 Jan 2017 08:51:45 +0000 (17:51 +0900)
committerSeok Hong <seok85.hong@samsung.com>
Wed, 18 Jan 2017 00:28:21 +0000 (09:28 +0900)
Change-Id: I7de1b8666c69708df8e72ea9e6e31cfc7e5ebe65
Signed-off-by: Seok Hong <seok85.hong@samsung.com>
21 files changed:
server/CMakeLists.txt
server/engine/dmcrypt-engine.cpp
server/engine/dmcrypt-engine.h
server/engine/ecryptfs-engine.cpp
server/engine/ecryptfs-engine.h
server/engine/ext4-engine.cpp
server/engine/ext4-engine.h
server/external-encryption.cpp
server/internal-encryption.cpp
server/progress-bar.cpp [new file with mode: 0644]
server/progress-bar.h [new file with mode: 0644]
server/progress-vconf-backend.cpp [new file with mode: 0644]
server/progress-vconf-backend.h [new file with mode: 0644]
server/secure-erase.cpp
tests/CMakeLists.txt
tests/dmcrypt-engine.cpp
tests/ecryptfs-engine.cpp
tests/ext4-engine.cpp
tools/apps/CMakeLists.txt
tools/apps/ode-gui/src/ui.c
tools/apps/secure-erase/src/ui.c

index 79ab042..2074888 100644 (file)
@@ -20,6 +20,8 @@ SET(SERVER_SRCS       main.cpp
                                app-bundle.cpp
                                file-footer.cpp
                                secure-erase.cpp
+                               progress-bar.cpp
+                               progress-vconf-backend.cpp
                                block-device.cpp
                                internal-encryption.cpp
                                external-encryption.cpp
index 383b5cb..292d73f 100644 (file)
@@ -80,8 +80,8 @@ static void convertKeyToHexASCII(const DMCryptEngine::data &key,
        key_ascii[a] = '\0';
 }
 
-DMCryptEngine::DMCryptEngine(const std::string &src, const std::string &dest) :
-       source(src), destination(dest)
+DMCryptEngine::DMCryptEngine(const std::string &src, const std::string &dest, const ProgressBar &prgsBar) :
+       source(src), destination(dest), progressBar(prgsBar)
 {
        // 1. Get Real Block device(src)'s infomation
        cryptInfo.init(src, "aes-cbc-essiv:sha256");
@@ -275,9 +275,9 @@ void DMCryptEngine::umount()
 #define CRYPT_INPLACE_BUFSIZE 4096
 #define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / 512)
 
-static void encryptInPlace(const std::string &dest_blkdev,
-                                                  const std::string &src_blkdev,
-                                                  const long src_blkdev_size)
+void DMCryptEngine::encryptInPlace(const std::string &dst_blkdev,
+                                                                  const std::string &src_blkdev,
+                                                                  const long src_blkdev_size)
 {
        // TODO(seok85.hong): support fast-encryption
 
@@ -285,14 +285,17 @@ static void encryptInPlace(const std::string &dest_blkdev,
 
        off64_t numblocks = src_blkdev_size / CRYPT_SECTORS_PER_BUFSIZE;
        off64_t remainder = src_blkdev_size % CRYPT_SECTORS_PER_BUFSIZE;
+       off64_t total = numblocks + remainder;
 
-       runtime::File dest(dest_blkdev, O_WRONLY);
+       runtime::File dst(dst_blkdev, O_WRONLY);
        runtime::File src(src_blkdev, O_RDONLY);
 
-       for (off64_t n = 0; n < (numblocks + remainder); n++) {
+       for (off64_t n = 0; n < total; n++) {
                src.read(buff, CRYPT_INPLACE_BUFSIZE);
-               dest.write(buff, CRYPT_INPLACE_BUFSIZE);
+               dst.write(buff, CRYPT_INPLACE_BUFSIZE);
+               progressBar.update(n, total, 1);
        }
+       progressBar.done();
 }
 
 void DMCryptEngine::encrypt(const DMCryptEngine::data &key)
index 7dd368d..b63a848 100644 (file)
@@ -20,6 +20,8 @@
 #include <vector>
 #include <string>
 
+#include "progress-bar.h"
+
 namespace ode {
 
 class CryptInfo {
@@ -40,7 +42,7 @@ private:
 
 class DMCryptEngine final {
 public:
-       DMCryptEngine(const std::string &src, const std::string &dest);
+       DMCryptEngine(const std::string &src, const std::string &dest, const ProgressBar &prgsBar);
        DMCryptEngine(const DMCryptEngine &) = delete;
        DMCryptEngine(DMCryptEngine &&) = delete;
        ~DMCryptEngine();
@@ -70,8 +72,14 @@ public:
        void setKeyMeta(const data &data);
 
 private:
+       void encryptInPlace(const std::string &dst_blkdev,
+                                               const std::string &src_blkdev,
+                                               const long src_blkdev_size);
+
+private:
        std::string source, destination;
        CryptInfo cryptInfo;
+       ProgressBar progressBar;
 };
 
 } // namespace ode
index dd48a2e..21c5677 100644 (file)
@@ -23,8 +23,8 @@
 
 namespace ode {
 
-EcryptfsEngine::EcryptfsEngine(const std::string &src, const std::string &dest) :
-       mSource(src), mDestination(dest)
+EcryptfsEngine::EcryptfsEngine(const std::string &src, const std::string &dest, const ProgressBar &prgsBar) :
+       mSource(src), mDestination(dest), progressBar(prgsBar)
 {
 }
 
@@ -270,11 +270,14 @@ int EcryptfsEngine::DoEncrypt(const data &key)
 
        if (mTotalFileCt) {
                mTotalCopied = 0;
+               mLastProg = 0;
+               progressBar.update(mLastProg);
                INFO("calling the recursive function EncryptFile (" + std::string(mPath) + ")");
                if (cryptInplace(mPath, "", false) != 0) {
                        INFO("Ecryptfs: Full Encryption couldn't complete");
                        goto error;
                }
+               progressBar.done();
        }
 
        return 0;
@@ -305,11 +308,14 @@ int EcryptfsEngine::DoDecrypt(const data &key)
 
        if (mTotalFileCt) {
                mTotalCopied = 0;
+               mLastProg = 0;
+               progressBar.update(mLastProg);
                INFO("calling the recursive function EncryptFile (" + std::string(mPath) + ")");
                if (cryptInplace(mPath, "", true) != 0) {
                        INFO("Ecryptfs: Full Decryption couldn't complete");
                        goto error;
                }
+               progressBar.done();
        }
 
        deleteEncryptMetaData(mMetaDataFile);
@@ -322,6 +328,20 @@ error:
        return -1;
 }
 
+void EcryptfsEngine::progress(long long size)
+{
+       int complPercentage = 0;
+
+       if (mTotalStSz != 0) {
+               complPercentage = (size * 100) / mTotalStSz;
+               if ((complPercentage - mLastProg) >= DELTA_PROGRESS) {
+                       INFO("Progress: " + std::to_string(complPercentage) + "%, Total Size: " + std::to_string(mTotalStSz));
+                       mLastProg = complPercentage;
+                       progressBar.update(mLastProg);
+               }
+       }
+}
+
 long long EcryptfsEngine::CopyImpl(int sfd, int dfd, long long fullsz, bool enctype)
 {
        long long ret = -1;
@@ -353,6 +373,8 @@ long long EcryptfsEngine::CopyImpl(int sfd, int dfd, long long fullsz, bool enct
                }
                total += rdsz;
                mTotalCopied += rdsz;
+
+               progress(mTotalCopied);
        }
 
        return ret ? -1 : total;
index b0d5b44..9fb7c86 100644 (file)
@@ -29,6 +29,8 @@
 #include <unistd.h>
 #include <utime.h>
 
+#include "../progress-bar.h"
+
 #define __u32 unsigned int
 
 #define ECRYPTFS_SIG_SIZE 8
@@ -96,13 +98,15 @@ typedef int32_t key_serial_t;
 #define WAS_ENCRYPTED 0
 #define WAS_ENCRYPTED_OTHER_DEVICE 1
 
+#define DELTA_PROGRESS 1
+
 #define check_dots(p) ((p)[0] == '.' && (!(p)[1] || ((p)[1] =='.'&& !(p)[2])))
 
 namespace ode {
 
 class EcryptfsEngine final {
 public:
-       EcryptfsEngine(const std::string& src, const std::string& dest);
+       EcryptfsEngine(const std::string& src, const std::string& dest, const ProgressBar& prgsBar);
        EcryptfsEngine(const EcryptfsEngine&) = delete;
        EcryptfsEngine(EcryptfsEngine&&) = delete;
        ~EcryptfsEngine();
@@ -205,6 +209,7 @@ public:
        int DoCrypt(const data &key, const char *path, int reqEnc, int excludeMedia);
        int DoEncrypt(const data &key);
        int DoDecrypt(const data &key);
+       void progress(long long size);
        long long CopyImpl(int sfd, int dfd, long long fullsz, bool enctype);
        ssize_t FullRead (int fd, void * buf, size_t count);
        ssize_t FullWrite (int fd, const void * buf, size_t len);
@@ -232,9 +237,11 @@ private:
        int mExcludeMedia;
        int mPreScanEncryptErr;
        int mPreScanDecryptErr;
+       int mLastProg;
        int mTotalFileCt;
        long long  mTotalStSz;
        long long mTotalCopied;
+       ProgressBar progressBar;
 };
 
 } // namespace ode
index 61e3a9f..c9a0d8d 100644 (file)
@@ -80,12 +80,14 @@ struct ext4_encryption_key {
        unsigned int size;
 } __attribute__((__packed__));
 
-// for now, It only suits for "/opt/usr"
+/* for now, It only suits for "/opt/usr" */
 namespace {
        std::string secondMountPoint("/opt/usr_encrypt");
        std::string bindMountPoint("/opt/usr_encrypt/secure");
        std::string ext4KeyringType("logon");
        std::string smackAccessLabel("security.SMACK64");
+       long long totalSize = 0;
+       long long curSize = 0;
 }
 
 const Ext4Engine::data generateKeyDesc(const ode::Ext4Engine::data& key)
@@ -160,7 +162,7 @@ static void copySmackLabel(std::string& srcPath, std::string& destPath)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 }
 
-static int copy(std::string& src, std::string& dest)
+int Ext4Engine::copy(std::string& src, std::string& dest)
 {
        int readFd, writeFd, ret;
        struct stat st;
@@ -180,9 +182,14 @@ static int copy(std::string& src, std::string& dest)
        copySmackLabel(src, dest);
        if (::chown(dest.c_str(), st.st_uid, st.st_gid) == -1)
                throw runtime::Exception(dest + runtime::GetSystemErrorMessage());
-       if (::sendfile(writeFd, readFd, 0, st.st_size))
+       if (::sendfile(writeFd, readFd, 0, st.st_size) == -1)
                return 1;
 
+       /* progress bar update */
+       curSize += st.st_size;
+       INFO("curSize is " + std::to_string(curSize));
+       progressBar.update(curSize, totalSize, 1);
+
        if (::fsync(writeFd) != 0)
                throw runtime::Exception(dest + runtime::GetSystemErrorMessage());
 
@@ -194,7 +201,57 @@ static int copy(std::string& src, std::string& dest)
        return 0;
 }
 
-static void listDir(std::string& source, std::string& dest, bool excludeFlag)
+static void preScanDir(std::string& dir)
+{
+       DIR* d;
+
+       d = ::opendir(dir.c_str());
+
+       if (!d)
+               throw runtime::Exception(dir + runtime::GetSystemErrorMessage());
+
+       while(1) {
+               struct dirent* entry;
+               std::string dName;
+
+               entry = ::readdir(d);
+               if (!entry) {
+                       break;
+               }
+               dName = entry->d_name;
+               if (!(entry->d_type & DT_DIR)) {
+                       std::string file = dir + "/" + dName;
+                       struct stat st;
+                       int statRet;
+
+                       statRet = ::stat(file.c_str(), &st);
+                       if (statRet != 0)
+                               throw runtime::Exception(file + runtime::GetSystemErrorMessage());
+                       INFO("[preListDir] " + file + " totalSize = " + std::to_string(totalSize) + " " +std::to_string(st.st_size));
+                       totalSize += st.st_size;
+               }
+
+               if (entry->d_type & DT_DIR) {
+                       if (dName.compare(".") != 0 && dName.compare("..") != 0) {
+                               std::string path;
+
+                               path = dir + "/" + dName;
+
+
+                               if (path.size() >= PATH_MAX)
+                                       throw runtime::Exception(path + " :path length has got too long");
+
+                               preScanDir(path);
+                       }
+               }
+       }
+
+       if (::closedir(d))
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+
+}
+
+void Ext4Engine::listDir(std::string& source, std::string& dest, bool excludeFlag)
 {
        DIR* d;
 
@@ -231,7 +288,7 @@ static void listDir(std::string& source, std::string& dest, bool excludeFlag)
                                pathS = source + "/" + dName;
                                pathD = dest + "/" +dName;
 
-                               // make new directory
+                               /* make new directory */
                                int mkdirRet, statRet;
                                struct stat st;
                                statRet = ::stat(pathS.c_str(), &st);
@@ -353,8 +410,8 @@ static bool getPolicy(const std::string& dirName)
        return true;
 }
 
-Ext4Engine::Ext4Engine(const std::string& src, const std::string& dest) :
-       source(src), destination(dest)
+Ext4Engine::Ext4Engine(const std::string& src, const std::string& dest, const ProgressBar &prgsBar) :
+       source(src), destination(dest), progressBar(prgsBar)
 {
 }
 
@@ -365,17 +422,17 @@ Ext4Engine::~Ext4Engine()
 void Ext4Engine::mount(const Ext4Engine::data& key)
 {
        addKey(key);
-       // mount : /dev/mmcblk0p21 /opt/usr_encrypt
+       /* mount : /dev/mmcblk0p21 /opt/usr_encrypt */
        if (::mount(source.c_str(), secondMountPoint.c_str(), "ext4", 0, 0) < 0)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
-       // bind mount :/opt/usr_encrypt/secure /opt/usr
+       /* bind mount :/opt/usr_encrypt/secure /opt/usr */
        if (::mount(bindMountPoint.c_str(), destination.c_str(), "ext4", MS_BIND, 0) < 0)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 }
 
 void Ext4Engine::umount()
 {
-       // for decrypt, umount /opt/usr
+       /* for decrypt, umount /opt/usr */
        if (::umount(destination.c_str()))
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 }
@@ -394,14 +451,17 @@ void Ext4Engine::encrypt(const Ext4Engine::data& key)
        if (!(copyFlag = prepareEncryptDir(sourceDir, destDir)))
                throw runtime::Exception("prepareEncryptDir failed");
 
-       // key add to keyring
+       preScanDir(secondMountPoint);
+       /* key add to keyring */
        addKeyToKeyring(key);
-       // set policy
+       /* set policy */
        setPolicy(bindMountPoint, key);
 
        if (copyFlag)
                listDir(secondMountPoint, bindMountPoint, true);
        INFO("[ext4 encrypt] copy done");
+
+       progressBar.done();
        if (::mount(bindMountPoint.c_str(), destDir.c_str(), "ext4", MS_BIND, 0) < 0)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 }
@@ -414,15 +474,19 @@ void Ext4Engine::decrypt(const Ext4Engine::data& key)
                throw runtime::Exception("directory isn't encrypted");
        addKeyToKeyring(key);
 
+       preScanDir(bindMountPoint);
+
        listDir(bindMountPoint, secondMountPoint, false);
        INFO("[ext4 decrypt] copy done");
+       progressBar.done();
+
        if (::open(bindMountPoint.c_str(), O_RDONLY) != -1)
                ::remove(bindMountPoint.c_str());
 
-       // umount /opt/usr_encrypt
+       /* umount /opt/usr_encrypt */
        if (::umount(secondMountPoint.c_str()))
                throw runtime::Exception(runtime::GetSystemErrorMessage());
-       // mount /dev/mmcblk0p21 /opt/usr
+       /* mount /dev/mmcblk0p21 /opt/usr */
        if (::mount(source.c_str(), destination.c_str(), "ext4", 0, 0) < 0)
                throw runtime::Exception(runtime::GetSystemErrorMessage());
 
index 80922a9..e9cdb22 100644 (file)
 #include <vector>
 #include <string>
 
+#include "progress-bar.h"
+
 namespace ode {
 
 class Ext4Engine final {
 public:
-       Ext4Engine(const std::string &src, const std::string &dest);
+       Ext4Engine(const std::string& src, const std::string& dest, const ProgressBar &prgsBar);
        Ext4Engine(const Ext4Engine&) = delete;
        Ext4Engine(Ext4Engine&&) = delete;
        ~Ext4Engine();
@@ -54,8 +56,12 @@ public:
        const data getKeyMeta();
        void setKeyMeta(const data &data);
 
+       int copy(std::string& src, std::string& dest);
+       void listDir(std::string& source, std::string& dest, bool excludeFlag);
+
 private:
        std::string source, destination;
+       ProgressBar progressBar;
 };
 
 } // namespace ode
index c54e5bd..b7cd063 100644 (file)
 #include <klay/dbus/connection.h>
 
 #include "rmi/external-encryption.h"
+#include "progress-bar.h"
+#include "progress-vconf-backend.h"
 
-#define EXTERNAL_STORAGE_PATH  "/opt/media/SDCardA1"
+#define EXTERNAL_STORAGE_PATH   "/opt/media/SDCardA1"
 #define DEFAULT_USER "owner"
 #define EXTERNAL_STORAGE_VCONF_KEY VCONFKEY_SDE_CRYPTO_STATE
 
@@ -41,7 +43,10 @@ namespace ode {
 
 namespace {
 
-EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH);
+VConfBackend vconfBackend(VCONFKEY_SDE_ENCRYPT_PROGRESS);
+ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
+
+EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH, progressBar);
 
 void killDependedApplications()
 {
@@ -51,11 +56,12 @@ void killDependedApplications()
        }
 }
 
-void showProgressUI(const std::string type) {
+void showProgressUI(const std::string type)
+{
        AppBundle bundle;
        bundle.add("mode", "progress");
        bundle.add("type", type);
-       bundle.add("target", "SD card encryption");
+       bundle.add("target", "External");
 
        Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
        launchpad.launch("org.tizen.ode-gui", bundle);
@@ -132,7 +138,7 @@ void externalCheckMount()
 
 }
 
-ExternalEncryption::ExternalEncryption(ODEControlContextctx) :
+ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
        context(ctx)
 {
        context.registerParametricMethod(this, "", (int)(ExternalEncryption::mount)(std::string));
@@ -151,7 +157,7 @@ ExternalEncryption::~ExternalEncryption()
 {
 }
 
-int ExternalEncryption::mount(const std::stringpassword)
+int ExternalEncryption::mount(const std::string &password)
 {
        KeyManager::data pwData(password.begin(), password.end());
        KeyManager keyManager(engine.getKeyMeta());
@@ -174,7 +180,7 @@ int ExternalEncryption::umount()
        return 0;
 }
 
-int ExternalEncryption::encrypt(const std::stringpassword)
+int ExternalEncryption::encrypt(const std::string &password)
 {
        KeyManager::data pwData(password.begin(), password.end());
        KeyManager keyManager;
@@ -201,7 +207,7 @@ int ExternalEncryption::encrypt(const std::string& password)
        return 0;
 }
 
-int ExternalEncryption::decrypt(const std::stringpassword)
+int ExternalEncryption::decrypt(const std::string &password)
 {
        KeyManager::data pwData(password.begin(), password.end());
        KeyManager keyManager(engine.getKeyMeta());
@@ -219,7 +225,7 @@ int ExternalEncryption::decrypt(const std::string& password)
                INFO("Umount internal storage...");
                try {
                        engine.umount();
-               } catch (runtime::Exceptione) {}
+               } catch (runtime::Exception &e) {}
 
                INFO("Decryption started...");
                engine.decrypt(MasterKey);
@@ -234,8 +240,8 @@ int ExternalEncryption::decrypt(const std::string& password)
        return 0;
 }
 
-int ExternalEncryption::changePassword(const std::stringoldPassword,
-                                                                               const std::string& newPassword)
+int ExternalEncryption::changePassword(const std::string &oldPassword,
+                                                                          const std::string &newPassword)
 {
        KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
        KeyManager::data newPwData(newPassword.begin(), newPassword.end());
index d0c4a27..1a50b5b 100644 (file)
@@ -39,7 +39,10 @@ namespace ode {
 
 namespace {
 
-DMCryptEngine engine("/dev/mmcblk0p25", INTERNAL_STORAGE_PATH);
+VConfBackend vconfBackend(VCONFKEY_ODE_ENCRYPT_PROGRESS);
+ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
+
+DMCryptEngine engine("/dev/mmcblk0p25", INTERNAL_STORAGE_PATH, progressBar);
 
 void stopDependedSystemdServices()
 {
@@ -74,7 +77,7 @@ void stopDependedSystemdServices()
 
 void showProgressUI(const std::string type) {
        std::vector<std::string> args = {
-               "ode-gui", "progress", type, "Internal storage encryption"
+               "ode-gui", "progress", type, "Internal"
        };
 
        runtime::Process proc("/usr/bin/ode-gui", args);
diff --git a/server/progress-bar.cpp b/server/progress-bar.cpp
new file mode 100644 (file)
index 0000000..0c1ed83
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include "progress-bar.h"
+
+namespace ode {
+
+ProgressBar::ProgressBar(CALLBACK const &callback)
+       : updater(callback), updateValue(0)
+{
+}
+
+ProgressBar::~ProgressBar()
+{
+}
+
+void ProgressBar::update(int value)
+{
+       if (updateValue != value) {
+               updateValue = value;
+               updater(updateValue);
+       }
+}
+
+void ProgressBar::update(int curCount, int totalCount, int unit)
+{
+       int percentage = ((curCount * 100) / totalCount) * unit;
+
+       if (updateValue != percentage) {
+               updateValue = percentage;
+               updater(updateValue);
+       }
+}
+
+void ProgressBar::done(void)
+{
+       updateValue = 100;
+       updater(100);
+}
+
+} // namespace ode
diff --git a/server/progress-bar.h b/server/progress-bar.h
new file mode 100644 (file)
index 0000000..45a30a7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __ODE_PROGRESS_BAR_H__
+#define __ODE_PROGRESS_BAR_H__
+
+#include <functional>
+#include <vconf.h>
+
+#include "progress-vconf-backend.h"
+
+namespace ode {
+
+class ProgressBar {
+public:
+       typedef std::function<void(int)> CALLBACK;
+
+       ProgressBar() = delete;
+       ProgressBar(CALLBACK const &callback);
+       ~ProgressBar();
+
+       void update(int value);
+       void update(int count, int totalCount, int unit);
+       void done(void);
+
+private:
+       CALLBACK updater;
+       int updateValue;
+};
+
+} // namespace ode
+
+#endif //__ODE_PROGRESS_BAR_H__
diff --git a/server/progress-vconf-backend.cpp b/server/progress-vconf-backend.cpp
new file mode 100644 (file)
index 0000000..12c5b65
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+#include "progress-vconf-backend.h"
+
+namespace ode {
+
+VConfBackend::VConfBackend(const std::string &k)
+       : key(k)
+{
+}
+
+VConfBackend::~VConfBackend()
+{
+}
+
+void VConfBackend::update(int value)
+{
+       // TODO
+       int ret = 0;
+       ret = ::vconf_set_str(key.c_str(), std::to_string(value).c_str());
+       if (ret != 0) {
+               /* [TBD] throw exception */
+       }
+}
+#if 0
+const std::string VconfBackend::getProgress(void)
+{
+       return ::vconf_get_str(key.c_str());
+}
+#endif
+
+} // namespace ode
diff --git a/server/progress-vconf-backend.h b/server/progress-vconf-backend.h
new file mode 100644 (file)
index 0000000..0e18ba7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __ODE_PROGRESS_VCONF_BACKEND_H__
+#define __ODE_PROGRESS_VCONF_BACKEND_H__
+
+#include <string>
+#include <vconf.h>
+
+namespace ode {
+
+class VConfBackend {
+public:
+       VConfBackend() = delete;
+       VConfBackend(const std::string &k);
+       ~VConfBackend();
+
+       void update(int value);
+
+private:
+       std::string key;
+};
+
+} // namespace ode
+
+#endif //__ODE_PROGRESS_VCONF_BACKEND_H__
index f91bc94..fe72e10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
 #include <linux/fs.h>
 #include <linux/fiemap.h>
 
+#include <vconf.h>
 #include <klay/exception.h>
 #include <klay/filesystem.h>
 #include <klay/audit/logger.h>
 
 #include "rmi/secure-erase.h"
+#include "progress-bar.h"
+#include "progress-vconf-backend.h"
 #include "block-device.h"
 #include "ext4-tool.h"
 
 namespace ode {
 
+namespace {
+VConfBackend vconfBackend(VCONFKEY_ODE_ERASE_PROGRESS);
+ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
+
+static int totalFileCount = 0;
+static int erasedFileCount = 0;
+
+static int getTotalFileCount(const std::string &name)
+{
+       int total = 0;
+       runtime::DirectoryIterator iter(name), end;
+
+       while (iter != end) {
+               std::string next = name + "/" + iter->getName();
+               runtime::File file(next);
+               if (!file.exists()) {
+                       return -1;
+               }
+
+               if (file.isFile()) {
+                       total++;
+               } else if (file.isDirectory()) {
+                       int subTotal = getTotalFileCount(next);
+                       if (subTotal != -1)
+                               total += subTotal;
+               }
+               ++iter;
+       }
+
+       return total;
+}
+
+} /* namespace */
+
 SecureErase::SecureErase(ODEControlContext &ctx) :
        context(ctx), devicePath("")
 {
@@ -51,10 +88,11 @@ int SecureErase::erase(const std::string &name)
                        devicePath = blockDevice.getName();
 
                        if (file.isFile()) {
-                               /* TBD */
+                               totalFileCount = 1;
                                fileErase(name);
                        } else if (file.isDirectory()) {
-                               /* TBD */
+                               totalFileCount = getTotalFileCount(name);
+                               erasedFileCount = 0;
                                directoryErase(name);
                        } else if (file.isDevice()) {
                                Ext4Tool ext4Tool(name);
@@ -62,11 +100,13 @@ int SecureErase::erase(const std::string &name)
                                unsigned int blockSize = (unsigned int)blockDevice.getSize();
 
                                for (unsigned int i = 0; i < totalBlock; i++) {
-                                       Block block(i*blockSize, blockSize);
+                                       Block block(i * blockSize, blockSize);
                                        blockDevice.discard(block);
+                                       progressBar.update(i, totalBlock, 1);
                                }
                        }
                        dropCachePage();
+                       progressBar.done();
                } catch (runtime::Exception &e) {}
        };
 
@@ -84,7 +124,7 @@ int SecureErase::clean(const std::string &name)
                        return -1;
        } catch (runtime::Exception &e) {}
 
-       auto cleanWorker = [name, this] () {
+       auto cleanWorker = [name, this]() {
                try {
                        BlockDevice blockDevice(name);
                        unsigned totalBlock, blockSize;
@@ -95,11 +135,14 @@ int SecureErase::clean(const std::string &name)
 
                        for (unsigned int i = 0; i < totalBlock; i++) {
                                if (!ext4Tool.isUsedBlock(i)) {
-                                       Block block(i*blockSize, blockSize);
+                                       Block block(i * blockSize, blockSize);
                                        blockDevice.discard(block);
                                }
+
+                               progressBar.update(i, totalBlock, 1);
                        }
                        dropCachePage();
+                       progressBar.done();
                } catch (runtime::Exception &e) {}
        };
 
@@ -150,6 +193,10 @@ int SecureErase::fileErase(const std::string &name)
                if (ret < 0) {
                        return -1;
                }
+
+               if (totalFileCount == 1) {
+                       progressBar.update(i, extentBlockCount, 1);
+               }
        }
 
        return ret;
@@ -157,8 +204,6 @@ int SecureErase::fileErase(const std::string &name)
 
 int SecureErase::directoryErase(const std::string &name)
 {
-       int ret = 0;
-
        runtime::DirectoryIterator iter(name), end;
        while (iter != end) {
                std::string next = name + "/" + iter->getName();
@@ -170,6 +215,8 @@ int SecureErase::directoryErase(const std::string &name)
                if (file.isFile()) {
                        fileErase(next);
                        ::remove(next.c_str());
+                       erasedFileCount++;
+                       progressBar.update(erasedFileCount, totalFileCount, 1);
                } else if (file.isDirectory()) {
                        directoryErase(next);
                }
@@ -178,8 +225,7 @@ int SecureErase::directoryErase(const std::string &name)
 
        fileErase(name);
        ::rmdir(name.c_str());
-
-       return ret;
+       return 0;
 }
 
 void SecureErase::dropCachePage()
index eff1d8b..a8c9773 100755 (executable)
@@ -25,6 +25,8 @@ SET(TEST_SRC  main.cpp
                                ../server/engine/ecryptfs-engine.cpp
                                ../server/key-manager/key-generator.cpp
                                ../server/key-manager/anti-forensics.cpp
+                               ../server/progress-bar.cpp
+                               ../server/progress-vconf-backend.cpp
 )
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_SRC})
@@ -33,9 +35,10 @@ PKG_CHECK_MODULES(TEST_DEPS REQUIRED klay
                                                                                glib-2.0
                                                                                gio-2.0
                                                                                openssl
+                                                                               vconf
 )
 
-INCLUDE_DIRECTORIES(SYSTEM ${TEST_DEPS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(SYSTEM ${TEST_DEPS_INCLUDE_DIRS} ../server)
 
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${TEST_DEPS_LIBRARIES})
 
index 082207b..ee4e44d 100644 (file)
@@ -29,6 +29,8 @@
 #include <klay/testbench.h>
 #include <klay/process.h>
 
+#include "../server/progress-bar.h"
+#include "../server/progress-vconf-backend.h"
 #include "../server/engine/dmcrypt-engine.cpp"
 
 #define TEST_USERDATA_NAME  "userdata"
@@ -42,6 +44,9 @@ static std::string test_real_mntpoint;
 
 // ode::DMCryptEngine gvTest("/dev/mmcblk0p25", "/opt/usr");
 
+ode::VConfBackend vconfBackend(VCONFKEY_ODE_ENCRYPT_PROGRESS);
+ode::ProgressBar progressBar(std::bind(&ode::VConfBackend::update, &vconfBackend, std::placeholders::_1));
+
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////
@@ -321,7 +326,7 @@ TESTCASE(DMCryptSanitizeKey)
 TESTCASE(DMCryptGetPathTest)
 {
        try {
-               ode::DMCryptEngine engine("/dev/mmcblk0p1", TEST_USERDATA_PATH);
+               ode::DMCryptEngine engine("/dev/mmcblk0p1", TEST_USERDATA_PATH, progressBar);
                if (engine.getSource() != "/dev/mmcblk0p1") {
                        throw runtime::Exception("Source doen't match");
                }
@@ -340,7 +345,7 @@ TESTCASE(DMCryptEncryptAndDecrypt)
                const std::string keystring = "01020304050607080910111213141516";
                const ode::DMCryptEngine::data key32bit(keystring.begin(), keystring.end());
 
-               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint);
+               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint, progressBar);
                engine.encrypt(key32bit);
 
                // check the encryption result of test_real_blkdev(/dev/loop0)
@@ -383,7 +388,7 @@ TESTCASE(DMCryptEncryptMountUnmountDecrypt)
                const std::string keystring = "01020304050607080910111213141516";
                const ode::DMCryptEngine::data key32bit(keystring.begin(), keystring.end());
 
-               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint);
+               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint, progressBar);
                engine.encrypt(key32bit);
                engine.mount(key32bit);
                {
@@ -437,7 +442,7 @@ TESTCASE(DMCryptEncryptButDecryptWithWrongKey)
                const std::string wrongkeystring = "SIZE_IS_SAME_BUT_WRONG_DECKEY___";
                const ode::DMCryptEngine::data wrongkey32bit(wrongkeystring.begin(), wrongkeystring.end());
 
-               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint);
+               ode::DMCryptEngine engine(test_real_blkdev, test_real_mntpoint, progressBar);
                engine.encrypt(key32bit);
 
                // check the encryption result of test_real_blkdev(/dev/loop0)
index cd00460..0f77ef4 100644 (file)
 #include <klay/testbench.h>
 
 #include "../server/engine/ecryptfs-engine.h"
+#include "../server/progress-bar.h"
+#include "../server/progress-vconf-backend.h"
 
-#define TEST_PATH      "/opt/usr"
+#define TEST_PATH   "/opt/usr"
 
 TESTCASE(EcryptfsGetPathTest)
 {
        try {
-               ode::EcryptfsEngine engine("/dev/mmcblkp0", "/opt/usr");
-               if (engine.getDestination() != "/dev/mmcblkp0") {
+               ode::VConfBackend vconfBackend(VCONFKEY_SDE_ENCRYPT_PROGRESS);
+               ode::ProgressBar progressBar(std::bind(&ode::VConfBackend::update, &vconfBackend, std::placeholders::_1));
+               ode::EcryptfsEngine engine("/dev/mmcblkp0", "/opt/usr", progressBar);
+               if (engine.getSource() != "/dev/mmcblkp0") {
                        throw runtime::Exception("Source doen't match");
                }
                if (engine.getDestination() != "/opt/usr") {
                        throw runtime::Exception("Destination doen't match");
                }
-       } catch (runtime::Exceptione) {
+       } catch (runtime::Exception &e) {
                TEST_FAIL(e.what());
        }
 }
index 7f6627d..c909347 100755 (executable)
@@ -25,7 +25,9 @@
 TESTCASE(Ext4GetPathTest)
 {
        try {
-               ode::Ext4Engine engine("/dev/mmcblkp0", "/opt/usr");
+               ode::VConfBackend vconfBackend(VCONFKEY_ODE_ENCRYPT_PROGRESS);
+               ode::ProgressBar progressBar(std::bind(&ode::VConfBackend::update, &vconfBackend, std::placeholders::_1));
+               ode::Ext4Engine engine("/dev/mmcblkp0", "/opt/usr", progressBar);
                if (engine.getDestination() != "/dev/mmcblkp0") {
                        throw runtime::Exception("Source doen't match");
                }
index 611c30b..5811840 100755 (executable)
@@ -24,6 +24,7 @@ PKG_CHECK_MODULES(EFL_APP REQUIRED
                capi-appfw-application
                capi-ui-efl-util
                evas
+               vconf
 )
 
 SET(ODE_APPS_ODE       ${ODE_APPS}/ode)
index 1c1bf07..f856cfd 100644 (file)
  * limitations under the License.
  *
  */
+
+#include <limits.h>
+#include <vconf.h>
+
 #include "ode.h"
 #include "widget.h"
 
 #define EDJ_PATH "/usr/apps/" PACKAGE "/res/" PACKAGE ".edj"
 
 static Evas_Object *win, *conform, *layout;
+static char key[PATH_MAX] = "";
+static int done = 0;
+
+static Eina_Bool progressbar_timer_cb(void *data)
+{
+       Evas_Object *progressbar = (Evas_Object *)data;
+       char *progress = NULL;
+       int percentage = 0;
+
+       if (done) {
+               ui_app_exit();
+               return ECORE_CALLBACK_DONE;
+       }
+
+       progress = vconf_get_str(key);
+       if (progress)
+               percentage = atoi(progress);
+
+       elm_progressbar_value_set(progressbar, (double)(percentage / 100.0));
+
+       if (percentage == 100) {
+               done = 1;
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       return ECORE_CALLBACK_PASS_ON;
+}
 
 void _create_base_window()
 {
@@ -37,10 +68,17 @@ void _create_base_window()
 
 void _create_progress_view(const char *type, const char *target)
 {
-       Evas_Object *progress_layout;
-       Evas_Object *progressbar;
+       Evas_Object *progress_layout, *progressbar;
        Evas_Object *title, *content;
-       char string[256];
+       char string[PATH_MAX] = "";
+
+       done = 0;
+
+       if (!strcmp(target, "Internal")) {
+               snprintf(key, PATH_MAX, "%s", VCONFKEY_ODE_ENCRYPT_PROGRESS);
+       } else if (!strcmp(target, "External")) {
+               snprintf(key, PATH_MAX, "%s", VCONFKEY_SDE_ENCRYPT_PROGRESS);
+       }
 
        progress_layout = _create_layout(layout, EDJ_PATH, "progress_layout");
 
@@ -52,12 +90,14 @@ void _create_progress_view(const char *type, const char *target)
 
        elm_object_part_content_set(progress_layout, "message_title", title);
 
-       progressbar = _create_progressbar(progress_layout, "pending");
+       progressbar = _create_progressbar(progress_layout, "default");
+       elm_progressbar_unit_format_set(progressbar, "%.0f%%");
        elm_object_part_content_set(progress_layout, "progress_indicator", progressbar);
 
        elm_object_part_content_set(progress_layout, "message_content", content);
-
        elm_object_part_content_set(layout, "elm.swallow.content", progress_layout);
 
+       elm_progressbar_value_set(progressbar, 0.0);
+       ecore_timer_add(1, progressbar_timer_cb, progressbar);
        return;
 }
index 99e926f..a1827ef 100644 (file)
@@ -110,6 +110,7 @@ static Eina_Bool progressbar_timer_cb(void *data)
        notification_h handle = NULL;
        char *progress = NULL;
        int percentage = 0;
+       double current_progress = 0.0, noti_progress = 0.0;
 
        handle = notification_load_by_tag("secure-erase-noti");
        if (handle == NULL) {
@@ -131,8 +132,12 @@ static Eina_Bool progressbar_timer_cb(void *data)
                ui_app_exit();
                return ECORE_CALLBACK_DONE;
        } else if (percentage < 100) {
-               notification_set_progress(handle, (double)(percentage / 100.0));
-               notification_update(handle);
+               current_progress = (double)(percentage / 100.0);
+               notification_get_progress(handle, &noti_progress);
+               if (current_progress != noti_progress) {
+                       notification_set_progress(handle, (double)(percentage / 100.0));
+                       notification_update(handle);
+               }
        }
 
        return ECORE_CALLBACK_PASS_ON;