Resolve implicit launch 38/244538/14
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 21 Sep 2020 10:04:28 +0000 (19:04 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 25 Sep 2020 05:24:59 +0000 (14:24 +0900)
To improve implicit launch performance, AMD finds the matched
applications when getting the implicit launch request.

Change-Id: I6519a314835ce2b69150c670bff281a0e880d7a9
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
37 files changed:
CMakeLists.txt
packaging/amd.spec
src/lib/CMakeLists.txt
src/lib/amd_app_control.cc [new file with mode: 0644]
src/lib/amd_app_control.h [new file with mode: 0644]
src/lib/amd_appinfo.c
src/lib/amd_config.h
src/lib/amd_launch.c
src/lib/amd_main.c
src/lib/api/amd_api_noti_msg.h
src/lib/app_control/app_control_resolver.hh [new file with mode: 0644]
src/lib/app_control/appsvc_chunk.hh [new file with mode: 0644]
src/lib/app_control/appsvc_db.cc [new file with mode: 0644]
src/lib/app_control/appsvc_db.hh [new file with mode: 0644]
src/lib/app_control/appsvc_manager.cc [new file with mode: 0644]
src/lib/app_control/appsvc_manager.hh [new file with mode: 0644]
src/lib/app_control/resolve_info.cc [new file with mode: 0644]
src/lib/app_control/resolve_info.hh [new file with mode: 0644]
src/lib/app_control/resolver.cc [new file with mode: 0644]
src/lib/app_control/resolver.hh [new file with mode: 0644]
src/lib/app_control/scheme_host_resolver.cc [new file with mode: 0644]
src/lib/app_control/scheme_host_resolver.hh [new file with mode: 0644]
src/lib/app_control/scheme_resolver.cc [new file with mode: 0644]
src/lib/app_control/scheme_resolver.hh [new file with mode: 0644]
src/lib/app_control/uri_resolver.cc [new file with mode: 0644]
src/lib/app_control/uri_resolver.hh [new file with mode: 0644]
src/lib/app_info/app_control_info.hh [new file with mode: 0644]
src/lib/app_info/app_info.cc [new file with mode: 0644]
src/lib/app_info/app_info.hh [new file with mode: 0644]
src/lib/app_info/app_info_chunk.hh [new file with mode: 0644]
src/lib/app_info/app_info_manager.cc [new file with mode: 0644]
src/lib/app_info/app_info_manager.hh [new file with mode: 0644]
src/lib/common/database.cc [new file with mode: 0644]
src/lib/common/database.hh [new file with mode: 0644]
src/lib/common/exception.hh [new file with mode: 0644]
src/lib/common/key_private.hh
src/lib/common/util.hh [new file with mode: 0644]

index 311063e70f34c71ddec3816a92d710ca5fc7af80..70a4ce716d8a5f2aa421e3ace9794f89eaf4da65 100644 (file)
@@ -40,6 +40,9 @@ SET(TARGET_AMD_MOD_WATCHDOG "amd-mod-watchdog")
 SET(TARGET_AMD_MOD_WAYLAND_CORE "amd-mod-wayland-core")
 SET(TARGET_AMD_MOD_WIDGET "amd-mod-widget")
 
+ENABLE_TESTING()
+SET(TARGET_AMD_UNIT_TESTS "amd-unit-tests")
+
 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
@@ -65,6 +68,7 @@ PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
 PKG_CHECK_MODULES(RUA_DEPS REQUIRED rua)
 PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager)
 PKG_CHECK_MODULES(SENSOR_DEPS REQUIRED sensor)
+PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3)
 PKG_CHECK_MODULES(TANCHOR_DEPS REQUIRED tanchor)
 PKG_CHECK_MODULES(TIZEN_EXTENSION_CLIENT_DEPS REQUIRED tizen-extension-client)
 PKG_CHECK_MODULES(TIZEN_LAUNCH_CLIENT_DEPS REQUIRED tizen-launch-client)
index 395eaa44dad931b4b1193ffdade7a7c0cd392b3a..8ad2ee3b15b583436be835de5d09cff2424cae63 100644 (file)
@@ -19,34 +19,39 @@ Requires(preun):  /usr/bin/systemctl
 Requires:   tizen-platform-config
 
 BuildRequires:  cmake
-BuildRequires:  pkgconfig(glib-2.0)
-BuildRequires:  pkgconfig(gio-2.0)
-BuildRequires:  pkgconfig(bundle)
-BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(security-manager)
-BuildRequires:  pkgconfig(rua)
 BuildRequires:  pkgconfig(aul)
-BuildRequires:  pkgconfig(vconf)
-BuildRequires:  pkgconfig(pkgmgr-info)
-BuildRequires:  pkgconfig(pkgmgr)
-BuildRequires:  pkgconfig(libtzplatform-config)
-BuildRequires:  pkgconfig(libsystemd)
+BuildRequires:  pkgconfig(bundle)
+BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(cert-svc-vcore)
 BuildRequires:  pkgconfig(cynara-client-async)
 BuildRequires:  pkgconfig(cynara-creds-socket)
 BuildRequires:  pkgconfig(cynara-session)
-BuildRequires:  pkgconfig(cert-svc-vcore)
-BuildRequires:  pkgconfig(xkbcommon)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(gio-2.0)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(iniparser)
+BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  pkgconfig(libsystemd)
+BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(pkgmgr)
+BuildRequires:  pkgconfig(pkgmgr-info)
+BuildRequires:  pkgconfig(rua)
+BuildRequires:  pkgconfig(security-manager)
 BuildRequires:  pkgconfig(sensor)
-BuildRequires:  pkgconfig(ttrace)
-BuildRequires:  pkgconfig(wayland-client)
+BuildRequires:  pkgconfig(sqlite3)
+BuildRequires:  pkgconfig(tanchor)
 BuildRequires:  pkgconfig(tizen-extension-client)
 BuildRequires:  pkgconfig(tizen-launch-client)
-BuildRequires:  pkgconfig(wayland-tbm-client)
-BuildRequires:  pkgconfig(capi-system-info)
-BuildRequires:  pkgconfig(libsmack)
-BuildRequires:  pkgconfig(iniparser)
+BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(uuid)
-BuildRequires:  pkgconfig(tanchor)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(wayland-client)
+BuildRequires:  pkgconfig(wayland-tbm-client)
+BuildRequires:  pkgconfig(xkbcommon)
+
+%if 0%{?gcov:1}
+BuildRequires:  lcov
+%endif
 
 %description
 Application management daemon
@@ -204,6 +209,15 @@ Group:      Application Framework/Service
 %description -n amd-mod-loader-manager
 This module is for managing loaders
 
+%if 0%{?gcov:1}
+%package gcov
+Summary:    AMD (gcov)
+Group:      Application Framework/Testing
+
+%description gcov
+AMD gcov objects
+%endif
+
 %define _moddir %{_datadir}/amd
 
 %if "%{?_prelink_enable}" == "y"
@@ -218,6 +232,13 @@ sed -i 's|TZ_SYS_DB|%{TZ_SYS_DB}|g' %{SOURCE1001}
 cp %{SOURCE1001} .
 
 %build
+%if 0%{?gcov:1}
+export CFLAGS+=" -fprofile-arcs -ftest-coverage"
+export CXXFLAGS+=" -fprofile-arcs -ftest-coverage"
+export FFLAGS+=" -fprofile-arcs -ftest-coverage"
+export LDFLAGS+=" -lgcov"
+%endif
+
 %if 0%{?simulator}
 CFLAGS="%{optflags} -D__emul__"; export CFLAGS
 %endif
@@ -242,10 +263,20 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 
 %__make %{?_smp_mflags}
 
+%if 0%{?gcov:1}
+mkdir -p gcov-obj
+find . -name '*.gcno' -exec cp '{}' gcov-obj ';'
+%endif
+
 %install
 rm -rf %{buildroot}
 %make_install
 
+%if 0%{?gcov:1}
+mkdir -p %{buildroot}%{_datadir}/gcov/obj
+install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
+%endif
+
 mkdir -p %{buildroot}%{_tmpfilesdir}
 mkdir -p %{buildroot}%{_unitdir}/basic.target.wants
 mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants
@@ -400,3 +431,8 @@ systemctl daemon-reload
 %manifest %{name}.manifest
 %license LICENSE
 %{_moddir}/mod/libamd-mod-loader-manager.so
+
+%if 0%{?gcov:1}
+%files gcov
+%{_datadir}/gcov/*
+%endif
index e82be44036c502721c477ed545820934f7975d9e..570c45d87156339f22b3acfad3579a1e97730708 100644 (file)
@@ -1,12 +1,22 @@
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} LIB_SRCS)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/api LIB_API_SRCS)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/app_com LIB_APP_COM_SRCS)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/common LIB_COMMON_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}
+  LIB_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/api
+  LIB_API_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/app_com
+  LIB_APP_COM_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/app_control
+  LIB_APP_CONTROL_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/app_info
+  LIB_APP_INFO_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/common
+  LIB_COMMON_SRCS)
 
 ADD_LIBRARY(${TARGET_LIB_AMD} SHARED
   ${LIB_SRCS}
   ${LIB_API_SRCS}
   ${LIB_APP_COM_SRCS}
+  ${LIB_APP_CONTROL_SRCS}
+  ${LIB_APP_INFO_SRCS}
   ${LIB_COMMON_SRCS}
 )
 SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES SOVERSION ${MAJORVER})
@@ -35,6 +45,7 @@ APPLY_PKG_CONFIG(${TARGET_LIB_AMD} PUBLIC
   LIBTZPLATFORM_CONFIG_DEPS
   PKGMGR_DEPS
   PKGMGR_INFO_DEPS
+  SQLITE3_DEPS
   TTRACE_DEPS
   UUID_DEPS
   VCONF_DEPS
diff --git a/src/lib/amd_app_control.cc b/src/lib/amd_app_control.cc
new file mode 100644 (file)
index 0000000..6899461
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <bundle_cpp.h>
+#include <pkgmgr-info.h>
+
+#include "lib/amd_app_control.h"
+#include "lib/amd_config.h"
+#include "lib/amd_login_monitor.h"
+#include "lib/amd_noti.h"
+#include "lib/amd_request.h"
+#include "lib/amd_util.h"
+#include "lib/api/aul_svc_priv_key.h"
+#include "lib/app_control/app_control_resolver.hh"
+#include "lib/app_control/appsvc_manager.hh"
+#include "lib/app_info/app_info_manager.hh"
+#include "lib/common/exception.hh"
+
+using namespace amd;
+
+namespace {
+
+static const char APP_CONTROL_OPERATION_GUIDE_PRIVACY_SETTING[] =
+    "http://tizen.org/appcontrol/operation/guide_privacy_setting";
+
+}  // namespace
+
+static bool __is_special_app(const std::string& app_id) {
+  if (app_id == APP_SELECTOR || app_id == SHARE_PANEL)
+    return true;
+
+  return false;
+}
+
+static bool __is_special_operation(const std::string& operation) {
+  if (operation == APP_CONTROL_OPERATION_GUIDE_PRIVACY_SETTING)
+    return true;
+
+  return false;
+}
+
+static void __verify_request(tizen_base::Bundle& b) {
+  int ret = b.GetType(AUL_K_FORCE_LAUNCH_APP_SELECTOR);
+  if (ret != BUNDLE_TYPE_NONE) {
+    b.Delete(AUL_K_APPID);
+    b.Add(AUL_K_APPID, APP_SELECTOR);
+  }
+
+  std::string operation = b.GetString(AUL_SVC_K_OPERATION);
+  std::string app_id = b.GetString(AUL_K_APPID);
+  if (__is_special_app(app_id) || __is_special_operation(operation)) {
+    b.Delete(AUL_SVC_K_CAN_BE_LEADER);
+    b.Add(AUL_SVC_K_CAN_BE_LEADER, "true");
+    b.Delete(AUL_SVC_K_REROUTE);
+    b.Add(AUL_SVC_K_REROUTE, "true");
+    b.Delete(AUL_SVC_K_RECYCLE);
+    b.Add(AUL_SVC_K_RECYCLE, "true");
+  }
+}
+
+int _app_control_resolve(uid_t uid, bundle* b) {
+  tizen_base::Bundle kb(b, false, false);
+  std::string app_id = kb.GetString(AUL_K_APPID);
+  if (app_id != "@UNKNOWN") {
+    __verify_request(kb);
+    return 0;
+  }
+
+  kb.Delete(AUL_K_APPID);
+  ResolveInfo info;
+  try {
+    info = ResolveInfo::Manager::Create(kb);
+  } catch (Exception& e) {
+    _E("Exception(%d) occurs", e.GetErrorCode());
+    return e.GetErrorCode();
+  }
+
+  _D("operation(%s), uri(%s), mime(%s)",
+      info.GetOperation().c_str(),
+      info.GetUri().c_str(),
+      info.GetMime().c_str());
+  std::vector<std::string> result;
+  if (TIZEN_FEATURE_SHARE_PANEL &&
+      (info.GetOperation() == AUL_SVC_OPERATION_SHARE ||
+       info.GetOperation() == AUL_SVC_OPERATION_MULTI_SHARE ||
+       info.GetOperation() == AUL_SVC_OPERATION_SHARE_TEXT)) {
+    result.push_back(SHARE_PANEL);
+    kb.Add(AUL_K_APPID, SHARE_PANEL);
+    kb.Add(AUL_K_APPID_LIST, result);
+    return 0;
+  }
+
+  result = AppControlResolver::GetInst().Resolve(uid, info);
+  if (result.size() == 0)
+    return -ENOENT;
+
+  if (result.size() == 1) {
+    kb.Add(AUL_K_APPID, result[0].c_str());
+  } else {
+    kb.Add(AUL_K_APPID, APP_SELECTOR);
+    kb.Add(AUL_SVC_K_URI_R_INFO, info.GetUriRInfo());
+  }
+
+  kb.Add(AUL_K_APPID_LIST, result);
+  __verify_request(kb);
+  _W("app_id(%s)", kb.GetString(AUL_K_APPID).c_str());
+  return 0;
+}
+
+static int __on_appinfo_insert(const char* msg, int arg1, int arg2, void* arg3,
+    bundle* arg4) {
+  uid_t uid = static_cast<uid_t>(arg1);
+  pkgmgrinfo_appinfo_h handle = static_cast<pkgmgrinfo_appinfo_h>(arg3);
+  AppInfoManager::GetInst().AddAppInfo(uid, handle);
+  return 0;
+}
+
+static int __on_appinfo_remove(const char* msg, int arg1, int arg2, void* arg3,
+    bundle* arg4) {
+  uid_t uid = static_cast<uid_t>(arg1);
+  char* appid = static_cast<char*>(arg3);
+  std::string app_id(appid);
+  AppInfoManager::GetInst().RemoveAppInfo(uid, app_id);
+  return 0;
+}
+
+static int __on_app_property_set_app_control_default_app(const char* msg,
+    int arg1, int arg2, void* arg3, bundle* arg4) {
+  tizen_base::Bundle b(arg4);
+  uid_t uid = static_cast<uid_t>(arg1);
+  AppSvcManager::GetInst().AddAppSvc(uid, b);
+  return 0;
+}
+
+static int __on_app_property_unset_app_control_default_app(const char* msg,
+    int arg1, int arg2, void* arg3, bundle* arg4) {
+  uid_t uid = static_cast<uid_t>(arg1);
+  char* app_id = static_cast<char*>(arg3);
+  AppSvcManager::GetInst().RemoveAppSvc(uid, app_id);
+  return 0;
+}
+
+static int __on_login_monitor_login(const char* msg,
+    int arg1, int arg2, void* arg3, bundle* arg4) {
+  uid_state state = static_cast<uid_state>(arg2);
+  if (state == UID_STATE_OPENING) {
+    uid_t uid = static_cast<uid_t>(arg1);
+    AppSvcManager::GetInst().LoadAppSvc(uid);
+  }
+
+  return 0;
+}
+
+static int __dispatch_app_get_appid_list(request_h req) {
+  uid_t target_uid = _request_get_target_uid(req);
+  bundle* b = _request_get_bundle(req);
+  int ret = _app_control_resolve(target_uid, b);
+  if (ret == 0)
+    ret = _request_get_cmd(req);
+  else
+    _E("_app_control_resolve() is failed. error(%d)", ret);
+
+  aul_sock_send_bundle_with_fd(_request_remove_fd(req), ret,
+      b, AUL_SOCK_NOREPLY);
+  _I("[APP_GET_APPID_LIST] result: %d", ret);
+  return 0;
+}
+
+int _app_control_resolver_init(void) {
+  static request_cmd_dispatch dispatch_table[] = {
+      {
+        .cmd = APP_GET_APPID_LIST,
+        .callback = __dispatch_app_get_appid_list
+      },
+  };
+
+  _D("APP_CONTROL_RESOLVER_INIT");
+  AppControlResolver::GetInst();
+
+  int ret = _request_register_cmds(dispatch_table,
+      ARRAY_SIZE(dispatch_table));
+  if (ret < 0)
+    return ret;
+
+  _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT,
+      __on_appinfo_insert);
+  _noti_listen(AMD_NOTI_MSG_APPINFO_REMOVE,
+      __on_appinfo_remove);
+  _noti_listen(AMD_NOTI_MSG_APP_PROPERTY_SET_APP_CONTROL_DEFAULT_APP,
+      __on_app_property_set_app_control_default_app);
+  _noti_listen(AMD_NOTI_MSG_APP_PROPERTY_UNSET_APP_CONTROL_DEFAULT_APP,
+      __on_app_property_unset_app_control_default_app);
+  _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN,
+      __on_login_monitor_login);
+  return 0;
+}
+
+void _app_control_resolver_fini(void) {
+  _D("APP_CONTROL_RESOLVER_FINI");
+}
diff --git a/src/lib/amd_app_control.h b/src/lib/amd_app_control.h
new file mode 100644 (file)
index 0000000..2247103
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __AMD_APP_CONTROL_H__
+#define __AMD_APP_CONTROL_H__
+
+#include <bundle.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _app_control_resolve(uid_t uid, bundle *b);
+
+int _app_control_resolver_init(void);
+
+void _app_control_resolver_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_APP_CONTROL_H__ */
index 724e4f4980a2b59276fa98e701b13dbe843621f5..2f8a107250bc4bf696619c4e27360d330acbabf6 100644 (file)
@@ -1167,6 +1167,7 @@ static struct user_appinfo *__add_user_appinfo(uid_t uid)
 {
        int r;
        struct user_appinfo *info;
+       pkgmgrinfo_appinfo_get_option option;
 
        info = calloc(1, sizeof(struct user_appinfo));
        if (info == NULL) {
@@ -1185,9 +1186,10 @@ static struct user_appinfo *__add_user_appinfo(uid_t uid)
 
        g_hash_table_insert(user_tbl, GINT_TO_POINTER(uid), info);
 
+       option = PMINFO_APPINFO_GET_CATEGORY | PMINFO_APPINFO_GET_APP_CONTROL |
+               PMINFO_APPINFO_GET_SPLASH_SCREEN;
        r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
-                       __appinfo_insert_handler, uid,
-                       PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
+                       __appinfo_insert_handler, uid, option, info);
        if (r != PMINFO_R_OK) {
                __remove_user_appinfo(uid);
                return NULL;
@@ -1861,12 +1863,14 @@ static void __reload_appinfo(gpointer key, gpointer value, gpointer user_data)
 {
        int r;
        struct user_appinfo *info = (struct user_appinfo *)value;
+       pkgmgrinfo_appinfo_get_option option;
 
        g_hash_table_remove_all(info->tbl);
 
+       option = PMINFO_APPINFO_GET_CATEGORY | PMINFO_APPINFO_GET_APP_CONTROL |
+               PMINFO_APPINFO_GET_SPLASH_SCREEN;
        r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
-                       __appinfo_insert_handler, info->uid,
-                       PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
+                       __appinfo_insert_handler, info->uid, option, info);
        if (r != PMINFO_R_OK) {
                __remove_user_appinfo(info->uid);
                return;
index 0e19506cfbb2ab12711c1ce46e0c4caddff1a865..138d4b197fd8626d9cc32e66cfa576755105edfd 100644 (file)
@@ -32,14 +32,19 @@ typedef enum {
 
 tizen_profile_t _config_get_tizen_profile(void);
 
-#define TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP \
+#define TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP                               \
        (!(_config_get_tizen_profile() & (TIZEN_PROFILE_TV)))
 
-#define TIZEN_FEATURE_BLOCK_INPUT \
-       (!(_config_get_tizen_profile() & (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
+#define TIZEN_FEATURE_BLOCK_INPUT                                              \
+       (!(_config_get_tizen_profile() &                                       \
+          (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
 
-#define TIZEN_FEATURE_AUTO_ROTATION \
-       (!(_config_get_tizen_profile() & (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
+#define TIZEN_FEATURE_AUTO_ROTATION                                            \
+       (!(_config_get_tizen_profile() &                                       \
+          (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
+
+#define TIZEN_FEATURE_SHARE_PANEL                                              \
+       (_config_get_tizen_profile() & TIZEN_PROFILE_MOBILE)
 
 unsigned int _config_get_onboot_interval(void);
 
index 538974bf19d5b5377ac3394b7c21ea5f35999ed1..7879341b652ae94d410ac532eed326459a4d421a 100644 (file)
@@ -43,8 +43,8 @@
 #include <vconf.h>
 
 #include "amd_anr_monitor.h"
-#include "amd_api_noti.h"
 #include "amd_app_com.h"
+#include "amd_app_control.h"
 #include "amd_app_property.h"
 #include "amd_app_status.h"
 #include "amd_appinfo.h"
@@ -1443,6 +1443,7 @@ static int __dispatch_app_start(request_h req)
        if (kb == NULL)
                return -1;
 
+       _app_control_resolve(_request_get_target_uid(req), kb);
        ret = __set_real_appid(_request_get_target_uid(req), kb);
        if (ret == 0 && _request_get_cmd(req) == APP_RESUME)
                bundle_del(kb, AUL_K_INSTANCE_ID);
index aa6b1ccbb7a83c599e96e3d1159c559c8d38056f..21cbb98b0920cceba9f55b813b53b81e57d92119 100644 (file)
@@ -31,8 +31,8 @@
 
 #include "amd_anr_monitor.h"
 #include "amd_api.h"
-#include "amd_api_noti.h"
 #include "amd_app_com.h"
+#include "amd_app_control.h"
 #include "amd_app_property.h"
 #include "amd_app_status.h"
 #include "amd_appinfo.h"
@@ -363,6 +363,7 @@ static int __init(void)
        _launcher_service_init();
        _signal_init();
        _launchpad_init();
+       _app_control_resolver_init();
 
        if (access(AMD_MOD_PATH, F_OK) == 0) {
                if (__load_modules(AMD_MOD_PATH) < 0)
@@ -390,6 +391,7 @@ static void __finish(void)
 {
        __unload_modules();
 
+       _app_control_resolver_fini();
        _launchpad_fini();
        _launcher_service_fini();
        _anr_monitor_fini();
index c7cd4049b3f9f9bacd5297859e3067452e009c1a..34cee26aa595fac6887093cdf497d2e1f5b36285 100644 (file)
@@ -938,6 +938,25 @@ extern "C" {
 #define AMD_NOTI_MSG_APP_GROUP_ACTIVATE_BELOW                                  \
        "app_gorup.activate_below"
 
+/**
+ * @brief Definition for the notification message: Sets default app of app-control.
+ * @details Input: arg1(uid_t) The user ID.\n
+ *          Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 6.0
+ * @see __dispatch_app_set_app_control_default_app()
+ */
+#define AMD_NOTI_MSG_APP_PROPERTY_SET_APP_CONTROL_DEFAULT_APP                  \
+       "app_property.set_app_control_default_app"
+
+/**
+ * @brief Definition for the notification message: Unsets default app of app-control.
+ * @details Input: arg1(uid_t) The user ID.\n
+ *          Input: arg3(const char *) The application ID.\n
+ * @since_tizen 6.0
+ * @see __dispatch_app_unset_app_control_default_app()
+ */
+#define AMD_NOTI_MSG_APP_PROPERTY_UNSET_APP_CONTROL_DEFAULT_APP                \
+       "app_property.unset_app_control_default_app"
 
 #ifdef __cplusplus
 }
diff --git a/src/lib/app_control/app_control_resolver.hh b/src/lib/app_control/app_control_resolver.hh
new file mode 100644 (file)
index 0000000..a93547c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_APP_CONTROL_RESOLVER_HH_
+#define LIB_APP_CONTROL_APP_CONTROL_RESOLVER_HH_
+
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "lib/app_control/resolver.hh"
+#include "lib/app_control/scheme_host_resolver.hh"
+#include "lib/app_control/scheme_resolver.hh"
+#include "lib/app_control/uri_resolver.hh"
+
+namespace amd {
+
+class AppControlResolver {
+ private:
+  AppControlResolver() = default;
+  ~AppControlResolver() {
+    if (!disposed_)
+      Dispose();
+  }
+
+ public:
+  static AppControlResolver& GetInst() {
+    static AppControlResolver inst;
+    if (inst.disposed_)
+      inst.Init();
+    return inst;
+  }
+
+  void Dispose() {
+    resolver_.reset();
+    disposed_ = true;
+  }
+
+  std::vector<std::string> Resolve(uid_t uid, const ResolveInfo& info) {
+    return resolver_->Resolve(uid, info);
+  }
+
+ private:
+  void Init() {
+    resolver_ = std::shared_ptr<Resolver>(
+        new (std::nothrow) UriResolver());
+    auto scheme_host_resolver = std::shared_ptr<Resolver>(
+        new (std::nothrow) SchemeHostResolver());
+    auto scheme_resolver = std::shared_ptr<Resolver>(
+        new (std::nothrow) SchemeResolver());
+    resolver_->SetNext(scheme_host_resolver)->SetNext(scheme_resolver);
+    disposed_ = false;
+  }
+
+ private:
+  bool disposed_ = true;
+  std::shared_ptr<Resolver> resolver_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_APP_CONTROL_RESOLVER_HH_
diff --git a/src/lib/app_control/appsvc_chunk.hh b/src/lib/app_control/appsvc_chunk.hh
new file mode 100644 (file)
index 0000000..37fa8b3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_APPSVC_CHUNK_HH_
+#define LIB_APP_CONTROL_APPSVC_CHUNK_HH_
+
+#include <string>
+#include <map>
+
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+class AppSvcChunk {
+ public:
+  AppSvcChunk() = default;
+  virtual ~AppSvcChunk() = default;
+
+  void Add(const std::string& app_control, const std::string& app_id) {
+    auto found = map_.find(app_control);
+    if (found != map_.end())
+      map_.erase(found);
+
+    map_[app_control] = app_id;
+  }
+
+  void Remove(const std::string& app_id) {
+    auto iter = map_.begin();
+    while (iter != map_.end()) {
+      if (iter->second == app_id)
+        iter = map_.erase(iter);
+      else
+        ++iter;
+    }
+  }
+
+  std::string Get(const std::string& app_control) {
+    auto found = map_.find(app_control);
+    if (found == map_.end())
+      return {};
+
+    return map_[app_control];
+  }
+
+ private:
+  std::map<std::string, std::string> map_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_APPSVC_CHUNK_HH_
diff --git a/src/lib/app_control/appsvc_db.cc b/src/lib/app_control/appsvc_db.cc
new file mode 100644 (file)
index 0000000..980cecf
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lib/app_control/appsvc_db.hh"
+#include "lib/common/key_private.hh"
+
+namespace amd {
+
+AppSvcDB::AppSvcDB(uid_t uid) : Database(GetDBPath(uid)) {
+}
+
+AppSvcDB::~AppSvcDB() = default;
+
+std::map<std::string, std::string> AppSvcDB::Select() {
+  static const char query[] = "SELECT operation, mime_type, uri, pkg_name "
+      "FROM appsvc;";
+  sqlite3_stmt* stmt;
+  __PREPARE_V2(GetHandle(), query, strlen(query), stmt);
+  std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_ptr(stmt,
+      sqlite3_finalize);
+
+  std::map<std::string, std::string> result;
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    int index = 0;
+    std::string operation = ColumnText(stmt, index++);
+    std::string mime_type = ColumnText(stmt, index++);
+    std::string uri = ColumnText(stmt, index++);
+    std::string pkg_name = ColumnText(stmt, index++);
+
+    std::string app_control(std::move(operation));
+    app_control += "|";
+    app_control += uri;
+    app_control += "|";
+    app_control += mime_type;
+
+    result[app_control] = pkg_name;
+  }
+
+  return result;
+}
+
+void AppSvcDB::Delete(const std::string& pkg_name) {
+  static const char query[] = "DELETE FROM appsvc WEHRE pkg_name = ?;";
+  sqlite3_stmt* stmt;
+  __PREPARE_V2(GetHandle(), query, strlen(query), stmt);
+  std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_ptr(stmt,
+      sqlite3_finalize);
+  __BIND_TEXT(GetHandle(), stmt, 1, pkg_name.c_str());
+  __STEP(GetHandle(), stmt);
+}
+
+std::string AppSvcDB::GetDBPath(uid_t uid) {
+  std::string db_path(tzplatform_getenv(TZ_SYS_DB));
+  if (uid != GLOBAL_USER)
+    db_path += "/user/" + std::to_string(uid);
+
+  db_path += "/.appsvc.db";
+  return db_path;
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/appsvc_db.hh b/src/lib/app_control/appsvc_db.hh
new file mode 100644 (file)
index 0000000..9aa1266
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_APPSVC_DB_HH_
+#define LIB_APP_CONTROL_APPSVC_DB_HH_
+
+#include <unistd.h>
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "lib/common/database.hh"
+
+namespace amd {
+
+class AppSvcDB : public Database {
+ public:
+  AppSvcDB(uid_t uid);
+  virtual ~AppSvcDB();
+
+  std::map<std::string, std::string> Select();
+  void Delete(const std::string& pkg_name);
+
+ private:
+  static std::string GetDBPath(uid_t uid);
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_APPSVC_DB_HH_
diff --git a/src/lib/app_control/appsvc_manager.cc b/src/lib/app_control/appsvc_manager.cc
new file mode 100644 (file)
index 0000000..96ed1aa
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lib/app_control/appsvc_db.hh"
+#include "lib/app_control/appsvc_manager.hh"
+#include "lib/common/exception.hh"
+#include "lib/api/aul_svc_priv_key.h"
+
+namespace amd {
+
+void AppSvcManager::AddAppSvc(uid_t uid, tizen_base::Bundle b) {
+  std::string operation = b.GetString(AUL_SVC_K_OPERATION);
+  std::string mime_type = b.GetString(AUL_SVC_K_MIME);
+  std::string uri = b.GetString(AUL_SVC_K_URI);
+  std::string pkg_name = b.GetString(AUL_SVC_K_PKG_NAME);
+
+  std::string app_control(std::move(operation));
+  app_control += "|";
+  app_control += uri.empty() ? "NULL" : uri;
+  app_control += "|";
+  app_control += mime_type.empty() ? "NULL" : mime_type;
+
+  AddAppSvc(uid, app_control, pkg_name);
+}
+
+void AppSvcManager::AddAppSvc(uid_t uid, const std::string& app_control,
+    const std::string& app_id) {
+  if (!PrepareAppSvcChunk(uid))
+    return;
+
+  appsvc_chunk_[uid]->Add(app_control, app_id);
+}
+
+void AppSvcManager::RemoveAppSvc(uid_t uid, const std::string& app_id) {
+  if (!PrepareAppSvcChunk(uid))
+    return;
+
+  appsvc_chunk_[uid]->Remove(app_id);
+}
+
+void AppSvcManager::LoadAppSvc(uid_t uid) {
+  if (!PrepareAppSvcChunk(uid))
+    return;
+
+  AppSvcDB db(uid);
+  try {
+    db.Open();
+    if (!db.IntegrityCheck())
+      return;
+
+    for (auto& kv : db.Select())
+      AddAppSvc(uid, kv.first, kv.second);
+  } catch (Exception& e) {
+    _E("Exception(%d) occurs", e.GetErrorCode());
+  }
+}
+
+std::string AppSvcManager::GetDefaultAppId(uid_t uid,
+    const std::string& app_control) {
+  if (!PrepareAppSvcChunk(uid))
+    return {};
+
+  return appsvc_chunk_[uid]->Get(app_control);
+}
+
+bool AppSvcManager::PrepareAppSvcChunk(uid_t uid) {
+  auto found = appsvc_chunk_.find(uid);
+  if (found != appsvc_chunk_.end())
+    return true;
+
+  auto* chunk = new (std::nothrow) AppSvcChunk();
+  if (chunk == nullptr) {
+    _E("Out of memory");
+    return false;
+  }
+
+  appsvc_chunk_[uid] = std::shared_ptr<AppSvcChunk>(chunk);
+  return true;
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/appsvc_manager.hh b/src/lib/app_control/appsvc_manager.hh
new file mode 100644 (file)
index 0000000..e0f9f07
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_APPSVC_MANAGER_HH_
+#define LIB_APP_CONTROL_APPSVC_MANAGER_HH_
+
+#include <bundle_cpp.h>
+#include <sys/types.h>
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "lib/app_control/appsvc_chunk.hh"
+
+namespace amd {
+
+class AppSvcManager {
+ private:
+  AppSvcManager() = default;
+  ~AppSvcManager() = default;
+
+ public:
+  static AppSvcManager& GetInst() {
+    static AppSvcManager inst;
+    return inst;
+  }
+
+  void AddAppSvc(uid_t uid, tizen_base::Bundle b);
+  void AddAppSvc(uid_t uid, const std::string& app_control,
+      const std::string& app_id);
+  void RemoveAppSvc(uid_t uid, const std::string& app_id);
+  void LoadAppSvc(uid_t uid);
+  std::string GetDefaultAppId(uid_t uid, const std::string& app_control);
+
+ private:
+  bool PrepareAppSvcChunk(uid_t uid);
+
+ private:
+  std::map<uid_t, std::shared_ptr<AppSvcChunk>> appsvc_chunk_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_APPSVC_MANAGER_HH_
diff --git a/src/lib/app_control/resolve_info.cc b/src/lib/app_control/resolve_info.cc
new file mode 100644 (file)
index 0000000..0e2f5c7
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aul.h>
+#include <errno.h>
+#include <glib.h>
+
+#include "lib/app_control/resolve_info.hh"
+#include "lib/common/exception.hh"
+#include "lib/common/key_private.hh"
+#include "lib/common/util.hh"
+#include "lib/api/aul_svc_priv_key.h"
+
+namespace amd {
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetPkgName(std::string pkg_name) {
+  pkg_name_ = std::move(pkg_name_);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetOperation(
+    std::string operation) {
+  operation_ = std::move(operation);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetUri(std::string uri) {
+  uri_ = std::move(uri);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetScheme(std::string scheme) {
+  scheme_ = std::move(scheme);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetHost(std::string host) {
+  host_ = std::move(host);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetUriRInfo(
+    std::string uri_r_info) {
+  uri_r_info_ = std::move(uri_r_info);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetOriginMime(
+    std::string origin_mime) {
+  origin_mime_ = std::move(origin_mime);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetMime(std::string mime) {
+  mime_ = std::move(mime);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetMType(std::string m_type) {
+  m_type_ = std::move(m_type);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetSType(std::string s_type) {
+  s_type_ = std::move(s_type);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetCategory(std::string category) {
+  category_ = std::move(category);
+  return *this;
+}
+
+ResolveInfo::Builder& ResolveInfo::Builder::SetWinId(std::string win_id) {
+  win_id_ = std::move(win_id);
+  return *this;
+}
+
+ResolveInfo ResolveInfo::Builder::Build() {
+  return ResolveInfo(pkg_name_, operation_,
+      uri_, scheme_,
+      host_, uri_r_info_,
+      origin_mime_, mime_,
+      m_type_, s_type_,
+      category_, win_id_);
+}
+
+void ResolveInfo::Manager::GetMime(std::string& uri, std::string& mime) {
+  if (uri.empty())
+    return;
+
+  bool need_check = false;
+  int index;
+  if (uri.compare(0, 1, "/") == 0) {
+    if (mime.empty()) {
+      need_check = true;
+      index = 0;
+    }
+    uri = "";
+  } else if (uri.compare(0, 8, "file:///") == 0) {
+    if (mime.empty()) {
+      need_check = true;
+      index = 7;
+    }
+  } else if (uri.compare(0, 6, "file:/") == 0) {
+    if (mime.empty()) {
+      need_check = true;
+      index = 5;
+    }
+  }
+
+  if (need_check) {
+    char mime_buf[256] = { 0, };
+    int ret = aul_get_mime_from_file(&(uri.c_str()[index]), mime_buf,
+        sizeof(mime_buf));
+    if (ret != AUL_R_OK) {
+      _E("aul_get_mime_from_file() is failed. error(%d)", ret);
+    } else {
+      mime = mime_buf;
+    }
+  }
+}
+
+int ResolveInfo::Manager::GetSchemeAndHost(const std::string& uri,
+    std::string& scheme, std::string& host, std::string& uri_r_info) {
+  if (uri.empty()) {
+    scheme = "NULL";
+    return 0;
+  }
+
+  GError* error = nullptr;
+  GRegex* regex = g_regex_new("^(([^:/?#]+):)?(//([^/?#]*))?",
+      static_cast<GRegexCompileFlags>(0),
+      static_cast<GRegexMatchFlags>(0),
+      &error);
+  if (regex == nullptr) {
+    _E("g_regex_new() is failed");
+    g_clear_error(&error);
+    return -ENOMEM;
+  }
+  std::unique_ptr<GRegex, decltype(g_regex_unref)*> regex_ptr(
+      regex, g_regex_unref);
+
+  GMatchInfo* match_info = nullptr;
+  gboolean ret = g_regex_match(regex, uri.c_str(),
+      static_cast<GRegexMatchFlags>(0), &match_info);
+  if (!ret)
+    return -EINVAL;
+
+  std::unique_ptr<GMatchInfo, decltype(g_match_info_free)*>
+    match_info_ptr(match_info, g_match_info_free);
+
+  gchar* scheme_ptr = g_match_info_fetch(match_info, 2);
+  if (scheme_ptr)
+    scheme = scheme_ptr;
+
+  gchar* host_ptr = g_match_info_fetch(match_info, 4);
+  if (host_ptr)
+    host = host_ptr;
+
+  if (scheme_ptr && host_ptr)
+    uri_r_info = scheme + "://" + host;
+
+  return 0;
+}
+
+ResolveInfo ResolveInfo::Manager::Create(const tizen_base::Bundle& b) {
+  ResolveInfo::Builder builder;
+  builder.SetPkgName(b.GetString(AUL_SVC_K_PKG_NAME));
+  builder.SetOperation(b.GetString(AUL_SVC_K_OPERATION));
+  builder.SetCategory(b.GetString(AUL_SVC_K_CATEGORY));
+  builder.SetWinId(b.GetString(AUL_SVC_K_WIN_ID));
+
+  std::string uri = b.GetString(AUL_SVC_K_URI);
+  std::string mime = b.GetString(AUL_SVC_K_MIME);
+  GetMime(uri, mime);
+  builder.SetOriginMime(mime);
+
+  std::string scheme;
+  std::string host;
+  std::string uri_r_info;
+  int ret = GetSchemeAndHost(uri, scheme, host, uri_r_info);
+  if (ret != 0)
+    THROW(ret);
+
+  builder.SetUriRInfo(uri_r_info);
+  builder.SetScheme(scheme);
+  builder.SetHost(host);
+  builder.SetUri(uri);
+
+  if (mime.empty()) {
+    mime = "NULL";
+  } else {
+    auto vec = Util::Split(mime, "/");
+    if (vec.size() > 1) {
+      std::string m_type = vec[0];
+      if (strncmp(m_type.c_str(), "*", 1) == 0)
+        m_type = "%";
+
+      std::string s_type = vec[1];
+      if (strncmp(s_type.c_str(), "*", 1) == 0)
+        s_type = "%";
+
+      mime = m_type + "/" + s_type;
+
+      builder.SetMType(m_type);
+      builder.SetSType(s_type);
+    }
+  }
+  builder.SetMime(mime);
+
+  return builder.Build();
+}
+
+ResolveInfo::ResolveInfo(std::string pkg_name, std::string operation,
+    std::string uri, std::string scheme,
+    std::string host, std::string uri_r_info,
+    std::string origin_mime, std::string mime,
+    std::string m_type, std::string s_type,
+    std::string category, std::string win_id)
+  : pkg_name_(std::move(pkg_name)),
+    operation_(std::move(operation)),
+    uri_(std::move(uri)),
+    scheme_(std::move(scheme)),
+    host_(std::move(host)),
+    uri_r_info_(std::move(uri_r_info)),
+    origin_mime_(std::move(origin_mime)),
+    mime_(std::move(mime)),
+    m_type_(std::move(m_type)),
+    s_type_(std::move(s_type)),
+    category_(std::move(category)),
+    win_id_(std::move(win_id)) {
+}
+
+ResolveInfo::~ResolveInfo() = default;
+
+void ResolveInfo::SetUriRInfo(std::string uri_r_info) {
+  uri_r_info_ = std::move(uri_r_info);
+}
+
+const std::string& ResolveInfo::GetPkgName() const {
+  return pkg_name_;
+}
+
+const std::string& ResolveInfo::GetOperation() const {
+  return operation_;
+}
+
+const std::string& ResolveInfo::GetUri() const {
+  return uri_;
+}
+
+const std::string& ResolveInfo::GetScheme() const {
+  return scheme_;
+}
+
+const std::string& ResolveInfo::GetHost() const {
+  return host_;
+}
+
+const std::string& ResolveInfo::GetUriRInfo() const {
+  return uri_r_info_;
+}
+
+const std::string& ResolveInfo::GetOriginMime() const {
+  return origin_mime_;
+}
+
+const std::string& ResolveInfo::GetMime() const {
+  return mime_;
+}
+
+const std::string& ResolveInfo::GetMType() const {
+  return m_type_;
+}
+
+const std::string& ResolveInfo::GetSType() const {
+  return s_type_;
+}
+
+const std::string& ResolveInfo::GetCategory() const {
+  return category_;
+}
+
+const std::string& ResolveInfo::GetWinId() const {
+  return win_id_;
+}
+
+}  // namespace core
diff --git a/src/lib/app_control/resolve_info.hh b/src/lib/app_control/resolve_info.hh
new file mode 100644 (file)
index 0000000..9fbb82c
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_RESOLVE_INFO_HH_
+#define LIB_APP_CONTROL_RESOLVE_INFO_HH_
+
+#include <bundle_cpp.h>
+
+#include <string>
+
+namespace amd {
+
+class ResolveInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetPkgName(std::string pkg_name);
+    Builder& SetOperation(std::string operation);
+    Builder& SetUri(std::string uri);
+    Builder& SetScheme(std::string scheme);
+    Builder& SetHost(std::string host);
+    Builder& SetUriRInfo(std::string uri_r_info);
+    Builder& SetOriginMime(std::string origin_mime);
+    Builder& SetMime(std::string mime);
+    Builder& SetMType(std::string m_type);
+    Builder& SetSType(std::string s_type);
+    Builder& SetCategory(std::string category);
+    Builder& SetWinId(std::string win_id);
+    ResolveInfo Build();
+
+   private:
+    std::string pkg_name_;
+    std::string operation_;
+    std::string uri_;
+    std::string scheme_;
+    std::string host_;
+    std::string uri_r_info_;
+    std::string origin_mime_;
+    std::string mime_;
+    std::string m_type_;
+    std::string s_type_;
+    std::string category_;
+    std::string win_id_;
+  };
+
+  class Manager {
+   public:
+    static ResolveInfo Create(const tizen_base::Bundle& b);
+   private:
+    static int GetSchemeAndHost(const std::string& uri,
+        std::string& scheme, std::string& host, std::string& uri_r_info);
+    static void GetMime(std::string& uri, std::string& mime);
+  };
+
+  ResolveInfo() = default;
+  ResolveInfo(std::string pkg_name, std::string operation,
+      std::string uri, std::string scheme,
+      std::string host, std::string uri_r_info,
+      std::string origin_mime, std::string mime,
+      std::string m_type, std::string s_type,
+      std::string category, std::string win_id);
+  virtual ~ResolveInfo();
+
+  void SetUriRInfo(std::string uri_r_info);
+
+  const std::string& GetPkgName() const;
+  const std::string& GetOperation() const;
+  const std::string& GetUri() const;
+  const std::string& GetScheme() const;
+  const std::string& GetHost() const;
+  const std::string& GetUriRInfo() const;
+  const std::string& GetOriginMime() const;
+  const std::string& GetMime() const;
+  const std::string& GetMType() const;
+  const std::string& GetSType() const;
+  const std::string& GetCategory() const;
+  const std::string& GetWinId() const;
+
+ private:
+  std::string pkg_name_;
+  std::string operation_;
+  std::string uri_;
+  std::string scheme_;
+  std::string host_;
+  std::string uri_r_info_;
+  std::string origin_mime_;
+  std::string mime_;
+  std::string m_type_;
+  std::string s_type_;
+  std::string category_;
+  std::string win_id_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_RESOLVE_INFO_HH_
diff --git a/src/lib/app_control/resolver.cc b/src/lib/app_control/resolver.cc
new file mode 100644 (file)
index 0000000..319d1eb
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+
+#include "lib/app_control/resolver.hh"
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+std::string Resolver::GetAppControl(const std::string& operation,
+    const std::string& uri,
+    const std::string& mime) {
+  std::string app_control = operation;
+  app_control += "|";
+  app_control += uri.empty() ? "NULL" : uri;
+  app_control += "|";
+  app_control += mime.empty() ? "NULL" : mime;
+  return app_control;
+}
+
+std::shared_ptr<AppControlInfo> Resolver::GetAppControlInfo(
+    const std::string& operation, const std::string& uri,
+    const std::string& mime, const std::string& m_type,
+    const std::string& s_type) {
+  return std::shared_ptr<AppControlInfo>(
+      new (std::nothrow) AppControlInfo(operation, uri, mime, m_type, s_type));
+}
+
+std::list<std::shared_ptr<AppControlInfo>> Resolver::GetAppControlInfos(
+    const std::string& operation, const std::string& uri,
+    const std::string& mime, const std::string& m_type,
+    const std::string& s_type) {
+  std::list<std::shared_ptr<AppControlInfo>> app_controls;
+  app_controls.push_back(
+      GetAppControlInfo(operation, uri, mime, m_type, s_type));
+  if (mime != "NULL") {
+    if (s_type != "%") {
+      app_controls.push_back(
+          GetAppControlInfo(operation, uri, m_type + "/*", m_type, "*"));
+    }
+
+    if (m_type != "%") {
+      app_controls.push_back(
+          GetAppControlInfo(operation, uri, "*/*", "*", "*"));
+    }
+  }
+
+  return app_controls;
+}
+
+std::list<std::string> Resolver::GetAppList(uid_t uid,
+    const std::string& category,
+    const std::list<std::shared_ptr<AppControlInfo>>& app_control_infos,
+    bool submode, bool glob) {
+  std::list<std::shared_ptr<AppInfo>> app_infos;
+  auto& chunk = AppInfoManager::GetInst().GetAppInfoChunk(uid);
+  for (auto& kv : chunk->Get()) {
+    auto& app_info = kv.second;
+    if (app_info->GetComponentType() != "uiapp")
+      continue;
+
+    if (CheckAppControl(app_info.get(), app_control_infos, glob)) {
+      _D("%s is added", app_info->GetAppId().c_str());
+      app_infos.push_back(app_info);
+    }
+  }
+
+  if (!category.empty()) {
+    auto iter = app_infos.begin();
+    while (iter != app_infos.end()) {
+      if (!(*iter)->CheckCategory(category))
+        iter = app_infos.erase(iter);
+      else
+        ++iter;
+    }
+  }
+
+  std::list<std::string> app_list;
+  for (auto& app_info : app_infos)
+    app_list.push_back(app_info->GetAppId());
+
+  if (submode) {
+    for (auto& app_info : app_infos) {
+      if (!app_info->GetSubmodeMainId().empty())
+        app_list.remove(app_info->GetSubmodeMainId());
+    }
+  }
+
+  return app_list;
+}
+
+bool Resolver::CheckMime(const AppControlInfo* ac1, const AppControlInfo* ac2) {
+  if (ac1->GetMime() == ac2->GetMime())
+    return true;
+
+  if (ac2->GetMType() == "%" && ac2->GetSType() == "%")
+    return true;
+
+  if (ac2->GetMType() != "%" && ac2->GetMType() != ac1->GetMType())
+    return false;
+
+  if (ac2->GetSType() != "%") {
+    auto length = ac2->GetSType().length();
+    if (length > ac1->GetSType().length())
+      length = ac1->GetSType().length();
+    if (strncasecmp(ac1->GetSType().c_str(), ac2->GetSType().c_str(), length))
+      return false;
+  }
+
+  return true;
+}
+
+bool Resolver::CheckAppControl(const AppInfo* app_info,
+    const std::list<std::shared_ptr<AppControlInfo>>& app_control_infos,
+    bool glob) {
+  for (auto& ac1 : app_info->GetAppControls()) {
+    for (auto& ac2 : app_control_infos) {
+      if (ac1->GetOperation() != ac2->GetOperation())
+        continue;
+
+      if (!CheckMime(ac1.get(), ac2.get()))
+        continue;
+
+      if (glob) {
+        gboolean match = g_pattern_match_simple(ac1->GetUri().c_str(),
+            ac2->GetUri().c_str());
+        if (match)
+          return true;
+      } else {
+        if (ac1->GetUri() == ac2->GetUri())
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/resolver.hh b/src/lib/app_control/resolver.hh
new file mode 100644 (file)
index 0000000..9399c25
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_RESOLVER_HH_
+#define LIB_APP_CONTROL_RESOLVER_HH_
+
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <list>
+
+#include "lib/app_control/resolve_info.hh"
+#include "lib/app_info/app_info_manager.hh"
+
+namespace amd {
+
+class Resolver {
+ public:
+  virtual std::shared_ptr<Resolver> SetNext(
+      std::shared_ptr<Resolver> resolver) = 0;
+  virtual std::vector<std::string> Resolve(uid_t uid,
+      const ResolveInfo& info) = 0;
+
+  static std::string GetAppControl(const std::string& operation,
+      const std::string& uri, const std::string& mime);
+
+  static std::shared_ptr<AppControlInfo> GetAppControlInfo(
+      const std::string& operation, const std::string& uri,
+      const std::string& mime, const std::string& m_type,
+      const std::string& s_type);
+
+  static std::list<std::shared_ptr<AppControlInfo>> GetAppControlInfos(
+      const std::string& operation, const std::string& uri,
+      const std::string& mime, const std::string& m_type,
+      const std::string& s_type);
+
+  static std::list<std::string> GetAppList(uid_t uid,
+      const std::string& category,
+      const std::list<std::shared_ptr<AppControlInfo>>& app_control_infos,
+      bool submode, bool glob);
+
+  static bool CheckAppControl(const AppInfo* app_info,
+      const std::list<std::shared_ptr<AppControlInfo>>& app_control_infos,
+      bool glob);
+
+ private:
+  static bool CheckMime(const AppControlInfo* ac1, const AppControlInfo* ac2);
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_RESOLVER_HH_
diff --git a/src/lib/app_control/scheme_host_resolver.cc b/src/lib/app_control/scheme_host_resolver.cc
new file mode 100644 (file)
index 0000000..61257e9
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "lib/app_control/appsvc_manager.hh"
+#include "lib/app_control/scheme_host_resolver.hh"
+#include "lib/common/exception.hh"
+
+namespace amd {
+
+std::shared_ptr<Resolver> SchemeHostResolver::SetNext(
+    std::shared_ptr<Resolver> resolver) {
+  next_resolver_ = resolver;
+  return resolver;
+}
+
+std::vector<std::string> SchemeHostResolver::Resolve(uid_t uid,
+    const ResolveInfo& info) {
+  std::string app_control = GetAppControl(info.GetOperation(),
+      info.GetUriRInfo(), info.GetOriginMime());
+  std::string app_id = AppSvcManager::GetInst().GetDefaultAppId(uid,
+      app_control);
+  if (!app_id.empty()) {
+    std::vector<std::string> result;
+    result.push_back(app_id);
+    return result;
+  }
+
+ auto app_control_infos = GetAppControlInfos(info.GetOperation(),
+     info.GetUriRInfo(), info.GetMime(), info.GetMType(), info.GetSType());
+  auto app_list = GetAppList(uid, "", app_control_infos, false, false);
+  if (app_list.size() == 0) {
+    if (next_resolver_.get() != nullptr)
+      return next_resolver_->Resolve(uid, info);
+
+    return {};
+  }
+
+  app_control_infos = GetAppControlInfos(info.GetOperation(), "*",
+      info.GetMime(), info.GetMType(), info.GetSType());
+  if (info.GetScheme() == "file" && info.GetMime() != "NULL") {
+    app_control_infos.merge(GetAppControlInfos(info.GetOperation(), "NULL",
+          info.GetMime(), info.GetMType(), info.GetSType()));
+  }
+
+  app_list = GetAppList(uid, info.GetCategory(), app_control_infos, true,
+      false);
+  if (app_list.size() > 0) {
+    std::vector<std::string> result {
+        std::make_move_iterator(std::begin(app_list)),
+        std::make_move_iterator(std::end(app_list))
+    };
+
+    return result;
+  }
+
+  if (next_resolver_.get() != nullptr)
+    return next_resolver_->Resolve(uid, info);
+
+  return {};
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/scheme_host_resolver.hh b/src/lib/app_control/scheme_host_resolver.hh
new file mode 100644 (file)
index 0000000..3221f97
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_SCHEME_HOST_RESOLVER_HH_
+#define LIB_APP_CONTROL_SCHEME_HOST_RESOLVER_HH_
+
+#include "lib/app_control/resolver.hh"
+
+namespace amd {
+
+class SchemeHostResolver : public Resolver {
+ public:
+   virtual std::shared_ptr<Resolver> SetNext(
+       std::shared_ptr<Resolver> resolver) override;
+   virtual std::vector<std::string> Resolve(uid_t uid,
+       const ResolveInfo& info) override;
+
+ private:
+   std::shared_ptr<Resolver> next_resolver_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_SCHEME_HOST_RESOLVER_HH_
diff --git a/src/lib/app_control/scheme_resolver.cc b/src/lib/app_control/scheme_resolver.cc
new file mode 100644 (file)
index 0000000..f3cdbdb
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "lib/app_control/appsvc_manager.hh"
+#include "lib/app_control/scheme_resolver.hh"
+#include "lib/common/exception.hh"
+
+namespace amd {
+
+std::shared_ptr<Resolver> SchemeResolver::SetNext(
+    std::shared_ptr<Resolver> resolver) {
+  next_resolver_ = resolver;
+  return resolver;
+}
+
+std::vector<std::string> SchemeResolver::Resolve(uid_t uid,
+    const ResolveInfo& info) {
+  std::string app_control = GetAppControl(info.GetOperation(),
+      info.GetScheme(), info.GetOriginMime());
+  std::string app_id = AppSvcManager::GetInst().GetDefaultAppId(uid,
+      app_control);
+  if (!app_id.empty()) {
+    std::vector<std::string> result;
+    result.push_back(app_id);
+    return result;
+  }
+
+  auto app_control_infos = GetAppControlInfos(info.GetOperation(),
+      info.GetScheme(), info.GetMime(), info.GetMType(), info.GetSType());
+  app_control_infos.merge(GetAppControlInfos(info.GetOperation(), "*",
+        info.GetMime(), info.GetMType(), info.GetSType()));
+  if (info.GetScheme() == "file" && info.GetMime() != "NULL") {
+    app_control_infos.merge(GetAppControlInfos(info.GetOperation(), "NULL",
+          info.GetMime(), info.GetMType(), info.GetSType()));
+  }
+
+  auto app_list = GetAppList(uid, info.GetCategory(), app_control_infos, true,
+      false);
+  if (app_list.size() > 0) {
+    std::vector<std::string> result {
+        std::make_move_iterator(std::begin(app_list)),
+        std::make_move_iterator(std::end(app_list))
+    };
+
+    if (result.size() > 1)
+      const_cast<ResolveInfo&>(info).SetUriRInfo(info.GetScheme());
+
+    return result;
+  }
+
+  if (next_resolver_.get() != nullptr)
+    return next_resolver_->Resolve(uid, info);
+
+  return {};
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/scheme_resolver.hh b/src/lib/app_control/scheme_resolver.hh
new file mode 100644 (file)
index 0000000..34351bd
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_SCHEME_RESOLVER_HH_
+#define LIB_APP_CONTROL_SCHEME_RESOLVER_HH_
+
+#include "lib/app_control/resolver.hh"
+
+namespace amd {
+
+class SchemeResolver : public Resolver {
+ public:
+   virtual std::shared_ptr<Resolver> SetNext(
+       std::shared_ptr<Resolver> resolver) override;
+   virtual std::vector<std::string> Resolve(uid_t uid,
+       const ResolveInfo& info) override;
+
+ private:
+   std::shared_ptr<Resolver> next_resolver_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_CONTROL_SCHEME_RESOLVER_HH_
diff --git a/src/lib/app_control/uri_resolver.cc b/src/lib/app_control/uri_resolver.cc
new file mode 100644 (file)
index 0000000..fcdd6a8
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "lib/app_control/appsvc_manager.hh"
+#include "lib/app_control/uri_resolver.hh"
+#include "lib/common/exception.hh"
+
+namespace amd {
+
+std::shared_ptr<Resolver> UriResolver::SetNext(
+    std::shared_ptr<Resolver> resolver) {
+  next_resolver_ = resolver;
+  return resolver;
+}
+
+std::vector<std::string> UriResolver::Resolve(uid_t uid,
+    const ResolveInfo& info) {
+  std::string app_control = GetAppControl(info.GetOperation(),
+      info.GetUri(), info.GetOriginMime());
+  std::string app_id = AppSvcManager::GetInst().GetDefaultAppId(uid,
+      app_control);
+  if (!app_id.empty()) {
+    std::vector<std::string> result;
+    result.push_back(app_id);
+    return result;
+  }
+
+  auto app_control_infos = GetAppControlInfos(info.GetOperation(),
+      info.GetUri(), info.GetMime(), info.GetMType(), info.GetSType());
+  auto app_list = GetAppList(uid, "", app_control_infos, false, true);
+  if (app_list.size() == 0) {
+    if (next_resolver_.get() != nullptr)
+      return next_resolver_->Resolve(uid, info);
+
+    return {};
+  }
+
+  if (!info.GetUriRInfo().empty()) {
+    app_control_infos = GetAppControlInfos(info.GetOperation(),
+        info.GetUriRInfo(), info.GetMime(), info.GetMType(), info.GetSType());
+  }
+
+  app_control_infos.merge(GetAppControlInfos(info.GetOperation(),
+        info.GetScheme(), info.GetMime(), info.GetMType(), info.GetSType()));
+  app_control_infos.merge(GetAppControlInfos(info.GetOperation(), "*",
+        info.GetMime(), info.GetMType(), info.GetSType()));
+  if (info.GetScheme() == "file" && info.GetMime() != "NULL") {
+    app_control_infos.merge(GetAppControlInfos(info.GetOperation(), "NULL",
+          info.GetMime(), info.GetMType(), info.GetSType()));
+  }
+
+  app_list = GetAppList(uid, info.GetCategory(), app_control_infos, true,
+      false);
+  if (app_list.size() > 0) {
+    std::vector<std::string> result {
+        std::make_move_iterator(std::begin(app_list)),
+        std::make_move_iterator(std::end(app_list))
+    };
+
+    if (result.size() > 1)
+      const_cast<ResolveInfo&>(info).SetUriRInfo(info.GetUri());
+
+    return result;
+  }
+
+  if (next_resolver_.get() != nullptr)
+    return next_resolver_->Resolve(uid, info);
+
+  return {};
+}
+
+}  // namespace amd
diff --git a/src/lib/app_control/uri_resolver.hh b/src/lib/app_control/uri_resolver.hh
new file mode 100644 (file)
index 0000000..7d8d352
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_CONTROL_URI_RESOLVER_HH_
+#define LIB_APP_CONTROL_URI_RESOLVER_HH_
+
+#include "lib/app_control/resolver.hh"
+
+namespace amd {
+
+class UriResolver : public Resolver {
+ public:
+  virtual std::shared_ptr<Resolver> SetNext(
+      std::shared_ptr<Resolver> resolver) override;
+  virtual std::vector<std::string> Resolve(uid_t uid,
+      const ResolveInfo& info) override;
+
+ private:
+  std::shared_ptr<Resolver> next_resolver_;
+};
+
+}  // namespace aul
+
+#endif  // LIB_APP_CONTROL_URI_RESOLVER_HH_
diff --git a/src/lib/app_info/app_control_info.hh b/src/lib/app_info/app_control_info.hh
new file mode 100644 (file)
index 0000000..f8d8ee5
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_INFO_APP_CONTROL_INFO_HH_
+#define LIB_APP_INFO_APP_CONTROL_INFO_HH_
+
+#include <string>
+
+namespace amd {
+
+class AppControlInfo {
+ public:
+  AppControlInfo(std::string operation, std::string uri, std::string mime,
+      std::string m_type, std::string s_type)
+    : operation_(std::move(operation)),
+      uri_(std::move(uri)),
+      mime_(std::move(mime)),
+      m_type_(std::move(m_type)),
+      s_type_(std::move(s_type)) {
+  }
+
+  virtual ~AppControlInfo() = default;
+
+  const std::string& GetOperation() const {
+    return operation_;
+  }
+
+  const std::string& GetUri() const {
+    return uri_;
+  }
+
+  const std::string& GetMime() const {
+    return mime_;
+  }
+
+  const std::string& GetMType() const {
+    return m_type_;
+  }
+
+  const std::string& GetSType() const {
+    return s_type_;
+  }
+
+ private:
+  std::string operation_;
+  std::string uri_;
+  std::string mime_;
+  std::string m_type_;
+  std::string s_type_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_INFO_APP_CONTROL_INFO_HH_
diff --git a/src/lib/app_info/app_info.cc b/src/lib/app_info/app_info.cc
new file mode 100644 (file)
index 0000000..6605d89
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <glib.h>
+
+#include "lib/app_info/app_info.hh"
+#include "lib/common/util.hh"
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+AppInfo::Builder& AppInfo::Builder::SetAppId(pkgmgrinfo_appinfo_h handle) {
+  char* app_id = nullptr;
+  int ret = pkgmgrinfo_appinfo_get_appid(handle, &app_id);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_appinfo_get_appid() is failed. error(%d)", ret);
+  else
+    app_id_ = app_id;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetComponentType(
+    pkgmgrinfo_appinfo_h handle) {
+  char* component_type = nullptr;
+  int ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_appinfo_get_component_type() is failed. error(%d)", ret);
+  else
+    component_type_ = component_type;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetSubmodeMainId(
+    pkgmgrinfo_appinfo_h handle) {
+  char* submode_main_id = nullptr;
+  int ret = pkgmgrinfo_appinfo_get_submode_mainid(handle, &submode_main_id);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_appinfo_get_submode_mainid() is failed. error(%d)", ret);
+  else
+    submode_main_id_ = submode_main_id;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetAppControl(pkgmgrinfo_appinfo_h handle) {
+  int ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
+      [](const char* operation, const char* uri, const char* mime,
+         void* user_data) -> int {
+        auto mime_type = Util::Split(mime ? mime : "NULL/", "/");
+        auto* app_control = new (std::nothrow) AppControlInfo(operation,
+            uri ? uri : "NULL", mime ? mime : "NULL",
+            mime_type[0], mime_type[1]);
+        if (app_control == nullptr) {
+          _E("Out of memory");
+          return -ENOMEM;
+        }
+
+        _W("%s|%s|%s",
+            app_control->GetOperation().c_str(),
+            app_control->GetUri().c_str(),
+            app_control->GetMime().c_str());
+        auto* builder = static_cast<AppInfo::Builder*>(user_data);
+        builder->app_controls_.emplace_back(app_control);
+        return 0;
+      }, this);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_appinfo_foreach_app_control() is failed. error(%d)", ret);
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetCategories(pkgmgrinfo_appinfo_h handle) {
+  int ret = pkgmgrinfo_appinfo_foreach_category(handle,
+      [](const char* category, void* user_data) -> int {
+        auto* builder = static_cast<AppInfo::Builder*>(user_data);
+        builder->categories_[category] = true;
+        return 0;
+      }, this);
+  if (ret != PMINFO_R_OK)
+    _E("pkgmgrinfo_appinfo_foreach_category() is failed. error(%d)", ret);
+
+  return *this;
+}
+
+AppInfo* AppInfo::Builder::Build() {
+  return new (std::nothrow) AppInfo(app_id_, component_type_, submode_main_id_,
+      app_controls_, categories_);
+}
+
+std::shared_ptr<AppInfo> AppInfo::Create(pkgmgrinfo_appinfo_h handle) {
+  Builder builder;
+  builder.SetAppId(handle);
+  builder.SetComponentType(handle);
+  builder.SetSubmodeMainId(handle);
+  builder.SetAppControl(handle);
+  builder.SetCategories(handle);
+  return std::shared_ptr<AppInfo>(builder.Build());
+}
+
+AppInfo::AppInfo(std::string app_id,
+    std::string component_type,
+    std::string submode_main_id,
+    std::list<std::shared_ptr<AppControlInfo>> app_controls,
+    std::map<std::string, bool> categories)
+  : app_id_(std::move(app_id)),
+    component_type_(std::move(component_type)),
+    submode_main_id_(std::move(submode_main_id)),
+    app_controls_(std::move(app_controls)),
+    categories_(std::move(categories)) {
+}
+
+AppInfo::~AppInfo() = default;
+
+const std::string& AppInfo::GetAppId() const {
+  return app_id_;
+}
+
+const std::string& AppInfo::GetComponentType() const {
+  return component_type_;
+}
+
+const std::string& AppInfo::GetSubmodeMainId() const {
+  return submode_main_id_;
+}
+
+const std::list<std::shared_ptr<AppControlInfo>>&
+AppInfo::GetAppControls() const {
+  return app_controls_;
+}
+
+bool AppInfo::CheckCategory(const std::string& category) const {
+  auto found = categories_.find(category);
+  if (found != categories_.end())
+    return true;
+
+  return false;
+}
+
+}  // namespace amd
diff --git a/src/lib/app_info/app_info.hh b/src/lib/app_info/app_info.hh
new file mode 100644 (file)
index 0000000..1fa9110
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_INFO_APP_INFO_HH_
+#define LIB_APP_INFO_APP_INFO_HH_
+
+#include <pkgmgr-info.h>
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+#include "lib/app_info/app_control_info.hh"
+
+namespace amd {
+
+class AppInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetAppId(pkgmgrinfo_appinfo_h handle);
+    Builder& SetComponentType(pkgmgrinfo_appinfo_h handle);
+    Builder& SetSubmodeMainId(pkgmgrinfo_appinfo_h handle);
+    Builder& SetAppControl(pkgmgrinfo_appinfo_h handle);
+    Builder& SetCategories(pkgmgrinfo_appinfo_h handle);
+    AppInfo* Build();
+
+   private:
+    std::string app_id_;
+    std::string component_type_;
+    std::string submode_main_id_;
+    std::list<std::shared_ptr<AppControlInfo>> app_controls_;
+    std::map<std::string, bool> categories_;
+  };
+
+  static std::shared_ptr<AppInfo> Create(pkgmgrinfo_appinfo_h handle);
+
+  AppInfo(std::string app_id,
+      std::string component_type,
+      std::string submode_main_id,
+      std::list<std::shared_ptr<AppControlInfo>> app_controls_,
+      std::map<std::string, bool> categories);
+  virtual ~AppInfo();
+
+  const std::string& GetAppId() const;
+  const std::string& GetComponentType() const;
+  const std::string& GetSubmodeMainId() const;
+  const std::list<std::shared_ptr<AppControlInfo>>& GetAppControls() const;
+  bool CheckCategory(const std::string& category) const;
+
+ private:
+  std::string app_id_;
+  std::string component_type_;
+  std::string submode_main_id_;
+  std::list<std::shared_ptr<AppControlInfo>> app_controls_;
+  std::map<std::string, bool> categories_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_INFO_APP_INFO_HH_
diff --git a/src/lib/app_info/app_info_chunk.hh b/src/lib/app_info/app_info_chunk.hh
new file mode 100644 (file)
index 0000000..91bdc55
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_INFO_APP_INFO_CHUNK_HH_
+#define LIB_APP_INFO_APP_INFO_CHUNK_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "lib/app_info/app_info.hh"
+
+namespace amd {
+
+class AppInfoChunk {
+ public:
+  AppInfoChunk() = default;
+  virtual ~AppInfoChunk() = default;
+
+  void Add(std::shared_ptr<AppInfo> app_info) {
+    app_info_[app_info->GetAppId()] = app_info;
+  }
+
+  void Remove(const std::string& app_id) {
+    auto found = app_info_.find(app_id);
+    if (found == app_info_.end())
+      return;
+
+    app_info_.erase(found);
+  }
+
+  std::map<std::string, std::shared_ptr<AppInfo>>& Get() {
+    return app_info_;
+  }
+
+ private:
+  std::map<std::string, std::shared_ptr<AppInfo>> app_info_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_INFO_APP_INFO_CHUNK_HH_
diff --git a/src/lib/app_info/app_info_manager.cc b/src/lib/app_info/app_info_manager.cc
new file mode 100644 (file)
index 0000000..4a65d8e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lib/app_info/app_info_manager.hh"
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+void AppInfoManager::AddAppInfo(uid_t uid, pkgmgrinfo_appinfo_h handle) {
+  if (!PrepareAppInfoChunk(uid))
+    return;
+
+  auto app_info = AppInfo::Create(handle);
+  if (app_info.get() == nullptr) {
+    _E("Out of memory");
+    return;
+  }
+
+  app_info_chunk_[uid]->Add(app_info);
+}
+
+void AppInfoManager::RemoveAppInfo(uid_t uid, const std::string& app_id) {
+  if (!PrepareAppInfoChunk(uid))
+    return;
+
+  app_info_chunk_[uid]->Remove(app_id);
+}
+
+std::shared_ptr<AppInfoChunk>& AppInfoManager::GetAppInfoChunk(uid_t uid) {
+  PrepareAppInfoChunk(uid);
+  return app_info_chunk_[uid];
+}
+
+bool AppInfoManager::PrepareAppInfoChunk(uid_t uid) {
+  auto found = app_info_chunk_.find(uid);
+  if (found != app_info_chunk_.end())
+    return true;
+
+  auto* chunk = new (std::nothrow) AppInfoChunk();
+  if (chunk == nullptr) {
+    _E("Out of memory");
+    return false;
+  }
+
+  app_info_chunk_[uid] = std::shared_ptr<AppInfoChunk>(chunk);
+  return true;
+}
+
+}  // namespace amd
diff --git a/src/lib/app_info/app_info_manager.hh b/src/lib/app_info/app_info_manager.hh
new file mode 100644 (file)
index 0000000..5929397
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_APP_INFO_APP_INFO_MANAGER_HH_
+#define LIB_APP_INFO_APP_INFO_MANAGER_HH_
+
+#include <pkgmgr-info.h>
+#include <sys/types.h>
+
+#include <map>
+#include <memory>
+
+#include "lib/app_info/app_info_chunk.hh"
+
+namespace amd {
+
+class AppInfoManager {
+ private:
+  AppInfoManager() = default;
+  ~AppInfoManager() = default;
+
+ public:
+  static AppInfoManager& GetInst() {
+    static AppInfoManager inst;
+    return inst;
+  }
+
+  void AddAppInfo(uid_t uid, pkgmgrinfo_appinfo_h handle);
+  void RemoveAppInfo(uid_t uid, const std::string& app_id);
+  std::shared_ptr<AppInfoChunk>& GetAppInfoChunk(uid_t uid);
+
+ private:
+  bool PrepareAppInfoChunk(uid_t uid);
+
+ private:
+  std::map<uid_t, std::shared_ptr<AppInfoChunk>> app_info_chunk_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_APP_INFO_APP_INFO_MANAGER_HH_
diff --git a/src/lib/common/database.cc b/src/lib/common/database.cc
new file mode 100644 (file)
index 0000000..d70f2b2
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include <memory>
+
+#include "lib/common/database.hh"
+#include "lib/common/exception.hh"
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+static const int BUSY_WAITING_USEC = 50000;
+static const int BUSY_WAITING_MAX = 40;
+
+Database::Database(std::string path) : path_(std::move(path)) {
+}
+
+Database::~Database() {
+  Close();
+}
+
+void Database::BeginTransaction() {
+  int ret = sqlite3_exec(db_, "BEGIN TRANSACTION", nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK)
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+}
+
+void Database::EndTransaction() {
+  int ret = sqlite3_exec(db_, "END TRANSACTION", nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK)
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+}
+
+void Database::Rollback() {
+  int ret = sqlite3_exec(db_, "ROLLBACK", nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK)
+    _E("sqlite3_exec() is failed. error(%s:%d", sqlite3_errmsg(db_), ret);
+}
+
+void Database::Open(int flags) {
+  sqlite3* db;
+  int ret = sqlite3_open_v2(path_.c_str(), &db, flags, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_open_v2() is failed. path(%s), error(%d)", path_.c_str(), ret);
+    THROW(-ret);
+  }
+
+  ret = sqlite3_busy_handler(db, BusyHandler,
+      static_cast<void*>(const_cast<char*>(path_.c_str())));
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_busy_handler() is failed. error(%s:%d)",
+        sqlite3_errmsg(db), ret);
+    sqlite3_close_v2(db);
+    THROW(-ret);
+  }
+
+  ret = sqlite3_exec(db, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db), ret);
+    sqlite3_close_v2(db);
+    THROW(-ret);
+  }
+
+  db_ = db;
+}
+
+void Database::Close() {
+  if (db_) {
+    sqlite3_close(db_);
+    db_ = nullptr;
+  }
+}
+
+sqlite3* Database::GetHandle() {
+  return db_;
+}
+
+std::string Database::ColumnText(sqlite3_stmt* stmt, int index) {
+  auto* text = reinterpret_cast<const char*>(sqlite3_column_text(stmt, index));
+  if (text)
+    return std::string(text);
+
+  return {};
+}
+
+void Database::Attach(const std::string& db_path, const std::string& name) {
+  std::string query = "ATTACH DATABASE '" + db_path + "' AS "+ name;
+  int ret = sqlite3_exec(db_, query.c_str(), nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+    THROW(-ret);
+  }
+}
+
+void Database::Detach(const std::string& name) {
+  std::string query = "DETACH DATABASE " + name;
+  int ret = sqlite3_exec(db_, query.c_str(), nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+    THROW(-ret);
+  }
+}
+
+void Database::SetJournalMode(const std::string& mode) {
+  std::string query = "PRAGMA journal_mode=" + mode;
+  int ret = sqlite3_exec(db_, query.c_str(), nullptr, nullptr, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_exec() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+    THROW(-ret);
+  }
+}
+
+bool Database::IntegrityCheck() {
+  static const char query[] = "PRAGMA integrity_check";
+  sqlite3_stmt* stmt;
+  int ret = sqlite3_prepare_v2(db_, query, strlen(query), &stmt, nullptr);
+  if (ret != SQLITE_OK) {
+    _E("sqlite3_prepare_v2() is failed. error(%s:%d)",
+        sqlite3_errmsg(db_), ret);
+    return false;
+  }
+
+  std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_ptr(
+      stmt, sqlite3_finalize);
+
+  ret = sqlite3_step(stmt);
+  if (ret != SQLITE_ROW) {
+    _E("sqlite3_step() is failed. error(%s:%d)", sqlite3_errmsg(db_), ret);
+    return false;
+  }
+
+  auto* res = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
+  if (res == nullptr) {
+    _E("sqlite3_column_text() is failed. error(%s)", sqlite3_errmsg(db_));
+    return false;
+  }
+
+  if (strcmp(res, "ok") != 0)
+    return false;
+
+  return true;
+}
+
+int Database::BusyHandler(void* data, int count) {
+  if (count < BUSY_WAITING_MAX) {
+    usleep(BUSY_WAITING_USEC);
+    return 1;
+  }
+  auto* path = static_cast<char*>(data);
+  _E("Database(%s) is busy", path);
+  return 0;
+}
+
+}  // namespace amd
diff --git a/src/lib/common/database.hh b/src/lib/common/database.hh
new file mode 100644 (file)
index 0000000..fee00bf
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_COMMON_DATABASE_HH_
+#define LIB_COMMON_DATABASE_HH_
+
+#include <sqlite3.h>
+
+#include <memory>
+#include <string>
+
+#include "lib/common/exception.hh"
+
+#define __PREPARE_V2(db, query, length, stmt) do {                             \
+  int ret = sqlite3_prepare_v2(db, query, length, &stmt, nullptr);             \
+  if (ret != SQLITE_OK) {                                                      \
+    _E("sqlite3_prepare_v2() is failed. error(%s:%d)",                         \
+        sqlite3_errmsg(db), ret);                                              \
+    THROW(-ret);                                                               \
+  }                                                                            \
+} while (0)
+
+
+#define __BIND_TEXT(db, stmt, i, text) do {                                    \
+  int ret = sqlite3_bind_text(stmt, i, text, -1, SQLITE_TRANSIENT);            \
+  if (ret != SQLITE_OK) {                                                      \
+    _E("sqlite3_bind_text() is failed. index(%d), error(%s:%d)",               \
+        i, sqlite3_errmsg(db), ret);                                           \
+    THROW(-ret);                                                               \
+  }                                                                            \
+} while (0)
+
+#define __STEP(db, stmt) do {                                                  \
+  int ret = sqlite3_step(stmt);                                                \
+  if (ret != SQLITE_DONE) {                                                    \
+    _E("sqlite3_step() is failed. error(%s:%d)", sqlite3_errmsg(db), ret);     \
+    THROW(-ret);                                                               \
+  }                                                                            \
+} while (0)
+
+#define JOURNAL_MODE_WAL "WAL"
+
+#define JOURNAL_MODE_PERSIST "PERSIST"
+
+#define JOURNAL_MODE_MEMORY "MEMORY"
+
+namespace amd {
+
+class Database {
+ public:
+  Database(std::string path);
+  virtual ~Database();
+
+  void Open(int flags = SQLITE_OPEN_READWRITE);
+  void Close();
+  bool IntegrityCheck();
+  void BeginTransaction();
+  void EndTransaction();
+  void Rollback();
+  sqlite3* GetHandle();
+  std::string ColumnText(sqlite3_stmt* stmt, int index);
+  void Attach(const std::string& db_path, const std::string& name);
+  void Detach(const std::string& name);
+  void SetJournalMode(const std::string& mode);
+
+ private:
+  static int BusyHandler(void* data, int count);
+
+ private:
+  std::string path_;
+  sqlite3* db_ = nullptr;
+};
+
+}  // namespace amd
+
+#endif  // LIB_COMMON_DATABASE_HH_
diff --git a/src/lib/common/exception.hh b/src/lib/common/exception.hh
new file mode 100644 (file)
index 0000000..14190b0
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_COMMON_EXCEPTION_HH_
+#define LIB_COMMON_EXCEPTION_HH_
+
+#include <libgen.h>
+
+#include <string>
+#include <exception>
+
+#include "lib/common/log_private.hh"
+
+#define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
+
+namespace amd {
+
+class Exception : public std::exception {
+ public:
+  explicit Exception(int error_code, std::string file, int line) {
+    error_code_ = error_code;
+    message_ = std::string(basename(const_cast<char*>(file.c_str()))) + ":" +
+        std::to_string(line) + " code:" + std::to_string(error_code_);
+    _E("%s", message_.c_str());
+  }
+
+  virtual ~Exception() {}
+
+  virtual const char* what(void) const noexcept {
+    return message_.c_str();
+  }
+
+  int GetErrorCode() {
+    return error_code_;
+  }
+
+ private:
+  int error_code_;
+  std::string message_;
+};
+
+}  // namespace amd
+
+#endif  // LIB_COMMON_EXCEPTION_HH_
index 79dec0d76232ce5dabfdab0b5f920b725ad65db7..3ebeb5d8bb9c05465efe3644a8e4c4c771dc01fe 100644 (file)
 #ifndef LIB_COMMON_KEY_PRIVATE_HH_
 #define LIB_COMMON_KEY_PRIVATE_HH_
 
+#include <tzplatform_config.h>
+
 #undef REGULAR_UID_MIN
 #define REGULAR_UID_MIN 5000
 
 #undef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
+#undef GLOBAL_USER
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
 #endif  // LIB_COMMON_KEY_PRIVATE_HH_
diff --git a/src/lib/common/util.hh b/src/lib/common/util.hh
new file mode 100644 (file)
index 0000000..4b1ee55
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_COMMON_UTIL_HH_
+#define LIB_COMMON_UTIL_HH_
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+namespace amd {
+
+class Util {
+ public:
+  static std::vector<std::string> Split(const std::string& str,
+      const std::string& delimiter) {
+    std::string string(str);
+    std::vector<std::string> result;
+    std::size_t pos;
+    while ((pos = string.find(delimiter)) != std::string::npos) {
+      std::string token = string.substr(0, pos);
+      result.push_back(token);
+      string.erase(0, pos + delimiter.length());
+    }
+    result.push_back(string);
+    return result;
+  }
+};
+
+}  // namespace core
+
+#endif  // LIB_COMMON_UTIL_HH_