Implement auto_close for apps using resource package 91/258191/14
authorIlho Kim <ilho159.kim@samsung.com>
Tue, 11 May 2021 10:31:37 +0000 (19:31 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Thu, 17 Jun 2021 05:12:18 +0000 (14:12 +0900)
If the resource package is updated when an app is using the package
with auto_close='true' option, the app is terminated

Change-Id: Iaeefaad42252a2eb725bf120344a6311d0010348
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
src/lib/amd_app_status.c
src/lib/amd_app_status.h
src/lib/amd_res_info.cc
src/lib/res_info/res_app_info.cc
src/lib/res_info/res_app_info.hh

index 778f10fc7a1108fd0cdab7ec8debe7531ac66bb8..0ac577d196bbbfa3b2126acaa753776dd4c6c835 100644 (file)
@@ -1300,6 +1300,56 @@ int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid)
        return 0;
 }
 
+static bool __need_to_kill_by_res_pkg(struct app_status_s *app_status,
+               const char *pkgid)
+{
+       GHashTable *res_pkg_tbl = _app_status_get_extra(
+                       app_status, APP_STATUS_RES_PACKAGE);
+       const char *auto_close;
+
+       if (!res_pkg_tbl)
+               return false;
+
+       if (!g_hash_table_contains(res_pkg_tbl, pkgid))
+               return false;
+
+       auto_close = (const char *)g_hash_table_lookup(res_pkg_tbl, pkgid);
+       if (auto_close && !strcmp(auto_close, "true"))
+               return true;
+
+       return false;
+}
+
+int _app_status_terminate_apps_by_res_pkgid(const char *pkgid, uid_t uid)
+{
+       GSList *iter;
+       struct app_status_s *app_status;
+       int ret;
+
+       if (pkgid == NULL)
+               return -1;
+
+       for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+               app_status = (struct app_status_s *)iter->data;
+               if (app_status->uid == uid &&
+                               app_status->status != STATUS_DYING &&
+                               __need_to_kill_by_res_pkg(app_status, pkgid)) {
+                       ret = _terminate_app_local(app_status->uid,
+                                       app_status->pid);
+                       if (ret < 0) {
+                               _E("Failed to terminate app(%d)",
+                                               app_status->pid);
+                       }
+
+                       _app_status_update_status(app_status, STATUS_DYING,
+                                       false, true);
+                       __delete_socket_path(app_status->pid, app_status->uid);
+               }
+       }
+
+       return 0;
+}
+
 int _app_status_get_appid_bypid(int fd, int pid)
 {
        int cmd = APP_GET_INFO_ERROR;
index bec8dd334c1a4c2435a3d6163a8c041bc44d634a..38746edf953d06ec3ec5c4aeedb5c65a34969b26 100644 (file)
@@ -28,6 +28,8 @@
 extern "C" {
 #endif
 
+#define APP_STATUS_RES_PACKAGE "res_package"
+
 typedef enum {
        AT_SERVICE_APP,
        AT_UI_APP,
@@ -137,6 +139,8 @@ int _app_status_terminate_apps(const char *appid, uid_t uid);
 
 int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid);
 
+int _app_status_terminate_apps_by_res_pkgid(const char *pkgid, uid_t uid);
+
 int _app_status_get_appid_bypid(int fd, int pid);
 
 int _app_status_get_pkgid_bypid(int fd, int pid);
index 0af59f95278e390f05ef6d4119167f5aef59e0ce..b65fac59031d5f3ac34b44cc838c5c1dedd994b7 100644 (file)
@@ -26,6 +26,7 @@
 #include <vector>
 #include <tuple>
 
+#include "lib/amd_app_status.h"
 #include "lib/amd_login_monitor.h"
 #include "lib/amd_noti.h"
 #include "lib/amd_res_info.h"
@@ -121,6 +122,7 @@ static int __on_package_update_start(const char* msg, int arg1, int arg2,
         continue;
 
       res_pkginfo->SetBlocking();
+      _app_status_terminate_apps_by_res_pkgid(pkgid, uids[i]);
     }
     free(uids);
     return NOTI_CONTINUE;
@@ -132,6 +134,7 @@ static int __on_package_update_start(const char* msg, int arg1, int arg2,
     return NOTI_CONTINUE;
 
   res_pkginfo->SetBlocking();
+  _app_status_terminate_apps_by_res_pkgid(pkgid, uid);
 
   return NOTI_CONTINUE;
 }
@@ -254,6 +257,56 @@ static int __on_package_update_error(const char* msg, int arg1, int arg2,
   return NOTI_CONTINUE;
 }
 
+static int __on_app_status_add(const char* msg, int arg1, int arg2,
+    void* arg3, bundle* b) {
+  app_status_h app_status = (app_status_h)arg3;
+  const char* appid = _app_status_get_appid(app_status);
+  uid_t uid = _app_status_get_uid(app_status);
+  std::shared_ptr<ResAppInfo> res_appinfo =
+      ResInfoManager::GetInst().GetUserResAppInfo(appid, uid);
+  if (!res_appinfo)
+    return NOTI_CONTINUE;
+
+  GHashTable* res_pkg_tbl = g_hash_table_new_full(g_str_hash,
+      g_str_equal, free, free);
+  if (!res_pkg_tbl) {
+    _E("Out of memory");
+    return NOTI_CONTINUE;
+  }
+
+  for (const auto& rc : res_appinfo->GetResControlList()) {
+    const std::shared_ptr<ResPkgInfo>& allowed_package = rc.GetAllowedPackage();
+    const std::shared_ptr<ResPkgInfo>& global_package = rc.GetGlobalPackage();
+    const std::string& auto_close = rc.GetAutoClose();
+    if (allowed_package) {
+      g_hash_table_insert(res_pkg_tbl,
+          strdup(allowed_package->GetPkgId().c_str()),
+          strdup(auto_close.c_str()));
+    }
+    if (global_package) {
+      g_hash_table_insert(res_pkg_tbl,
+          strdup(global_package->GetPkgId().c_str()),
+          strdup(auto_close.c_str()));
+    }
+  }
+
+  _app_status_set_extra(app_status, APP_STATUS_RES_PACKAGE, res_pkg_tbl);
+
+  return NOTI_CONTINUE;
+}
+
+static int __on_app_status_destroy(const char* msg, int arg1, int arg2,
+    void* arg3, bundle* data) {
+  app_status_h app_status = (app_status_h)arg3;
+  GHashTable* res_pkg_tbl = reinterpret_cast<GHashTable*>(
+      _app_status_get_extra(app_status, APP_STATUS_RES_PACKAGE));
+
+  if (res_pkg_tbl)
+    g_hash_table_destroy(res_pkg_tbl);
+
+  return NOTI_CONTINUE;
+}
+
 int _resinfo_init(void) {
   _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START,
       __on_login_monitor_login_start);
@@ -273,6 +326,10 @@ int _resinfo_init(void) {
       __on_package_update_end);
   _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
       __on_package_update_error);
+  _noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
+      __on_app_status_add);
+  _noti_listen(AMD_NOTI_MSG_APP_STATUS_DESTROY,
+      __on_app_status_destroy);
 
   return 0;
 }
index c9a7273188cf6de8a7be157bc2ab985c7523e0b6..31fc081f469f8eb23d2628fa205d9d8ef8a169a9 100644 (file)
 
 namespace amd {
 
+const std::string& ResControl::GetResType() const {
+  return res_type;
+}
+
+const std::string& ResControl::GetMinResVersion() const {
+  return min_res_version;
+}
+
+const std::string& ResControl::GetMaxResVersion() const {
+  return max_res_version;
+}
+
+const std::string& ResControl::GetAutoClose() const {
+  return auto_close;
+}
+
+const std::shared_ptr<ResPkgInfo>& ResControl::GetAllowedPackage() const {
+  return allowed_package;
+}
+
+const std::shared_ptr<ResPkgInfo>& ResControl::GetGlobalPackage() const {
+  return global_package;
+}
+
 std::shared_ptr<ResAppInfo> ResAppInfo::CreateResAppInfo(
     const pkgmgrinfo_appinfo_h handle, uid_t uid) {
   char* appid;
@@ -84,6 +108,10 @@ const std::string& ResAppInfo::GetAppId() {
   return appid_;
 }
 
+const std::vector<ResControl>& ResAppInfo::GetResControlList() {
+  return res_control_list_;
+}
+
 void ResAppInfo::ClearResControlMountInfo() {
   for (auto& res_control : res_control_list_) {
     res_control.allowed_package.reset();
index 5af5a58c52b6147535676fc97764394f0e0d18a4..ec729736eb02cd0f0aa556eb5fe7e23577898c65 100644 (file)
@@ -42,6 +42,13 @@ struct ResControl {
         allowed_package(nullptr),
         global_package(nullptr) {}
 
+  const std::string& GetResType() const;
+  const std::string& GetMinResVersion() const;
+  const std::string& GetMaxResVersion() const;
+  const std::string& GetAutoClose() const;
+  const std::shared_ptr<ResPkgInfo>& GetAllowedPackage() const;
+  const std::shared_ptr<ResPkgInfo>& GetGlobalPackage() const;
+
  private:
   std::string res_type;
   std::string min_res_version;
@@ -59,6 +66,7 @@ class ResAppInfo {
       const pkgmgrinfo_appinfo_h handle, uid_t uid);
 
   const std::string& GetAppId();
+  const std::vector<ResControl>& GetResControlList();
   void ClearResControlMountInfo();
   void UpdateResControlMountInfo(
       const std::map<std::string, std::shared_ptr<ResPkgInfo>>& res_pkgs);