Fix aul_svc_get_appid_by_alias_appid_for_uid() function 22/260522/1
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 28 Jun 2021 08:15:07 +0000 (17:15 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 28 Jun 2021 08:15:07 +0000 (17:15 +0900)
If the amd ready file is not existed, the caller process accesses to the
database directly to get the appid using the alias appid.

Change-Id: I964e3b0b3d82ac699214a1b963b109e081bce619
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/aul_svc.cc

index 4f98330..252d029 100644 (file)
@@ -17,6 +17,7 @@
 #include <bundle.h>
 #include <bundle_cpp.h>
 #include <bundle_internal.h>
+#include <dlfcn.h>
 #include <glib.h>
 #include <iniparser.h>
 #include <stdio.h>
@@ -26,6 +27,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <atomic>
 #include <memory>
 #include <string>
 #include <vector>
 
 namespace {
 
+constexpr const char kPathAmdReady[] = "/run/.amd_ready";
+constexpr const char kPathLibAulServer[] = "/usr/lib/libaul-server.so.0";
+constexpr const char kAulServiceForeachUsrAliasInfo[] =
+    "aul_service_foreach_usr_alias_info";
+
 class CbInfo {
  public:
   CbInfo(int request_code, aul_svc_res_fn res_fn,
@@ -76,6 +83,16 @@ class CbInfo {
   void* user_data_;
 };
 
+class AliasInfo {
+ public:
+  AliasInfo(std::string alias_appid)
+      : alias_appid_(std::move(alias_appid)) {
+  }
+
+  std::string alias_appid_;
+  std::string appid_;
+};
+
 int SetBundle(bundle* b, const char* key, const char* value) {
   if (bundle_get_type(b, key) != BUNDLE_TYPE_NONE) {
     if (bundle_del(b, key) != BUNDLE_ERROR_NONE)
@@ -316,6 +333,68 @@ int SendAndReceive(int cmd, uid_t uid, bundle* request, bundle** response) {
   return AUL_SVC_RET_OK;
 }
 
+std::atomic<bool> amd_ready { false };
+bool IsAmdReady() {
+  if (amd_ready)
+    return amd_ready;
+
+  if (access(kPathAmdReady, F_OK) == 0) {
+    amd_ready.exchange(true);
+    return amd_ready;
+  }
+
+  return false;
+}
+
+using AulServiceAliasInfoCb =
+    bool (*)(const char*, const char*, void*);
+using AulServiceForeachUsrAliasInfoFunc =
+    int (*)(AulServiceAliasInfoCb, uid_t, void*);
+
+int GetAppIdByAliasAppIdFromDB(const char* alias_appid, char** app_id,
+    uid_t uid) {
+  void* handle = dlopen(kPathLibAulServer, RTLD_LAZY | RTLD_GLOBAL);
+  if (handle == nullptr) {
+    _E("dlopen() is failed. path(%s), error(%s)", kPathLibAulServer, dlerror());
+    return AUL_SVC_RET_ERROR;
+  }
+
+  std::unique_ptr<void, decltype(dlclose)*> handle_auto(handle, dlclose);
+  auto* func = reinterpret_cast<AulServiceForeachUsrAliasInfoFunc>(
+      dlsym(handle, kAulServiceForeachUsrAliasInfo));
+  if (func == nullptr) {
+    _E("dlsym() is failed. error(%s)", dlerror());
+    return AUL_SVC_RET_ERROR;
+  }
+
+  AliasInfo info(alias_appid);
+  int ret = func(
+      [](const char* alias_appid, const char* appid, void* user_data) -> bool {
+        auto* info = static_cast<AliasInfo*>(user_data);
+        if (info->alias_appid_ == alias_appid) {
+          info->appid_ = appid;
+          return false;
+        }
+
+        return true;
+      }, uid, &info);
+  if (ret != 0) {
+    _E("%s() is failed. error(%d)", kAulServiceForeachUsrAliasInfo, ret);
+    return AUL_SVC_RET_ERROR;
+  }
+
+  if (info.appid_.empty())
+    return AUL_SVC_RET_ERROR;
+
+  *app_id = strdup(info.appid_.c_str());
+  if (*app_id == nullptr) {
+    _E("strdup() is failed");
+    return AUL_SVC_RET_ENOMEM;
+  }
+
+  return AUL_SVC_RET_OK;
+}
+
 }  // namespace
 
 extern "C" API int aul_svc_set_operation(bundle* b, const char* operation) {
@@ -684,6 +763,9 @@ extern "C" API int aul_svc_get_appid_by_alias_appid_for_uid(
     return AUL_SVC_RET_EINVAL;
   }
 
+  if (!IsAmdReady())
+    return GetAppIdByAliasAppIdFromDB(alias_appid, appid, uid);
+
   bundle* response;
   tizen_base::Bundle request;
   request.Add(AUL_K_ALIAS_APPID, alias_appid);