Implement lightuser feature 18/274018/4
authorJunghyun Yeon <jungh.yeon@samsung.com>
Wed, 20 Apr 2022 05:25:58 +0000 (14:25 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Fri, 22 Apr 2022 05:47:08 +0000 (14:47 +0900)
- Add directory creation/deletion/clear logic for light user.

Change-Id: Ic8fc3dae52da1a2bbcc3257846ad4a527c1a6353
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
CMakeLists.txt
packaging/app-installers.spec
src/common/CMakeLists.txt
src/common/shared_dirs.cc
src/common/step/configuration/step_parse_manifest.cc
src/common/step/configuration/step_parse_manifest.h
src/common/step/filesystem/step_recover_change_owner.cc
src/common/step/filesystem/step_remove_files.cc
src/common/step/filesystem/step_remove_user_data.cc
src/common/utils/file_util.cc
src/common/utils/file_util.h

index 7bb5529..d7ec4b5 100644 (file)
@@ -66,6 +66,7 @@ PKG_CHECK_MODULES(LIBSYSTEMD_DEPS REQUIRED libsystemd)
 PKG_CHECK_MODULES(TTRACE_DEPS REQUIRED ttrace)
 PKG_CHECK_MODULES(TRUST_ANCHOR_DEPS REQUIRED tanchor)
 PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(LIBSESSIOND_DEPS REQUIRED libsessiond)
 
 FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem program_options iostreams)
 
index 950041b..cd30eab 100644 (file)
@@ -40,6 +40,7 @@ BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(tanchor)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(gmock)
+BuildRequires:  pkgconfig(libsessiond)
 
 Requires: ca-certificates-tizen
 Requires: libtzplatform-config
index 0a91410..5e6d804 100644 (file)
@@ -55,6 +55,7 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_COMMON} PUBLIC
   TTRACE_DEPS
   TRUST_ANCHOR_DEPS
   Boost
+  LIBSESSIOND_DEPS
 )
 
 # Extra
index 8d64368..89d3527 100644 (file)
@@ -83,7 +83,7 @@ const char kSkelAppDir[] = "skel/apps_rw";
 const char kExternalStoragePrivilege[] =
     "http://tizen.org/privilege/externalstorage.appdata";
 const char kSystemShareGroupName[] = "system_share";
-
+const char kSubssesionDir[] = "subsessions";
 // 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) {
@@ -412,6 +412,24 @@ bool PerformExternalDirectoryCreationForUser(uid_t user,
   if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
     return false;
 
+  for (auto& lw_user : GetLightUserList(user)) {
+    bf::path storage_apps_lw_path = storage_apps_path
+        / kSubssesionDir / lw_user / "apps";
+    if (!bf::exists(storage_apps_lw_path)) {
+      bs::error_code error;
+      bf::create_directories(storage_apps_lw_path, error);
+      if (error) {
+        LOG(ERROR) << "Failed to create directory: "
+                   << storage_apps_path.c_str();
+        return false;
+      }
+    }
+
+    if (CreateExternalUserDirectories(user, pkgid,
+        storage_apps_lw_path.string()))
+      return false;
+  }
+
   return true;
 }
 
@@ -425,8 +443,20 @@ bool PerformExternalDirectoryDeletionForUser(uid_t user,
   }
 
   bf::path storage_apps_path = bf::path(storage_path) / "apps";
-  return DeleteDirectories(
-      GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid);
+  if (!DeleteDirectories(
+      GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid))
+    return false;
+
+  for (auto& lw_user : GetLightUserList(user)) {
+    bf::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) {
@@ -530,31 +560,40 @@ bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
   UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
-    bf::path apps_rw = std::get<2>(l) / "apps_rw";
+    bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<bf::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 (auto entry : shared_dirs) {
+          bf::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;
+      }
     }
   }
 
@@ -578,17 +617,26 @@ bool DeletePerUserStorageDirectories(const std::string& pkgid,
   UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
-    bf::path apps_rw = std::get<2>(l) / "apps_rw";
+    bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<bf::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;
@@ -660,7 +708,14 @@ bool DeleteUserExternalDirectories(const std::string& pkgid) {
     if (!DeleteDirectories(apps_rw, pkgid)) {
       return false;
     }
+
+    for (auto& lw_user : GetLightUserList(uid)) {
+      bf::path apps_rw_lw(std::get<2>(l) / kSubssesionDir / lw_user / "apps_rw");
+      if (!DeleteDirectories(apps_rw_lw, pkgid))
+        return false;
+    }
   }
+
   return true;
 }
 
@@ -671,7 +726,6 @@ bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
     return false;
   }
 
-  bool result = true;
   UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
@@ -680,15 +734,28 @@ bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
     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;
+
+    bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<bf::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) {
+      bf::path dst_dir = apps_rw / pkgid;
+      if (!bf::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) {
@@ -717,24 +784,36 @@ bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
     return true;
   }
 
-  bool result = true;
   UserList list = ci::GetUserList();
   for (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;
+
+    bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+    std::vector<bf::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) {
+      bf::path dst_dir = apps_rw / pkgid;
+      if (!bf::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) {
@@ -808,22 +887,30 @@ bool CreatePerUserSharedDataDir(const std::string& pkgid) {
     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;
+    bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<bf::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;
-    }
 
-    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 (auto entry : shared_dirs) {
+        bf::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;
+      }
     }
   }
 
@@ -844,11 +931,19 @@ bool DeletePerUserSharedDataDir(const std::string& pkgid) {
   ci::UserList list = ci::GetUserList();
   for (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;
-  }
 
+    bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<bf::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;
 }
 
@@ -866,8 +961,17 @@ bool BackupPerUserSharedDataDir(const std::string& pkgid) {
   ci::UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
-    if (!BackupSharedDataDir(pkgid, uid))
-      return false;
+    bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<bf::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;
@@ -887,8 +991,17 @@ bool RestorePerUserSharedDataDir(const std::string& pkgid) {
   ci::UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
-    if (!RestoreSharedDataDir(pkgid, uid))
-      return false;
+    bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<bf::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;
+    }
   }
 
   return true;
@@ -908,8 +1021,17 @@ bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
   ci::UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
-    if (!RemoveBackupSharedDataDir(pkgid, uid))
-      return false;
+    bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+    std::vector<bf::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;
index b11ce10..906fda2 100644 (file)
@@ -16,6 +16,7 @@
 #include <tpk_manifest_handlers/dependencies_handler.h>
 #include <tpk_manifest_handlers/description_handler.h>
 #include <tpk_manifest_handlers/feature_handler.h>
+#include <tpk_manifest_handlers/light_user_handler.h>
 #include <tpk_manifest_handlers/package_handler.h>
 #include <tpk_manifest_handlers/privileges_handler.h>
 #include <tpk_manifest_handlers/profile_handler.h>
@@ -814,6 +815,26 @@ bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
   return true;
 }
 
+bool StepParseManifest::FillLightUserInfo(manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::LightUserInfo> light_user_info =
+      std::static_pointer_cast<const tpk::parse::LightUserInfo>(
+          parser_->GetManifestData(tpk::parse::LightUserInfo::Key()));
+  if (!light_user_info) {
+    manifest->light_user_switch_mode = strdup("default");
+    return true;
+  }
+
+  if (light_user_info->switch_mode().empty()) {
+    LOG(ERROR) << "Invalid switch mode";
+    return false;
+  }
+
+  manifest->light_user_switch_mode =
+      strdup(light_user_info->switch_mode().c_str());
+
+  return true;
+}
+
 bool StepParseManifest::CheckFeatures() {
   auto feature_info =
         std::static_pointer_cast<const tpk::parse::FeatureInfo>(
@@ -1307,6 +1328,8 @@ bool StepParseManifest::FillManifestX(manifest_x* manifest) {
     return false;
   if (!FillDependencyInfo(manifest))
     return false;
+  if (!FillLightUserInfo(manifest))
+    return false;
   return true;
 }
 
index 7d824b2..58f360b 100644 (file)
@@ -74,6 +74,7 @@ class StepParseManifest : public common_installer::Step {
   bool FillTrustAnchorInfo(manifest_x* manifest);
   bool FillDependencyInfo(manifest_x* manifest);
   bool FillComponentBasedApplicationInfo(manifest_x* manifest);
+  bool FillLightUserInfo(manifest_x* manifest);
   int GetSupportModeVal(std::string support_mode);
   bool CheckFeatures();
   void AppendSplashScreen(application_x* app, const std::string& src,
index 6a153a5..85177b7 100644 (file)
@@ -16,6 +16,7 @@
 #include <cassert>
 #include <cstring>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "common/utils/paths.h"
@@ -34,6 +35,7 @@ const char kData[] = "data";
 const char kShared[] = ".shared";
 const char kSharedTmp[] = ".shared_tmp";
 const char kSystemShareGroupName[] = "system_share";
+const char kSubssesionDir[] = "subsessions";
 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
 const gid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
 
@@ -86,20 +88,43 @@ Step::Status StepRecoverChangeOwner::RecoveryUpdate() {
     for (auto l : list) {
       uid_t lu = std::get<0>(l);
       gid_t lg = std::get<1>(l);
-      bf::path apps_rw = ci::GetRootAppPath(false, lu);
-      bf::path pkg_root = apps_rw / context_->pkgid.get();
-      if (!ci::SetPackageDirectoryOwnerAndPermissions(pkg_root, lu))
-        return Step::Status::ERROR;
-
-      if (!SetSharedDirOwnershipAndPermissions(apps_rw, context_->pkgid.get(),
-              lu, lg))
-        return Step::Status::ERROR;
+      bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+      std::vector<bf::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) {
+        bf::path pkg_root = apps_rw / context_->pkgid.get();
+        if (!ci::SetPackageDirectoryOwnerAndPermissions(pkg_root, lu))
+          return Step::Status::ERROR;
+
+        if (!SetSharedDirOwnershipAndPermissions(apps_rw,
+                context_->pkgid.get(), lu, lg))
+          return Step::Status::ERROR;
+      }
     }
   } else {
-    bf::path apps_rw = ci::GetRootAppPath(false, uid);
-      if (!SetSharedDirOwnershipAndPermissions(apps_rw, context_->pkgid.get(),
-              context_->uid.get(), *gid))
-        return Step::Status::ERROR;
+    ci::UserList list = ci::GetUserList();
+    for (auto& l : list) {
+      uid_t lu = std::get<0>(l);
+      if (lu != uid)
+        continue;
+
+      bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+      std::vector<bf::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 (!SetSharedDirOwnershipAndPermissions(apps_rw,
+                context_->pkgid.get(), context_->uid.get(), *gid))
+          return Step::Status::ERROR;
+      }
+    }
   }
 
   return ChangeOwnershipIconsAndManifest(gid, uid);
index a605741..e32943a 100644 (file)
@@ -24,6 +24,7 @@ namespace bf = boost::filesystem;
 namespace {
 
 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+const char kSubsesionDir[] = "subsessions";
 
 bool SkipRWDirectories(const bf::path& path) {
   static const std::vector<std::string> dirs_to_ignore = {
@@ -73,9 +74,6 @@ Step::Status StepRemoveFiles::precheck() {
 }
 
 Step::Status StepRemoveFiles::process() {
-  // Use RootAppPath + Pkgid because of ReadonlyUpdateUninstall
-  bf::path pkg_path = context_->GetPkgPath();
-
   // We need to unmount external storage before removing package directory
   // because mount point is inside
   if (context_->external_storage)
@@ -90,32 +88,41 @@ Step::Status StepRemoveFiles::process() {
   }
 
   bool is_error = false;
-  if (is_keep_rwdata) {
-    bool ret;
-    for (bf::directory_iterator itr(pkg_path); itr != bf::directory_iterator();
-        ++itr) {
-      if (bf::is_directory(itr->status())) {
-        if (SkipRWDirectories(itr->path().leaf())) {
-          LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
-          continue;
+  std::vector<bf::path> root_paths;
+  // Use RootAppPath + Pkgid because of ReadonlyUpdateUninstall
+  root_paths.push_back(context_->root_application_path.get());
+
+  for (auto& lw_user : GetLightUserList(context_->uid.get()))
+    root_paths.push_back(context_->root_application_path.get() / kSubsesionDir /
+                        lw_user);
+
+  for (auto& root_path : root_paths) {
+    if (is_keep_rwdata) {
+      bool ret;
+      for (bf::directory_iterator itr(root_path / context_->pkgid.get());
+          itr != bf::directory_iterator(); ++itr) {
+        if (bf::is_directory(itr->status())) {
+          if (SkipRWDirectories(itr->path().leaf())) {
+            LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
+            continue;
+          }
+          ret = RemoveAll(itr->path());
+        } else {
+          ret = Remove(itr->path());
         }
-        ret = RemoveAll(itr->path());
-      } else {
-        ret = Remove(itr->path());
+        if (!ret)
+          is_error = true;
       }
-      if (!ret)
+    } else {
+      if (!RemoveAll(root_path / context_->pkgid.get()) ||
+          !common_installer::DeleteSharedDirectories(root_path,
+              context_->pkgid.get()))
         is_error = true;
     }
-  } else {
-    if (!RemoveAll(pkg_path) ||
-        !common_installer::DeleteSharedDirectories(
-            context_->root_application_path.get(),
-            context_->pkgid.get()))
-      is_error = true;
-  }
 
-  if (is_error)
-    return Status::ERROR;
+    if (is_error)
+      return Status::ERROR;
+  }
 
   // Remove package files at extended storage
   if (context_->storage.get() == Storage::EXTENDED) {
@@ -126,6 +133,16 @@ Step::Status StepRemoveFiles::process() {
       return Status::APP_DIR_ERROR;
   }
 
+  for (auto& lw_user : GetLightUserList(context_->uid.get())) {
+    if (context_->storage.get() == Storage::EXTENDED) {
+      bf::path extended_path =
+          bf::path(GetExtendedRootAppPath(context_->uid.get())) /
+          kSubsesionDir / lw_user / context_->pkgid.get();
+      if (!RemoveAll(extended_path))
+        return Status::APP_DIR_ERROR;
+    }
+  }
+
   // Remove stored signature file
   if (!RemoveSignature(context_->pkgid.get(),
                         context_->is_readonly_package.get()))
index fc2fd20..83e0c6c 100644 (file)
@@ -5,6 +5,8 @@
 #include "common/step/filesystem/step_remove_user_data.h"
 
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "common/installer_context.h"
 #include "common/shared_dirs.h"
@@ -19,6 +21,7 @@ namespace {
 const char kDataDir[] = "data";
 const char kCacheDir[] = "cache";
 const char kSharedDir[] = ".shared";
+const char kSubssesionDir[] = "subsessions";
 
 bool RemoveContents(const bf::path& path) {
   if (!bf::exists(path))
@@ -45,19 +48,28 @@ Step::Status StepRemoveUserData::process() {
 
   UserList list = ci::GetUserList();
   for (auto l : list) {
-    bf::path apps_rw(std::get<2>(l) / "apps_rw");
-    if (!RemoveContents(apps_rw / context_->pkgid.get() / kDataDir)) {
-      LOG(ERROR) << "Failed to remove contents of data dir";
-      return Step::Status::APP_DIR_ERROR;
-    }
-    if (!RemoveContents(apps_rw / context_->pkgid.get() / kCacheDir)) {
-      LOG(ERROR) << "Failed to remove contents of cache dir";
-      return Step::Status::APP_DIR_ERROR;
-    }
-    if (!RemoveContents(
-            apps_rw / kSharedDir / context_->pkgid.get() / kDataDir)) {
-      LOG(ERROR) << "Failed to remove contents of shared/data dir";
-      return Step::Status::APP_DIR_ERROR;
+    uid_t uid = std::get<0>(l);
+    bf::path owner_apps_rw(std::get<2>(l) / "apps_rw");
+    std::vector<bf::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 (!RemoveContents(apps_rw / context_->pkgid.get() / kDataDir)) {
+        LOG(ERROR) << "Failed to remove contents of data dir";
+        return Step::Status::APP_DIR_ERROR;
+      }
+      if (!RemoveContents(apps_rw / context_->pkgid.get() / kCacheDir)) {
+        LOG(ERROR) << "Failed to remove contents of cache dir";
+        return Step::Status::APP_DIR_ERROR;
+      }
+        if (!RemoveContents(apps_rw / kSharedDir / context_->pkgid.get() /
+                            kDataDir)) {
+        LOG(ERROR) << "Failed to remove contents of shared/data dir";
+        return Step::Status::APP_DIR_ERROR;
+      }
     }
   }
 
index 76ce1de..5f3dda4 100644 (file)
@@ -8,6 +8,8 @@
 #include <unzip.h>
 #include <zlib.h>
 
+#include <sessiond.h>
+
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/filesystem/operations.hpp>
@@ -739,4 +741,21 @@ bf::path RelativePath(const bf::path& from,
   return result;
 }
 
+std::vector<std::string> GetLightUserList(uid_t uid) {
+  int user_count = 0;
+  int *user_list = nullptr;
+  int ret = subsession_get_user_list(
+      static_cast<int>(uid), &user_list, &user_count);
+  if (ret != TIZEN_ERROR_NONE) {
+    LOG(ERROR) << "Failed to get light user list : " << ret;
+    return {};
+  }
+
+  std::vector<std::string> result_list;
+  for (int i = 0; i < user_count; i++)
+    result_list.emplace_back(std::to_string(user_list[i]));
+
+  return result_list;
+}
+
 }  // namespace common_installer
index 19de7f6..983e685 100644 (file)
@@ -8,6 +8,7 @@
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/path.hpp>
 #include <string>
+#include <vector>
 
 namespace common_installer {
 
@@ -97,6 +98,8 @@ bool IsSubDir(const boost::filesystem::path& path,
 boost::filesystem::path RelativePath(const boost::filesystem::path& from,
                                      const boost::filesystem::path& to);
 
+std::vector<std::string> GetLightUserList(uid_t uid);
+
 }  // namespace common_installer
 
 #endif  // COMMON_UTILS_FILE_UTIL_H_