Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / shared_dirs.cc
index 447ce05..c0f0641 100644 (file)
@@ -7,11 +7,6 @@
 #include <manifest_parser/utils/logging.h>
 #include <manifest_parser/utils/version_number.h>
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/program_options.hpp>
-#include <boost/system/error_code.hpp>
-
 #include <glib.h>
 #include <gio/gio.h>
 #include <vcore/Certificate.h>
 #include <cstring>
 #include <cstdio>
 #include <exception>
+#include <filesystem>
 #include <iterator>
+#include <optional>
 #include <regex>
 #include <string>
+#include <system_error>
 #include <utility>
 #include <vector>
 #include <tuple>
 #include "common/utils/user_util.h"
 #include "common/utils/glist_range.h"
 
-namespace bf = boost::filesystem;
-namespace bpo = boost::program_options;
-namespace bs = boost::system;
 namespace ci = common_installer;
+namespace fs = std::filesystem;
 
 namespace {
 
@@ -83,38 +79,41 @@ const char kSkelAppDir[] = "skel/apps_rw";
 const char kExternalStoragePrivilege[] =
     "http://tizen.org/privilege/externalstorage.appdata";
 const char kSystemShareGroupName[] = "system_share";
+const char kSubssesionDir[] = "subsession";
 
 // the input path should be root directory of package.
 // for example: "../apps_rw/pkgid" or "../.shared/pkgid"
-bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
-  boost::optional<gid_t> gid = ci::GetGidByUid(uid);
+bool SetPackageDirectoryOwnerAndPermissions(const fs::path& path, uid_t uid) {
+  std::optional<gid_t> gid = ci::GetGidByUid(uid);
   if (!gid)
     return false;
 
-  bf::perms perms755 = bf::all_all ^ bf::group_write ^ bf::others_write;
-  bf::perms perms644 =
-      bf::owner_read | bf::owner_write | bf::group_read | bf::others_read;
-  bf::perms perms_setgid = perms755 | bf::set_gid_on_exe;
-  boost::optional<gid_t> system_share =
+  using fs::perms;
+  perms perms755 = perms::all ^ perms::group_write ^ perms::others_write;
+  perms perms644 = perms::owner_read | perms::owner_write |
+      perms::group_read | perms::others_read;
+  perms perms_setgid = perms755 | perms::set_gid;
+
+  std::optional<gid_t> system_share =
     ci::GetGidByGroupName(kSystemShareGroupName);
   // root path
   if (!ci::SetDirOwnershipAndPermissions(path, perms755, uid, *gid))
     return false;
 
-  for (bf::recursive_directory_iterator iter(path);
-      iter != bf::recursive_directory_iterator(); ++iter) {
-    if (bf::is_symlink(symlink_status(iter->path()))) {
+  for (fs::recursive_directory_iterator iter(path);
+      iter != fs::recursive_directory_iterator(); ++iter) {
+    if (fs::is_symlink(symlink_status(iter->path()))) {
       // skip symlink path
       continue;
-    } else if (bf::is_directory(iter->path()) && iter.level() == 0 &&
+    } else if (fs::is_directory(iter->path()) && iter.depth() == 0 &&
         (iter->path().filename() == ".mmc" ||
             iter->path().filename() == ".pkg" ||
             iter->path().filename() == "tep")) {
       // skip path which is related to mount or directory installer creates
       continue;
-    } else if (bf::is_directory(iter->path())) {
+    } else if (fs::is_directory(iter->path())) {
       bool is_rw = false;
-      if (iter.level() == 0 &&
+      if (iter.depth() == 0 &&
               (iter->path().filename() == kData ||
                iter->path().filename() == kCache))
         is_rw = true;
@@ -124,7 +123,7 @@ bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
         return false;
     } else {
       bool is_bin = false;
-      if (iter.level() == 1 && iter->path().parent_path().filename() == "bin")
+      if (iter.depth() == 1 && iter->path().parent_path().filename() == "bin")
         is_bin = true;
       if (!ci::SetDirOwnershipAndPermissions(
               iter->path(), is_bin ? perms755 : perms644, uid, *gid))
@@ -134,23 +133,23 @@ bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
   return true;
 }
 
-bf::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
+fs::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
   std::string username = ci::GetUsernameByUid(user);
   if (username.empty())
     return {};
 
-  bf::path apps_rw;
-  apps_rw = bf::path(apps_prefix.c_str()) / username / "apps_rw";
+  fs::path apps_rw;
+  apps_rw = fs::path(apps_prefix.c_str()) / username / "apps_rw";
   return apps_rw;
 }
 
-bool DeleteSharedDataDirectories(const bf::path& path,
+bool DeleteSharedDataDirectories(const fs::path& path,
                                  const std::string& pkgid) {
   if (!ci::RemoveAll(path / pkgid / kSharedDataDir))
     return false;
 
   std::vector<std::string> shared_dirs(kSharedDataEntries);
-  for (auto entry : shared_dirs) {
+  for (const auto& entry : shared_dirs) {
     if (!ci::RemoveAll(path / entry / pkgid))
       return false;
   }
@@ -158,19 +157,20 @@ bool DeleteSharedDataDirectories(const bf::path& path,
   return true;
 }
 
-bool CreateSharedDataDirectories(const bf::path& path,
+bool CreateSharedDataDirectories(const fs::path& path,
                                  const std::string& pkgid) {
   if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
-      !ci::CreateDir(path / kSharedTmpDir / pkgid))
+      !ci::CreateDir(path / kSharedTmpDir / pkgid) ||
+      !ci::CreateDir(path / pkgid / kShared))
     return false;
 
-  bf::current_path(path / pkgid / kShared);
-  if (bf::exists(path / pkgid / kShared / kData))
+  fs::current_path(path / pkgid / kShared);
+  if (fs::exists(path / pkgid / kShared / kData))
     return true;
-  bf::path relative_path = ci::RelativePath(path / kSharedDir / pkgid / kData,
-                                            bf::current_path() / kData);
-  bs::error_code error;
-  bf::create_symlink(relative_path, kData, error);
+  fs::path relative_path = fs::relative(path / kSharedDir / pkgid / kData,
+      fs::current_path());
+  std::error_code error;
+  fs::create_symlink(relative_path, kData, error);
   if (error) {
     LOG(ERROR) << "Failed to create symlink : " << error.message();
     return false;
@@ -179,8 +179,8 @@ bool CreateSharedDataDirectories(const bf::path& path,
   return true;
 }
 
-bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
-  bf::path base_dir = app_dir / pkgid;
+bool DeleteDirectories(const fs::path& app_dir, const std::string& pkgid) {
+  fs::path base_dir = app_dir / pkgid;
   if (!ci::RemoveAll(base_dir))
     return false;
   if (!DeleteSharedDataDirectories(app_dir, pkgid))
@@ -188,35 +188,35 @@ bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
   return true;
 }
 
-bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
+bool CreateSymlinkFiles(const fs::path& src_dir, const fs::path& dst_dir) {
   std::vector<std::string> rofiles(kReadOnlyEntries);
-  for (bf::directory_iterator file(src_dir);
-      file != bf::directory_iterator();
+  for (fs::directory_iterator file(src_dir);
+      file != fs::directory_iterator();
       ++file) {
-    if (bf::is_regular_file(file->path())) {
-      bf::path current(file->path());
-      bf::path file_name = current.filename();
+    if (fs::is_regular_file(file->path())) {
+      fs::path current(file->path());
+      fs::path file_name = current.filename();
       LOG(DEBUG) << "file_name: " << file_name;
       rofiles.push_back(file_name.string());
     }
   }
 
-  bs::error_code error;
+  std::error_code error;
   for (auto& entry : rofiles) {
-    bf::path src_path = src_dir / entry;
-    bf::path dst_path = dst_dir / entry;
-    if (!bf::exists(src_path)) {
+    fs::path src_path = src_dir / entry;
+    fs::path dst_path = dst_dir / entry;
+    if (!fs::exists(src_path)) {
       // check if symlink for .mmc/bin,lib,res, then do not skip
-      if (!bf::is_symlink(symlink_status(src_path))) {
+      if (!fs::is_symlink(symlink_status(src_path))) {
         LOG(INFO) << "src_path not exist : " << src_path;
         continue;
       }
     }
-    if (bf::exists(dst_path) || bf::is_symlink(symlink_status(dst_path))) {
+    if (fs::exists(dst_path) || fs::is_symlink(symlink_status(dst_path))) {
       LOG(WARNING) << "dst_path exist, skip : " << dst_path;
       continue;
     }
-    bf::create_symlink(src_path, dst_path, error);
+    fs::create_symlink(src_path, dst_path, error);
     if (error) {
       LOG(ERROR) << "Symlink creation failure src_path: " << src_path
                  << " dst_path: " << dst_path;
@@ -227,15 +227,15 @@ bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
   return true;
 }
 
-bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
-  bs::error_code error;
-  for (bf::directory_iterator file(dst_dir);
-      file != bf::directory_iterator();
+bool DeleteSymlinkFiles(const fs::path& src_dir, const fs::path& dst_dir) {
+  std::error_code error;
+  for (fs::directory_iterator file(dst_dir);
+      file != fs::directory_iterator();
       ++file) {
-    bf::path current(file->path());
-    if (!bf::is_symlink(symlink_status(current)))
+    fs::path current(file->path());
+    if (!fs::is_symlink(symlink_status(current)))
       continue;
-    bf::path resolved_path = bf::read_symlink(current, error);
+    fs::path resolved_path = fs::read_symlink(current, error);
     if (error) {
       LOG(ERROR) << "Failed to get resolved path of symlink: " << current
                  << ", error: " << error.message();
@@ -243,13 +243,13 @@ bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
     }
 
     LOG(DEBUG) << "resolved_path: " << resolved_path;
-    bf::path parent = resolved_path.parent_path();
+    fs::path parent = resolved_path.parent_path();
     if (parent.empty() || (parent != src_dir)) {
       LOG(WARNING) << "Parent is empty or not equal to src, parent: ("
                    << parent << ")";
       continue;
     }
-    bf::remove(current, error);
+    fs::remove(current, error);
     if (error) {
       LOG(ERROR) << "Symlink deletion failure for: " << current
                   << ", error: " << error.message();
@@ -257,9 +257,9 @@ bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
     }
     LOG(DEBUG) << "removed: " << current;
   }
-  bf::path shared_res = dst_dir / kSharedResDir;
-  if (bf::is_symlink(symlink_status(shared_res))) {
-      bf::remove(shared_res, error);
+  fs::path shared_res = dst_dir / kSharedResDir;
+  if (fs::is_symlink(symlink_status(shared_res))) {
+      fs::remove(shared_res, error);
       if (error) {
           LOG(ERROR) << "Symlink deletion failure for: " << shared_res
                      << ", error: " << error.message();
@@ -269,11 +269,11 @@ bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
   return true;
 }
 
-bool CreateStorageDirectories(const boost::filesystem::path& root_path,
+bool CreateStorageDirectories(const fs::path& root_path,
                               const std::string& pkgid,
                               bool trusted, bool shareddata,
                               const std::vector<const char*> additional_dirs) {
-  bf::path path(root_path / pkgid);
+  fs::path path(root_path / pkgid);
   if (!ci::CreateDir(path)) {
     LOG(ERROR) << "Failed to create dir: " << path;
     return false;
@@ -284,9 +284,9 @@ bool CreateStorageDirectories(const boost::filesystem::path& root_path,
   if (trusted)
     dirs.push_back(kSharedTrustedDir);
 
-  bs::error_code error;
+  std::error_code error;
   for (auto& entry : dirs) {
-    bf::path subpath = path / entry;
+    fs::path subpath = path / entry;
     if (!ci::CreateDir(subpath)) {
       LOG(ERROR) << "Failed to create directory: " << subpath;
       return false;
@@ -301,7 +301,7 @@ bool CreateStorageDirectories(const boost::filesystem::path& root_path,
       return false;
   }
 
-  bf::path shared_cache_path = path / kSharedCacheDir;
+  fs::path shared_cache_path = path / kSharedCacheDir;
   // remove shared/cache (do not support)
   if (!ci::RemoveAll(shared_cache_path))
     return false;
@@ -309,7 +309,7 @@ bool CreateStorageDirectories(const boost::filesystem::path& root_path,
   return true;
 }
 
-bool BackupSharedDataDirectories(const bf::path& apps_rw,
+bool BackupSharedDataDirectories(const fs::path& apps_rw,
     const std::string& pkgid) {
   if (!ci::MakeBackup(apps_rw / pkgid / kSharedDataDir))
     return false;
@@ -320,7 +320,7 @@ bool BackupSharedDataDirectories(const bf::path& apps_rw,
   return true;
 }
 
-bool RestoreSharedDataDirectories(const bf::path& apps_rw,
+bool RestoreSharedDataDirectories(const fs::path& apps_rw,
     const std::string& pkgid) {
   if (!ci::RestoreBackup(apps_rw / pkgid / kSharedDataDir))
     return false;
@@ -331,7 +331,7 @@ bool RestoreSharedDataDirectories(const bf::path& apps_rw,
   return true;
 }
 
-bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
+bool RemoveBackupSharedDataDirectories(const fs::path& apps_rw,
     const std::string& pkgid) {
   if (!ci::RemoveBackup(apps_rw / pkgid / kSharedDataDir))
     return false;
@@ -344,7 +344,7 @@ bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
 
 bool CreateExternalUserDirectories(uid_t user, const std::string& pkgid,
     const std::string& apps_prefix) {
-  boost::optional<gid_t> gid = ci::GetGidByUid(user);
+  std::optional<gid_t> gid = ci::GetGidByUid(user);
   if (!gid)
     return false;
 
@@ -357,7 +357,7 @@ bool CreateExternalUserDirectories(uid_t user, const std::string& pkgid,
   LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
              << *gid;
 
-  bf::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
+  fs::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
   if (apps_rw.empty()) {
     LOG(DEBUG) << "Directory not exists: " << apps_rw;
     return false;
@@ -390,17 +390,17 @@ std::string GetDirectoryPathForExternalStorage() {
 
 bool PerformExternalDirectoryCreationForUser(uid_t user,
                                              const std::string& pkgid) {
-  bf::path storage_path = GetExternalCardPath();
+  fs::path storage_path = GetExternalCardPath();
 
-  if (!bf::exists(storage_path)) {
+  if (!fs::exists(storage_path)) {
     LOG(WARNING) << "External storage (SD Card) is not mounted.";
     return false;
   }
 
-  bf::path storage_apps_path = storage_path / "apps";
-  if (!bf::exists(storage_apps_path)) {
-    bs::error_code error;
-    bf::create_directories(storage_apps_path, error);
+  fs::path storage_apps_path = storage_path / "apps";
+  if (!fs::exists(storage_apps_path)) {
+    std::error_code error;
+    fs::create_directories(storage_apps_path, error);
     if (error) {
       LOG(ERROR) << "Failed to create directory: "
           << storage_apps_path.c_str();
@@ -411,26 +411,56 @@ bool PerformExternalDirectoryCreationForUser(uid_t user,
   if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
     return false;
 
+  for (auto& lw_user : GetLightUserList(user)) {
+    fs::path storage_apps_lw_path = storage_apps_path
+        / kSubssesionDir / lw_user / "apps";
+    if (!fs::exists(storage_apps_lw_path)) {
+      std::error_code error;
+      fs::create_directories(storage_apps_lw_path, error);
+      if (error) {
+        LOG(ERROR) << "Failed to create directory: "
+                   << storage_apps_lw_path.c_str();
+        return false;
+      }
+    }
+
+    if (CreateExternalUserDirectories(user, pkgid,
+        storage_apps_lw_path.string()))
+      return false;
+  }
+
   return true;
 }
 
 bool PerformExternalDirectoryDeletionForUser(uid_t user,
                                              const std::string& pkgid) {
-  bf::path storage_path = GetExternalCardPath();
-  if (!bf::exists(storage_path)) {
+  fs::path storage_path = GetExternalCardPath();
+  if (!fs::exists(storage_path)) {
     LOG(WARNING) << "External storage (SD Card) is not mounted. "
         << "It will be ignored";
     return true;
   }
 
-  bf::path storage_apps_path = bf::path(storage_path) / "apps";
-  return DeleteDirectories(
-      GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid);
+  fs::path storage_apps_path = fs::path(storage_path) / "apps";
+  if (!DeleteDirectories(
+      GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid))
+    return false;
+
+  for (auto& lw_user : GetLightUserList(user)) {
+    fs::path storage_apps_lw_path =
+        storage_apps_path / kSubssesionDir / lw_user / "apps";
+    if (!DeleteDirectories(
+            GetDirectoryPathForStorage(user, storage_apps_lw_path.string()),
+            pkgid))
+      return false;
+  }
+
+  return true;
 }
 
 bool PerformExternalDirectoryCreationForAllUsers(const std::string& pkgid) {
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     if (!PerformExternalDirectoryCreationForUser(std::get<0>(l),
                                                  pkgid))
       LOG(WARNING) << "Could not create external storage directories for user: "
@@ -441,7 +471,7 @@ bool PerformExternalDirectoryCreationForAllUsers(const std::string& pkgid) {
 
 bool PerformExternalDirectoryCreationForAllPkgs() {
   UserList list = ci::GetUserList();
-  for (auto l  : list) {
+  for (const auto& l  : list) {
     uid_t uid = std::get<0>(l);
     pkgmgrinfo_pkginfo_filter_h filter_handle = nullptr;
     int ret = pkgmgrinfo_pkginfo_filter_create(&filter_handle);
@@ -456,14 +486,14 @@ bool PerformExternalDirectoryCreationForAllPkgs() {
 
     ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(filter_handle,
         [](const pkgmgrinfo_pkginfo_h handle, void* user_data) -> int {
-          uid_t uid =
+          uid_t u =
               static_cast<uid_t>(reinterpret_cast<uintptr_t>(user_data));
           char* pkgid = nullptr;
 
-          int ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
-          if (ret != PMINFO_R_OK)
+          int r = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+          if (r != PMINFO_R_OK)
             return -1;
-          if (!PerformExternalDirectoryCreationForUser(uid, pkgid))
+          if (!PerformExternalDirectoryCreationForUser(u, pkgid))
             return -1;
 
           return 0;
@@ -482,7 +512,7 @@ bool PerformExternalDirectoryCreationForAllPkgs() {
 
 bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
     ci::PkgQueryInterface pkg_query(pkgid, uid);
     LOG(DEBUG) << "Deleting directories for user: " << uid;
@@ -503,8 +533,8 @@ bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
     bool shareddata, bool is_readonly,
     const std::vector<const char*> additional_dirs) {
   // create skel dir
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!::CreateStorageDirectories(skel_apps_rw, pkgid, trusted, shareddata,
           additional_dirs)) {
     LOG(ERROR) << "Failed to create skeleton storage directories";
@@ -512,42 +542,57 @@ bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
   }
 
   std::string error_message;
-  if (!RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
-          kGlobalUserUid, is_readonly, &error_message)) {
+  if (!RegisterSecurityContextForPath(pkgid, {}, skel_apps_rw / pkgid,
+      kGlobalUserUid, is_readonly, &error_message)) {
     LOG(ERROR) << "Failed to register security context for path: "
                << skel_apps_rw / pkgid << ", error_message: " << error_message;
     return false;
   }
 
+  if (!is_readonly) {
+    fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+    if (!CreateSymlinkFiles(src_dir, skel_apps_rw / pkgid))
+      return false;
+  }
+
   // create per user dir
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    bf::path apps_rw = std::get<2>(l) / "apps_rw";
+    fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l)
+          / kSubssesionDir / lw_user / "apps_rw");
+
     LOG(DEBUG) << "Creating directories for user: " << uid;
-    if (!::CreateStorageDirectories(apps_rw, pkgid, trusted, shareddata,
-         additional_dirs)) {
-      LOG(ERROR) << "Failed to create storage directory for user: " << uid;
-      return false;
-    }
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!::CreateStorageDirectories(apps_rw, pkgid, trusted, shareddata,
+          additional_dirs)) {
+        LOG(ERROR) << "Failed to create storage directory for user: " << uid;
+        return false;
+      }
 
-    if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
-      return false;
+      if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+        return false;
 
-    if (shareddata) {
-      std::vector<std::string> shared_dirs(kSharedDataEntries);
-      for (auto entry : shared_dirs) {
-        bf::path shared_dst = apps_rw / entry / pkgid;
-        if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
-          return false;
+      if (shareddata) {
+        std::vector<std::string> shared_dirs(kSharedDataEntries);
+        for (const auto& entry : shared_dirs) {
+          fs::path shared_dst = apps_rw / entry / pkgid;
+          if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+            return false;
+        }
       }
-    }
 
-    if (!RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
-            false, &error_message)) {
-      LOG(ERROR) << "Failed to register security context for path: "
-                 << apps_rw / pkgid << ", error_message: " << error_message;
-      return false;
+      if (!RegisterSecurityContextForPath(pkgid, {}, apps_rw / pkgid, uid,
+          false, &error_message)) {
+        LOG(ERROR) << "Failed to register security context for path: "
+                   << apps_rw / pkgid << ", error_message: " << error_message;
+        return false;
+      }
     }
   }
 
@@ -557,8 +602,8 @@ bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
 bool DeletePerUserStorageDirectories(const std::string& pkgid,
     bool keep_rwdata) {
   // delete skel dir
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!ci::RemoveAll(skel_apps_rw / pkgid)) {
     LOG(ERROR) << "Failed to delete skeleton storage directories";
     return false;
@@ -569,25 +614,34 @@ bool DeletePerUserStorageDirectories(const std::string& pkgid,
 
   // delete per user dir
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    bf::path apps_rw = std::get<2>(l) / "apps_rw";
+    fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
     LOG(DEBUG) << "Deleting directories for user: " << uid;
-    if (!ci::RemoveAll(apps_rw / pkgid)) {
-      LOG(ERROR) << "Failed to delete storage directory for user: " << uid;
-      return false;
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!ci::RemoveAll(apps_rw / pkgid)) {
+        LOG(ERROR) << "Failed to delete storage directory for user: " << uid;
+        return false;
+      }
     }
+  }
 
-    if (!ci::DeletePerUserSharedDataDir(pkgid)) {
-      LOG(ERROR) << "Failed to delete per user shared data dir";
-      return false;
-    }
+  if (!ci::DeletePerUserSharedDataDir(pkgid)) {
+    LOG(ERROR) << "Failed to delete per user shared data dir";
+    return false;
   }
 
   return true;
 }
 
-bool CreateStorageDirectories(const boost::filesystem::path& path,
+bool CreateStorageDirectories(const fs::path& path,
                               const std::string& pkgid, uid_t uid,
                               bool trusted, bool shareddata) {
   if (!::CreateStorageDirectories(path, pkgid, trusted,
@@ -601,16 +655,16 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
 
   if (shareddata) {
     std::vector<std::string> shared_dirs(kSharedDataEntries);
-    for (auto entry : shared_dirs) {
-      bf::path shared_dst = path / entry / pkgid;
+    for (const auto& entry : shared_dirs) {
+      fs::path shared_dst = path / entry / pkgid;
       if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
         return false;
     }
   }
 
   std::string error_message;
-  if (!RegisterSecurityContextForPath(pkgid, path / pkgid, uid, false,
-                                      &error_message)) {
+  if (!RegisterSecurityContextForPath(pkgid, {}, path / pkgid, uid, false,
+      &error_message)) {
     LOG(ERROR) << "Failed to register security context for path: " << path
                << ", error_message: " << error_message;
     return false;
@@ -619,31 +673,27 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
   return true;
 }
 
-bool DeleteStorageDirectories(const boost::filesystem::path& path,
-                              const std::string& pkgid) {
-  std::vector<const char*> dirs;
-  dirs.assign(kEntries.begin() + 1, kEntries.end());
-  dirs.push_back(kSharedTrustedDir);
-  dirs.push_back(kSharedCacheDir);
-  for (auto& entry : dirs) {
-    bf::path subpath = path / pkgid / entry;
-    if (!ci::RemoveAll(subpath))
-      return false;
-  }
-  if (!DeleteSharedDataDirectories(path, pkgid))
-    return false;
-
-  return true;
+void RemoveRWDirectories(const fs::path& root) {
+  if (!RemoveAll(root / kCache))
+    LOG(ERROR) << "Failed to remove packaged cache directory";
+  if (!RemoveAll(root / kData))
+    LOG(ERROR) << "Failed to remove packaged data directory";
+  if (!RemoveAll(root / kSharedCacheDir))
+    LOG(ERROR) << "Failed to remove packaged shared/cache directory";
+  if (!RemoveAll(root / kSharedDataDir))
+    LOG(ERROR) << "Failed to remove packaged shared/data directory";
+  if (!RemoveAll(root / kSharedTrustedDir))
+    LOG(ERROR) << "Failed to remove packaged shared/trusted directory";
 }
 
-bool DeleteSharedDirectories(const bf::path& path,
+bool DeleteSharedDirectories(const fs::path& path,
                              const std::string& pkgid) {
   return DeleteSharedDataDirectories(path, pkgid);
 }
 
 bool DeleteUserExternalDirectories(const std::string& pkgid) {
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
     ci::PkgQueryInterface pkg_query(pkgid, uid);
     if (pkg_query.IsPackageInstalled()) {
@@ -653,52 +703,71 @@ bool DeleteUserExternalDirectories(const std::string& pkgid) {
 
     LOG(DEBUG) << "Deleting external directories of " << pkgid
                << ", for uid: " << uid;
-    bf::path apps_rw(std::get<2>(l) / "apps_rw");
+    fs::path apps_rw(std::get<2>(l) / "apps_rw");
     if (!DeleteDirectories(apps_rw, pkgid)) {
       return false;
     }
+
+    for (auto& lw_user : GetLightUserList(uid)) {
+      fs::path apps_rw_lw(std::get<2>(l) / kSubssesionDir / lw_user / "apps_rw");
+      if (!DeleteDirectories(apps_rw_lw, pkgid))
+        return false;
+    }
   }
+
   return true;
 }
 
 bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
-  bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
-  if (!bf::exists(src_dir)) {
+  fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+  if (!fs::exists(src_dir)) {
     LOG(ERROR) << "src_dir not exists";
     return false;
   }
 
-  bool result = true;
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
     LOG(DEBUG) << "Creating symlinks for uid: " << uid;
     // check installed user private app.
     ci::PkgQueryInterface pkg_query(pkgid, uid);
     if (pkg_query.IsPackageInstalled())
       continue;
-    bf::path apps_rw(std::get<2>(l) / "apps_rw");
-    bf::path dst_dir = apps_rw / pkgid;
-    if (!bf::exists(dst_dir)) {
-      LOG(WARNING) << "dst_dir not exists";
-      continue;
+
+    fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      fs::path dst_dir = apps_rw / pkgid;
+      if (!fs::exists(dst_dir)) {
+        LOG(WARNING) << "dst_dir not exists";
+        continue;
+      }
+
+      if (!CreateSymlinkFiles(src_dir, dst_dir))
+        return false;
     }
-    result = CreateSymlinkFiles(src_dir, dst_dir);
   }
-  return result;
+
+  return true;
 }
 
 bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
-  bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
-  if (!bf::exists(src_dir)) {
+  fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+  if (!fs::exists(src_dir)) {
     LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
     return true;
   }
 
   tzplatform_set_user(uid);
-  bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
+  fs::path dst_dir = fs::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
   tzplatform_reset_user();
-  if (!bf::exists(dst_dir)) {
+  if (!fs::exists(dst_dir)) {
     LOG(WARNING) << "dst_dir not exists";
     return true;
   }
@@ -708,43 +777,55 @@ bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
 }
 
 bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
-  bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
-  if (!bf::exists(src_dir)) {
+  fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+  if (!fs::exists(src_dir)) {
     LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
     return true;
   }
 
-  bool result = true;
   UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
     LOG(DEBUG) << "Deleting symlinks for uid: " << uid;
+
     // check installed user private app.
     ci::PkgQueryInterface pkg_query(pkgid, uid);
     if (pkg_query.IsPackageInstalled())
       continue;
-    bf::path apps_rw(std::get<2>(l) / "apps_rw");
-    bf::path dst_dir = apps_rw / pkgid;
-    if (!bf::exists(dst_dir)) {
-      LOG(WARNING) << "dst_dir not exists";
-      continue;
+
+    fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      fs::path dst_dir = apps_rw / pkgid;
+      if (!fs::exists(dst_dir)) {
+        LOG(WARNING) << "dst_dir not exists";
+        continue;
+      }
+
+      if (!DeleteSymlinkFiles(src_dir, dst_dir))
+        return false;
     }
-    result = DeleteSymlinkFiles(src_dir, dst_dir);
   }
-  return result;
+
+  return true;
 }
 
 bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
-  bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
-  if (!bf::exists(src_dir)) {
+  fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+  if (!fs::exists(src_dir)) {
     LOG(ERROR) << "src_dir not exists";
     return false;
   }
 
   tzplatform_set_user(uid);
-  bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
+  fs::path dst_dir = fs::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
   tzplatform_reset_user();
-  if (!bf::exists(dst_dir)) {
+  if (!fs::exists(dst_dir)) {
     LOG(WARNING) << "dst_dir not exists";
     return true;
   }
@@ -752,12 +833,12 @@ bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
   return result;
 }
 
-bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
+bool SetPackageDirectoryOwnerAndPermissions(const fs::path& path, uid_t uid) {
   return ::SetPackageDirectoryOwnerAndPermissions(path, uid);
 }
 
 bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
-  if (bf::exists(kDisableLegacySharedDataDirSupport))
+  if (fs::exists(kDisableLegacySharedDataDirSupport))
     return false;
   utils::VersionNumber api_ver(api_version);
   if (api_ver < ver30)
@@ -767,14 +848,14 @@ bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
 }
 
 bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
-  bf::path apps_rw = ci::GetRootAppPath(false, uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, uid);
   if (!CreateSharedDataDirectories(apps_rw, pkgid))
     return false;
 
-  bf::path path = apps_rw / pkgid;
+  fs::path path = apps_rw / pkgid;
   std::string error_message;
-  if (!ci::RegisterSecurityContextForPath(pkgid, path, uid, false,
-          &error_message)) {
+  if (!ci::RegisterSecurityContextForPath(pkgid, {}, path, uid, false,
+      &error_message)) {
     LOG(ERROR) << "Failed to register security context for path: " << path
                << ", error_message: " << error_message;
     return false;
@@ -785,15 +866,15 @@ bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
 
 bool CreatePerUserSharedDataDir(const std::string& pkgid) {
   // create skel dir
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   LOG(DEBUG) <<  "Creating directory : " << skel_apps_rw;
   if (!CreateSharedDataDirectories(skel_apps_rw, pkgid))
     return false;
 
   std::string error_message;
-  if (!ci::RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
-          kGlobalUserUid, false, &error_message)) {
+  if (!ci::RegisterSecurityContextForPath(pkgid, {}, skel_apps_rw / pkgid,
+      kGlobalUserUid, false, &error_message)) {
     LOG(ERROR) << "Failed to register security context for path: "
                << skel_apps_rw / pkgid << ", error_message: " << error_message;
     return false;
@@ -801,27 +882,34 @@ bool CreatePerUserSharedDataDir(const std::string& pkgid) {
 
   // create per user dir
   ci::UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
     LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
 
-    bf::path apps_rw = ci::GetRootAppPath(false, uid);
-    if (!CreateSharedDataDirectories(apps_rw, pkgid))
-      return false;
+    fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
 
-    std::vector<std::string> shared_dirs(kSharedDataEntries);
-    for (auto entry : shared_dirs) {
-      bf::path shared_dst = apps_rw / entry / pkgid;
-      if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!CreateSharedDataDirectories(apps_rw, pkgid))
         return false;
-    }
 
-    std::string error_message;
-    if (!ci::RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
-        false, &error_message)) {
-      LOG(ERROR) << "Failed to register security context for path: "
-                 << apps_rw / pkgid << ", error_message: " << error_message;
-      return false;
+      std::vector<std::string> shared_dirs(kSharedDataEntries);
+      for (const auto& entry : shared_dirs) {
+        fs::path shared_dst = apps_rw / entry / pkgid;
+        if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+          return false;
+      }
+
+      if (!ci::RegisterSecurityContextForPath(pkgid, {}, apps_rw / pkgid, uid,
+                                              false, &error_message)) {
+        LOG(ERROR) << "Failed to register security context for path: "
+                   << apps_rw / pkgid << ", error_message: " << error_message;
+        return false;
+      }
     }
   }
 
@@ -829,85 +917,159 @@ bool CreatePerUserSharedDataDir(const std::string& pkgid) {
 }
 
 bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid) {
-  bf::path apps_rw = ci::GetRootAppPath(false, uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, uid);
   return DeleteSharedDataDirectories(apps_rw, pkgid);
 }
 
 bool DeletePerUserSharedDataDir(const std::string& pkgid) {
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!DeleteSharedDataDirectories(skel_apps_rw, pkgid))
     return false;
 
   ci::UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    bf::path apps_rw = ci::GetRootAppPath(false, uid);
-    if (!DeleteSharedDataDirectories(apps_rw, pkgid))
-      return false;
-  }
 
+    fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!DeleteSharedDataDirectories(apps_rw, pkgid))
+        return false;
+    }
+  }
   return true;
 }
 
 bool BackupSharedDataDir(const std::string& pkgid, uid_t uid) {
-  bf::path apps_rw = ci::GetRootAppPath(false, uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, uid);
   return BackupSharedDataDirectories(apps_rw, pkgid);
 }
 
 bool BackupPerUserSharedDataDir(const std::string& pkgid) {
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!BackupSharedDataDirectories(skel_apps_rw, pkgid))
     return false;
 
   ci::UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    if (!BackupSharedDataDir(pkgid, uid))
-      return false;
+    fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!BackupSharedDataDirectories(apps_rw, pkgid))
+        return false;
+    }
   }
 
   return true;
 }
 
 bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid) {
-  bf::path apps_rw = ci::GetRootAppPath(false, uid);
-  return RestoreSharedDataDirectories(apps_rw, pkgid);
+  fs::path apps_rw = ci::GetRootAppPath(false, uid);
+  if (!RestoreSharedDataDirectories(apps_rw, pkgid))
+    return false;
+
+  if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+    return false;
+
+  std::vector<std::string> shared_dirs(kSharedDataEntries);
+  for (const auto& entry : shared_dirs) {
+    fs::path shared_dst = apps_rw / entry / pkgid;
+    if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+      return false;
+  }
+
+  std::string error_message;
+  if (!RegisterSecurityContextForPath(pkgid, {}, apps_rw / pkgid, uid, false,
+                                      &error_message)) {
+    LOG(ERROR) << "Failed to register security context for path: " << apps_rw
+               << ", error_message: " << error_message;
+    return false;
+  }
+
+  return true;
 }
 
 bool RestorePerUserSharedDataDir(const std::string& pkgid) {
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!RestoreSharedDataDirectories(skel_apps_rw, pkgid))
     return false;
 
+  std::string error_message;
   ci::UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    if (!RestoreSharedDataDir(pkgid, uid))
-      return false;
+    fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!RestoreSharedDataDirectories(apps_rw, pkgid))
+        return false;
+
+      if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+        return false;
+
+      std::vector<std::string> shared_dirs(kSharedDataEntries);
+      for (const auto& entry : shared_dirs) {
+        fs::path shared_dst = apps_rw / entry / pkgid;
+        if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+          return false;
+      }
+
+      if (!RegisterSecurityContextForPath(pkgid, {}, apps_rw / pkgid, uid,
+          false, &error_message)) {
+        LOG(ERROR) << "Failed to register security context for path: "
+                   << apps_rw / pkgid << ", error_message: " << error_message;
+        return false;
+      }
+    }
   }
 
   return true;
 }
 
 bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid) {
-  bf::path apps_rw = ci::GetRootAppPath(false, uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, uid);
   return RemoveBackupSharedDataDirectories(apps_rw, pkgid);
 }
 
 bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
-  bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-      bf::path(kSkelAppDir);
+  fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      fs::path(kSkelAppDir);
   if (!RemoveBackupSharedDataDirectories(skel_apps_rw, pkgid))
     return false;
 
   ci::UserList list = ci::GetUserList();
-  for (auto l : list) {
+  for (const auto& l : list) {
     uid_t uid = std::get<0>(l);
-    if (!RemoveBackupSharedDataDir(pkgid, uid))
-      return false;
+    fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<fs::path> apps_rw_paths;
+    apps_rw_paths.push_back(std::move(owner_apps_rw));
+    for (auto& lw_user : GetLightUserList(uid))
+      apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+                              "apps_rw");
+
+    for (auto& apps_rw : apps_rw_paths) {
+      if (!RemoveBackupSharedDataDirectories(apps_rw, pkgid))
+        return false;
+    }
   }
 
   return true;