#include <bundle.h>
#include <bundle_cpp.h>
#include <bundle_internal.h>
+#include <dlfcn.h>
#include <glib.h>
#include <iniparser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <atomic>
#include <memory>
+#include <mutex>
#include <string>
+#include <unordered_map>
#include <vector>
#include "aul/app_control/resolve_info.hh"
namespace {
+constexpr const char kPathAmdReady[] = "/run/.amd_ready";
+constexpr const char kPathLibAulServer[] = LIBDIR "/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,
void* user_data_;
};
+class AliasInfo {
+ public:
+ explicit AliasInfo(std::string alias_appid)
+ : alias_appid_(std::move(alias_appid)) {
+ }
+
+ std::string alias_appid_;
+ std::string appid_;
+};
+
+class AppSvcAlias {
+ public:
+ AppSvcAlias() = default;
+
+ void Load() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (loaded_)
+ return;
+
+ dictionary* dict = iniparser_load("/usr/share/appsvc/alias.ini");
+ if (dict == nullptr) {
+ loaded_ = true;
+ return;
+ }
+
+ std::string delimiter = "Alias:";
+ for (int i = 0; i < dict->n; ++i) {
+ if (dict->key[i] == nullptr || dict->val[i] == nullptr)
+ continue;
+
+ std::string key = dict->key[i];
+ key.erase(0, key.find(delimiter) + delimiter.length() + 1);
+ std::string value = dict->val[i];
+ map_[key] = value;
+ }
+
+ iniparser_freedict(dict);
+ loaded_ = true;
+ }
+
+ std::string GetAliasAppId(const std::string& alias_appid) {
+ auto found = map_.find(alias_appid);
+ if (found == map_.end())
+ return {};
+
+ SECURE_LOGD("alias_appid: %s, appid: %s",
+ alias_appid.c_str(), found->second.c_str());
+ return found->second;
+ }
+
+ private:
+ bool loaded_ = false;
+ std::unordered_map<std::string, std::string> map_;
+ std::mutex mutex_;
+};
+
+AppSvcAlias appsvc_alias;
+
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)
}
std::string GetAliasAppId(const char* appid) {
- dictionary* dic = iniparser_load("/usr/share/appsvc/alias.ini");
- if (dic == nullptr)
- return {};
-
- auto dic_ptr = std::unique_ptr<dictionary, decltype(iniparser_freedict)*>(
- dic, iniparser_freedict);
-
- std::string key = std::string("Alias:") + appid;
- const char* value = iniparser_getstring(dic, key.c_str(), nullptr);
- SECURE_LOGD("appid(%s), alias_id(%s)", appid, value);
- if (value == nullptr)
- return {};
-
- return std::string(value);
+ appsvc_alias.Load();
+ return appsvc_alias.GetAliasAppId(appid);
}
bool IsSpecialApp(const char* appid) {
const char* launch_mode = aul_svc_get_launch_mode(request);
if (launch_mode && !strcmp(launch_mode, "group")) {
int ret = bundle_get_type(request, AUL_K_INSTANCE_ID);
- if (ret != BUNDLE_TYPE_NONE)
+ if (ret == BUNDLE_TYPE_NONE)
aul_set_instance_info(appid.c_str(), request);
}
}
return AUL_SVC_RET_ENOMATCH;
case AUL_R_ECANCELED:
return AUL_SVC_RET_ECANCELED;
+ case AUL_R_ETIMEOUT:
+ return AUL_SVC_RET_ETIMEOUT;
default:
return AUL_SVC_RET_ELAUNCH;
}
bundle_del(b, AUL_SVC_K_RES_VAL);
auto* cb_info = static_cast<CbInfo*>(data);
+ if (cb_info == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
if (cb_info->res_fn_) {
cb_info->res_fn_(b, cb_info->request_code_,
static_cast<aul_svc_result_val>(res), cb_info->user_data_);
+ cb_info->res_fn_ = nullptr;
}
if (cb_info->err_cb_ != nullptr)
error = AulErrorConvert(error);
auto* cb_info = static_cast<CbInfo*>(data);
+ if (cb_info == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
if (cb_info->err_cb_) {
cb_info->err_cb_(cb_info->request_code_, error, cb_info->user_data_);
cb_info->err_cb_ = nullptr;
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;
+ }
+
+ auto dl_closer = [](void* ptr) {
+ dlclose(ptr);
+ };
+
+ std::unique_ptr<void, decltype(dl_closer)> handle_auto(handle, dl_closer);
+ 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) {
return AUL_SVC_RET_EINVAL;
}
- std::string alias_id = ::GetAliasAppId(appid);
- if (!alias_id.empty())
- appid = alias_id.c_str();
+ if (TIZEN_FEATURE_APPSVC_ALIAS) {
+ std::string alias_id = ::GetAliasAppId(appid);
+ if (!alias_id.empty())
+ return ::SetBundle(b, AUL_SVC_K_PKG_NAME, alias_id.c_str());
+ }
return ::SetBundle(b, AUL_SVC_K_PKG_NAME, appid);
}
extern "C" API int aul_svc_run_service_for_uid(bundle* b, int request_code,
aul_svc_res_fn cbfunc, void* data, uid_t uid) {
CbInfo* cb_info = nullptr;
- if (cbfunc)
+ if (cbfunc) {
cb_info = new (std::nothrow) CbInfo(request_code, cbfunc, nullptr, data);
+ if (cb_info == nullptr)
+ LOGE("Out of memory");
+ }
std::tuple<aul_svc_res_fn, void*> param { cbfunc, data };
int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
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);
CbInfo* cb_info = new (std::nothrow) CbInfo(request_code, cbfunc, err_cb,
user_data);
+ if (cb_info == nullptr)
+ _E("Out of memory");
+
int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
[](const std::string& appid, bundle* request, uid_t uid,
CbInfo* info) -> int {
auto* cb_info = new (std::nothrow) CbInfo(request_code, nullptr, err_cb,
user_data);
+ if (cb_info == nullptr)
+ _E("Out of memory");
+
int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
[](const std::string& appid, bundle* request, uid_t uid,
CbInfo* info) -> int {
free(appid_array);
}
+extern "C" API int aul_svc_set_window_position(bundle* b,
+ int x, int y, int w, int h) {
+ if (b == nullptr) {
+ _E("Invalid parameter");
+ return AUL_SVC_RET_EINVAL;
+ }
+
+ ::SetBundle(b, AUL_K_HINT_SCREEN_POS_X, std::to_string(x).c_str());
+ ::SetBundle(b, AUL_K_HINT_SCREEN_POS_Y, std::to_string(y).c_str());
+ ::SetBundle(b, AUL_K_HINT_SCREEN_WIDTH, std::to_string(w).c_str());
+ ::SetBundle(b, AUL_K_HINT_SCREEN_HEIGHT, std::to_string(h).c_str());
+
+ return AUL_SVC_RET_OK;
+}
+
+extern "C" API int aul_svc_get_window_position(bundle* b,
+ int* x, int* y, int* w, int* h) {
+ if (b == nullptr ||
+ x == nullptr ||
+ y == nullptr ||
+ w == nullptr ||
+ h == nullptr) {
+ _E("Invalid parameter");
+ return AUL_SVC_RET_EINVAL;
+ }
+
+ char* x_str = nullptr;
+ char* y_str = nullptr;
+ char* w_str = nullptr;
+ char* h_str = nullptr;
+
+ bundle_get_str(b , AUL_K_HINT_SCREEN_POS_X, &x_str);
+ bundle_get_str(b , AUL_K_HINT_SCREEN_POS_Y, &y_str);
+ bundle_get_str(b , AUL_K_HINT_SCREEN_WIDTH, &w_str);
+ bundle_get_str(b , AUL_K_HINT_SCREEN_HEIGHT, &h_str);
+
+ if (x_str == nullptr ||
+ y_str == nullptr ||
+ w_str == nullptr ||
+ h_str == nullptr) {
+ _E("failed to get position");
+ return AUL_SVC_RET_ERROR;
+ }
+
+ *x = atoi(x_str);
+ *y = atoi(y_str);
+ *w = atoi(w_str);
+ *h = atoi(h_str);
+
+ return AUL_SVC_RET_OK;
+}
+
extern "C" API int aul_svc_set_defapp(const char* op, const char* mime_type,
const char* uri, const char* defapp) {
DEPRECATION_WARNING();