-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(amd)
-PROJECT(amd C CXX)
-
-FOREACH(flag ${pkgs_CFLAGS})
- SET(EXTRA_FLAGS "${EXTRA_FLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
-SET(EXTRA_FLAGS "${EXTRA_FLAGS} -Wl,-zdefs" )
-SET(EXTRA_FLAGS "${EXTRA_FLAGS} -fvisibility=hidden")
-SET(EXTRA_FLAGS "${EXTRA_FLAGS} -fpic")
-SET(EXTRA_FLAGS "${EXTRA_FLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_FLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-zdefs")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS} -std=c++14")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++14")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-# Linker flags
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-
-#################################################################
-# Build AMD #
-#################################################################
-SET(AMD "amd")
-AUX_SOURCE_DIRECTORY(src/amd AMD_SRCS)
-
-INCLUDE(FindPkgConfig)
-
-FOREACH(flag ${AMD_PKGS_CFLAGS})
- SET(EXTRA_FLAGS "${EXTRA_FLAGS} ${flag}")
-ENDFOREACH(flag)
-
-ADD_EXECUTABLE(${AMD} ${AMD_SRCS})
-
-IF(_TIZEN_FEATURE_PRELINK)
-MESSAGE(STATUS "[__PRELINK__] Enable")
-SET_TARGET_PROPERTIES(${AMD} PROPERTIES COMPILE_FLAGS "${EXTRA_FLAGS}")
-TARGET_LINK_LIBRARIES(${AMD} ${AMD_PKGS_LDFLAGS} "-ldl -Wl,-z,relro")
-ELSE(_TIZEN_FEATURE_PRELINK)
-MESSAGE(STATUS "[__PRELINK__] Disable")
-SET_TARGET_PROPERTIES(${AMD} PROPERTIES COMPILE_FLAGS "${EXTRA_FLAGS} -fPIE")
-TARGET_LINK_LIBRARIES(${AMD} ${AMD_PKGS_LDFLAGS} "-pie -ldl -Wl,-z,relro")
-ENDIF(_TIZEN_FEATURE_PRELINK)
-INSTALL(TARGETS ${AMD} DESTINATION bin)
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-#################################################################
-# Build AMD Library #
-#################################################################
-SET(LIB_AMD "libamd")
-AUX_SOURCE_DIRECTORY(src/core CORE_AMD_SRCS)
-AUX_SOURCE_DIRECTORY(src/lib LIB_AMD_SRCS)
-AUX_SOURCE_DIRECTORY(src/core/app_com CORE_APP_COM_AMD_SRCS)
-AUX_SOURCE_DIRECTORY(src/core/common CORE_COMMON_AMD_SRCS)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
-SET(HEADERS_LIB_AMD
- amd.h
- amd_mod_common.h
- amd_api_noti.h
- amd_api_wayland.h
- amd_api_app_status.h
- amd_api_appinfo.h
- amd_api_launch_context.h
- amd_api_app_com.h
- amd_api_request.h
- amd_api_cynara.h
- amd_api_launch.h
- amd_api_launchpad.h
- amd_api_login_monitor.h
- amd_api_suspend.h
- amd_api_signal.h
- amd_api_inotify.h
- amd_api_util.h
- amd_api_socket.h
- amd_api_config.h
- amd_api_proc.h
- amd_api_app_property.h
- amd_api_compinfo.h
- amd_api_comp_status.h
- amd_api_noti_msg.h
- amd_api_logger.h
- amd_api_launch_mode.h
- )
+## Target amd
+SET(TARGET_AMD "amd")
+SET(TARGET_LIB_AMD "libamd")
+
+## Target modules
+SET(TARGET_AMD_MOD_BOOST "amd-mod-boost")
+SET(TARGET_AMD_MOD_COMPLICATION "amd-mod-complication")
+SET(TARGET_AMD_MOD_COMPONENT_MANAGER "amd-mod-component-manager")
+SET(TARGET_AMD_MOD_COOLDOWN "amd-mod-cooldown")
+SET(TARGET_AMD_MOD_CYNARA_CORE "amd-mod-cynara-core")
+SET(TARGET_AMD_MOD_EXTRACTOR "amd-mod-extractor")
+SET(TARGET_AMD_MOD_INPUT "amd-mod-input")
+SET(TARGET_AMD_MOD_JOB_SCHEDULER "amd-mod-job-scheduler")
+SET(TARGET_AMD_MOD_LAUNCHPAD "amd-mod-launchpad")
+SET(TARGET_AMD_MOD_LOADER_MANAGER "amd-mod-loader-manager")
+SET(TARGET_AMD_MOD_RPC_PORT "amd-mod-rpc-port")
+SET(TARGET_AMD_MOD_RUA "amd-mod-rua")
+SET(TARGET_AMD_MOD_SCREEN_RESOLUTION "amd-mod-screen-resolution")
+SET(TARGET_AMD_MOD_SHARE "amd-mod-share")
+SET(TARGET_AMD_MOD_SPLASH_SCREEN "amd-mod-splash-screen")
+SET(TARGET_AMD_MOD_UI_CORE "amd-mod-ui-core")
+SET(TARGET_AMD_MOD_WATCH "amd-mod-watch")
+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")
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
INCLUDE(FindPkgConfig)
-
-SET(LIB_AMD_PKG_CHECK_MODULES
- dlog
- aul
- glib-2.0
- gio-2.0
- vconf
- pkgmgr-info
- pkgmgr
- bundle
- libsystemd
- cert-svc-vcore
- libtzplatform-config
- ttrace
- capi-system-info
- iniparser
- uuid
- )
-
-PKG_CHECK_MODULES(LIB_AMD_PKGS REQUIRED ${LIB_AMD_PKG_CHECK_MODULES})
-
-FOREACH(flag ${LIB_AMD_PKGS_CFLAGS})
- SET(EXTRA_FLAGS_LIB_AMD "${EXTRA_FLAGS_LIB_AMD} ${flag}")
-ENDFOREACH(flag)
-
-ADD_LIBRARY(${LIB_AMD} SHARED
- ${CORE_AMD_SRCS}
- ${LIB_AMD_SRCS}
- ${CORE_APP_COM_AMD_SRCS}
- ${CORE_COMMON_AMD_SRCS})
-SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES COMPILE_FLAGS "${EXTRA_FLAGS_LIB_AMD}")
-SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES OUTPUT_NAME amd)
-TARGET_LINK_LIBRARIES(${LIB_AMD} ${LIB_AMD_PKGS_LDFLAGS} "-ldl -lpthread")
-
-CONFIGURE_FILE(${LIB_AMD}.pc.in ${AMD}.pc @ONLY)
-
-INSTALL(TARGETS ${LIB_AMD} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${AMD}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-FOREACH(hfile ${HEADERS_LIB_AMD})
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/${hfile} DESTINATION include/amd)
-ENDFOREACH(hfile)
-
-ADD_CUSTOM_TARGET(${LIB_AMD}.so ALL
- COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIB_INSTALL_DIR}/${LIB_AMD}.so.${MAJORVER} ${LIB_AMD}.so)
-ADD_DEPENDENCIES(${LIB_AMD}.so ${LIB_AMD})
-INSTALL(FILES ${LIB_AMD}.so DESTINATION ${AMD_MODULES_DIR})
-
-ADD_SUBDIRECTORY(modules)
+INCLUDE(ApplyPkgConfig)
+
+PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul)
+PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
+PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info)
+PKG_CHECK_MODULES(CERT_SVC_VCORE_DEPS REQUIRED cert-svc-vcore)
+PKG_CHECK_MODULES(CYNARA_CLIENT_ASYNC_DEPS REQUIRED cynara-client-async)
+PKG_CHECK_MODULES(CYNARA_CREDS_SOCKET_DEPS REQUIRED cynara-creds-socket)
+PKG_CHECK_MODULES(CYNARA_SESSION_DEPS REQUIRED cynara-session)
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
+PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
+PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
+PKG_CHECK_MODULES(INIPARSER_DEPS REQUIRED iniparser)
+PKG_CHECK_MODULES(LIBSMACK_DEPS REQUIRED libsmack)
+PKG_CHECK_MODULES(LIBSYSTEMD_DEPS REQUIRED libsystemd)
+PKG_CHECK_MODULES(LIBTZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
+PKG_CHECK_MODULES(PKGMGR_DEPS REQUIRED pkgmgr)
+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(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)
+PKG_CHECK_MODULES(TTRACE_DEPS REQUIRED ttrace)
+PKG_CHECK_MODULES(UUID_DEPS REQUIRED uuid)
+PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
+PKG_CHECK_MODULES(WAYLAND_CLIENT_DEPS REQUIRED wayland-client)
+PKG_CHECK_MODULES(WAYLAND_TBM_CLIENT_DEPS REQUIRED wayland-tbm-client)
+PKG_CHECK_MODULES(XKBCOMMON_DEPS REQUIRED xkbcommon)
+
+ADD_SUBDIRECTORY(src)
--- /dev/null
+# Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+# TARGET - valid cmake target
+# PRIVACY - dependency can be inherited by dependent targets or not:
+# PUBLIC - this should be used by default, cause compile/link flags passing
+# PRIVATE - do not passes any settings to dependent targets,
+# may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+# - ${DEP_NAME}_LIBRARIES
+# - ${DEP_NAME}_INCLUDE_DIRS
+# - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+ MATH(EXPR DEST_INDEX "${ARGC}-1")
+ FOREACH(I RANGE 2 ${DEST_INDEX})
+ IF(NOT ${ARGV${I}}_FOUND)
+ MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+ ENDIF(NOT ${ARGV${I}}_FOUND)
+ TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+ TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+ STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+ SET(CFLAGS_LIST ${CFLAGS_STR})
+ SEPARATE_ARGUMENTS(CFLAGS_LIST)
+ FOREACH(OPTION ${CFLAGS_LIST})
+ TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+ ENDFOREACH(OPTION)
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+ ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <amd_api_noti.h>
-#include <amd_api_appinfo.h>
-#include <amd_api_wayland.h>
-#include <amd_api_app_status.h>
-#include <amd_api_launch_context.h>
-#include <amd_api_app_com.h>
-#include <amd_api_request.h>
-#include <amd_api_cynara.h>
-#include <amd_api_launch.h>
-#include <amd_api_launchpad.h>
-#include <amd_api_suspend.h>
-#include <amd_api_login_monitor.h>
-#include <amd_api_signal.h>
-#include <amd_api_inotify.h>
-#include <amd_api_util.h>
-#include <amd_api_socket.h>
-#include <amd_api_config.h>
-#include <amd_api_proc.h>
-#include <amd_api_app_property.h>
-#include <amd_api_compinfo.h>
-#include <amd_api_comp_status.h>
-#include <amd_api_logger.h>
-#include <amd_api_launch_mode.h>
+++ /dev/null
-/*
- * Copyright (c) 2018 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_ANR_MONITOR_H__
-#define __AMD_ANR_MONITOR_H__
-
-#include <sys/types.h>
-#include <unistd.h>
-
-int _anr_monitor_add_timer(pid_t pid);
-
-int _anr_monitor_remove_timer(pid_t pid);
-
-int _anr_monitor_init(void);
-
-void _anr_monitor_fini(void);
-
-#endif /* __AMD_ANR_MONITOR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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_API_H__
-#define __AMD_API_H__
-
-#ifdef EXPORT
-#undef EXPORT
-#endif
-#define EXPORT __attribute__ ((visibility("default")))
-
-#ifdef EXPORT_API
-#undef EXPORT_API
-#endif
-#define EXPORT_API EXPORT
-
-#endif /* __AMD_API_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <bundle.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int amd_app_com_send(const char *endpoint, int cpid, bundle *envelope, uid_t uid);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2018 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_API_APP_PROPERTY_H__
-#define __AMD_API_APP_PROPERTY_H__
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *amd_app_property_h;
-
-amd_app_property_h amd_app_property_find(uid_t uid);
-
-int amd_app_property_metadata_add_filter(const char *key, const char *value);
-
-int amd_app_property_metadata_remove_filter(const char *key,
- const char *value);
-
-int amd_app_property_metadata_foreach(amd_app_property_h app_property,
- const char *appid, const char *key,
- int (*callback)(const char *value, void *user_data),
- void *user_data);
-
-const char *amd_app_property_get_real_appid(amd_app_property_h app_property,
- const char *alias_appid);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AMD_API_APP_PROPERTY_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <glib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- AMD_AT_SERVICE_APP,
- AMD_AT_UI_APP,
- AMD_AT_WIDGET_APP,
- AMD_AT_WATCH_APP,
- AMD_AT_COMPONENT_BASED_APP,
-} amd_app_type_e;
-
-typedef struct app_status_s *amd_app_status_h;
-typedef void (*amd_app_status_cb)(amd_app_status_h h, void *user_data);
-
-amd_app_status_h amd_app_status_find_by_effective_pid(int pid);
-amd_app_status_h amd_app_status_find_by_pid(int pid);
-amd_app_status_h amd_app_status_find_by_appid(const char *appid, uid_t uid);
-int amd_app_status_get_pid(amd_app_status_h h);
-int amd_app_status_is_running(amd_app_status_h h);
-uid_t amd_app_status_get_uid(amd_app_status_h h);
-int amd_app_status_get_status(amd_app_status_h h);
-bool amd_app_status_is_home_app(amd_app_status_h h);
-int amd_app_status_get_first_caller_pid(amd_app_status_h h);
-const char *amd_app_status_get_appid(amd_app_status_h h);
-const char *amd_app_status_get_pkgid(amd_app_status_h h);
-const char *amd_app_status_get_instance_id(amd_app_status_h h);
-int amd_app_status_foreach_running_info(amd_app_status_cb callback,
- void *user_data);
-int amd_app_status_terminate_apps(const char *appid, uid_t uid);
-bool amd_app_status_is_starting(amd_app_status_h h);
-int amd_app_status_get_app_type(amd_app_status_h app_status);
-int amd_app_status_set_extra(amd_app_status_h app_status, const char *key,
- void *data);
-int amd_app_status_remove_extra(amd_app_status_h app_status, const char *key);
-void *amd_app_status_get_extra(amd_app_status_h app_status, const char *key);
-
-const char *amd_app_status_get_leader_id(amd_app_status_h app_status);
-int amd_app_status_set_leader_id(amd_app_status_h app_status, const char *id);
-int amd_app_status_get_fg_cnt(amd_app_status_h app_status);
-int amd_app_status_get_timestamp(amd_app_status_h app_status);
-int amd_app_status_term_bg_apps(GCompareFunc func);
-bool amd_app_status_get_bg_launch(amd_app_status_h app_status);
-amd_app_status_h amd_app_status_find_by_instance_id(const char *appid,
- const char *instance_id, uid_t uid);
-void amd_app_status_find_service_apps(amd_app_status_h app_status, int status,
- void (*send_event_to_svc_core)(int, uid_t), bool suspend);
-int amd_app_status_get_process_cnt(const char *appid);
-const char *amd_app_status_get_app_path(amd_app_status_h app_status);
-bool amd_app_status_is_exiting(amd_app_status_h app_status);
-int amd_app_status_register_pid(int pid, const char *appid, uid_t uid);
-bool amd_app_status_is_debug_mode(amd_app_status_h app_status);
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum _amd_appinfo_type {
- AMD_AIT_NAME = 0,
- AMD_AIT_EXEC,
- AMD_AIT_PKGTYPE,
- AMD_AIT_ONBOOT, /* start on boot: boolean */
- AMD_AIT_RESTART, /* auto restart: boolean */
- AMD_AIT_MULTI,
- AMD_AIT_HWACC,
- AMD_AIT_PERM,
- AMD_AIT_PKGID,
- AMD_AIT_PRELOAD,
- AMD_AIT_STATUS,
- AMD_AIT_POOL,
- AMD_AIT_COMPTYPE,
- AMD_AIT_TEP,
- AMD_AIT_MOUNTABLE_PKG,
- AMD_AIT_STORAGE_TYPE,
- AMD_AIT_BG_CATEGORY,
- AMD_AIT_LAUNCH_MODE,
- AMD_AIT_GLOBAL,
- AMD_AIT_EFFECTIVE_APPID,
- AMD_AIT_TASKMANAGE,
- AMD_AIT_VISIBILITY,
- AMD_AIT_APPTYPE,
- AMD_AIT_ROOT_PATH,
- AMD_AIT_SPLASH_SCREEN,
- AMD_AIT_SPLASH_SCREEN_DISPLAY,
- AMD_AIT_API_VERSION,
- AMD_AIT_ENABLEMENT,
- AMD_AIT_COOLDOWN,
- AMD_AIT_SYSTEM,
- AMD_AIT_IME,
- AMD_AIT_IGNORE,
- AMD_AIT_MAX
-} amd_appinfo_type;
-
-typedef struct appinfo *amd_appinfo_h;
-typedef struct appinfo_splash_image *amd_appinfo_splash_image_h;
-
-#define APP_TYPE_SERVICE "svcapp"
-#define APP_TYPE_UI "uiapp"
-#define APP_TYPE_WIDGET "widgetapp"
-#define APP_TYPE_WATCH "watchapp"
-#define APP_TYPE_COMPONENT_BASED "componentbasedapp"
-
-#define APP_ENABLEMENT_MASK_ACTIVE 0x1
-
-typedef void (*amd_appinfo_iter_callback)(void *user_data,
- const char *filename, amd_appinfo_h h);
-int amd_appinfo_insert(uid_t uid, const char *pkgid);
-amd_appinfo_h amd_appinfo_find(uid_t caller_uid, const char *appid);
-const char *amd_appinfo_get_value(amd_appinfo_h h, amd_appinfo_type type);
-const void *amd_appinfo_get_ptr_value(amd_appinfo_h h, amd_appinfo_type type);
-int amd_appinfo_get_int_value(amd_appinfo_h h, amd_appinfo_type type, int *val);
-int amd_appinfo_get_boolean(amd_appinfo_h h, amd_appinfo_type type, bool *val);
-int amd_appinfo_set_value(amd_appinfo_h h, amd_appinfo_type type,
- const char *val);
-int amd_appinfo_set_ptr_value(amd_appinfo_h h, amd_appinfo_type type,
- void *val);
-int amd_appinfo_set_int_value(amd_appinfo_h h, amd_appinfo_type type, int val);
-void amd_appinfo_foreach(uid_t uid, amd_appinfo_iter_callback cb,
- void *user_data);
-int amd_appinfo_load(uid_t uid);
-void amd_appinfo_unload(uid_t uid);
-amd_appinfo_splash_image_h amd_appinfo_find_splash_image(amd_appinfo_h h,
- const char *name, bool landscape);
-const char *amd_appinfo_splash_image_get_source(amd_appinfo_splash_image_h h);
-const char *amd_appinfo_splash_image_get_type(amd_appinfo_splash_image_h h);
-int amd_appinfo_splash_image_get_indicator_display(
- amd_appinfo_splash_image_h h);
-int amd_appinfo_splash_image_get_color_depth(amd_appinfo_splash_image_h h);
-bool amd_appinfo_is_pkg_updating(const char *pkgid);
-int amd_appinfo_get_cert_visibility(const char *pkgid, uid_t uid);
-bool amd_appinfo_is_platform_app(const char *appid, uid_t uid);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *amd_comp_status_h;
-
-typedef enum {
- AMD_CT_FRAME_COMP,
- AMD_CT_SERVICE_COMP,
-} amd_comp_type_e;
-
-amd_comp_status_h amd_comp_status_find(const char *comp_id);
-
-amd_comp_status_h amd_comp_status_find_by_instance_id(const char *instance_id);
-
-amd_comp_status_h amd_comp_status_find_by_window(int window);
-
-pid_t amd_comp_status_get_pid(amd_comp_status_h h);
-
-const char *amd_comp_status_get_comp_id(amd_comp_status_h h);
-
-int amd_comp_status_set_leader_id(amd_comp_status_h h, const char *instance_id);
-
-const char *amd_comp_status_get_leader_id(amd_comp_status_h h);
-
-const char *amd_comp_status_get_instance_id(amd_comp_status_h h);
-
-int amd_comp_status_get_comp_type(amd_comp_status_h h);
-
-int amd_comp_status_get_status(amd_comp_status_h h);
-
-int amd_comp_status_set_window(amd_comp_status_h h, int window);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define COMPONENT_TYPE_FRAME "frame"
-#define COMPONENT_TYPE_SERVICE "service"
-
-typedef enum _amd_compinfo_type {
- AMD_COMPINFO_TYPE_NAME = 0,
- AMD_COMPINFO_TYPE_APPID,
- AMD_COMPINFO_TYPE_TYPE,
- AMD_COMPINFO_TYPE_LAUNCH_MODE,
- AMD_COMPINFO_TYPE_TASKMANAGE,
- AMD_COMPINFO_TYPE_MAIN,
- AMD_COMPINFO_TYPE_ICON_DISPLAY,
- AMD_COMPINFO_TYPE_MAX
-} amd_compinfo_type;
-
-typedef void *amd_compinfo_h;
-
-typedef void (*amd_compinfo_foreach_cb)(amd_compinfo_h,
- const char *appid, const char *id, void *user_data);
-
-amd_compinfo_h amd_compinfo_find(uid_t uid, const char *id);
-const char *amd_compinfo_get_value(amd_compinfo_h info, amd_compinfo_type type);
-int amd_compinfo_foreach(uid_t uid, amd_compinfo_foreach_cb callback,
- void *user_data);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2018 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_API_CONFIG_H__
-#define __AMD_API_CONFIG_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- AMD_TIZEN_PROFILE_UNKNOWN = 0,
- AMD_TIZEN_PROFILE_MOBILE = 0x1,
- AMD_TIZEN_PROFILE_WEARABLE = 0x2,
- AMD_TIZEN_PROFILE_TV = 0x4,
- AMD_TIZEN_PROFILE_IVI = 0x8,
- AMD_TIZEN_PROFILE_COMMON = 0x10,
-} amd_tizen_profile_t;
-
-amd_tizen_profile_t amd_config_get_tizen_profile(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AMD_API_CONFIG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <amd_api_request.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PRIVILEGE_WIDGET_VIEWER \
- "http://tizen.org/privilege/widget.viewer"
-#define PRIVILEGE_APPMANAGER_LAUNCH \
- "http://tizen.org/privilege/appmanager.launch"
-#define PRIVILEGE_APPMANAGER_KILL \
- "http://tizen.org/privilege/appmanager.kill"
-#define PRIVILEGE_APPMANAGER_KILL_BGAPP \
- "http://tizen.org/privilege/appmanager.kill.bgapp"
-#define PRIVILEGE_DOWNLOAD \
- "http://tizen.org/privilege/download"
-#define PRIVILEGE_CALL \
- "http://tizen.org/privilege/call"
-#define PRIVILEGE_SYSTEM_SETTING \
- "http://tizen.org/privilege/systemsettings.admin"
-#define PRIVILEGE_PLATFORM \
- "http://tizen.org/privilege/internal/default/platform"
-#define PRIVILEGE_PACKAGEMANAGER_INFO \
- "http://tizen.org/privilege/packagemanager.info"
-#define PRIVILEGE_PACKAGEMANAGER_ADMIN \
- "http://tizen.org/privilege/packagemanager.admin"
-
-enum amd_cynara_result {
- AMD_CYNARA_RET_ERROR = -2,
- AMD_CYNARA_RET_DENIED,
- AMD_CYNARA_RET_ALLOWED,
- AMD_CYNARA_RET_UNKNOWN,
- AMD_CYNARA_RET_CONTINUE,
-};
-
-typedef struct caller_info *amd_cynara_caller_info_h;
-
-typedef int (*amd_cynara_checker_func)(amd_cynara_caller_info_h info, amd_request_h req,
- void *data);
-typedef int (*amd_cynara_sub_checker_func)(amd_cynara_caller_info_h info, amd_request_h req);
-
-typedef struct _amd_cynara_checker {
- int cmd;
- amd_cynara_checker_func checker;
- void *data;
- int priority;
-} amd_cynara_checker;
-
-typedef void (*amd_cynara_response_cb)(enum amd_cynara_result res, amd_request_h request);
-
-typedef struct _amd_cynara_ops {
- int (*register_checkers)(const amd_cynara_checker *checkers, int cnt);
- int (*sub_checker_add)(const char *name, amd_cynara_sub_checker_func func);
- int (*sub_checker_check)(const char *name, amd_cynara_caller_info_h info, amd_request_h req);
-
- int (*check_async)(amd_request_h req, amd_cynara_response_cb callback);
- int (*check)(amd_cynara_caller_info_h info, amd_request_h req, void *data);
- int (*check_offline)(amd_request_h req, const char *appid, const char *privilege);
-} amd_cynara_ops;
-
-typedef struct _amd_cynara_caller_info_ops {
- const char *(*get_client)(amd_cynara_caller_info_h info);
-} amd_cynara_caller_info_ops;
-
-int amd_cynara_check_privilege(amd_request_h req, amd_cynara_response_cb callback);
-int amd_cynara_check_privilege_offline(amd_request_h req, const char *appid, const char *privilege);
-int amd_cynara_register_checkers(const amd_cynara_checker *checkers, int cnt);
-int amd_cynara_simple_checker(amd_cynara_caller_info_h info, amd_request_h req, void *data);
-const char *amd_cynara_caller_info_get_client(amd_cynara_caller_info_h info);
-int amd_cynara_sub_checker_add(const char *name, amd_cynara_sub_checker_func func);
-int amd_cynara_sub_checker_check(const char *name, amd_cynara_caller_info_h info, amd_request_h req);
-int amd_cynara_register_ops(amd_cynara_ops ops, amd_cynara_caller_info_ops ci_ops);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <sys/inotify.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct inotify_watch_info_s *amd_inotify_watch_info_h;
-
-typedef bool (*amd_inotify_watch_cb)(const char *event_name, void *data);
-
-amd_inotify_watch_info_h amd_inotify_add_watch(const char *path, uint32_t mask,
- amd_inotify_watch_cb callback, void *data);
-void amd_inotify_rm_watch(amd_inotify_watch_info_h handle);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <amd_api_request.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- AMD_LAUNCH_MODE_NORMAL,
- AMD_LAUNCH_MODE_BLOCK,
-} amd_launch_mode_e;
-
-int amd_launch_start_app(const char *appid, amd_request_h req, bool *pending,
- bool *bg_launch, bool new_instance);
-int amd_launch_term_sub_app(int pid, uid_t uid);
-int amd_launch_start_onboot_apps(uid_t uid);
-void amd_launch_set_mode(amd_launch_mode_e mode);
-int amd_launch_term_sub_inst(pid_t pid, const char *inst_id, uid_t uid);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <amd_api_appinfo.h>
-#include <amd_api_app_status.h>
-#include <amd_api_comp_status.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct launch_s *amd_launch_context_h;
-
-amd_appinfo_h amd_launch_context_get_appinfo(amd_launch_context_h h);
-const char *amd_launch_context_get_appid(amd_launch_context_h h);
-const char *amd_launch_context_get_instance_id(amd_launch_context_h h);
-int amd_launch_context_get_pid(amd_launch_context_h h);
-bool amd_launch_context_is_subapp(amd_launch_context_h h);
-bool amd_launch_context_is_bg_launch(amd_launch_context_h h);
-int amd_launch_context_set_pid(amd_launch_context_h h, int pid);
-bool amd_launch_context_is_new_instance(amd_launch_context_h h);
-int amd_launch_context_set_subapp(amd_launch_context_h h, bool is_subapp);
-int amd_launch_context_set_app_status(amd_launch_context_h h,
- amd_app_status_h status);
-int amd_launch_context_set_comp_status(amd_launch_context_h h,
- amd_comp_status_h status);
-void amd_launch_context_set_custom_effect(amd_launch_context_h h,
- bool is_custom_effect);
-bool amd_launch_context_is_custom_effect(amd_launch_context_h h);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include <bundle_internal.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool amd_launch_mode_is_group_mode(bundle *kb, uid_t uid);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <bundle.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int (*amd_launcher_cb)(bundle *b, uid_t uid, void *user_data);
-
-int amd_launchpad_set_launcher(amd_launcher_cb launcher, void *user_data);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LOGGER_PATH "/var/log/appfw/amd"
-
-typedef void *amd_logger_h;
-
-int amd_logger_create(const char *path, amd_logger_h *handle);
-
-int amd_logger_destroy(amd_logger_h handle);
-
-int amd_logger_print(amd_logger_h handle, const char *tag,
- const char *format, ...);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum amd_uid_state_e {
- AMD_UID_STATE_UNKNOWN = 0x00,
- AMD_UID_STATE_OPENING = 0x01,
- AMD_UID_STATE_LINGERING = 0x02,
- AMD_UID_STATE_ONLINE = 0x04,
- AMD_UID_STATE_ACTIVE = 0x08,
- AMD_UID_STATE_CLOSING = 0x10,
- AMD_UID_STATE_OFFLINE = 0x20,
-} amd_uid_state;
-
-int amd_login_monitor_get_uids(uid_t **uids);
-amd_uid_state amd_login_monitor_get_uid_state(uid_t uid);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <bundle.h>
-#include <amd_api_noti_msg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AMD_NOTI_CONTINUE 0
-#define AMD_NOTI_STOP -2
-
-typedef int (*amd_noti_cb)(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data);
-
-int amd_noti_send(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data);
-int amd_noti_listen(const char *msg, amd_noti_cb callback);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Definition for the notification message: The application information is inserted.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(pkgmgrinfo_appinfo_h) The pkgmgr appinfo handle.\n
- * @since_tizen 5.5
- *
- * @see __appinfo_insert_handler()
- * @see __appinfo_update_handler()
- */
-#define AMD_NOTI_MSG_APPINFO_INSERT \
- "appinfo.insert"
-
-/**
- * @brief Definition for the notification message: The application information is removed.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char*) The application ID.\n
- * @since_tizen 5.5
- *
- * @see __appinfo_update_handler()
- */
-#define AMD_NOTI_MSG_APPINFO_REMOVE \
- "appinfo.remove"
-
-/**
- * @brief Definition for the notification message: The application informations are reloaded.
- * @details Input: arg1(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see __reload_appinfo()
- */
-#define AMD_NOTI_MSG_APPINFO_RELOAD \
- "appinfo.reload"
-
-/**
- * @brief Definition for the notification message: The application informations are loaded.
- * @details Input: arg1(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see _appinfo_load()
- */
-#define AMD_NOTI_MSG_APPINFO_LOAD \
- "appinfo.load"
-
-/**
- * @brief Definition for the notification message: The application informations are unloaded.
- * @details Input: arg1(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see _appinfo_unload()
- */
-#define AMD_NOTI_MSG_APPINFO_UNLOAD \
- "appinfo.unload"
-/**
- * @brief Definition for the notification message: The package update is failed.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char *) The package ID.\n
- * @since_tizen 5.5
- *
- * @see __package_event_cb()
- */
-#define AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR \
- "appinfo.package.update.error"
-
-/**
- * @brief Definition for the notification message: The package is deleted.
- * @details Input: arg1(uid_t) The user ID.\n
- * arg3(const char *) The package ID.\n
- * @since_tizen 5.5
- *
- * @see __package_event_cb()
- */
-#define AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END \
- "appinfo.package.uninstall.end"
-
-/**
- * @brief Definition for the notification message: The package is installed.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char *) The package ID.\n
- * @since_tizen 5.5
- *
- * @see __package_event_cb()
- */
-#define AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END \
- "appinfo.package.install.end"
-
-/**
- * @brief Definition for the notification message: The package is updated.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char *) The package ID.\n
- * @since_tizen 5.5
- *
- * @see __package_event_cb()
- */
-#define AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END \
- "appinfo.package.update.end"
-
-/**
- * @brief Definition for the notification message: The application is enabled.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char *) The application ID.\n
- * @since_tizen 5.5
- *
- * @see __handle_app_event_end()
- */
-#define AMD_NOTI_MSG_APPINFO_APP_ENABLED_END \
- "appinfo.app.enabled.end"
-
-/**
- * @brief Definition for the notification message: The application is disabled.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(const char *) The application ID.\n
- * @since_tizen 5.5
- *
- * @see __handle_app_event_end()
- */
-#define AMD_NOTI_MSG_APPINFO_APP_DISABLED_END \
- "appinfo.app.disabled.end"
-
-/**
- * @brief Definition for the notification message: The running applications in the background should be terminated.
- * @since_tizen 5.5
- *
- * @see __check_running_uiapp_list()
- */
-#define AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS \
- "app_status.term_bg_apps"
-
-/**
- * @brief Definition for the notification message: The status information of the running application will be destroyed.
- * @details Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __destroy_app_status()
- */
-#define AMD_NOTI_MSG_APP_STATUS_DESTROY \
- "app_status.destroy"
-
-/**
- * @brief Definition for the notification message: The status information is added.
- * @details Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see _app_status_add_app_info()
- */
-#define AMD_NOTI_MSG_APP_STATUS_ADD \
- "app_status.add"
-
-/**
- * @brief Definition for the notification message: The status information will be updated.
- * @details Input: arg1(int) The status.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see _app_status_update_status()
- */
-#define AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START \
- "app_status.update_status.start"
-
-/**
- * @brief Definition for the notification message: The status information is updated.
- * @details Input: arg1(bool) The flag if true, the status is updated forcedly.\n
- * Input: arg2(bool) The flag if true, the group info has to be updated.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see _app_status_update_status()
- */
-#define AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END \
- "app_status.update_status.end"
-
-/**
- * @brief Definition for the notification message: The status information will be destroyed.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see _app_status_cleanup()
- */
-#define AMD_NOTI_MSG_APP_STATUS_CLEANUP \
- "app_status.cleanup"
-
-/**
- * @brief Definition for the notification message: The application is sending the registration request.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg3(amd_appinfo_h) The app info handle.\n
- * @since_tizen 5.5
- *
- * @see _app_status_register_pid()
- */
-#define AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID \
- "app_status.app_register_pid"
-
-/**
- * @brief Definition for the notification message: The status information of the running component is added.
- * @details Input: arg3(amd_comp_status_h) The comp status handle.\n
- * @since_tizen 5.5
- *
- * @see _comp_status_add_comp_info()
- */
-#define AMD_NOTI_MSG_COMP_STATUS_ADD \
- "comp_status.add"
-
-/**
- * @brief Definition for the notification message: The status information of the running component is destroyed.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(const char *) The instance ID.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_comp_notify_exit()
- */
-#define AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT \
- "comp_status.notify.exit"
-
-/**
- * @brief Definition for the notification message: The status information of the running component is updated.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(bool) The flag if true, the group info has to be updated.\n
- * Input: arg3(amd_comp_status_h) The comp status handle.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_comp_status_update()
- */
-#define AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END \
- "comp_status.update_status.end"
-
-/**
- * @brief Definition for the notification message: The poweroff state is changed.
- * @details Input: arg1(int) The state of the poweroff.
- * @since_tizen 5.5
- *
- * @see __poweroff_state_cb()
- */
-#define AMD_NOTI_MSG_LAUNCH_POWEROFF_STATE_CHANGE \
- "poweroff.state.change"
-
-/**
- * @brief Definition for the notification message: The termination request will be sent to the running application.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg3(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see _term_app()
- * @see _term_app_v2()
- */
-#define AMD_NOTI_MSG_LAUNCH_TERM_APP_START \
- "launch.term_app.start"
-
-/**
- * @brief Definition for the notification message: The termination request will be sent to the running application.
- * @details If the application is running in the background, the application will be terminated.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg3(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see _term_bgapp()
- */
-#define AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START \
- "launch.term_bgapp.start"
-
-/**
- * @brief Definition for the notification message: The recv() is failed.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user Id.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __reply_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_RECV_ERROR \
- "launch.recv.error"
-
-/**
- * @brief Definition for the notification message: The recv() is failed by timeout.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __recv_timeout_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT \
- "launch.recv.timeout"
-
-/**
- * @brief Definition for the notification message: The launch request will be sent to the running application.
- * @details The launch request is will be sent to the running application.
- * This message is occurred before sending the request.
- * @details Input: arg1(int) The AUL command.\n
- * Input: arg2(int) The process ID.\n
- * Input: arg3(amd_request_h) The request handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __nofork_processing()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START \
- "launch.do_starting_app.relaunch.start"
-
-/**
- * @brief Definition for the notification message: The application is running in the foreground.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_status_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_STATUS_FG \
- "launch.status.fg"
-
-/**
- * @brief Definition for the notification message: The application is running in the background.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_status_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_STATUS_BG \
- "launch.status.bg"
-
-/**
- * @brief Definition for the notification message: The application has a focus.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_status_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS \
- "launch.status.focus"
-
-/**
- * @brief Definition for the notification message: The window of the application is hidden.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_status_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_STATUS_HIDE \
- "launch.status.hide"
-
-/**
- * @brief Definition for the notification message: The application is launched.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_status_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH \
- "launch.status.launch"
-
-/**
- * @brief Definition for the notification message: The launch request is started.
- * @details Input: arg3(amd_request_h) The request handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_start()
- * @see __dispatch_rpc_port_prepare_stub()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_START_START \
- "launch.app_start.start"
-
-/**
- * @brief Definition for the notification message: The launch request is failed.
- * @details Input: arg1(int) The result.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_start()
- * @see __dispatch_rpc_port_prepare_stub()
- */
-#define AMD_NOTI_MSG_LAUNCH_FAIL \
- "launch.fail"
-
-/**
- * @brief Definition for the notification message: The launch request is pended.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(bool) The flag if true, the request is for the background launch.
- * Input: arg3(amd_request_h) The request handle.\n
- * Input: arg4(amd_request_reply_h) The request reply handle.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_start()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_START_PEND \
- "launch.app_start.pend"
-
-/**
- * @brief Definition for the notification message: The launch request is ended.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(bool) The flag if true, the request is for the background launch.
- * Input: arg3(amd_request_h) The request handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_start()
- * @see __dispatch_rpc_port_prepare_stub()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_START_END \
- "launch.app_start.end"
-
-/**
- * @brief Definition for the notification message: The app result request is started.
- * @details Input: arg1(int) The process group ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(const char *) The application ID.\n
- * Input: arg4(bundle *b) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_result()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_RESULT_START \
- "launch.app_result.start"
-
-/**
- * @brief Definition for the notification message: The app result request is ended.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(int) The result.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_result()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_RESULT_END \
- "launch.app_result.end"
-
-/**
- * @brief Definition for the notification message: The app startup signal request is ended.
- * @details The request is received from the launched app process.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg3(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see __dispatch_app_startup_signal()
- */
-#define AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END \
- "launch.app_startup_signal.end"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request is started.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg3(amd_appinfo_h) The appinfo handle.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_START \
- "launch.prepare.start"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request that is launching the UI application is started.
- * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
- * @details Input: arg1(int) The status of the application.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_launch_context_h) The launch context handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START \
- "launch.prepare.ui.start"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request that is launching the UI application is ended.
- * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
- * @details Input: arg1(bool) The flag if true, the request is for the background launch.
- * Input: arg2(int) The process ID of the caller.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END \
- "launch.prepare.ui.end"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request that is launching the Service application is.
- * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
- * @details Input: arg3(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_SERVICE \
- "launch.prepare.service"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request that is launching the Widget application is.
- * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
- * @details Input: arg3(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET \
- "launch.prepare.widget"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request that is launching the Component-based application is started.
- * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
- * @details Input: arg1(int) The status of the application.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_launch_context_h) The launch context handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START \
- "launch.prepare.component-based.start"
-
-/**
- * @brief Definition for the notification message: Preparing the launch request is ended.
- * @details Input: arg1(int) The process ID of the caller.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_appinfo_h) The appinfo handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __prepare_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_PREPARE_END \
- "launch.prepare.end"
-
-/**
- * @brief Definition for the notification message: The application is dead.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __kill_and_cleanup_status()
- * @see __app_dead_handler()
- */
-#define AMD_NOTI_MSG_LAUNCH_MAIN_APP_DEAD \
- "main.app_dead"
-
-/**
- * @brief Definition for the notification message: The re-launch request is canceled.
- * @details Input: arg1(int) The result.\n
- * @since_tizen 5.5
- *
- * @see __do_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL \
- "launch.do_starting_app.relaunch.cancel"
-
-/**
- * @brief Definition for the notification message: The re-launch request is end.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg3(amd_launch_context_h) The launch context handle.\n
- * Input: arg4(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- * @see __do_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END \
- "launch.do_starting_app.relaunch.end"
-
-/**
- * @brief Definition for the notification message: The launch request will be started.
- * @details This message is occurred before sending the launch request to the launchpad.
- * While getting the request in the launchpad, the launchpad make a child process to launch the application.
- * @details Input: arg1(int) The AUL command.\n
- * Input: arg2(bool) The flag if true, the request is for background launch.\n
- * Input: arg3(amd_launch_context_h) The launch context handle.\n
- * Input: arg4(bundle *) The bundel object.\n
- * @since_tizen 5.5
- *
- * @see __do_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START \
- "launch.do_starting_app.start"
-
-/**
- * @brief Definition for the notification message: The launch request is canceled.
- * @details Input: arg1(int) The result.\n
- * @since_tizen 5.5
- *
- * @see __do_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL \
- "launch.do_starting_app.cancel"
-
-/**
- * @brief Definition for the notification message: The launch request is ended.
- * @details The app process is created.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(bool) The flag if true, the request is for background launch.\n
- * Input: arg3(amd_launch_context_h) The launch context.\n
- * Input: arg4(amd_request_h) The request handle.\n
- * @since_tizen 5.5
- *
- * @see __do_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END \
- "launch.do_starting_app.end"
-
-/**
- * @brief Definition for the notification message: The launch request is completed.
- * @details This message is occurred before saving some informations(app_status and comp_status).
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(bool) The flag if true, a new process is created.\n
- * Input: arg3(amd_appinfo_h) The appinfo handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __complete_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_COMPLETE_START \
- "launch.complete.start"
-
-/**
- * @brief Definition for the notification message: The launch request is completed.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_appinfo_h) The appinfo handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __complete_starting_app()
- */
-#define AMD_NOTI_MSG_LAUNCH_COMPLETE_END \
- "launch.complete.end"
-
-/**
- * @brief Definition for the notification message: The user login is starting.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg2(int) The state of the user session.\n
- * @since_tizen 5.5
- *
- * @see __user_login()
- */
-#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START \
- "login_monitor.login.start"
-
-/**
- * @brief Definition for the notification message: The user logged in.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg2(int) The state of the user session.\n
- * @since_tizen 5.5
- *
- * @see __user_login()
- */
-#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN \
- "login_monitor.login"
-
-/**
- * @brief Definition for the notification message: The user logged out.
- * @details Input: arg1(uid_t) The user ID.\n
- * Input: arg2(int) The state of the user session.\n
- * @since_tizen 5.5
- *
- * @see __user_logout()
- */
-#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT \
- "login_monitor.logout"
-
-/**
- * @brief Definition for the notification message: The booting is finished.
- * @details The message is occurred after the system session and the user session are ready.
- * @details Input: arg1(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see __startup_finished_cb()
- */
-#define AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED \
- "startup.finished"
-
-/**
- * @brief Definition for the notification message: The app process is dead.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(amd_app_status_h) The app status handle.\n
- * @since_tizen 5.5
- *
- * @see __app_dead_handler()
- */
-#define AMD_NOTI_MSG_MAIN_APP_DEAD \
- "main.app_dead"
-
-/**
- * @brief Definition for the notification message: The user is initialized.
- * @details Input: arg1(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see _request_usr_init()
- */
-#define AMD_NOTI_MSG_REQUEST_USER_INIT \
- "request.user_init"
-
-/**
- * @brief Definition for the notification message: The watchdog signal will be sent.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(int) The signal number.\n
- * @since_tizen 5.5
- *
- * @see _signal_send_watchdog()
- */
-#define AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START \
- "signal.send_watchdog.start"
-
-/**
- * @brief Definition for the notification message: The memory status is changed to normal.
- * @since_tizen 5.5
- *
- * @see __memory_status_changed_cb()
- */
-#define AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL \
- "util.low_memory.normal"
-
-/**
- * @brief Definition for the notification message: Saving a RUA information is started.
- * @details If the return value is less than AMD_NOTI_STOP, the RUA information is not saved.
- * @details Input: arg3(amd_request_h) The request handle.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 5.5
- *
- * @see __on_launch_pending()
- * @see __on_launch_ending()
- * @remarks This message is sent from the `amd-mod-rua` module.
- */
-#define AMD_NOTI_MSG_RUA_SAVE_CRITICAL \
- "rua.save.critical"
-
-/**
- * @brief Definition for the notification message: The app screen is updated.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(int) The window ID.\n
- * @since_tizen 5.5
- *
- * @see __on_launch_status()
- * @remarks This message is sent from the `amd-mod-screen-connector` module.
- */
-#define AMD_NOTI_MSG_SCREEN_CONNECTOR_APP_SCREEN_UPDATE \
- "screen_connector.app_screen.update"
-
-/**
- * @brief Definition for the notification message: Recycling the window is ended.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(int) The window ID.\n
- * @since_tizen 5.5
- *
- * @see __app_group_context_do_recycle()
- * @remarks Thie message is sent from the `amd-mod-ui-core` module.
- */
-#define AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END \
- "app_group.do_recycle.end"
-
-/**
- * @brief Definition for the notification message: The window is set.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(int) The window ID.\n
- * Input: arg3(const char *) The instance ID.\n
- * @remarks The instance ID(arg3) can be nullptr.
- * @since_tizen 5.5
- *
- * @see __dispatch_app_group_set_window()
- * @see __dispatch_app_group_set_window_v2()
- * @remarks Thie message is sent from the `amd-mod-ui-core` module.
- */
-#define AMD_NOTI_MSG_APP_GROUP_WINDOW_SET \
- "app_group.window.set"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `tizen_input_device_manager`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER \
- "wayland.listener.tizen_input_device_manager"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `tizen_keyrouter`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER \
- "wayland.listener.tizen_keyrouter"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `wl_seat`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT \
- "wayland.listener.wl_seat"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `tizen_launch_appinfo`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_APPINFO \
- "wayland.listener.tizen_launch_appinfo"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `tizen_launch_effect`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_EFFECT \
- "wayland.listener.tizen_launch_effect"
-
-/**
- * @brief Definition for the notification message: The wayland interface is added.
- * @details The interface is `tizen_policy`.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg2(int) The version.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_POLICY \
- "wayland.listener.tizen_policy"
-
-/**
- * @brief Definition for the notification message: The wayland interface is removed.
- * @details Input: arg1(int) The interface ID.\n
- * Input: arg3(struct wl_registry *) The wayland registry.\n
- * @since_tizen 5.5
- *
- * @see __wl_listener_remove_cb()
- * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
- */
-#define AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE \
- "wayland.listener.remove"
-
-/**
- * @brief Definition for the notification message: Sending the running widget information is started.
- * @details Input: arg2(uid_t) The user ID.\n
- * Input: arg3(const char*) The instance ID.\n
- * Output: arg1(int *) The window ID.\n
- * @since_tizen 5.5
- *
- * @see __send_running_info()
- * @remarks Thie message is sent from the `amd-mod-widget` module.
- */
-#define AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND \
- "widget.running_info.send"
-
-/**
- * @brief Definition for the notification message: The widget will be restarted.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * @since_tizen 5.5
- *
- * @see __on_app_dead()
- * @remarks Thie message is sent from the `amd-mod-widget` module.
- */
-#define AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART \
- "widget.on_app_dead.restart"
-
-/**
- * @brief Definition for the notification message: The app group context is destroying.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(int) The window ID.\n
- * Input: arg3(const char *) The instance ID.\n
- * @since_tizen 5.5
- * @see __destroy_app_group_context()
- */
-#define AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT \
- "app_group.destroy.app_group_context"
-
-/**
- * @brief Definition for the notification message: The app group activate below.
- * @details Input: arg1(int) The process ID.\n
- * Input: arg2(uid_t) The user ID.\n
- * Input: arg3(const char *) The application ID.\n
- * Input: arg4(bundle *) The bundle object.\n
- * @since_tizen 6.0
- * @see __dispatch_app_group_activate_below()
- */
-#define AMD_NOTI_MSG_APP_GROUP_ACTIVATE_BELOW \
- "app_gorup.activate_below"
-
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2018 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_API_PROC_H__
-#define __AMD_API_PROC_H__
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int amd_proc_get_attr(pid_t pid, char *buf, int buf_size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AMD_API_PROC_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <glib.h>
-#include <bundle.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct request_s *amd_request_h;
-typedef int (*amd_request_cmd_dispatch_cb)(amd_request_h req);
-typedef struct _amd_request_cmd_dispatch {
- int cmd;
- amd_request_cmd_dispatch_cb callback;
-} amd_request_cmd_dispatch;
-
-typedef void* amd_request_reply_h;
-
-int amd_request_send_result(amd_request_h req, int res);
-int amd_request_send_raw(amd_request_h req, int cmd, unsigned char *data, int len);
-int amd_request_get_fd(amd_request_h req);
-int amd_request_get_pid(amd_request_h req);
-int amd_request_get_cmd(amd_request_h req);
-int amd_request_set_cmd(amd_request_h req, int cmd);
-bundle *amd_request_get_bundle(amd_request_h req);
-amd_request_h amd_request_create_local(int cmd, uid_t uid, int pid, bundle *kb);
-void amd_request_free_local(amd_request_h req);
-int amd_request_remove_fd(amd_request_h req);
-int amd_request_reply_for_pending_request(int pid);
-int amd_request_flush_pending_request(int pid);
-uid_t amd_request_get_target_uid(amd_request_h req);
-uid_t amd_request_get_uid(amd_request_h req);
-pid_t amd_request_get_target_pid(amd_request_h req);
-int amd_request_usr_init(uid_t uid);
-int amd_request_register_cmds(const amd_request_cmd_dispatch *cmds, int cnt);
-int amd_request_reply_append(int pid, void *reply);
-int amd_request_reply_remove(int pid, void *reply);
-amd_request_reply_h amd_request_reply_create(amd_request_h req,
- pid_t pid, int result, int cmd);
-int amd_request_reply_add_extra(amd_request_reply_h handle, const char *key,
- void *extra, void (*extra_free_cb)(void *data));
-int amd_request_reply_foreach_extra(int pid, int (*callback)(const char *key, void *data));
-int amd_request_get_len(amd_request_h req);
-unsigned char *amd_request_get_raw(amd_request_h req);
-struct timespec *amd_request_get_start_time(amd_request_h req);
-int amd_request_set_request_type(amd_request_h req, const char *req_type);
-const char *amd_request_get_request_type(amd_request_h req);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int (*amd_signal_ready_cb)(void *user_data);
-
-int amd_signal_send_tep_mount(char *mnt_path[], const char *pkgid);
-
-int amd_signal_send_tep_unmount(const char *mnt_path);
-
-int amd_signal_send_watchdog(int pid, int signal_num);
-
-int amd_signal_add_ready_cb(amd_signal_ready_cb callback, void *user_data);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-#include <stdbool.h>
-#include <bundle.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- PAD_CMD_PREPARE_APP_DEFINED_LOADER = 17,
-} pad_cmd_e;
-
-void amd_socket_send_result(int fd, int res, bool close);
-
-int amd_socket_send_cmd_to_launchpad(uid_t uid, pad_cmd_e cmd, bundle *b);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <amd_api_appinfo.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AMD_SUSPEND_TYPE_EXCLUDE "exclude"
-#define AMD_SUSPEND_TYPE_INCLUDE "include"
-
-enum amd_suspend_status_e {
- AMD_SUSPEND_STATUS_EXCLUDE,
- AMD_SUSPEND_STATUS_INCLUDE,
-};
-
-enum amd_background_category_e {
- AMD_BACKGROUND_CATEGORY_MEDIA = 0x01,
- AMD_BACKGROUND_CATEGORY_DOWNLOAD = 0x02,
- AMD_BACKGROUND_CATEGORY_BACKGROUND_NETWORK = 0x04,
- AMD_BACKGROUND_CATEGORY_LOCATION = 0x08,
- AMD_BACKGROUND_CATEGORY_SENSOR = 0x10,
- AMD_BACKGROUND_CATEGORY_IOT_COMMUNICATION = 0x20,
- AMD_BACKGROUND_CATEGORY_SYSTEM = 0x40
-};
-
-bool amd_suspend_is_excluded(int pid);
-bool amd_suspend_is_allowed_background(amd_appinfo_h ai);
-void amd_suspend_add_timer(int pid);
-void amd_suspend_remove_timer(int pid);
-int amd_suspend_add_proc(int pid);
-int amd_suspend_remove_proc(int pid);
-int amd_suspend_update_status(int pid, int status);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool amd_util_check_oom(void);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void *amd_wayland_get_display(void);
-void amd_wayland_set_display(void *display);
-void *amd_wayland_get_tizen_policy(void);
-void amd_wayland_set_tizen_policy(void *tizen_policy);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2015 - 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_COM_H__
-#define __AMD_APP_COM_H__
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <bundle.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int _app_com_broker_init(void);
-
-int _app_com_broker_fini(void);
-
-int _app_com_client_remove(int cpid);
-
-int _app_com_send(const char *endpoint, int cpid, bundle *envelope, uid_t uid);
-
-const char *_app_com_get_privilege(const char *endpoint);
-
-bool _app_com_endpoint_exists(const char *endpoint);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AMD_APP_COM_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <glib.h>
-#include <pkgmgr-info.h>
-
-#define METADATA_LARGEMEMORY "http://tizen.org/metadata/largememory"
-#define METADATA_OOMTERMINATION "http://tizen.org/metadata/oomtermination"
-#define METADATA_VIPAPP "http://tizen.org/metadata/vipapp"
-
-typedef struct app_property_s *app_property_h;
-
-int _app_property_add_alias_info(app_property_h app_property,
- const char *alias_appid, const char *appid);
-int _app_property_remove_alias_info(app_property_h app_property,
- const char *alias_appid, const char *appid);
-const char *_app_property_get_real_appid(app_property_h app_property,
- const char *alias_appid);
-GList *_app_property_get_allowed_app_list(app_property_h app_property,
- const char *appid);
-app_property_h _app_property_find(uid_t uid);
-int _app_property_insert(uid_t uid, const char *appid,
- const pkgmgrinfo_appinfo_h handle);
-int _app_property_delete(uid_t uid, const char *appid);
-int _app_property_load(uid_t uid);
-void _app_property_unload(uid_t uid);
-int _app_property_init(void);
-void _app_property_fini(void);
-void _app_property_cache_invalidate(app_property_h app_property);
-bool _app_property_metadata_query_bool(app_property_h app_property,
- const char *appid, const char *key);
-int _app_property_metadata_foreach(app_property_h app_property,
- const char *appid, const char *key,
- int (*callback)(const char *value, void *data),
- void *user_data);
-bool _app_property_metadata_match(app_property_h app_property,
- const char *appid, const char *key, const char *value);
-bool _app_property_metadata_query_activation(app_property_h app_property,
- const char *appid, const char *key);
-int _app_property_metadata_add_filter(const char *key, const char *value);
-int _app_property_metadata_remove_filter(const char *key, const char *value);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <glib.h>
-#include <stdbool.h>
-
-#include "amd_appinfo.h"
-
-typedef enum {
- AT_SERVICE_APP,
- AT_UI_APP,
- AT_WIDGET_APP,
- AT_WATCH_APP,
- AT_COMPONENT_BASED_APP,
-} app_type_e;
-
-typedef struct app_status_s *app_status_h;
-
-int _app_status_register_pid(int pid, const char *appid, uid_t uid);
-int _app_status_set_extra(app_status_h app_status, const char *key, void *data);
-int _app_status_remove_extra(app_status_h app_status, const char *key);
-void *_app_status_get_extra(app_status_h app_status, const char *key);
-int _app_status_add_app_info(const struct appinfo *ai, int pid,
- bool is_subapp, uid_t uid, int caller_pid,
- bool bg_launch, const char *instance_id,
- bool debug_mode);
-int _app_status_remove_all_app_info_with_uid(uid_t uid);
-int _app_status_remove(app_status_h app_status);
-int _app_status_update_status(app_status_h app_status, int status, bool force,
- bool update_group_info);
-int _app_status_update_last_caller_pid(app_status_h app_status, int caller_pid);
-int _app_status_update_bg_launch(app_status_h app_status, bool bg_launch);
-int _app_status_get_process_cnt(const char *appid);
-bool _app_status_is_home_app(app_status_h app_status);
-int _app_status_get_pid(app_status_h app_status);
-int _app_status_get_last_caller_pid(app_status_h app_status);
-int _app_status_is_running(app_status_h app_status);
-int _app_status_get_status(app_status_h app_status);
-uid_t _app_status_get_uid(app_status_h app_status);
-const char *_app_status_get_appid(app_status_h app_status);
-const char *_app_status_get_pkgid(app_status_h app_status);
-int _app_status_get_leader_pid(app_status_h app_status);
-int _app_status_set_leader_pid(app_status_h app_status, int pid);
-int _app_status_get_fg_cnt(app_status_h app_status);
-int _app_status_get_timestamp(app_status_h app_status);
-int _app_status_term_bg_apps(GCompareFunc func);
-bool _app_status_get_bg_launch(app_status_h app_status);
-const char *_app_status_get_instance_id(app_status_h app_stauts);
-int _app_status_get_app_type(app_status_h app_status);
-bool _app_status_socket_exists(app_status_h app_status);
-bool _app_status_is_starting(app_status_h app_status);
-int _app_status_update_is_starting(app_status_h app_status, bool is_starting);
-bool _app_status_is_exiting(app_status_h app_status);
-int _app_status_update_is_exiting(app_status_h app_status, bool is_exiting);
-const char *_app_status_get_app_path(app_status_h app_status);
-app_status_h _app_status_find(int pid);
-app_status_h _app_status_find_v2(int pid);
-app_status_h _app_status_find_by_appid(const char *appid, uid_t uid);
-app_status_h _app_status_find_by_appid_v2(const char *appid, uid_t uid);
-app_status_h _app_status_find_with_org_caller(const char *appid, uid_t uid,
- int caller_pid);
-app_status_h _app_status_find_by_instance_id(const char *appid,
- const char *instance_id, uid_t uid);
-void _app_status_find_service_apps(app_status_h app_status, int status,
- void (*send_event_to_svc_core)(int, uid_t), bool suspend);
-void _app_status_check_service_only(app_status_h app_status,
- void (*send_event_to_svc_core)(int, uid_t));
-int _app_status_send_running_appinfo(int fd, int cmd, uid_t uid);
-int _app_status_foreach_running_appinfo(void (*callback)(app_status_h, void *),
- void *data);
-int _app_status_terminate_apps(const char *appid, uid_t uid);
-int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid);
-int _app_status_get_appid_bypid(int fd, int pid);
-int _app_status_get_pkgid_bypid(int fd, int pid);
-int _app_status_get_instance_id_bypid(int fd, int pid);
-int _app_status_get_org_caller_pid(app_status_h app_status);
-int _app_status_publish_status(int pid, int context_status);
-void _app_status_cleanup(app_status_h app_status);
-int _app_status_usr_init(uid_t uid);
-void _app_status_usr_fini(uid_t uid);
-int _app_status_init(void);
-int _app_status_finish(void);
-const char *_app_status_get_leader_id(app_status_h app_status);
-int _app_status_set_leader_id(app_status_h app_status, const char *leader_id);
-bool _app_status_is_debug_mode(app_status_h app_status);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <glib.h>
-#include <stdbool.h>
-
-#define AIT_START 0
-enum appinfo_type {
- AIT_NAME = AIT_START,
- AIT_EXEC,
- AIT_PKGTYPE,
- AIT_ONBOOT, /* start on boot: boolean */
- AIT_RESTART, /* auto restart: boolean */
- AIT_MULTI,
- AIT_HWACC,
- AIT_PERM,
- AIT_PKGID,
- AIT_PRELOAD,
- AIT_STATUS,
- AIT_POOL,
- AIT_COMPTYPE,
- AIT_TEP,
- AIT_MOUNTABLE_PKG,
- AIT_STORAGE_TYPE,
- AIT_BG_CATEGORY,
- AIT_LAUNCH_MODE,
- AIT_GLOBAL,
- AIT_EFFECTIVE_APPID,
- AIT_TASKMANAGE,
- AIT_VISIBILITY,
- AIT_APPTYPE,
- AIT_ROOT_PATH,
- AIT_SPLASH_SCREEN,
- AIT_SPLASH_SCREEN_DISPLAY,
- AIT_API_VERSION,
- AIT_ENABLEMENT,
- AIT_COOLDOWN,
- AIT_SYSTEM,
- AIT_IME,
- AIT_IGNORE,
- AIT_MAX
-};
-
-struct appinfo {
- char *val[AIT_MAX];
-};
-
-struct appinfo_splash_screen {
- GHashTable *portrait;
- GHashTable *landscape;
-};
-
-struct appinfo_splash_image {
- char *src;
- char *type;
- char *indicatordisplay;
- char *color_depth;
-};
-
-#define APP_TYPE_SERVICE "svcapp"
-#define APP_TYPE_UI "uiapp"
-#define APP_TYPE_WIDGET "widgetapp"
-#define APP_TYPE_WATCH "watchapp"
-#define APP_TYPE_COMPONENT_BASED "componentbasedapp"
-
-#define APP_ENABLEMENT_MASK_ACTIVE 0x1
-#define APP_ENABLEMENT_MASK_REQUEST 0x2
-
-typedef void (*appinfo_iter_callback)(void *user_data,
- const char *filename, struct appinfo *c);
-int _appinfo_init(void);
-void _appinfo_fini(void);
-int _appinfo_insert(uid_t uid, const char *pkgid);
-struct appinfo *_appinfo_find(uid_t caller_uid, const char *appid);
-const char *_appinfo_get_value(const struct appinfo *c, enum appinfo_type type);
-const void *_appinfo_get_ptr_value(const struct appinfo *c,
- enum appinfo_type type);
-int _appinfo_get_int_value(const struct appinfo *c, enum appinfo_type type,
- int *val);
-int _appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type,
- bool *val);
-int _appinfo_set_value(struct appinfo *c, enum appinfo_type, const char *val);
-int _appinfo_set_ptr_value(struct appinfo *c, enum appinfo_type, void *val);
-int _appinfo_set_int_value(struct appinfo *c, enum appinfo_type type, int val);
-void _appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data);
-int _appinfo_load(uid_t uid);
-void _appinfo_unload(uid_t uid);
-struct appinfo_splash_image *_appinfo_find_splash_image(struct appinfo *c,
- const char *name, bool landscape);
-const char *_appinfo_splash_image_get_source(struct appinfo_splash_image *s);
-const char *_appinfo_splash_image_get_type(struct appinfo_splash_image *s);
-int _appinfo_splash_image_get_indicator_display(struct appinfo_splash_image *s);
-int _appinfo_splash_image_get_color_depth(struct appinfo_splash_image *s);
-bool _appinfo_is_pkg_updating(const char *pkgid);
-int _appinfo_get_cert_visibility(const char *pkgid, uid_t uid);
-bool _appinfo_is_platform_app(const char *appid, uid_t uid);
+++ /dev/null
-/*
- * 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_BOOT_MANAGER_H__
-#define __AMD_BOOT_MANAGER_H__
-
-#include <sys/types.h>
-#include <unistd.h>
-
-int _boot_manager_start_onboot_apps(uid_t uid);
-
-int _boot_manager_init(void);
-
-void _boot_manager_fini(void);
-
-#endif /* __AMD_BOOT_MANAGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <aul_comp_types.h>
-
-#include "amd_compinfo.h"
-
-typedef void *comp_status_h;
-
-typedef enum {
- CT_FRAME_COMP,
- CT_SERVICE_COMP,
-} comp_type_e;
-
-const char *_comp_status_generate_instance(const char *comp_id);
-
-int _comp_status_add_comp_info(compinfo_h ci, pid_t pid,
- const char *instance_id, bool is_subcomp);
-
-comp_status_h _comp_status_find(const char *comp_id);
-
-comp_status_h _comp_status_find_by_instance_id(const char *instance_id);
-
-comp_status_h _comp_status_find_by_window(int window);
-
-comp_status_h _comp_status_find_v2(pid_t pid, const char *instance_id);
-
-pid_t _comp_status_get_pid(comp_status_h h);
-
-const char *_comp_status_get_comp_id(comp_status_h h);
-
-const char *_comp_status_get_instance_id(comp_status_h h);
-
-int _comp_status_get_comp_type(comp_status_h h);
-
-const char *_comp_status_get_leader_id(comp_status_h h);
-
-int _comp_status_set_leader_id(comp_status_h h, const char *instance_id);
-
-int _comp_status_get_status(comp_status_h h);
-
-int _comp_status_set_window(comp_status_h h, int window);
-
-bool _comp_status_is_running(comp_status_h h);
-
-int _comp_status_init(void);
-
-void _comp_status_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#define COMPONENT_TYPE_FRAME "frame"
-#define COMPONENT_TYPE_SERVICE "service"
-
-#define CIT_START 0
-typedef enum compinfo_type_e {
- CIT_NAME = CIT_START,
- CIT_APPID,
- CIT_TYPE,
- CIT_LAUNCH_MODE,
- CIT_TASKMANAGE,
- CIT_MAIN,
- CIT_ICON_DISPLAY,
- CIT_MAX
-} compinfo_type;
-
-typedef void *compinfo_h;
-
-typedef void (*compinfo_foreach_cb)(compinfo_h info,
- const char *appid, const char *id, void *user_data);
-
-compinfo_h _compinfo_find(uid_t uid, const char *id);
-const char *_compinfo_get_value(compinfo_h handle, compinfo_type type);
-int _compinfo_foreach(uid_t uid, compinfo_foreach_cb callback, void *user_data);
-int _compinfo_init(void);
-void _compinfo_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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_CONFIG_H__
-#define __AMD_CONFIG_H__
-
-typedef enum {
- TIZEN_PROFILE_UNKNOWN = 0,
- TIZEN_PROFILE_MOBILE = 0x1,
- TIZEN_PROFILE_WEARABLE = 0x2,
- TIZEN_PROFILE_TV = 0x4,
- TIZEN_PROFILE_IVI = 0x8,
- TIZEN_PROFILE_COMMON = 0x10,
-} tizen_profile_t;
-
-tizen_profile_t _config_get_tizen_profile(void);
-
-#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_AUTO_ROTATION \
- (!(_config_get_tizen_profile() & (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
-
-unsigned int _config_get_onboot_interval(void);
-unsigned int _config_get_fg_timeout(void);
-unsigned int _config_get_max_launch_failure(void);
-int _config_init(void);
-void _config_fini(void);
-
-#endif /* __AMD_CONFIG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 - 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.
- */
-
-#pragma once
-
-#include "amd_request.h"
-
-#define SYSPOPUP_NAME "_INTERNAL_SYSPOPUP_NAME_"
-#define PRIVILEGE_WIDGET_VIEWER \
- "http://tizen.org/privilege/widget.viewer"
-#define PRIVILEGE_APPMANAGER_LAUNCH \
- "http://tizen.org/privilege/appmanager.launch"
-#define PRIVILEGE_APPMANAGER_KILL \
- "http://tizen.org/privilege/appmanager.kill"
-#define PRIVILEGE_APPMANAGER_KILL_BGAPP \
- "http://tizen.org/privilege/appmanager.kill.bgapp"
-#define PRIVILEGE_DOWNLOAD \
- "http://tizen.org/privilege/download"
-#define PRIVILEGE_CALL \
- "http://tizen.org/privilege/call"
-#define PRIVILEGE_SYSTEM_SETTING \
- "http://tizen.org/privilege/systemsettings.admin"
-#define PRIVILEGE_PLATFORM \
- "http://tizen.org/privilege/internal/default/platform"
-#define PRIVILEGE_PACKAGEMANAGER_INFO \
- "http://tizen.org/privilege/packagemanager.info"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum amd_cynara_res {
- AMD_CYNARA_ERROR = -2,
- AMD_CYNARA_DENIED,
- AMD_CYNARA_ALLOWED,
- AMD_CYNARA_UNKNOWN,
- AMD_CYNARA_CONTINUE,
-};
-
-typedef struct caller_info *caller_info_h;
-
-typedef int (*checker_func)(caller_info_h info, request_h req,
- void *data);
-typedef int (*sub_checker_func)(caller_info_h info, request_h req);
-
-typedef struct _cynara_checker {
- int cmd;
- checker_func checker;
- void *data;
- int priority;
-} cynara_checker;
-
-typedef void (*cynara_response_cb)(enum amd_cynara_res res, request_h request);
-
-typedef struct _cynara_ops {
- int (*register_checkers)(const cynara_checker *checkers, int cnt);
- int (*sub_checker_add)(const char *name, sub_checker_func func);
- int (*sub_checker_check)(const char *name, caller_info_h info, request_h req);
-
- int (*check_async)(request_h req, cynara_response_cb callback);
- int (*check)(caller_info_h info, request_h req, void *data);
- int (*check_offline)(request_h req, const char *appid, const char *privilege);
-} cynara_ops;
-
-typedef struct _cynara_caller_info_ops {
- const char *(*get_client)(caller_info_h info);
-} cynara_caller_info_ops;
-
-int _cynara_init(void);
-void _cynara_finish(void);
-int _cynara_check_privilege(request_h req, cynara_response_cb callback);
-int _cynara_check_privilege_offline(request_h req, const char *appid, const char *privilege);
-int _cynara_register_checkers(const cynara_checker *checkers, int cnt);
-int _cynara_simple_checker(caller_info_h info, request_h req, void *data);
-const char *_cynara_caller_info_get_client(caller_info_h info);
-int _cynara_sub_checker_add(const char *name, sub_checker_func func);
-int _cynara_sub_checker_check(const char *name, caller_info_h info, request_h req);
-int _cynara_register_ops(cynara_ops ops, cynara_caller_info_ops ci_ops);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-int _direct_launch_init(void);
-void _direct_launch_fini(void);
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <sys/inotify.h>
-
-typedef struct inotify_watch_info_s *inotify_watch_info_h;
-
-typedef bool (*inotify_watch_cb)(const char *event_name, void *data);
-
-inotify_watch_info_h _inotify_add_watch(const char *path, uint32_t mask,
- inotify_watch_cb callback, void *data);
-void _inotify_rm_watch(inotify_watch_info_h handle);
-int _inotify_init(void);
-void _inotify_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <bundle.h>
-
-#include "amd_request.h"
-#include "amd_util.h"
-#include "amd_appinfo.h"
-#include "amd_app_status.h"
-#include "amd_comp_status.h"
-
-#define PROC_STATUS_LAUNCH 0
-#define PROC_STATUS_FG 3
-#define PROC_STATUS_BG 4
-#define PROC_STATUS_FOCUS 5
-#define PROC_STATUS_HIDE 7
-
-typedef struct launch_s *launch_h;
-
-typedef enum {
- LAUNCH_MODE_NORMAL,
- LAUNCH_MODE_BLOCK,
-} launch_mode_e;
-
-int _resume_app(int pid, request_h req);
-int _pause_app(int pid, request_h req);
-int _term_app(int pid, request_h req);
-int _term_req_app(int pid, request_h req);
-int _term_bgapp(int pid, request_h req);
-int _term_sub_app(int pid, uid_t uid);
-int _term_sub_inst(pid_t pid, const char *inst_id, uid_t uid);
-int _launch_start_app(const char *appid, request_h req, bool *pending,
- bool *bg_launch, bool new_instance);
-int _launch_start_app_local(uid_t uid, const char *appid);
-int _launch_start_app_local_with_bundle(uid_t uid, const char *appid,
- bundle *kb);
-int _launch_start_onboot_app_local(uid_t uid, const char *appid,
- struct appinfo *ai);
-int _launch_init(void);
-void _launch_set_focused_pid(int pid);
-int _launch_get_focused_pid(void);
-int _term_app_v2(int pid, request_h req, bool *pend);
-int _launch_start_onboot_apps(uid_t uid);
-int _terminate_app_local(uid_t uid, int pid);
-int _launch_context_get_pid(launch_h h);
-int _launch_context_set_pid(launch_h h, int pid);
-const char *_launch_context_get_appid(launch_h h);
-bool _launch_context_is_new_instance(launch_h h);
-int _launch_context_set_subapp(launch_h h, bool is_subapp);
-int _launch_context_set_app_status(launch_h h, app_status_h status);
-int _launch_context_set_comp_status(launch_h h, comp_status_h status);
-const char *_launch_context_get_instance_id(launch_h h);
-bool _launch_context_is_subapp(launch_h h);
-bool _launch_context_is_bg_launch(launch_h h);
-const struct appinfo *_launch_context_get_appinfo(launch_h h);
-void _launch_context_set_custom_effect(launch_h h, bool is_custom_effect);
-bool _launch_context_is_custom_effect(launch_h h);
-void _launch_set_mode(launch_mode_e mode);
-int _launch_resume_inst(int pid, request_h req);
-int _launch_pause_inst(int pid, request_h req);
-int _launch_terminate_bg_inst(int pid, request_h req);
-int _launch_terminate_inst(int pid, request_h req);
-int _launch_send_sigkill(int pid, uid_t uid);
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include <bundle_internal.h>
-
-bool _launch_mode_is_group_mode(bundle *kb, uid_t uid);
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#pragma once
-
-int _launcher_service_init(void);
-
-void _launcher_service_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <bundle.h>
-
-int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
- void *user_data);
-
-int _launchpad_launch(bundle *kb, uid_t uid);
-
-int _launchpad_recover_launcher(uid_t uid);
-
-int _launchpad_init(void);
-
-void _launchpad_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#define LOG_MAX_STRING_SIZE 256
-
-typedef struct logger_s *logger_h;
-
-int _logger_create(const char *path, logger_h *handle);
-
-int _logger_destroy(logger_h handle);
-
-int _logger_print(logger_h handle, const char *tag, const char *format, ...);
-
-int _logger_get_fd(logger_h handle, int *fd);
-
-int _logger_init(void);
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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_LOGIN_MONITOR_H__
-#define __AMD_LOGIN_MOINTOR_H__
-
-#include <unistd.h>
-#include <sys/types.h>
-
-typedef enum uid_state_e {
- UID_STATE_UNKNOWN = 0x00,
- UID_STATE_OPENING = 0x01,
- UID_STATE_LINGERING = 0x02,
- UID_STATE_ONLINE = 0x04,
- UID_STATE_ACTIVE = 0x08,
- UID_STATE_CLOSING = 0x10,
- UID_STATE_OFFLINE = 0x20,
-} uid_state;
-
-pid_t _login_monitor_get_launchpad_pid(uid_t uid);
-void _login_monitor_set_uid_state(uid_t uid, uid_state state);
-uid_state _login_monitor_get_uid_state(uid_t uid);
-int _login_monitor_get_uids(uid_t **uids);
-int _login_monitor_init(void);
-void _login_monitor_fini(void);
-
-#endif /* __AMD_LOGIN_MONITOR_H__ */
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <dlog.h>
-
-#ifndef _E
-#define _E LOGE
-#endif
-
-#ifndef _W
-#define _W LOGW
-#endif
-
-#ifndef _I
-#define _I LOGI
-#endif
-
-#ifndef _D
-#define _D LOGD
-#endif
-
-#ifndef EXPORT
-#define EXPORT __attribute__ ((visibility("default")))
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
-#ifndef REGULAR_UID_MIN
-#define REGULAR_UID_MIN 5000
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2017 - 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.
- */
-
-#pragma once
-
-#include <bundle.h>
-
-#include "amd_api_noti_msg.h"
-
-#define NOTI_CONTINUE 0
-#define NOTI_STOP -2
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int (*noti_cb)(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data);
-
-int _noti_send(const char *msg, int arg1, int arg2, void *arg3, bundle *data);
-int _noti_listen(const char *msg, noti_cb callback);
-int _noti_init(void);
-void _noti_fini(void);
-
-#ifdef __cplusplus
-}
-#endif
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2018 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_PROC_H__
-#define __AMD_PROC_H__
-
-#include <sys/types.h>
-#include <unistd.h>
-
-int _proc_get_attr(pid_t pid, char *buf, int buf_size);
-
-#endif /* __AMD_PROC_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 - 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.
- */
-
-#pragma once
-
-#include <glib.h>
-#include <bundle.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct request_s *request_h;
-typedef int (*request_cmd_dispatch_cb)(request_h req);
-typedef struct _request_cmd_dispatch {
- int cmd;
- request_cmd_dispatch_cb callback;
-} request_cmd_dispatch;
-
-typedef void* request_reply_h;
-
-int _request_send_result(request_h req, int res);
-int _request_send_raw(request_h req, int cmd, unsigned char *data, int len);
-int _request_get_fd(request_h req);
-int _request_get_pid(request_h req);
-int _request_get_cmd(request_h req);
-int _request_set_cmd(request_h req, int cmd);
-bundle *_request_get_bundle(request_h req);
-request_h _request_create_local(int cmd, uid_t uid, int pid, bundle *kb);
-void _request_free_local(request_h req);
-int _request_remove_fd(request_h req);
-int _request_reply_for_pending_request(int pid);
-int _request_flush_pending_request(int pid);
-uid_t _request_get_target_uid(request_h req);
-uid_t _request_get_uid(request_h req);
-pid_t _request_get_target_pid(request_h req);
-int _request_usr_init(uid_t uid);
-int _request_register_cmds(const request_cmd_dispatch *cmds, int cnt);
-int _request_init(void);
-void _request_fini(void);
-int _request_reply_reset_pending_timer(request_h req, unsigned int interval, int pid);
-int _request_reply_append(int pid, void *reply);
-int _request_reply_remove(int pid, void *reply);
-request_reply_h _request_reply_create(request_h req, pid_t pid, int result, int cmd);
-int _request_reply_add_extra(request_reply_h handle, const char *key,
- void *extra, void (*extra_free_cb)(void *data));
-int _request_reply_foreach_extra(int pid, int (*callback)(const char *key, void *data));
-int _request_get_len(request_h req);
-unsigned char *_request_get_raw(request_h req);
-struct timespec *_request_get_start_time(request_h req);
-int _request_set_request_type(request_h req, const char *req_type);
-const char *_request_get_request_type(request_h req);
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2019 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#define RESOURCED_ATTRIBUTE_LARGEMEMORY 0x01
-#define RESOURCED_ATTRIBUTE_OOMTERMINATION 0X02
-#define RESOURCED_ATTRIBUTE_WEB_APP 0x04
-#define RESOURCED_ATTRIBUTE_DOWNLOAD_APP 0x08
-#define RESOURCED_ATTRIBUTE_SERVICE_APP 0x10
-#define RESOURCED_ATTRIBUTE_VIP_APP 0x20
-
-typedef enum {
- POWEROFF_NONE = 0,
- POWEROFF_POPUP,
- POWEROFF_DIRECT,
- POWEROFF_RESTART,
-} poweroff_e;
-
-typedef int (*signal_ready_cb)(void *user_data);
-
-int _signal_init(void);
-
-int _signal_send_watchdog(int pid, int signal_num);
-
-int _signal_send_proc_prelaunch(const char *appid, const char *pkgid,
- int attribute, int category);
-
-int _signal_send_proc_suspend(int pid);
-
-int _signal_send_tep_mount(char *mnt_path[], const char *pkgid);
-
-int _signal_send_tep_unmount(const char *mnt_path);
-
-int _signal_subscribe_startup_finished(int (*callback)(uid_t uid, void *data),
- void *user_data);
-
-int _signal_unsubscribe_startup_finished(void);
-
-int _signal_send_display_lock_state(const char *state, const char *flag,
- unsigned int timeout);
-
-int _signal_send_system_service(int pid);
-
-int _signal_send_display_unlock_state(const char *state, const char *flag);
-
-int _signal_subscribe_poweroff_state(void (*callback)(int state, void *data),
- void *user_data);
-
-int _signal_check_system_boot_finished(bool *finished);
-
-int _signal_get_proc_status_async(int pid,
- void (*callback)(int pid, int status, int focused, void *data),
- void *data);
-
-int _signal_add_ready_cb(signal_ready_cb callback, void *user_data);
-
-int _signal_send_app_dead(int pid);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <bundle.h>
-
-#define LAUNCHPAD_PROCESS_POOL_SOCK ".launchpad-process-pool-sock"
-
-#define PAD_CMD_LAUNCH 0
-#define PAD_CMD_VISIBILITY 10
-#define PAD_CMD_ADD_LOADER 11
-#define PAD_CMD_REMOVE_LOADER 12
-#define PAD_CMD_MAKE_DEFAULT_SLOTS 13
-#define PAD_CMD_DEMAND 14
-#define PAD_CMD_PING 15
-#define PAD_CMD_UPDATE_APP_TYPE 16
-
-int _create_sock_activation(void);
-int _create_server_sock(void);
-int _send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd,
- bundle *kb);
-int _send_cmd_to_launchpad_async(const char *pad_type, uid_t uid, int cmd,
- bundle *kb);
-void _send_result_to_client(int fd, int res);
-void _send_result_to_client_v2(int fd, int res);
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-
-#include "amd_appinfo.h"
-
-#define SUSPEND_TYPE_EXCLUDE "exclude"
-#define SUSPEND_TYPE_INCLUDE "include"
-
-enum suspend_status_e {
- SUSPEND_STATUS_EXCLUDE,
- SUSPEND_STATUS_INCLUDE,
-};
-
-enum background_category_e {
- BACKGROUND_CATEGORY_MEDIA = 0x01,
- BACKGROUND_CATEGORY_DOWNLOAD = 0x02,
- BACKGROUND_CATEGORY_BACKGROUND_NETWORK = 0x04,
- BACKGROUND_CATEGORY_LOCATION = 0x08,
- BACKGROUND_CATEGORY_SENSOR = 0x10,
- BACKGROUND_CATEGORY_IOT_COMMUNICATION = 0x20,
- BACKGROUND_CATEGORY_SYSTEM = 0x40
-};
-
-int _suspend_exclude(int pid);
-int _suspend_include(int pid);
-bool _suspend_is_excluded(int pid);
-bool _suspend_is_allowed_background(const struct appinfo *ai);
-void _suspend_add_timer(int pid);
-void _suspend_remove_timer(int pid);
-int _suspend_add_proc(int pid);
-int _suspend_remove_proc(int pid);
-int _suspend_update_status(int pid, int status);
-void _suspend_init(void);
-void _suspend_fini(void);
+++ /dev/null
-/*
- * 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_UNIX_SIGNAL_H__
-#define __AMD_UNIX_SIGNAL_H__
-
-int _unix_signal_init(void);
-
-void _unix_signal_fini(void);
-
-#endif /* __AMD_UNIX_SIGNAL_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#include <unistd.h>
-#include <dlog.h>
-#include <glib.h>
-#include <stdbool.h>
-#include <tzplatform_config.h>
-
-#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD"
-
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-#define _D(fmt, arg...) LOGD(fmt, ##arg)
-#define _W(fmt, arg...) LOGW(fmt, ##arg)
-#define _I(fmt, arg...) LOGI(fmt, ##arg)
-
-#define MAX_LOCAL_BUFSZ 128
-#define MAX_PID_STR_BUFSZ 20
-#define MAX_UID_STR_BUFSZ 20
-
-#define MAX_PACKAGE_STR_SIZE 512
-#define MAX_PACKAGE_APP_PATH_SIZE 512
-
-#define REGULAR_UID_MIN 5000
-
-#define GSLIST_FOREACH_SAFE(list, l, l_next) \
- for (l = list, l_next = g_slist_next(l); \
- l; \
- l = l_next, l_next = g_slist_next(l))
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-int _util_save_log(const char *tag, const char *message);
-int _util_init(void);
-void _util_fini(void);
-bool _util_check_oom(void);
-int _util_unlink(const char *path);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-#define AUL_DBUS_PATH "/aul/dbus_handler"
-#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
-#define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
-#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
-#define AUL_DBUS_HOMELAUNCH_SIGNAL "home_launch"
-
-#define AUL_APP_STATUS_DBUS_PATH "/Org/Tizen/Aul/AppStatus"
-#define AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE "org.tizen.aul.AppStatus"
-#define STATUS_FOREGROUND "fg"
-#define STATUS_BACKGROUND "bg"
-#define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST "AppLaunch"
-#define AUL_APP_STATUS_DBUS_RESUME_REQUEST "AppResume"
-#define AUL_APP_STATUS_DBUS_TERMINATE_REQUEST "AppTerminate"
-#define AUL_APP_STATUS_DBUS_STATUS_CHANGE "AppStatusChange"
-#define AUL_APP_STATUS_DBUS_GROUP "AppGroup"
-#define AUL_APP_STATUS_DBUS_TERMINATED "AppTerminated"
-
-#define ROTATION_BUS_NAME "org.tizen.system.coord"
-#define ROTATION_OBJECT_PATH "/Org/Tizen/System/Coord/Rotation"
-#define ROTATION_INTERFACE_NAME "org.tizen.system.coord.rotation"
-#define ROTATION_METHOD_NAME "Degree"
-
-#define APPFW_SUSPEND_HINT_PATH "/Org/Tizen/Appfw/SuspendHint"
-#define APPFW_SUSPEND_HINT_INTERFACE "org.tizen.appfw.SuspendHint"
-#define APPFW_SUSPEND_HINT_SIGNAL "SuspendHint"
-
-#define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
-#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
-#define RESOURCED_FREEZER_SIGNAL "FreezerState"
-
-#define RESOURCED_PROC_OBJECT "/Org/Tizen/ResourceD/Process"
-#define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
-#define RESOURCED_PROC_METHOD "ProcExclude"
-#define RESOURCED_PROC_PRELAUNCH_SIGNAL "ProcPrelaunch"
-#define RESOURCED_PROC_WATCHDOG_SIGNAL "ProcWatchdog"
-#define RESOURCED_PROC_GROUP_SIGNAL "ProcGroup"
-#define RESOURCED_SYSTEM_SERVICE_SIGNAL "SystemService"
-#define RESOURCED_ALLOWED_BG_ATTRIBUTE 0x100
-#define RESOURCED_BG_MANAGEMENT_ATTRIBUTE 0x200
-#define RESOURCED_API_VER_2_4_ATTRIBUTE 0x400
-
-#define PASS_BUS_NAME "org.tizen.system.pass"
-#define PASS_PATH_PMQOS "/Org/Tizen/System/Pass/Pmqos"
-#define PASS_INTERFACE_PMQOS "org.tizen.system.pass.pmqos"
-#define PASS_METHOD_APPLAUNCH "AppLaunch"
-
-#define SYSTEM_BUS_NAME "org.tizen.system.deviced"
-#define TEP_BUS_NAME SYSTEM_BUS_NAME
-#define TEP_OBJECT_PATH "/Org/Tizen/System/DeviceD/Tzip"
-#define TEP_INTERFACE_NAME "org.tizen.system.deviced.Tzip"
-#define TEP_MOUNT_METHOD "Mount"
-#define TEP_UNMOUNT_METHOD "Unmount"
-#define TEP_IS_MOUNTED_METHOD "IsMounted"
-
-#define WM_PROC_NAME "org.enlightenment.wm"
-#define WM_PROC_PATH "/org/enlightenment/wm"
-#define WM_PROC_INTERFACE "org.enlightenment.wm.proc"
-#define WM_PROC_METHOD "GetProcStatus"
-
-#define SD_BUS_NAME "org.freedesktop.systemd1"
-#define SD_OBJECT_PATH "/org/freedesktop/systemd1"
-#define SD_MANAGER_INTERFACE "org.freedesktop.systemd1.Manager"
-#define SD_STARTUP_FINISHED_SIGNAL "StartupFinished"
-#define SD_USER_SESSION_STARTUP_FINISHED_SIGNAL "UserSessionStartupFinished"
-#define SD_SUBSCRIBE_METHOD "Subscribe"
-#define SD_UNIT_OBJECT_PATH "/org/freedesktop/systemd1/unit/default_2etarget"
-#define SD_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
-#define SD_GET_METHOD "Get"
-#define SD_SYSTEM_STATE_METHOD "SystemState"
-
-#define SYSTEM_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display"
-#define SYSTEM_INTERFACE_DISPLAY "org.tizen.system.deviced.display"
-#define SYSTEM_LOCK_STATE "lockstate"
-#define SYSTEM_UNLOCK_STATE "unlockstate"
-#define SYSTEM_LCD_OFF "lcdoff"
-#define SYSTEM_STAY_CUR_STATE "staycurstate"
-#define SYSTEM_SLEEP_MARGIN "sleepmargin"
-
-#define SYSTEM_PATH_POWEROFF "/Org/Tizen/System/DeviceD/PowerOff"
-#define SYSTEM_INTERFACE_POWEROFF "org.tizen.system.deviced.PowerOff"
-#define SYSTEM_POWEROFF_STATE_SIGNAL "ChangeState"
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#pragma once
-
-/** AUL SVC internal private key */
-#define AUL_SVC_K_OPERATION "__APP_SVC_OP_TYPE__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_URI "__APP_SVC_URI__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_MIME "__APP_SVC_MIME_TYPE__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_DATA "__APP_SVC_DATA__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_PKG_NAME "__APP_SVC_PKG_NAME__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_CATEGORY "__APP_SVC_CATEGORY__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_RES_VAL "__APP_SVC_K_RES_VAL__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_WIN_ID "__APP_SVC_K_WIN_ID__"
-/** AUL SVC internal private key */
-#define AUL_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+++ /dev/null
-# Package Information for pkg-config
-
-prefix=/usr
-exec_prefix=@EXEC_PREFIX@
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDE_INSTALL_DIR@
-
-Name: libamd
-Description: amd library for making plugins
-Version: @VERSION@
-Requires: bundle
-Libs: -L${libdir} -lamd
-Cflags: -I${includedir} -I${includedir}/amd
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-ADD_SUBDIRECTORY(wayland-core)
-ADD_SUBDIRECTORY(cooldown)
-ADD_SUBDIRECTORY(splash-screen)
-ADD_SUBDIRECTORY(input)
-ADD_SUBDIRECTORY(widget)
-ADD_SUBDIRECTORY(launchpad)
-ADD_SUBDIRECTORY(share)
-ADD_SUBDIRECTORY(ui-core)
-ADD_SUBDIRECTORY(extractor)
-ADD_SUBDIRECTORY(cynara-core)
-ADD_SUBDIRECTORY(rua)
-ADD_SUBDIRECTORY(watch)
-ADD_SUBDIRECTORY(job-scheduler)
-ADD_SUBDIRECTORY(boost)
-ADD_SUBDIRECTORY(rpc-port)
-ADD_SUBDIRECTORY(complication)
-ADD_SUBDIRECTORY(watchdog)
-ADD_SUBDIRECTORY(screen-resolution)
-ADD_SUBDIRECTORY(component-manager)
-ADD_SUBDIRECTORY(loader-manager)
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_BOOST "amd-mod-boost")
-SET(AMD_MOD_BOOST_DIR ${CMAKE_SOURCE_DIR}/modules/boost)
-PROJECT(${AMD_MOD_BOOST} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_BOOST_DIR}/src AMD_MOD_BOOST_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_BOOST_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- vconf
- bundle
- )
-
-pkg_check_modules(amd_mod_boost_pkgs REQUIRED ${AMD_MOD_BOOST_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_boost_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_BOOST_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_BOOST} ${AMD_MOD_BOOST_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_BOOST} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_BOOST} ${amd_mod_boost_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_BOOST} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <amd.h>
-#include <vconf.h>
-#include <aul_cmd.h>
-#include <aul_svc_priv_key.h>
-#include <bundle_internal.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_BOOST"
-
-#define PASS_BUS_NAME "org.tizen.system.pass"
-#define PASS_PATH_PMQOS "/Org/Tizen/System/Pass/Pmqos"
-#define PASS_INTERFACE_PMQOS "org.tizen.system.pass.pmqos"
-#define PASS_METHOD_APPLAUNCH "AppLaunch"
-
-#define APP_BOOSTING_PERIOD 1500
-#define APP_BOOSTING_STOP 0
-
-#define APP_CONTROL_OPERATION_MAIN \
- "http://tizen.org/appcontrol/operation/main"
-
-static GDBusConnection *__system_conn;
-
-static GDBusConnection *__get_system_conn(void)
-{
- GError *err = NULL;
-
- if (__system_conn)
- return __system_conn;
-
- __system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (__system_conn == NULL) {
- _E("g_bus_get_sync() is failed: %s", err->message);
- g_error_free(err);
- return NULL;
- }
-
- return __system_conn;
-}
-
-static int __send_cpu_boost_request(int req)
-{
- GError *err = NULL;
- GDBusMessage *msg;
- GDBusConnection *conn;
- int res = 0;
-
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- msg = g_dbus_message_new_method_call(PASS_BUS_NAME,
- PASS_PATH_PMQOS,
- PASS_INTERFACE_PMQOS,
- PASS_METHOD_APPLAUNCH);
- if (msg == NULL) {
- _E("g_dbus_message_new_method_call() is failed.");
- return -1;
- }
-
- g_dbus_message_set_body(msg, g_variant_new("(i)", req));
- if (g_dbus_connection_send_message(conn,
- msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE,
- NULL,
- &err) == FALSE) {
- _E("g_dbus_connection_send_message() is failed(%s)",
- err->message);
- res = -1;
- }
-
- g_dbus_connection_flush(conn, NULL, NULL, NULL);
- g_object_unref(msg);
- g_clear_error(&err);
-
- _D("send cpu boost req(%d)", req);
-
- return res;
-}
-
-static int __on_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- __send_cpu_boost_request(APP_BOOSTING_PERIOD);
- return 0;
-}
-
-static int __on_cancel(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- __send_cpu_boost_request(APP_BOOSTING_STOP);
- return 0;
-}
-
-static int __on_launch(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- __send_cpu_boost_request(APP_BOOSTING_STOP);
- return 0;
-}
-
-static int __on_relaunch_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *kb)
-{
- int cmd = arg1;
- const char *op;
- int lcd_status = 0;
-
- op = bundle_get_val(kb, AUL_SVC_K_OPERATION);
- if ((op && !strcmp(op, APP_CONTROL_OPERATION_MAIN)) ||
- cmd == APP_OPEN) {
- vconf_get_int(VCONFKEY_PM_STATE, &lcd_status);
- if (lcd_status == VCONFKEY_PM_STATE_LCDOFF)
- _D("LCD OFF: Skip app launch boost");
- else
- __send_cpu_boost_request(APP_BOOSTING_PERIOD);
- }
-
- return 0;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("boost init");
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START,
- __on_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
- __on_cancel);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH,
- __on_launch);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START,
- __on_relaunch_start);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("boost finish");
-
- if (__system_conn) {
- g_object_unref(__system_conn);
- __system_conn = NULL;
- }
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_COMPLICATION "amd-mod-complication")
-SET(AMD_MOD_COMPLICATION_DIR ${CMAKE_SOURCE_DIR}/modules/complication)
-PROJECT(${AMD_MOD_COMPLICATION} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_COMPLICATION_DIR}/src AMD_MOD_COMPLICATION_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_COMPLICATION_PKG_CHECK_MODULES
- dlog
- aul
- )
-
-pkg_check_modules(amd_mod_complication_pkgs REQUIRED ${AMD_MOD_COMPLICATION_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_complication_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_COMPLICATION_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_COMPLICATION} ${AMD_MOD_COMPLICATION_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_COMPLICATION} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_COMPLICATION} ${amd_mod_complication_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_COMPLICATION} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_COMPLICATION"
-
-#define MAX_NR_OF_DESCRIPTORS 2
-#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
-
-static int __dispatch_complication_start(amd_request_h req)
-{
- bundle *b = amd_request_get_bundle(req);
- pid_t caller_pid = amd_request_get_pid(req);
- uid_t target_uid = amd_request_get_target_uid(req);
- amd_appinfo_h ai;
- const char *appid;
- const char *comp_type;
- int pid;
- bool dummy_pending = false;
- bool dummy_bg_launch = false;
-
- if (!b) {
- _E("Invalid parameter");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get appid");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- ai = amd_appinfo_find(target_uid, appid);
- if (!ai) {
- _E("Failed to find %s:%u", appid, target_uid);
- amd_request_send_result(req, -ENOENT);
- return -1;
- }
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (!comp_type) {
- amd_request_send_result(req, -1);
- return -1;
- }
-
- if (strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
- _E("Target(%s) is not a service-app", appid);
- amd_request_send_result(req, -EREJECTED);
- return -1;
- }
-
- amd_request_set_request_type(req, "complication");
- amd_request_set_cmd(req, APP_START_ASYNC);
- pid = amd_launch_start_app(appid, req,
- &dummy_pending, &dummy_bg_launch,
- false);
- if (pid < 0) {
- _E("Failed to send launch request(%s)",
- appid);
- return -1;
- }
-
- _I("[__COMPLICATION__] appid(%s), pid(%d), caller_pid(%d)",
- appid, pid, caller_pid);
-
- return 0;
-}
-
-static int __complication_cynara_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- int r;
-
- r = amd_cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
- if (r <= AMD_CYNARA_RET_DENIED)
- return r;
-
- return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
-}
-
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = COMPLICATION_UPDATE_REQUEST,
- .callback = __dispatch_complication_start
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = COMPLICATION_UPDATE_REQUEST,
- .checker = __complication_cynara_checker,
- .data = NULL,
- .priority = 10
- },
-};
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- _D("complication init");
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register cynara checkers");
- return -1;
- }
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("complication finish");
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_COMPONENT_MANAGER "amd-mod-component-manager")
-PROJECT(${AMD_MOD_COMPONENT_MANAGER} C CXX)
-
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/request_handler)
-
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src
- AMD_MOD_COMPONENT_MANAGER_SOURCES)
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src/request_handler
- AMD_MOD_COMPONENT_MANAGER_REQUEST_HANDLER_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_COMPONENT_MANAGER_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- bundle
- aul
- )
-
-pkg_check_modules(amd_mod_component_manager_pkgs REQUIRED
- ${AMD_MOD_COMPONENT_MANAGER_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_component_manager_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -std=c++11")
-
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_COMPONENT_MANAGER}
- ${AMD_MOD_COMPONENT_MANAGER_SOURCES}
- ${AMD_MOD_COMPONENT_MANAGER_REQUEST_HANDLER_SOURCES}
- )
-SET_TARGET_PROPERTIES(${AMD_MOD_COMPONENT_MANAGER} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_COMPONENT_MANAGER} ${amd_mod_component_manager_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_COMPONENT_MANAGER}
- DESTINATION ${AMD_MODULES_DIR}/mod
- COMPONENT RunctimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2019 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 "component_info.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-
-ComponentInfo::LocalizedInfo::LocalizedInfo(std::string locale,
- std::string icon,
- std::string label)
- : locale_(std::move(locale)),
- icon_(std::move(icon)),
- label_(std::move(label)) {
-}
-
-ComponentInfo::LocalizedInfo::~LocalizedInfo() = default;
-
-std::string ComponentInfo::LocalizedInfo::GetLocale() {
- return locale_;
-}
-
-std::string ComponentInfo::LocalizedInfo::GetIcon() {
- return icon_;
-}
-
-std::string ComponentInfo::LocalizedInfo::GetLabel() {
- return label_;
-}
-
-ComponentInfo::ComponentInfo(uid_t uid, std::string component_id)
- : handle_(nullptr, aul_compinfo_destroy), uid_(uid) {
- aul_compinfo_h handle_inst = nullptr;
- aul_compinfo_usr_create(component_id.c_str(), uid, &handle_inst);
- handle_.reset(handle_inst);
-}
-
-ComponentInfo::ComponentInfo(aul_compinfo_h info, uid_t uid)
- : handle_(info, aul_compinfo_destroy), uid_(uid) {
-}
-
-ComponentInfo::~ComponentInfo() = default;
-
-std::string ComponentInfo::GetAppID() {
- const char* app_id = nullptr;
- aul_compinfo_get_app_id(handle_.get(), &app_id);
- if (app_id)
- return std::string(app_id);
-
- return std::string("");
-}
-
-std::string ComponentInfo::GetComponentID() {
- const char* comp_id = nullptr;
- aul_compinfo_get_comp_id(handle_.get(), &comp_id);
- if (comp_id)
- return std::string(comp_id);
-
- return std::string("");
-}
-
-std::string ComponentInfo::GetType() {
- const char* type = nullptr;
- aul_compinfo_get_type(handle_.get(), &type);
- if (type)
- return std::string(type);
-
- return std::string("");
-}
-
-std::string ComponentInfo::GetLaunchMode() {
- const char* launch_mode = nullptr;
- aul_compinfo_get_launch_mode(handle_.get(), &launch_mode);
- if (launch_mode)
- return std::string(launch_mode);
-
- return std::string("");
-}
-
-bool ComponentInfo::IsMainComponent() {
- bool is_main_comp = false;
- aul_compinfo_is_main_comp(handle_.get(), &is_main_comp);
- return is_main_comp;
-}
-
-bool ComponentInfo::IsIconDisplay() {
- bool is_icon_display = false;
- aul_compinfo_is_icon_display(handle_.get(), &is_icon_display);
- return is_icon_display;
-}
-
-bool ComponentInfo::IsManagedByTaskManager() {
- bool managed = false;
- aul_compinfo_is_taskmanage(handle_.get(), &managed);
- return managed;
-}
-
-std::vector<std::unique_ptr<ComponentInfo::LocalizedInfo>>
-ComponentInfo::GetLocalizedInfos() {
- std::vector<std::unique_ptr<LocalizedInfo>> infos;
- aul_compinfo_usr_foreach_localized_info(GetComponentID().c_str(), uid_,
- [](aul_compinfo_localized_info_h handle, void* user_data) -> bool {
- const char* locale;
- aul_compinfo_localized_info_get_locale(handle, &locale);
- const char* icon;
- aul_compinfo_localized_info_get_icon(handle, &icon);
- if (icon == nullptr)
- icon = "";
- const char* label;
- aul_compinfo_localized_info_get_label(handle, &label);
- if (label == nullptr)
- label = "";
-
- auto* infos = static_cast<std::vector<std::unique_ptr<LocalizedInfo>>*>(
- user_data);
- infos->emplace_back(
- new (std::nothrow) LocalizedInfo(locale, icon, label));
- return true;
- }, &infos);
- return infos;
-}
-
-tizen_base::Bundle ComponentInfo::ToBundle() {
- tizen_base::Bundle b;
- b.Add(AUL_K_APPID, GetAppID());
- b.Add(AUL_K_COMPONENT_ID, GetComponentID());
- b.Add(AUL_K_COMPONENT_TYPE, GetType());
- b.Add(AUL_K_LAUNCH_MODE, GetLaunchMode());
- b.Add(AUL_K_MAIN_COMP, IsMainComponent() ? "true" : "false");
- b.Add(AUL_K_ICON_DISPLAY, IsIconDisplay() ? "true" : "false");
- b.Add(AUL_K_TASK_MANAGE, IsManagedByTaskManager() ? "true" : "false");
-
- std::vector<std::string> localized_info_arr;
- std::vector<std::string> localized_info_size_arr;
- for (auto& info : GetLocalizedInfos()) {
- tizen_base::Bundle localized_info_b;
- localized_info_b.Add(AUL_K_LOCALE, info->GetLocale());
- localized_info_b.Add(AUL_K_ICON, info->GetIcon());
- localized_info_b.Add(AUL_K_LABEL, info->GetLabel());
-
- auto raw = localized_info_b.ToRaw();
- localized_info_arr.emplace_back(reinterpret_cast<char*>(raw.first.get()));
- localized_info_size_arr.push_back(std::to_string(raw.second));
- }
- b.Add(AUL_K_LOCALIZED_INFO, localized_info_arr);
- b.Add(AUL_K_LOCALIZED_INFO_SIZE, localized_info_size_arr);
- return b;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 COMPONENT_INFO_H_
-#define COMPONENT_INFO_H_
-
-#include <unistd.h>
-#include <aul_comp_info_internal.h>
-#include <bundle_cpp.h>
-
-#include <string>
-#include <memory>
-#include <vector>
-
-namespace component_manager {
-
-class ComponentInfo {
- public:
- class LocalizedInfo {
- public:
- LocalizedInfo(std::string locale, std::string icon, std::string label);
- virtual ~LocalizedInfo();
-
- std::string GetLocale();
- std::string GetIcon();
- std::string GetLabel();
-
- private:
- std::string locale_;
- std::string icon_;
- std::string label_;
- };
-
- public:
- ComponentInfo(uid_t uid, std::string component_id);
- ComponentInfo(aul_compinfo_h info, uid_t uid);
- virtual ~ComponentInfo();
-
- std::string GetAppID();
- std::string GetComponentID();
- std::string GetType();
- std::string GetLaunchMode();
- bool IsMainComponent();
- bool IsIconDisplay();
- bool IsManagedByTaskManager();
- std::vector<std::unique_ptr<LocalizedInfo>> GetLocalizedInfos();
-
- tizen_base::Bundle ToBundle();
-
- private:
- std::unique_ptr<std::remove_pointer<aul_compinfo_h>::type,
- decltype(aul_compinfo_destroy)*> handle_;
- uid_t uid_;
-};
-
-} // namespace component_manager
-
-#endif // COMPONENT_INFO_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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_cmd.h>
-
-#include "component_manager.h"
-#include "request_handler/component_info_get.h"
-#include "request_handler/component_info_foreach.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-using namespace component_manager::request_handler;
-
-int ComponentManager::Register() {
- int ret = RegisterCommands();
- if (ret< 0)
- return ret;
-
- ret = RegisterCynaraCheckers();
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int ComponentManager::Dispatch(std::unique_ptr<Request> req) {
- return dispatcher_->Dispatch(std::move(req));
-}
-
-void ComponentManager::Init() {
- dispatcher_ = std::unique_ptr<Dispatcher>(new (std::nothrow) Dispatcher());
- dispatcher_->Register(std::shared_ptr<RequestHandler>(
- new (std::nothrow) ComponentInfoGet()));
- dispatcher_->Register(std::shared_ptr<RequestHandler>(
- new (std::nothrow) ComponentInfoForeach()));
-
- initialized_ = true;
-}
-
-int ComponentManager::RegisterCommands() {
- static amd_request_cmd_dispatch dispatch_table[] = {
- {
- .cmd = COMP_INFO_GET,
- .callback = OnDispatch
- },
- {
- .cmd = COMP_INFO_FOREACH,
- .callback = OnDispatch
- },
- };
-
- int ret = amd_request_register_cmds(dispatch_table,
- ARRAY_SIZE(dispatch_table));
- if (ret < 0) {
- _E("Failed to register AMD request cmds");
- return ret;
- }
-
- return 0;
-}
-
-int ComponentManager::RegisterCynaraCheckers() {
- void* packagemanager_info = const_cast<char*>(PRIVILEGE_PACKAGEMANAGER_INFO);
- static amd_cynara_checker cynara_checkers[] = {
- {
- .cmd = COMP_INFO_GET,
- .checker = amd_cynara_simple_checker,
- .data = packagemanager_info
- },
- {
- .cmd = COMP_INFO_FOREACH,
- .checker = amd_cynara_simple_checker,
- .data = packagemanager_info
- },
- };
-
- int ret = amd_cynara_register_checkers(cynara_checkers,
- ARRAY_SIZE(cynara_checkers));
- if (ret < 0) {
- _E("Failed to register cynara checkers");
- return ret;
- }
-
- return 0;
-}
-
-int ComponentManager::OnDispatch(amd_request_h request) {
- auto req = std::unique_ptr<Request>(new (std::nothrow) Request(request));
- auto& inst = ComponentManager::GetInst();
- if (inst.Dispatch(std::move(req)) < 0) {
- _E("Failed to dispatch request");
- return -1;
- }
-
- return 0;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 COMPONENT_MANAGER_H_
-#define COMPONENT_MANAGER_H_
-
-#include <amd.h>
-
-#include <string>
-#include <memory>
-
-#include "dispatcher.h"
-
-namespace component_manager {
-
-class ComponentManager {
- private:
- ComponentManager() = default;
- ~ComponentManager() = default;
-
- public:
- ComponentManager(const ComponentManager&) = delete;
- ComponentManager& operator = (const ComponentManager&) = delete;
-
- static ComponentManager& GetInst() {
- static ComponentManager inst;
- if (!inst.initialized_)
- inst.Init();
- return inst;
- }
-
- int Register();
- int Dispatch(std::unique_ptr<Request> req);
-
- private:
- void Init();
- int RegisterCommands();
- int RegisterCynaraCheckers();
-
- private:
- static int OnDispatch(amd_request_h req);
-
- private:
- bool initialized_ = false;
- std::unique_ptr<Dispatcher> dispatcher_;
-};
-
-} // namespace component_manager
-
-#endif // COMPONENT_MANAGER_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "AMD_COMPONENT_MANAGER"
-
+++ /dev/null
-/*
- * Copyright (c) 2019 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 "dispatcher.h"
-#include "pending_job.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-
-Dispatcher::Dispatcher() {
- for (int i = 0; i < MAX_WORKER; ++i) {
- std::string name = "compmgr+" + std::to_string(i + 1);
- workers_.emplace_back(new (std::nothrow) Worker(name));
- }
-}
-
-Dispatcher::~Dispatcher() = default;
-
-int Dispatcher::Dispatch(std::unique_ptr<Request> req) {
- int cmd = req->GetCmd();
- auto iter = map_.find(cmd);
- if (iter == map_.end()) {
- _W("Failed to find handler. cmd(%d)", cmd);
- return -1;
- }
-
- auto handler = map_[cmd];
- workers_[GetWorkerID()]->Send(
- std::shared_ptr<PendingJob>(
- new (std::nothrow) PendingJob(std::move(req), handler)));
- return 0;
-}
-
-bool Dispatcher::Register(std::shared_ptr<RequestHandler> handler) {
- int cmd = handler->GetCmd();
- auto iter = map_.find(cmd);
- if (iter != map_.end()) {
- _W("Already exists. command[%d]", cmd);
- return false;
- }
-
- map_[cmd] = std::move(handler);
- _W("Register command[%d]", cmd);
- return true;
-}
-
-int Dispatcher::GetWorkerID() {
- int worker_id = 0;
- for (int i = 1; i < MAX_WORKER; i++) {
- if (workers_[worker_id]->GetJobCount() > workers_[i]->GetJobCount())
- worker_id = i;
- }
-
- return worker_id;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 DISPATCHER_H_
-#define DISPATCHER_H_
-
-#include <map>
-#include <memory>
-
-#include "request.h"
-#include "request_handler.h"
-#include "worker.h"
-
-namespace component_manager {
-
-class Dispatcher {
- public:
- Dispatcher();
- virtual ~Dispatcher();
-
- int Dispatch(std::unique_ptr<Request> req);
- bool Register(std::shared_ptr<RequestHandler> handler);
-
- private:
- int GetWorkerID();
-
- private:
- static const int MAX_WORKER = 2;
-
- private:
- std::map<int, std::shared_ptr<RequestHandler>> map_;
- std::vector<std::unique_ptr<Worker>> workers_;
-};
-
-} // namespace component_manager
-
-#endif // DISPATCHER_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 "job.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-
-Job::Job(std::string name, IJobHandler* handler) :
- name_(std::move(name)), handler_(handler) {
-}
-
-Job::~Job() = default;
-
-Job::Job(const Job& job) {
- name_ = job.name_;
- handler_ = job.handler_;
-}
-
-Job& Job::operator = (const Job& job) {
- if (this != &job) {
- name_ = job.name_;
- handler_ = job.handler_;
- }
- return *this;
-}
-
-Job::Job(Job&& job) noexcept {
- name_ = std::move(job.name_);
- handler_ = job.handler_;
- job.handler_ = nullptr;
-}
-
-Job& Job::operator = (Job&& job) noexcept {
- if (this != &job) {
- name_ = std::move(job.name_);
- handler_ = job.handler_;
- job.handler_ = nullptr;
- }
- return *this;
-}
-
-void Job::Do() {
- if (handler_ != nullptr)
- handler_->OnJob();
- _I("[__JOB__] name(%s)", name_.c_str());
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 JOB_H_
-#define JOB_H_
-
-#include <string>
-
-namespace component_manager {
-
-class Job {
- public:
- class IJobHandler {
- public:
- virtual void OnJob() = 0;
- };
-
- Job(std::string name, IJobHandler* handler);
- virtual ~Job();
- Job(const Job& job);
- Job& operator = (const Job& b);
- Job(Job&& job) noexcept;
- Job& operator = (Job&& job) noexcept;
-
- void Do();
-
- private:
- std::string name_;
- IJobHandler* handler_;
-};
-
-} // namespace component_manager
-
-#endif // JOB_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 "component_manager.h"
-#include "component_manager_private.h"
-
-using namespace component_manager;
-
-extern "C" EXPORT int AMD_MOD_INIT(void) {
- _D("Component Manager Initialize");
-
- auto& inst = ComponentManager::GetInst();
- int ret = inst.Register();
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-extern "C" EXPORT void AMD_MOD_FINI(void) {
- _D("Component Manager Finalize");
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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_cmd.h>
-
-#include "pending_job.h"
-
-namespace component_manager {
-
-PendingJob::PendingJob(std::unique_ptr<Request> req,
- std::shared_ptr<RequestHandler> handler)
- : Job(std::string(aul_cmd_convert_to_string(req->GetCmd())), this),
- req_(std::move(req)),
- handler_(std::move(handler)) {
-}
-
-void PendingJob::OnJob() {
- handler_->Handle(req_);
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 PENDING_JOB_H_
-#define PENDING_JOB_H_
-
-#include <memory>
-
-#include "job.h"
-#include "request_handler.h"
-
-namespace component_manager {
-
-class PendingJob : public Job, Job::IJobHandler {
- public:
- PendingJob(std::unique_ptr<Request> req,
- std::shared_ptr<RequestHandler> handler);
-
- private:
- void OnJob() override;
-
- private:
- std::unique_ptr<Request> req_;
- std::shared_ptr<RequestHandler> handler_;
-};
-
-} // namespace component_manager
-
-#endif // PENDING_JOB_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 "request.h"
-
-namespace component_manager {
-
-Request::Request(amd_request_h req) {
- fd_ = amd_request_remove_fd(req);
- cmd_ = amd_request_get_cmd(req);
- target_uid_ = amd_request_get_target_uid(req);
- b_ = tizen_base::Bundle(amd_request_get_bundle(req));
-}
-
-Request::Request(int fd, int cmd, uid_t target_uid, tizen_base::Bundle b)
- : fd_(fd), cmd_(cmd), target_uid_(target_uid), b_(std::move(b)) {
-}
-
-Request::~Request() {
- if (fd_)
- close(fd_);
-}
-
-Request::Request(const Request& req) {
- fd_ = req.fd_;
- cmd_ = req.cmd_;
- target_uid_ = req.target_uid_;
- b_ = req.b_;
-}
-
-Request& Request::operator = (const Request& req) {
- if (this != &req) {
- fd_ = req.fd_;
- cmd_ = req.cmd_;
- target_uid_ = req.target_uid_;
- b_ = req.b_;
- }
- return *this;
-}
-
-Request::Request(Request&& req) noexcept {
- fd_ = req.fd_;
- req.fd_ = 0;
- cmd_ = req.cmd_;
- req.cmd_ = -1;
- target_uid_ = req.target_uid_;
- req.target_uid_ = 0;
- b_ = std::move(req.b_);
-}
-
-Request& Request::operator = (Request&& req) noexcept {
- if (this != &req) {
- fd_ = req.fd_;
- req.fd_ = 0;
- cmd_ = req.cmd_;
- req.cmd_ = -1;
- target_uid_ = req.target_uid_;
- req.target_uid_ = 0;
- b_ = std::move(req.b_);
- }
- return *this;
-}
-
-int Request::RemoveFd() {
- int fd = fd_;
- fd_ = 0;
- return fd;
-}
-
-int Request::GetFd() const {
- return fd_;
-}
-
-int Request::GetCmd() const {
- return cmd_;
-}
-
-uid_t Request::GetTargetUid() const {
- return target_uid_;
-}
-
-const tizen_base::Bundle& Request::GetBundle() const {
- return b_;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 REQUEST_H_
-#define REQUEST_H_
-
-#include <amd.h>
-#include <unistd.h>
-
-#include <bundle_cpp.h>
-
-namespace component_manager {
-
-class Request {
- public:
- Request(amd_request_h req);
- Request(int fd, int cmd, uid_t target_uid, tizen_base::Bundle b);
- ~Request();
-
- Request(const Request& req);
- Request& operator = (const Request& req);
- Request(Request&& req) noexcept;
- Request& operator = (Request&& req) noexcept;
-
- int RemoveFd();
- int GetFd() const;
- int GetCmd() const;
- uid_t GetTargetUid() const;
- const tizen_base::Bundle& GetBundle() const;
-
- private:
- int fd_;
- int cmd_;
- uid_t target_uid_;
- tizen_base::Bundle b_;
-};
-
-} // namespace component_manager
-
-#endif // REQUEST_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 <memory>
-
-#include "request_handler.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-
-RequestHandler::RequestHandler(int cmd, std::string name)
- : cmd_(cmd), name_(std::move(name)) {
-}
-
-RequestHandler::~RequestHandler() = default;
-
-RequestHandler::RequestHandler(const RequestHandler& handler) {
- cmd_ = handler.cmd_;
- name_ = handler.name_;
-}
-
-RequestHandler& RequestHandler::operator = (const RequestHandler& handler) {
- if (this != &handler) {
- cmd_ = handler.cmd_;
- name_ = handler.name_;
- }
- return *this;
-}
-
-RequestHandler::RequestHandler(RequestHandler&& handler) noexcept {
- cmd_ = handler.cmd_;
- handler.cmd_ = 0;
- name_ = std::move(handler.name_);
-}
-
-RequestHandler& RequestHandler::operator = (RequestHandler&& handler) noexcept {
- if (this != &handler) {
- cmd_ = handler.cmd_;
- handler.cmd_ = 0;
- name_ = std::move(handler.name_);
- }
- return *this;
-}
-
-int RequestHandler::Handle(std::unique_ptr<Request>& req) {
- _W("Command: %s[%d]", name_.c_str(), cmd_);
- return 0;
-}
-
-int RequestHandler::GetCmd() const {
- return cmd_;
-}
-
-std::string RequestHandler::GetName() {
- return name_;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 REQUEST_HANDLER_H_
-#define REQUEST_HANDLER_H_
-
-#include <string>
-#include <memory>
-
-#include "request.h"
-
-namespace component_manager {
-
-class RequestHandler {
- public:
- RequestHandler(int cmd, std::string name);
- virtual ~RequestHandler();
-
- RequestHandler(const RequestHandler& handler);
- RequestHandler& operator = (const RequestHandler& handler);
- RequestHandler(RequestHandler&& handler) noexcept;
- RequestHandler& operator = (RequestHandler&& handler) noexcept;
-
- virtual int Handle(std::unique_ptr<Request>& req);
-
- int GetCmd() const;
- std::string GetName();
-
- private:
- int cmd_;
- std::string name_;
-};
-
-} // namespace component_manager
-
-#endif // REQUEST_HANDLER_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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_comp_info_internal.h>
-#include <aul_cmd.h>
-#include <errno.h>
-
-#ifdef _GNU_SOURCE
-#undef _GNU_SOURCE
-#endif
-#include <aul_sock.h>
-#include <amd.h>
-
-#include "component_info.h"
-#include "request_handler/component_info_foreach.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-namespace request_handler {
-
-class ComponentInfoForeachUserData {
- public:
- ComponentInfoForeachUserData(uid_t uid, void* user_data)
- : uid_(uid), user_data_(user_data) { }
-
- uid_t uid_;
- void* user_data_;
-};
-
-ComponentInfoForeach::ComponentInfoForeach()
- : RequestHandler(COMP_INFO_FOREACH, "COMP_INFO_FOREACH") {
-}
-
-int ComponentInfoForeach::Handle(std::unique_ptr<Request>& req) {
- RequestHandler::Handle(req);
-
- std::vector<std::unique_ptr<ComponentInfo>> infos;
- ComponentInfoForeachUserData user_data(req->GetTargetUid(), &infos);
- int ret = aul_compinfo_usr_foreach_compinfo(req->GetTargetUid(),
- [](aul_compinfo_h handle, void* user_data) -> bool {
- aul_compinfo_h clone = nullptr;
- aul_compinfo_clone(handle, &clone);
- if (clone == nullptr) {
- _E("Failed to clone compinfo");
- return false;
- }
-
- auto* data = static_cast<ComponentInfoForeachUserData*>(user_data);
- auto* infos = static_cast<std::vector<std::unique_ptr<ComponentInfo>>*>(
- data->user_data_);
- infos->emplace_back(
- new (std::nothrow) ComponentInfo(clone, data->uid_));
- return true;
- }, &user_data);
- if (ret < 0) {
- _E("Failed to retrieve component info. error(%d)", ret);
- amd_socket_send_result(req->GetFd(), ret, false);
- return ret;
- }
-
- amd_socket_send_result(req->GetFd(), infos.size(), false);
- for (auto& info : infos) {
- auto b = info->ToBundle();
- bundle* b_raw = b.GetHandle();
- ret = aul_sock_send_bundle_with_fd(req->GetFd(), APP_GET_INFO_OK, b_raw,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send bundle data. error(%d)", ret);
- return ret;
- }
- }
-
- _I("[%s][%d]", GetName().c_str(), GetCmd());
- return 0;
-}
-
-} // namespace request_handler
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 REUQEST_HANDLER_COMPONENT_INFO_FOREACH_H_
-#define REQUEST_HANDLER_COMPONENT_INFO_FOREACH_H_
-
-#include <string>
-
-#include "request_handler.h"
-
-namespace component_manager {
-namespace request_handler {
-
-class ComponentInfoForeach : public RequestHandler {
- public:
- ComponentInfoForeach();
-
- virtual int Handle(std::unique_ptr<Request>& req) override;
-};
-
-} // namespace request_handler
-} // namespace component_manager
-
-#endif // REQUEST_HANDLER_COMPONENT_INFO_FOREACH_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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_comp_info_internal.h>
-#include <aul_cmd.h>
-#include <errno.h>
-
-#ifdef _GNU_SOURCE
-#undef _GNU_SOURCE
-#endif
-#include <aul_sock.h>
-
-#include "component_info.h"
-#include "request_handler/component_info_get.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-namespace request_handler {
-
-ComponentInfoGet::ComponentInfoGet()
- : RequestHandler(COMP_INFO_GET, "COMP_INFO_GET") {
-}
-
-int ComponentInfoGet::Handle(std::unique_ptr<Request>& req) {
- RequestHandler::Handle(req);
-
- auto& b = req->GetBundle();
- std::string component_id = b.GetString(AUL_K_COMPONENT_ID);
- if (component_id.empty()) {
- _E("Failed to get component ID");
- aul_sock_send_raw_with_fd(req->GetFd(), AUL_R_EINVAL, NULL, 0,
- AUL_SOCK_ASYNC);
- return -1;
- }
-
- aul_compinfo_h handle_inst;
- int ret = aul_compinfo_usr_create(component_id.c_str(), req->GetTargetUid(),
- &handle_inst);
- if (ret != AUL_R_OK) {
- _E("Failed to create component info. error(%d)", ret);
- aul_sock_send_raw_with_fd(req->GetFd(), ret, NULL, 0, AUL_SOCK_ASYNC);
- return ret;
- }
-
- ComponentInfo info(handle_inst, req->GetTargetUid());
- auto info_b = info.ToBundle();
- bundle* b_raw = info_b.GetHandle();
- ret = aul_sock_send_bundle_with_fd(req->GetFd(), APP_GET_INFO_OK, b_raw,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send bundle data. error(%d)", ret);
- return ret;
- }
-
- _I("[%s][%d]", GetName().c_str(), GetCmd());
- return 0;
-}
-
-} // namespace request_handler
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 REUQEST_HANDLER_COMPONENT_INFO_GET_H_
-#define REQUEST_HANDLER_COMPONENT_INFO_GET_H_
-
-#include <string>
-
-#include "request_handler.h"
-
-namespace component_manager {
-namespace request_handler {
-
-class ComponentInfoGet : public RequestHandler {
- public:
- ComponentInfoGet();
-
- virtual int Handle(std::unique_ptr<Request>& req) override;
-};
-
-} // namespace request_handler
-} // namespace component_manager
-
-#endif // REQUEST_HANDLER_COMPONENT_INFO_GET_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 SHARED_QUEUE_H_
-#define SHARED_QUEUE_H_
-
-#include <condition_variable>
-#include <thread>
-#include <mutex>
-#include <memory>
-#include <queue>
-
-namespace component_manager {
-
-template <class T>
-class SharedQueue {
- public:
- SharedQueue() = default;
- virtual ~SharedQueue() = default;
-
- void Push(T item) {
- std::lock_guard<std::mutex> lock(mutex_);
- queue_.push(item);
- cond_var_.notify_one();
- }
-
- T WaitAndPop() {
- std::unique_lock<std::mutex> lock(mutex_);
- while (queue_.empty())
- cond_var_.wait(lock);
-
- auto item = std::move(queue_.front());
- queue_.pop();
- return item;
- }
-
- bool IsEmpty() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.empty();
- }
-
- unsigned int Size() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.size();
- }
-
- private:
- std::queue<T> queue_;
- mutable std::mutex mutex_;
- std::condition_variable cond_var_;
-};
-
-} // namespace component_manager
-
-#endif // SHARED_QUEUE_H_
+++ /dev/null
-/*
- * Copyright (c) 2019 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 <sys/types.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <fcntl.h>
-
-#include "worker.h"
-#include "component_manager_private.h"
-
-namespace component_manager {
-
-Worker::Worker(std::string name) : name_(std::move(name)) {
- thread_ = std::thread([&]{
- SetComm();
- Run();
- });
-}
-
-Worker::~Worker() {
- Quit();
- Join();
-}
-
-bool Worker::Join() {
- if (!thread_.joinable())
- return false;
-
- thread_.join();
- return true;
-}
-
-void Worker::Send(std::shared_ptr<Job> job) {
- queue_.Push(std::move(job));
-}
-
-void Worker::Run() {
- do {
- auto job = queue_.WaitAndPop();
- job->Do();
- } while (!done_);
-}
-
-unsigned int Worker::GetJobCount() const {
- return queue_.Size();
-}
-
-void Worker::Quit() {
- Send(std::shared_ptr<Job>(new (std::nothrow) Job("Quit", this)));
-}
-
-void Worker::SetComm() {
- pid_t tid = syscall(__NR_gettid);
- _I("[__WORKER__] Thread(%d)", tid);
-
- std::string path = "/proc/" + std::to_string(tid) + "/comm";
- int fd = open(path.c_str(), O_WRONLY);
- if (fd < 0) {
- _E("Failed to open %s. error(%d)", path.c_str(), errno);
- return;
- }
-
- ssize_t bytes_written = write(fd, name_.c_str(), name_.length() + 1);
- if (bytes_written < 0) {
- _E("Failed to write name(%s)", name_.c_str());
- close(fd);
- return;
- }
-
- close(fd);
-}
-
-void Worker::OnJob() {
- done_ = true;
-}
-
-} // namespace component_manager
+++ /dev/null
-/*
- * Copyright (c) 2019 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 WORKER_H_
-#define WORKER_H_
-
-#include <thread>
-#include <memory>
-#include <string>
-#include <queue>
-
-#include "shared_queue.h"
-#include "job.h"
-
-namespace component_manager {
-
-class Worker : public Job::IJobHandler {
- public:
- Worker(std::string name);
- ~Worker();
-
- void Send(std::shared_ptr<Job> job);
- void Run();
- unsigned int GetJobCount() const;
-
- private:
- bool Join();
- void Quit();
- void SetComm();
- void OnJob() override;
-
- private:
- std::string name_;
- std::thread thread_;
- bool done_ = false;
- SharedQueue<std::shared_ptr<Job>> queue_;
-};
-
-} // namespace component_manager
-
-#endif // WORKER_H_
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_COOLDOWN "amd-mod-cooldown")
-SET(AMD_MOD_COOLDOWN_DIR ${CMAKE_SOURCE_DIR}/modules/cooldown)
-PROJECT(${AMD_MOD_COOLDOWN} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_COOLDOWN_DIR}/src AMD_MOD_COOLDOWN_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_COOLDOWN_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- )
-
-pkg_check_modules(amd_mod_cooldown_pkgs REQUIRED ${AMD_MOD_COOLDOWN_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_cooldown_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_COOLDOWN_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_COOLDOWN} ${AMD_MOD_COOLDOWN_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_COOLDOWN} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_COOLDOWN} ${amd_mod_cooldown_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_COOLDOWN} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.application.manager.conf DESTINATION /etc/dbus-1/system.d)
+++ /dev/null
-<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
- <policy user="root">
- <allow own="org.tizen.application.manager"/>
- <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
- </policy>
- <policy user="app_fw">
- <allow own="org.tizen.application.manager"/>
- <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
- </policy>
- <policy user="system">
- <allow own="org.tizen.application.manager"/>
- <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
- </policy>
- <policy user="system_fw">
- <allow own="org.tizen.application.manager"/>
- <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
- </policy>
- <policy context="default">
- <deny own="org.tizen.application.manager"/>
- <deny send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
- </policy>
-</busconfig>
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_COOLDOWN"
-
-#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
-#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
-#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
-
-#define AMD_DBUS_INTERFACE "org.tizen.application.manager"
-#define AMD_DBUS_OBJECT_PATH "/Org/Tizen/Application/Manager"
-
-#define COOLDOWN_STATUS_RELEASE "release"
-#define COOLDOWN_STATUS_LIMIT "limit"
-
-enum cooldown_status_val {
- COOLDOWN_RELEASE,
- COOLDOWN_WARNING,
- COOLDOWN_LIMIT,
-};
-
-static int cooldown_status;
-static GDBusConnection *__conn;
-static guint __registration_id;
-
-static void __cooldown_limitaction(amd_app_status_h app_status, void *data)
-{
- amd_appinfo_h ai;
- const char *taskmanage;
- const char *cooldown;
- const char *appid;
- int app_type;
- uid_t uid;
-
- if (app_status == NULL)
- return;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_WIDGET_APP || app_type == AMD_AT_WATCH_APP)
- return;
-
- uid = amd_app_status_get_uid(app_status);
- appid = amd_app_status_get_appid(app_status);
- ai = amd_appinfo_find(uid, appid);
- if (ai == NULL)
- return;
-
- cooldown = amd_appinfo_get_value(ai, AMD_AIT_COOLDOWN);
- if (cooldown && strcmp(cooldown, "true") != 0) {
- if (app_type == AMD_AT_UI_APP) {
- taskmanage = amd_appinfo_get_value(ai,
- AMD_AIT_TASKMANAGE);
- if (taskmanage && strcmp(taskmanage, "true") != 0)
- return;
- }
-
- amd_app_status_terminate_apps(appid, uid);
- }
-}
-
-static void __cooldown_release(void)
-{
- amd_uid_state state;
- uid_t *uids;
- int r;
- int i;
-
- r = amd_login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; ++i) {
- state = amd_login_monitor_get_uid_state(uids[i]);
- if (state == AMD_UID_STATE_ACTIVE)
- amd_launch_start_onboot_apps(uids[i]);
- }
- free(uids);
-}
-
-static int __check_cooldown_mode(amd_appinfo_h ai)
-{
- const char *taskmanage;
- const char *cooldown;
- const char *comptype;
-
- if (cooldown_status != COOLDOWN_LIMIT)
- return 0;
-
- cooldown = amd_appinfo_get_value(ai, AMD_AIT_COOLDOWN);
- if (cooldown && strcmp(cooldown, "true") == 0)
- return 0;
-
- comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comptype == NULL) {
- _E("Failed to get comptype");
- return -1;
- }
-
- if (strcmp(comptype, APP_TYPE_WIDGET) == 0 ||
- strcmp(comptype, APP_TYPE_WATCH) == 0)
- return 0;
-
- if (strcmp(comptype, APP_TYPE_UI) == 0) {
- taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
- if (taskmanage && strcmp(taskmanage, "false") == 0)
- return 0;
- }
-
- _W("Cannot launch this application in COOLDOWN mode");
- return -1;
-}
-
-static int __on_check_mode(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_appinfo_h info = arg3;
-
- return __check_cooldown_mode(info);
-}
-
-static int __on_check_status(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- if (cooldown_status == COOLDOWN_LIMIT)
- return -1;
-
- return 0;
-}
-
-static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
-{
- GError *err = NULL;
- GVariant *result;
- uid_t uid = (uid_t)-1;
-
- result = g_dbus_connection_call_sync(connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- "GetConnectionUnixUser",
- g_variant_new("(s)", name),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &err);
- if (result == NULL) {
- _E("g_dbus_connection_call_sync() is failed. error(%s)",
- err->message);
- g_error_free(err);
- return uid;
- }
-
- g_variant_get(result, "(u)", &uid);
- g_variant_unref(result);
-
- return uid;
-}
-
-static void __handle_method_call(GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- int result = 0;
- char *status = NULL;
- uid_t uid;
-
- uid = __get_caller_uid(connection,
- g_dbus_method_invocation_get_sender(invocation));
- if (uid == (uid_t)-1) {
- result = -1;
- goto end;
- }
-
- if (uid >= REGULAR_UID_MIN) {
- _E("Reject request. uid(%u)", uid);
- result = -1;
- goto end;
- }
-
- if (g_strcmp0(method_name, "Cooldown") == 0) {
- g_variant_get(parameters, "(&s)", &status);
- _W("[__COOLDOWN__] status(%s)", status);
- if (g_strcmp0(status, COOLDOWN_STATUS_LIMIT) == 0) {
- cooldown_status = COOLDOWN_LIMIT;
- amd_app_status_foreach_running_info(
- __cooldown_limitaction,
- NULL);
- } else if (g_strcmp0(status, COOLDOWN_STATUS_RELEASE) == 0) {
- cooldown_status = COOLDOWN_RELEASE;
- __cooldown_release();
- } else {
- result = -1;
- }
- } else {
- _E("Invalid request(%s)", method_name);
- result = -1;
- }
-
-end:
- g_dbus_method_invocation_return_value(invocation,
- g_variant_new("(i)", result));
-}
-
-static guint __get_owner_id(GDBusConnection *connection,
- const char *interface_name)
-{
- GError *err = NULL;
- guint owner_id = 0;
- GVariant* result;
-
- result = g_dbus_connection_call_sync(connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS,
- "RequestName",
- g_variant_new("(su)",
- interface_name,
- G_BUS_NAME_OWNER_FLAGS_NONE),
- G_VARIANT_TYPE("(u)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &err);
- if (err) {
- _E("g_dbus_connection_call_sync() is failed. error(%s)",
- err->message);
- g_error_free(err);
- return 0;
- }
-
- if (result == NULL) {
- _E("Failed to get RequestName");
- return 0;
- }
-
- g_variant_get(result, "(u)", &owner_id);
- if (owner_id == 0) {
- _E("Acquiring the own name is failed");
- g_variant_unref(result);
- return 0;
- }
-
- _D("Acquiring the own name : %u", owner_id);
- g_variant_unref(result);
-
- return owner_id;
-}
-
-static int __init_request_handler(void *user_data)
-{
- static const char introspection_xml[] =
- "<node>"
- " <interface name='org.tizen.application.manager'>"
- " <method name='Cooldown'>"
- " <arg type='s' name='status' direction='in'/>"
- " <arg type='i' name='ret' direction='out'/>"
- " </method>"
- " </interface>"
- "</node>";
- static const GDBusInterfaceVTable interface_vtable = {
- __handle_method_call,
- NULL,
- NULL
- };
- GDBusNodeInfo *introspection_data;
- GError *err = NULL;
- guint owner_id;
-
- __conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!__conn) {
- _E("g_bus_get_sync() is failed. error(%s)",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- introspection_data = g_dbus_node_info_new_for_xml(introspection_xml,
- &err);
- if (!introspection_data) {
- _E("g_dbus_node_info_new_for_xml() is failed. error(%s)",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- __registration_id = g_dbus_connection_register_object(
- __conn,
- AMD_DBUS_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- NULL,
- NULL,
- &err);
- g_dbus_node_info_unref(introspection_data);
- if (__registration_id == 0) {
- _E("g_dbus_connection_register_object() is failed. error(%s)",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- owner_id = __get_owner_id(__conn, AMD_DBUS_INTERFACE);
- _I("registration_id(%u), owner_id(%u)", __registration_id, owner_id);
-
- return 0;
-}
-
-static void __fini_request_handler(void)
-{
- if (__registration_id > 0) {
- g_dbus_connection_unregister_object(__conn, __registration_id);
- __registration_id = 0;
- }
-
- if (__conn) {
- g_object_unref(__conn);
- __conn = NULL;
- }
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("cooldown init");
- amd_signal_add_ready_cb(__init_request_handler, NULL);
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
- __on_check_mode);
- amd_noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
- __on_check_status);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("cooldown fini");
- __fini_request_handler();
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_CYNARA_CORE "amd-mod-cynara-core")
-SET(AMD_MOD_CYNARA_CORE_DIR ${CMAKE_SOURCE_DIR}/modules/cynara-core)
-PROJECT(${AMD_MOD_CYNARA_CORE} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_CYNARA_CORE_DIR}/src AMD_MOD_CYNARA_CORE_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_CYNARA_CORE_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- cynara-client-async
- cynara-creds-socket
- cynara-session
- security-manager
- cert-svc-vcore
- )
-
-pkg_check_modules(amd_mod_cynara_core_pkgs REQUIRED ${AMD_MOD_CYNARA_CORE_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_cynara_core_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_CYNARA_CORE_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_CYNARA_CORE} ${AMD_MOD_CYNARA_CORE_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_CYNARA_CORE} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_CYNARA_CORE} ${amd_mod_cynara_core_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_CYNARA_CORE} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <malloc.h>
-#include <stdlib.h>
-#include <cynara-client-async.h>
-#include <cynara-creds-socket.h>
-#include <cynara-session.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <glib.h>
-#include <glib-unix.h>
-#include <aul_sock.h>
-#include <aul_svc.h>
-#include <aul_svc_priv_key.h>
-#include <aul.h>
-#include <amd.h>
-#include <security-manager.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_CYNARA_CORE"
-
-#define MAX_LOCAL_BUFSZ 128
-
-static cynara_async *r_cynara;
-static int cynara_fd = -1;
-static guint cynara_fd_id;
-static GHashTable *__checker_table;
-static GList *__sub_checkers;
-
-struct caller_info {
- GHashTable *id_table;
-
- char *user;
- char *client;
- char *session;
- char *appid;
- uid_t uid;
- bool offline;
-
- amd_cynara_response_cb callback;
- void *user_data;
-};
-
-typedef struct _cynara_sub_checker {
- char *name;
- amd_cynara_sub_checker_func checker;
-} cynara_sub_checker;
-
-static int __check_privilege_offline(const char *appid, const char *privilege,
- uid_t uid);
-
-static gboolean __cancel_func(gpointer key, gpointer value, gpointer user_data)
-{
- int r;
-
- r = cynara_async_cancel_request(r_cynara, GPOINTER_TO_UINT(key));
- if (r != CYNARA_API_SUCCESS)
- _E("cynara_async_cancel_request failed.");
-
- return TRUE;
-}
-
-static void __destroy_caller_info(struct caller_info *info)
-{
- if (info == NULL)
- return;
-
- if (info->appid)
- free(info->appid);
-
- if (info->client)
- free(info->client);
-
- if (info->session)
- free(info->session);
-
- if (info->user)
- free(info->user);
-
- if (info->id_table) {
- g_hash_table_foreach_remove(info->id_table, __cancel_func, NULL);
- g_hash_table_destroy(info->id_table);
- }
-
- free(info);
-}
-
-static int __get_caller_info_from_cynara(int sockfd, struct caller_info *info)
-{
- pid_t pid;
- int r;
- char buf[MAX_LOCAL_BUFSZ];
-
- if (info == NULL)
- return -1;
-
- r = cynara_creds_socket_get_pid(sockfd, &pid);
- if (r != CYNARA_API_SUCCESS) {
- cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
- _E("cynara_creds_socket_get_pid failed: %s", buf);
- return -1;
- }
-
- info->session = cynara_session_from_pid(pid);
- if (info->session == NULL) {
- _E("cynara_session_from_pid failed.");
- return -1;
- }
-
- r = cynara_creds_socket_get_user(sockfd, USER_METHOD_DEFAULT,
- &(info->user));
- if (r != CYNARA_API_SUCCESS) {
- cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
- _E("cynara_cred_socket_get_user failed.");
- return -1;
- }
-
- r = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_DEFAULT,
- &(info->client));
- if (r != CYNARA_API_SUCCESS) {
- cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
- _E("cynara_creds_socket_get_client failed.");
- return -1;
- }
-
- info->offline = false;
-
- return 0;
-}
-
-static void __resp_cb(cynara_check_id id, cynara_async_call_cause cause,
- int resp, void *data)
-{
- enum amd_cynara_result res;
- struct caller_info *info = (struct caller_info *)data;
- char *privilege;
-
- _D("check id %u, cause %d, resp %d", id, cause, resp);
-
- privilege = g_hash_table_lookup(info->id_table,
- GUINT_TO_POINTER(id));
- if (privilege == NULL) {
- _W("Cynara: resp: %u not exist in id_table", id);
- return;
- }
- _I("privilege(%s)", privilege);
-
- g_hash_table_remove(info->id_table, GUINT_TO_POINTER(id));
-
- switch (cause) {
- case CYNARA_CALL_CAUSE_ANSWER:
- if (resp == CYNARA_API_ACCESS_ALLOWED) {
- if (g_hash_table_size(info->id_table) > 0)
- return;
- res = AMD_CYNARA_RET_ALLOWED;
- } else {
- _E("cynara denied (%s|%s|%s|%d)",
- info->client, info->session,
- info->user, id);
- res = AMD_CYNARA_RET_DENIED;
- }
- break;
- case CYNARA_CALL_CAUSE_CANCEL:
- _D("Cynara: resp: resp %d canceled", id);
- return;
- case CYNARA_CALL_CAUSE_FINISH:
- case CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE:
- default:
- _E("Cynara: resp: not answer");
- res = AMD_CYNARA_RET_ERROR;
- break;
- }
-
- if (info->callback)
- info->callback(res, info->user_data);
-
- __destroy_caller_info(info);
-}
-
-static enum amd_cynara_result __check_server(struct caller_info *info,
- const char *privilege)
-{
- int r;
- cynara_check_id id;
-
- r = cynara_async_create_request(r_cynara, info->client, info->session,
- info->user, privilege,
- &id, __resp_cb, info);
- if (r != CYNARA_API_SUCCESS) {
- _E("cynara_async_create_request error : %d", r);
- return AMD_CYNARA_RET_ERROR;
- }
-
- g_hash_table_insert(info->id_table, GUINT_TO_POINTER(id),
- strdup(privilege));
-
- return AMD_CYNARA_RET_UNKNOWN;
-}
-
-static enum amd_cynara_result __check_cache(struct caller_info *info,
- const char *privilege)
-{
- int ret;
-
- ret = cynara_async_check_cache(r_cynara, info->client, info->session,
- info->user, privilege);
- switch (ret) {
- case CYNARA_API_ACCESS_ALLOWED:
- ret = AMD_CYNARA_RET_ALLOWED;
- break;
- case CYNARA_API_ACCESS_DENIED:
- ret = AMD_CYNARA_RET_DENIED;
- break;
- case CYNARA_API_CACHE_MISS:
- ret = AMD_CYNARA_RET_UNKNOWN;
- break;
- default:
- _E("cynara cache error %d (%s|%s|%s)", ret,
- info->client, info->session, info->user);
- ret = AMD_CYNARA_RET_UNKNOWN;
- break;
- }
-
- return ret;
-}
-
-static int __cynara_simple_checker(amd_cynara_caller_info_h info, amd_request_h req, void *data)
-{
- int ret;
- const char *privilege = data;
-
- if (info->offline) {
- ret = __check_privilege_offline(info->appid, privilege,
- info->uid);
- } else {
- ret = __check_cache(info, privilege);
- }
- if (ret != AMD_CYNARA_RET_UNKNOWN) {
- if (ret == AMD_CYNARA_RET_DENIED) {
- _E("cynara denied (%s|%s|%s|%s)", privilege,
- info->client, info->session, info->user);
- }
- return ret;
- }
-
- return __check_server(info, privilege);
-}
-
-static int __check_privilege_by_checker(amd_request_h req, amd_cynara_caller_info_h info)
-{
- int ret;
- amd_cynara_checker *checker;
-
- checker = g_hash_table_lookup(__checker_table,
- GINT_TO_POINTER(amd_request_get_cmd(req)));
- if (checker && checker->checker) {
- ret = checker->checker(info, req, checker->data);
- return ret;
- }
-
- return 0;
-}
-
-static bool __has_checker(amd_request_h req)
-{
- amd_cynara_checker *checker;
-
- checker = g_hash_table_lookup(__checker_table,
- GINT_TO_POINTER(amd_request_get_cmd(req)));
- if (checker)
- return true;
-
- return false;
-}
-
-static int __verify_caller_process(amd_request_h req)
-{
- amd_app_status_h app_status;
- const char *appid;
- pid_t pid;
- uid_t uid;
- char attr[512] = { 0, };
- int r;
-
- uid = amd_request_get_uid(req);
- if (uid < REGULAR_UID_MIN)
- return 0;
-
- pid = amd_request_get_pid(req);
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (app_status) {
- appid = amd_app_status_get_appid(app_status);
- if (amd_appinfo_is_platform_app(appid, uid))
- return 0;
- } else {
- r = amd_proc_get_attr(pid, attr, sizeof(attr));
- if (r != 0) {
- _E("Failed to get attr. pid(%d)", pid);
- return -1;
- }
-
- if (!strcmp(attr, "User"))
- return 0;
- }
-
- _E("Reject request. caller(%d)", pid);
-
- return -1;
-}
-
-static bool __is_indirect_request(amd_request_h req)
-{
- const char *req_type;
-
- req_type = amd_request_get_request_type(req);
- if (req_type && !strcmp(req_type, "indirect-request"))
- return true;
-
- return false;
-}
-
-static int __check_org_caller(bundle *b,
- const char *org_caller_appid, uid_t org_caller_uid)
-{
- amd_appinfo_h appinfo;
- const char *org_caller_pkgid;
- const char *pkgid;
-
- appinfo = amd_appinfo_find(org_caller_uid, org_caller_appid);
- if (!appinfo) {
- _E("Failed to find appinfo(%s:%u)",
- org_caller_appid, org_caller_uid);
- return -1;
- }
-
- pkgid = amd_appinfo_get_value(appinfo, AMD_AIT_PKGID);
- if (!pkgid) {
- _E("Critical error!");
- return -1;
- }
-
- org_caller_pkgid = bundle_get_val(b, AUL_K_ORG_CALLER_PKGID);
- if (!org_caller_pkgid) {
- _E("Failed to get pkgid");
- return -1;
- }
-
- if (strcmp(pkgid, org_caller_pkgid) != 0) {
- _E("%s is not equal to %s", org_caller_pkgid, pkgid);
- return -1;
- }
-
- return 0;
-}
-
-static int __get_org_caller_info_from_bundle(bundle *b,
- struct caller_info *info)
-{
- int r;
- const char *str;
-
- str = bundle_get_val(b, AUL_K_ORG_CALLER_APPID);
- if (!str) {
- _E("Failed to get org caller appid");
- return -1;
- }
-
- info->appid = strdup(str);
- if (!info->appid) {
- _E("Out of memory");
- return -1;
- }
-
- str = bundle_get_val(b, AUL_K_ORG_CALLER_UID);
- if (!str) {
- _E("Failed to get org caller uid");
- return -1;
- }
-
- info->uid = strtoul(str, NULL, 10);
-
- r = __check_org_caller(b, info->appid, info->uid);
- if (r < 0)
- return -1;
-
- info->offline = true;
- _D("Orginal caller(%s:%u)", info->appid, info->uid);
-
- return 0;
-}
-
-static struct caller_info *__create_caller_info(amd_request_h req,
- amd_cynara_response_cb callback)
-{
- int r;
- struct caller_info *info;
- bundle *b;
-
- info = calloc(1, sizeof(*info));
- if (info == NULL) {
- _E("insufficient memory");
- return NULL;
- }
-
- if (__is_indirect_request(req)) {
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- __destroy_caller_info(info);
- return NULL;
- }
-
- r = __get_org_caller_info_from_bundle(b, info);
- if (r < 0) {
- _E("Failed to get org caller info");
- __destroy_caller_info(info);
- return NULL;
- }
- } else {
- r = __get_caller_info_from_cynara(amd_request_get_fd(req),
- info);
- if (r < 0) {
- _E("Failed to get caller info");
- __destroy_caller_info(info);
- return NULL;
- }
- }
-
- info->callback = callback;
- info->user_data = req;
-
- info->id_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, free);
-
- return info;
-}
-
-static int __cynara_check_privilege(amd_request_h req, amd_cynara_response_cb callback)
-{
- int r;
- struct caller_info *info;
-
- if (!__has_checker(req)) {
- _D("No proper checker. Skip checking privileges (cmd = %d)",
- amd_request_get_cmd(req));
- return AMD_CYNARA_RET_ALLOWED;
- }
-
- if (__is_indirect_request(req)) {
- r = __verify_caller_process(req);
- if (r != 0)
- return AMD_CYNARA_RET_DENIED;
- }
-
- info = __create_caller_info(req, callback);
- if (info == NULL)
- return -1;
-
- r = __check_privilege_by_checker(req, info);
-
- if (r != AMD_CYNARA_RET_UNKNOWN)
- __destroy_caller_info(info);
-
- return r;
-}
-
-static int __check_privilege_offline(const char *appid, const char *privilege,
- uid_t uid)
-{
- int priv_ret;
- int ret;
-
- ret = security_manager_app_has_privilege(appid, privilege,
- uid, &priv_ret);
- if (ret < 0) {
- _E("failed to check privilege (%d)", ret);
- return AMD_CYNARA_RET_DENIED;
- }
-
- if (priv_ret != 1)
- return AMD_CYNARA_RET_DENIED;
-
- return AMD_CYNARA_RET_ALLOWED;
-}
-
-static int __cynara_check_privilege_offline(amd_request_h req,
- const char *appid, const char *privilege)
-{
- return __check_privilege_offline(appid, privilege,
- amd_request_get_target_uid(req));
-}
-
-static gboolean __proc_cb(gint fd, GIOCondition cond, gpointer data)
-{
- int ret;
-
- if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
- cynara_fd_id = 0;
- return G_SOURCE_REMOVE;
- }
-
- ret = cynara_async_process(r_cynara);
- if (ret != CYNARA_API_SUCCESS)
- _E("process error %d", ret);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void __status_cb(int old_fd, int new_fd, cynara_async_status status,
- void *data)
-{
- if (old_fd != -1) {
- if (cynara_fd_id) {
- g_source_remove(cynara_fd_id);
- cynara_fd_id = 0;
- }
- cynara_fd = -1;
- }
-
- if (new_fd != -1) {
- GIOCondition cond;
-
- cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-
- if (status == CYNARA_STATUS_FOR_RW)
- cond |= G_IO_OUT;
-
- cynara_fd_id = g_unix_fd_add(new_fd, cond, __proc_cb, data);
- cynara_fd = new_fd;
- }
-}
-
-static int __cynara_register_checkers(const amd_cynara_checker *checkers, int cnt)
-{
- int i;
- amd_cynara_checker *c;
-
- if (cnt <= 0 || !__checker_table || !checkers)
- return -1;
-
- for (i = 0; i < cnt; i++) {
- c = g_hash_table_lookup(__checker_table,
- GINT_TO_POINTER(checkers[i].cmd));
- if (c) {
- if (checkers[i].priority <= c->priority)
- continue;
-
- g_hash_table_remove(__checker_table,
- GINT_TO_POINTER(checkers[i].cmd));
- }
-
- g_hash_table_insert(__checker_table,
- GINT_TO_POINTER(checkers[i].cmd),
- (gpointer)(&checkers[i]));
- }
-
- return 0;
-}
-
-static const char *__cynara_caller_info_get_client(amd_cynara_caller_info_h info)
-{
- if (!info)
- return NULL;
-
- return info->client;
-}
-
-static int __cynara_sub_checker_add(const char *name, amd_cynara_sub_checker_func func)
-{
- cynara_sub_checker *c;
-
- if (!name || !func)
- return -1;
-
- c = calloc(1, sizeof(cynara_sub_checker));
- if (!c)
- return -1;
-
- c->name = strdup(name);
- c->checker = func;
-
- if (!(c->name)) {
- free(c);
- return -1;
- }
-
- __sub_checkers = g_list_append(__sub_checkers, c);
-
- return 0;
-}
-
-static int __cynara_sub_checker_check(const char *name, amd_cynara_caller_info_h info, amd_request_h req)
-{
- GList *i = __sub_checkers;
- cynara_sub_checker *c;
- int ret;
-
- if (!name || !info || !req)
- return AMD_CYNARA_RET_ERROR;
-
- while (i) {
- c = i->data;
- if (!strcmp(name, c->name)) {
- ret = c->checker(info, req);
- if (ret != AMD_CYNARA_RET_CONTINUE)
- return ret;
- }
-
- i = g_list_next(i);
- }
-
- return AMD_CYNARA_RET_CONTINUE;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int ret;
-
- _D("Cynara-core init");
- ret = cynara_async_initialize(&r_cynara, NULL, __status_cb, NULL);
- if (ret != CYNARA_API_SUCCESS) {
- _E("cynara initialize failed. %d", ret);
- return ret;
- }
-
- __checker_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, NULL);
-
- amd_cynara_ops ops = {
- .register_checkers = __cynara_register_checkers,
- .sub_checker_add = __cynara_sub_checker_add,
- .sub_checker_check = __cynara_sub_checker_check,
- .check_async = __cynara_check_privilege,
- .check = __cynara_simple_checker,
- .check_offline = __cynara_check_privilege_offline
- };
-
- amd_cynara_caller_info_ops ci_ops = {
- .get_client = __cynara_caller_info_get_client
- };
-
- return amd_cynara_register_ops(ops, ci_ops);
-}
-
-static void __free_sub_checker(gpointer data)
-{
- cynara_sub_checker *c = data;
-
- free(c->name);
- free(c);
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("Cynara-core fini");
- if (r_cynara == NULL)
- return;
-
- if (cynara_fd_id) {
- g_source_remove(cynara_fd_id);
- cynara_fd_id = 0;
- }
-
- cynara_async_finish(r_cynara);
- r_cynara = NULL;
- cynara_fd = -1;
-
- if (__checker_table) {
- g_hash_table_destroy(__checker_table);
- __checker_table = NULL;
- }
-
- if (__sub_checkers) {
- g_list_free_full(__sub_checkers, __free_sub_checker);
- __sub_checkers = NULL;
- }
-}
-
-
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_EXTRACTOR "amd-mod-extractor")
-SET(AMD_MOD_EXTRACTOR_DIR ${CMAKE_SOURCE_DIR}/modules/extractor)
-PROJECT(${AMD_MOD_EXTRACTOR} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_EXTRACTOR_DIR}/src AMD_MOD_EXTRACTOR_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_EXTRACTOR_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- libtzplatform-config
- )
-
-pkg_check_modules(amd_mod_extractor_pkgs REQUIRED ${AMD_MOD_EXTRACTOR_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_extractor_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_EXTRACTOR_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_EXTRACTOR} ${AMD_MOD_EXTRACTOR_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_EXTRACTOR} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_EXTRACTOR} ${amd_mod_extractor_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_EXTRACTOR} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <aul.h>
-#include <bundle_internal.h>
-#include <tzplatform_config.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_EXTRACTOR"
-
-#define PATH_APP_ROOT tzplatform_getenv(TZ_USER_APP)
-#define PATH_GLOBAL_APP_RO_ROOT tzplatform_getenv(TZ_SYS_RO_APP)
-#define PATH_GLOBAL_APP_RW_ROOT tzplatform_getenv(TZ_SYS_RW_APP)
-
-typedef char **(_extractor_mountable)(const amd_appinfo_h ai);
-
-static GHashTable *mount_point_hash;
-
-static char **__extractor_mountable_get_tep_paths(const amd_appinfo_h ai)
-{
- char tep_path[PATH_MAX];
- char **mnt_path;
- const char *tep_name;
- const char *root_path;
-
- if (ai == NULL)
- return NULL;
-
- tep_name = amd_appinfo_get_value(ai, AMD_AIT_TEP);
- if (tep_name == NULL)
- return NULL;
-
- mnt_path = (char **)malloc(sizeof(char *) * 2);
- if (mnt_path == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- mnt_path[1] = strdup(tep_name);
- if (mnt_path[1] == NULL) {
- _E("Out of memory");
- free(mnt_path);
- return NULL;
- }
-
- root_path = amd_appinfo_get_value(ai, AMD_AIT_ROOT_PATH);
- snprintf(tep_path, PATH_MAX, "%s/tep/mount", root_path);
- mnt_path[0] = strdup(tep_path);
- if (mnt_path[0] == NULL) {
- _E("Out of memory");
- free(mnt_path[1]);
- free(mnt_path);
- return NULL;
- }
-
- return mnt_path;
-}
-
-static char **__extractor_mountable_get_tpk_paths(const amd_appinfo_h ai)
-{
- char mount_point[PATH_MAX];
- char **mnt_path;
- const char *tpk;
- const char *root_path;
-
- if (ai == NULL)
- return NULL;
-
- tpk = amd_appinfo_get_value(ai, AMD_AIT_MOUNTABLE_PKG);
- if (tpk == NULL)
- return NULL;
-
- mnt_path = (char **)malloc(sizeof(char *) * 2);
- if (mnt_path == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- mnt_path[1] = strdup(tpk);
- if (mnt_path[1] == NULL) {
- _E("Out of memory");
- free(mnt_path);
- return NULL;
- }
- root_path = amd_appinfo_get_value(ai, AMD_AIT_ROOT_PATH);
- snprintf(mount_point, PATH_MAX, "%s/.pkg", root_path);
- mnt_path[0] = strdup(mount_point);
- if (mnt_path[0] == NULL) {
- free(mnt_path[1]);
- free(mnt_path);
- return NULL;
- }
-
- return mnt_path;
-}
-
-static void __free_path(char **path, int cnt)
-{
- int i;
-
- if (path == NULL)
- return;
-
- for (i = 0; i < cnt; i++) {
- if (path[i])
- free(path[i]);
- }
- free(path);
-}
-
-static void __free_set(gpointer data)
-{
- g_hash_table_destroy((GHashTable *)data);
-}
-
-static void __prepare_map(void)
-{
- if (mount_point_hash == NULL) {
- mount_point_hash = g_hash_table_new_full(g_str_hash,
- g_str_equal, free, __free_set);
- }
-}
-
-static void __put_mount_path(const amd_appinfo_h ai, const char *str)
-{
- const char *appid;
- GHashTable *set;
-
- __prepare_map();
- set = g_hash_table_lookup(mount_point_hash, str);
- if (set == NULL) {
- set = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, NULL);
- if (set == NULL)
- return;
- g_hash_table_insert(mount_point_hash, strdup(str), set);
- }
-
- appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
- g_hash_table_insert(set, strdup(appid), NULL);
-}
-
-static bool __is_unmountable(const char *appid, const char *key)
-{
- GHashTable *set;
-
- if (amd_app_status_get_process_cnt(appid) > 1)
- return false;
-
- __prepare_map();
- set = g_hash_table_lookup(mount_point_hash, key);
-
- if (set == NULL)
- return false;
-
- g_hash_table_remove(set, appid);
- if (g_hash_table_size(set) > 0)
- return false;
-
- return true;
-}
-
-static void __extractor_mount(const amd_appinfo_h ai, bundle *kb,
- _extractor_mountable mountable)
-{
- int ret;
- const char **array = NULL;
- int len = 0;
- const char *default_array[1] = { NULL };
- char **new_array = NULL;
- int i;
- bool dup = false;
- const char *pkgid = NULL;
- char **mnt_path;
-
- mnt_path = mountable(ai);
- if (mnt_path == NULL)
- return;
-
- if (!mnt_path[0] || !mnt_path[1]) {
- __free_path(mnt_path, 2);
- return;
- }
-
- array = bundle_get_str_array(kb, AUL_K_TEP_PATH, &len);
- if (array == NULL) {
- default_array[0] = mnt_path[0];
- bundle_add_str_array(kb, AUL_K_TEP_PATH,
- default_array, 1);
- } else {
- for (i = 0; i < len; i++) {
- if (strcmp(mnt_path[0], array[i]) == 0) {
- dup = true;
- break;
- }
- }
-
- if (!dup) {
- new_array = calloc(len + 1, sizeof(char *));
- if (new_array == NULL) {
- _E("out of memory");
- __free_path(mnt_path, 2);
- return;
- }
-
- for (i = 0; i < len; i++) {
- new_array[i] = strdup(array[i]);
- if (new_array[i] == NULL) {
- _E("Out of memory");
- __free_path(new_array, i);
- return;
- }
- }
- new_array[len] = strdup(mnt_path[0]);
- if (new_array[len] == NULL) {
- _E("Out of memory");
- __free_path(new_array, len);
- return;
- }
- bundle_del(kb, AUL_K_TEP_PATH);
- bundle_add_str_array(kb, AUL_K_TEP_PATH,
- (const char **)new_array, len + 1);
- __free_path(new_array, len + 1);
- }
- }
-
- __put_mount_path(ai, mnt_path[0]);
- ret = aul_is_tep_mount_dbus_done(mnt_path[0]);
- if (ret != 1) {
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- ret = amd_signal_send_tep_mount(mnt_path, pkgid);
- if (ret < 0) {
- _E("dbus error %d", ret);
- } else {
- _D("Mount request was sent %s %s",
- mnt_path[0], mnt_path[1]);
- }
- }
-
- __free_path(mnt_path, 2);
-}
-
-static void __extractor_unmount(int pid, _extractor_mountable mountable)
-{
- const char *appid;
- amd_appinfo_h ai;
- int ret;
- char **mnt_path;
- amd_app_status_h app_status;
- uid_t uid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL)
- return;
-
- uid = amd_app_status_get_uid(app_status);
- appid = amd_app_status_get_appid(app_status);
- if (appid == NULL)
- return;
-
- ai = amd_appinfo_find(uid, appid);
- if (ai == NULL)
- return;
-
- mnt_path = mountable(ai);
- if (mnt_path == NULL)
- return;
-
- if (!__is_unmountable(appid, mnt_path[0]))
- return;
-
- g_hash_table_remove(mount_point_hash, mnt_path[0]);
- ret = amd_signal_send_tep_unmount(mnt_path[0]);
- if (ret < 0)
- _E("Failed to send unmount: %s", mnt_path[0]);
- else
- _D("Unmount request was sent %s", mnt_path[0]);
-
- __free_path(mnt_path, 2);
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = arg3;
- int pid;
-
- pid = amd_app_status_get_pid(app_status);
- __extractor_unmount(pid, __extractor_mountable_get_tep_paths);
- __extractor_unmount(pid, __extractor_mountable_get_tpk_paths);
-
- return 0;
-}
-
-static int __on_launch_prepared(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- const amd_appinfo_h info = arg3;
-
- __extractor_mount(info, data, __extractor_mountable_get_tep_paths);
- __extractor_mount(info, data, __extractor_mountable_get_tpk_paths);
-
- return 0;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("extractor init");
-
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
- __on_launch_prepared);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("extractor fini");
-}
-
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_INPUT "amd-mod-input")
-SET(AMD_MOD_INPUT_DIR ${CMAKE_SOURCE_DIR}/modules/input)
-PROJECT(${AMD_MOD_INPUT} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_INPUT_DIR}/src AMD_MOD_INPUT_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_INPUT_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- wayland-client
- wayland-tbm-client
- tizen-extension-client
- xkbcommon
- capi-system-info
- )
-
-pkg_check_modules(amd_mod_input_pkgs REQUIRED ${AMD_MOD_INPUT_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_input_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_INPUT_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_INPUT} ${AMD_MOD_INPUT_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_INPUT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_INPUT} ${amd_mod_input_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_INPUT} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
-INSTALL(FILES ${AMD_MOD_INPUT_DIR}/conf/amd_input.conf DESTINATION ${AMD_MODULES_DIR}/conf)
+++ /dev/null
-[Setting]
-# Input lock timeout interval: 1 sec
-InputLockTimeout=1000
+++ /dev/null
-/*
- * Copyright (c) 2018 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_INPUT_CONFIG_H__
-#define __AMD_INPUT_CONFIG_H__
-
-int _input_config_init(void);
-
-void _input_config_fini(void);
-
-unsigned int _input_config_get_timeout_interval(void);
-
-#endif /* __AMD_INPUT_CONFIG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "AMD_INPUT"
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include <stdbool.h>
-#include <malloc.h>
-#include <sys/mman.h>
-
-#include <glib.h>
-#include <wayland-client.h>
-#include <tizen-extension-client-protocol.h>
-#include <xkbcommon/xkbcommon.h>
-#include <aul.h>
-#include <amd.h>
-
-#include "amd_input_config.h"
-#include "amd_input_private.h"
-
-static bool locked;
-static bool init_done;
-static guint timer;
-static unsigned int timeout_val;
-static int latest_pid;
-static struct tizen_keyrouter *keyrouter;
-static struct tizen_input_device_manager *input_devmgr;
-static struct wl_display *display;
-static struct wl_seat *seat;
-static guint sid;
-
-struct xkb_context *g_ctx;
-struct xkb_keymap *g_keymap;
-struct wl_keyboard *keyboard;
-static uint32_t keyrouter_id;
-static uint32_t input_devmgr_id;
-static uint32_t seat_id;
-
-typedef struct _keycode_map {
- xkb_keysym_t keysym;
- xkb_keycode_t *keycodes;
- int nkeycodes;
-} keycode_map;
-
-static int __input_lock(void);
-static int __input_unlock(void);
-
-#define TIZEN_FEATURE_BLOCK_INPUT \
- (!(amd_config_get_tizen_profile() & \
- (AMD_TIZEN_PROFILE_TV | AMD_TIZEN_PROFILE_IVI)))
-
-static void __keyboard_keymap(void *data, struct wl_keyboard *keyboard,
- uint32_t format, int fd, uint32_t size)
-{
- char *map = NULL;
-
- LOGD("format=%d, fd=%d, size=%d", format, fd, size);
- if (!g_ctx) {
- LOGE("This client failed to make xkb context");
- close(fd);
- return;
- }
-
- if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
- LOGE("Invaild format: %d", format);
- close(fd);
- return;
- }
-
- map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
- if (map == MAP_FAILED) {
- LOGE("Failed to mmap from fd(%d) size(%d)", fd, size);
- close(fd);
- return;
- }
-
- if (g_keymap)
- xkb_map_unref(g_keymap);
-
- g_keymap = xkb_map_new_from_string(g_ctx, map,
- XKB_KEYMAP_FORMAT_TEXT_V1, 0);
- munmap(map, size);
- if (!g_keymap)
- LOGE("Failed to get keymap from fd(%d)", fd);
- close(fd);
-}
-
-static void __keyboard_enter(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, struct wl_surface *surface,
- struct wl_array *keys)
-{
- LOGD("serial=%d", serial);
-}
-
-static void __keyboard_leave(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, struct wl_surface *surface)
-{
- LOGD("serial=%d", serial);
-}
-
-static void __keyboard_key(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w)
-{
- LOGD("serial=%d, time=%d, key=%d, state_w=%d",
- serial, time, key, state_w);
-}
-
-static void __keyboard_modifiers(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
- uint32_t mods_locked, uint32_t group)
-{
- LOGD("serial=%d, mods_depressed=%d, mods_latched=%d mods_locked=%d, " \
- "group=%d", serial, mods_depressed, mods_latched,
- mods_locked, group);
-}
-
-static const struct wl_keyboard_listener keyboard_listener = {
- .keymap = __keyboard_keymap,
- .enter = __keyboard_enter,
- .leave = __keyboard_leave,
- .key = __keyboard_key,
- .modifiers = __keyboard_modifiers
-};
-
-static gboolean __timeout_handler(void *data)
-{
- timer = 0;
- __input_unlock();
- return FALSE;
-}
-
-static void __find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key,
- void *data)
-{
- keycode_map *found_keycodes = (keycode_map *)data;
- xkb_keysym_t keysym = found_keycodes->keysym;
- int nsyms = 0;
- const xkb_keysym_t *syms_out = NULL;
- xkb_keycode_t *keycodes;
-
- nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
- if (nsyms && syms_out && *syms_out == keysym) {
- found_keycodes->nkeycodes++;
- keycodes = realloc(found_keycodes->keycodes,
- sizeof(int) * found_keycodes->nkeycodes);
- if (keycodes == NULL) {
- LOGE("Failed to reallocate the keycodes");
- found_keycodes->nkeycodes--;
- return;
- }
- found_keycodes->keycodes = keycodes;
- found_keycodes->keycodes[found_keycodes->nkeycodes - 1] = key;
- }
-}
-
-static int __xkb_keycode_from_keysym(struct xkb_keymap *keymap,
- xkb_keysym_t keysym, xkb_keycode_t **keycodes)
-{
- keycode_map found_keycodes = {0,};
-
- found_keycodes.keysym = keysym;
- xkb_keymap_key_for_each(g_keymap, __find_keycode, &found_keycodes);
- *keycodes = found_keycodes.keycodes;
-
- return found_keycodes.nkeycodes;
-}
-
-static void __keygrab_request(struct tizen_keyrouter *tizen_keyrouter,
- struct wl_surface *surface, uint32_t key, uint32_t mode)
-{
- tizen_keyrouter_set_keygrab(tizen_keyrouter, surface, key, mode);
- LOGD("request set_keygrab (key:%d, mode:%d)!", key, mode);
-}
-
-static void __keyungrab_request(struct tizen_keyrouter *tizen_keyrouter,
- struct wl_surface *surface, uint32_t key)
-{
- tizen_keyrouter_unset_keygrab(tizen_keyrouter, surface, key);
- LOGD("request unset_keygrab (key:%d)!", key);
-}
-
-static void __do_keygrab(const char *keyname, uint32_t mode)
-{
- xkb_keysym_t keysym = 0x0;
- int nkeycodes = 0;
- xkb_keycode_t *keycodes = NULL;
- int i;
-
- keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
- nkeycodes = __xkb_keycode_from_keysym(g_keymap, keysym, &keycodes);
-
- for (i = 0; i < nkeycodes; i++) {
- LOGD("%s's keycode is %d (nkeycode: %d)",
- keyname, keycodes[i], nkeycodes);
- __keygrab_request(keyrouter, NULL, keycodes[i], mode);
- }
- free(keycodes);
- keycodes = NULL;
-}
-
-static void __do_keyungrab(const char *keyname)
-{
- xkb_keysym_t keysym = 0x0;
- int nkeycodes = 0;
- xkb_keycode_t *keycodes = NULL;
- int i;
-
- keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
- nkeycodes = __xkb_keycode_from_keysym(g_keymap, keysym, &keycodes);
-
- for (i = 0; i < nkeycodes; i++) {
- LOGD("%s's keycode is %d (nkeycode: %d)\n",
- keyname, keycodes[i], nkeycodes);
- __keyungrab_request(keyrouter, NULL, keycodes[i]);
- }
- free(keycodes);
- keycodes = NULL;
-}
-
-static int __xkb_init(void)
-{
- if (!g_ctx) {
- g_ctx = xkb_context_new(0);
- if (!g_ctx) {
- LOGE("Failed to get xkb_context");
- return -1;
- }
- }
-
- return 0;
-}
-
-static void __xkb_fini(void)
-{
- if (g_ctx) {
- xkb_context_unref(g_ctx);
- g_ctx = NULL;
- }
-}
-
-static void __input_device_info(void *data,
- struct tizen_input_device *tizen_input_device,
- const char *name, uint32_t class, uint32_t subclass,
- struct wl_array *axes)
-{
- LOGD("device info - name: %s, class: %d, subclass: %d",
- name, class, subclass);
-}
-
-static void __input_device_event_device(void *data,
- struct tizen_input_device *tizen_input_device,
- unsigned int serial, const char *name, uint32_t time)
-{
- LOGD("event device - name: %s, time: %d", name, time);
-}
-
-static void __input_device_axis(void *data,
- struct tizen_input_device *tizen_input_device,
- uint32_t axis_type, wl_fixed_t value)
-{
- LOGD("axis - axis_type: %d, value: %lf",
- axis_type, wl_fixed_to_double(value));
-}
-
-static const struct tizen_input_device_listener input_device_listener = {
- __input_device_info,
- __input_device_event_device,
- __input_device_axis,
-};
-
-static void __cb_device_add(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager,
- uint32_t serial, const char *name,
- struct tizen_input_device *device, struct wl_seat *seat)
-{
- LOGD("%s device is added!", name);
- tizen_input_device_add_listener(device, &input_device_listener, NULL);
-}
-
-static void __cb_device_remove(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager,
- uint32_t serial, const char *name,
- struct tizen_input_device *device, struct wl_seat *seat)
-{
- LOGD("%s device is removed!", name);
- tizen_input_device_release(device);
-}
-
-static void __cb_error(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager,
- uint32_t errorcode)
-{
- LOGE("error: %d", errorcode);
-}
-
-static void __cb_block_expired(void *data,
- struct tizen_input_device_manager *tizen_input_device_manager)
-{
- LOGD("block expired");
-}
-
-static struct tizen_input_device_manager_listener input_devmgr_listener = {
- __cb_device_add,
- __cb_device_remove,
- __cb_error,
- __cb_block_expired
-};
-
-static int __on_lock(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_app_status_h app_status = arg3;
- int status;
- int caller_pid = arg2;
- amd_app_status_h caller_app_status;
- int caller_app_type;
-
- if (TIZEN_FEATURE_BLOCK_INPUT) {
- caller_app_status = amd_app_status_find_by_pid(caller_pid);
- if (!caller_app_status)
- return 0;
-
- caller_app_type = amd_app_status_get_app_type(
- caller_app_status);
- if (caller_app_type == AMD_AT_SERVICE_APP)
- return 0;
-
- status = amd_app_status_get_status(app_status);
- if (status != STATUS_VISIBLE && !arg1)
- __input_lock();
- }
-
- return 0;
-}
-
-static int __on_unlock(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- int status = arg1;
- int pid = amd_app_status_get_pid(app_status);
-
- if (TIZEN_FEATURE_BLOCK_INPUT) {
- if (latest_pid == pid && status == STATUS_VISIBLE)
- __input_unlock();
- }
-
- return 0;
-}
-
-static int __on_launch_complete(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comptype;
-
- comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comptype && !strcmp(comptype, APP_TYPE_UI))
- latest_pid = arg1;
-
- return 0;
-}
-
-static int __on_registry_handler(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
- struct wl_registry *registry = (struct wl_registry *)arg3;
-
- if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER)) {
- if (!input_devmgr) {
- input_devmgr_id = id;
- input_devmgr = wl_registry_bind(registry, id,
- &tizen_input_device_manager_interface,
- 2);
- LOGD("input_devmgr(%p)", input_devmgr);
- if (tizen_input_device_manager_add_listener(input_devmgr,
- &input_devmgr_listener, NULL) < 0) {
- LOGE("Failed to add listener");
- }
- }
- } else if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER)) {
- if (!keyrouter) {
- keyrouter_id = id;
- keyrouter = wl_registry_bind(registry, id,
- &tizen_keyrouter_interface, 1);
- LOGD("keyrouter(%p)", keyrouter);
- }
- } else if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT)) {
- if (!seat) {
- seat_id = id;
- seat = wl_registry_bind(registry, id,
- &wl_seat_interface, 1);
- if (!seat)
- return -1;
-
- LOGD("seat(%p)", seat);
- keyboard = wl_seat_get_keyboard(seat);
- wl_keyboard_add_listener(keyboard, &keyboard_listener,
- NULL);
- LOGD("keyboard(%p)", keyboard);
- }
- }
-
- return 0;
-}
-
-static int __on_registry_remover(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
-
- if (id == keyrouter_id && keyrouter) {
- tizen_keyrouter_destroy(keyrouter);
- keyrouter = NULL;
- keyrouter_id = 0;
- LOGW("tizen keyrouter is destroyed");
- }
-
- if (id == input_devmgr_id && input_devmgr) {
- tizen_input_device_manager_destroy(input_devmgr);
- input_devmgr = NULL;
- input_devmgr_id = 0;
- LOGW("tizen input device manager is destroyed");
- }
-
- if (id == seat_id && seat) {
- if (keyboard) {
- wl_keyboard_destroy(keyboard);
- keyboard = NULL;
- }
-
- wl_seat_destroy(seat);
- seat = NULL;
- seat_id = 0;
- LOGW("wl seat is destroyed");
- }
-
- return 0;
-}
-
-static int __input_init(void)
-{
- if (!display) {
- display = amd_wayland_get_display();
- if (!display) {
- LOGD("Failed to connect to wayland compositor");
- return -1;
- }
- }
-
- if (__xkb_init() < 0)
- return -1;
-
- LOGD("Connected to wayland compositor!");
-
- if (input_devmgr == NULL) {
- LOGE("input_devmgr is null");
- return -1;
- }
-
- if (keyrouter == NULL) {
- LOGE("keyrouter is null");
- return -1;
- }
-
- if (seat == NULL) {
- LOGE("seat is null");
- return -1;
- }
-
- if (keyboard == NULL) {
- LOGE("keyboard is null");
- return -1;
- }
-
- wl_display_flush(display);
- wl_display_roundtrip(display);
-
- if (g_keymap == NULL) {
- LOGE("g_keymap is null");
- return -1;
- }
-
- init_done = true;
-
- return 0;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- LOGD("input init");
-
- _input_config_init();
- timeout_val = _input_config_get_timeout_interval();
-
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER,
- __on_registry_handler);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER,
- __on_registry_handler);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT,
- __on_registry_handler);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
- __on_registry_remover);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START,
- __on_unlock);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_FAIL,
- __on_unlock);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END,
- __on_lock);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- __on_launch_complete);
- __xkb_init();
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- __xkb_fini();
- if (sid > 0) {
- g_source_remove(sid);
- sid = 0;
- }
- _input_config_fini();
-}
-
-static int __input_lock(void)
-{
- if (locked)
- __input_unlock();
-
- if (!init_done && __input_init() < 0)
- return -1;
-
- LOGD("call tizen_input_device_manager_block_events");
- tizen_input_device_manager_block_events(input_devmgr, 0,
- TIZEN_INPUT_DEVICE_MANAGER_CLAS_TOUCHSCREEN |
- TIZEN_INPUT_DEVICE_MANAGER_CLAS_MOUSE, timeout_val);
- timer = g_timeout_add(timeout_val, __timeout_handler, NULL);
- __do_keygrab("XF86Back", TIZEN_KEYROUTER_MODE_EXCLUSIVE);
- wl_display_roundtrip(display);
-
- locked = true;
-
- return 0;
-}
-
-static int __input_unlock(void)
-{
- if (!locked)
- return 0;
-
- if (!init_done && __input_init() < 0)
- return -1;
-
- LOGD("call tizen_input_device_manager_unblock_events");
- tizen_input_device_manager_unblock_events(input_devmgr, 0);
- __do_keyungrab("XF86Back");
- wl_display_roundtrip(display);
-
- locked = false;
- if (timer > 0) {
- g_source_remove(timer);
- timer = 0;
- }
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <iniparser.h>
-
-#include "amd_input_config.h"
-#include "amd_input_private.h"
-
-#define CONFIG_PATH "/usr/share/amd/conf/amd_input.conf"
-#define CONFIG_SECTION_NAME "Setting"
-#define CONFIG_KEY_LOCK_TIMEOUT "InputLockTimeout"
-
-struct input_config_s {
- unsigned int interval;
-};
-
-static struct input_config_s __config;
-
-static int __input_config_get_int(dictionary *d,
- const char *section, const char *key)
-{
- char buf[512];
-
- snprintf(buf, sizeof(buf), "%s:%s", section, key);
-
- return iniparser_getint(d, buf, -1);
-}
-
-static int __input_config_load(const char *path)
-{
- dictionary *d;
- int r;
-
- r = access(path, R_OK);
- if (r != 0) {
- _E("Failed to access %s. errno(%d)", path, errno);
- return -1;
- }
-
- d = iniparser_load(path);
- if (!d) {
- _E("Failed to load %s by iniparser", path);
- return -1;
- }
-
- r = __input_config_get_int(d, CONFIG_SECTION_NAME,
- CONFIG_KEY_LOCK_TIMEOUT);
- if (r > 0) {
- __config.interval = r;
- _W("Interval: %u", __config.interval);
- }
-
- iniparser_freedict(d);
-
- return 0;
-}
-
-unsigned int _input_config_get_timeout_interval(void)
-{
- return __config.interval;
-}
-
-int _input_config_init(void)
-{
- _D("Input config init");
-
- __config.interval = 1000; /* 1 sec */
-
- if (__input_config_load(CONFIG_PATH) < 0)
- _W("Failed to load input config");
-
- return 0;
-}
-
-void _input_config_fini(void)
-{
- _D("Input config fini");
- __config.interval = 0;
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_JOB_SCHEDULER "amd-mod-job-scheduler")
-SET(AMD_MOD_JOB_SCHEDULER_DIR ${CMAKE_SOURCE_DIR}/modules/job-scheduler)
-PROJECT(${AMD_MOD_JOB_SCHEDULER} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_JOB_SCHEDULER_DIR}/src AMD_MOD_JOB_SCHEDULER_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_JOB_SCHEDULER_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- )
-
-pkg_check_modules(amd_mod_job_scheduler_pkgs REQUIRED ${AMD_MOD_JOB_SCHEDULER_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_job_scheduler_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_JOB_SCHEDULER_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_JOB_SCHEDULER} ${AMD_MOD_JOB_SCHEDULER_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_JOB_SCHEDULER} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_JOB_SCHEDULER} ${amd_mod_job_scheduler_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_JOB_SCHEDULER} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_job_scheduler.h>
-#include <bundle_internal.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_JOB_SCHEDULER"
-
-struct job_s {
- char *id;
- pid_t pid;
- guint timer;
-};
-
-static GHashTable *__job_table;
-
-static int __remove_job(const char *id, pid_t pid);
-
-static void __destroy_job(gpointer data)
-{
- struct job_s *job = (struct job_s *)data;
-
- if (job == NULL)
- return;
-
- if (job->timer)
- g_source_remove(job->timer);
-
- if (job->id)
- free(job->id);
-
- free(job);
-}
-
-static gboolean __job_timeout_handler(gpointer data)
-{
- struct job_s *job = (struct job_s *)data;
-
- _D("job_id(%s), pid(%d)", job->id, job->pid);
- job->timer = 0;
- __remove_job(job->id, job->pid);
-
- return G_SOURCE_REMOVE;
-}
-
-static struct job_s *__create_job(const char *id, pid_t pid)
-{
- struct job_s *job;
-
- job = malloc(sizeof(struct job_s));
- if (job == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- job->id = strdup(id);
- if (job->id == NULL) {
- _E("Out of memory");
- free(job);
- return NULL;
- }
-
- job->timer = g_timeout_add(5000, __job_timeout_handler, job);
- if (job->timer == 0) {
- _E("Failed to add timer");
- free(job->id);
- free(job);
- return NULL;
- }
-
- job->pid = pid;
-
- return job;
-}
-
-static struct job_s *__find_job(GList *list, const char *id)
-{
- struct job_s *job;
- GList *iter;
-
- iter = list;
- while (iter) {
- job = (struct job_s *)iter->data;
- if (strcmp(job->id, id) == 0)
- return job;
-
- iter = iter->next;
- }
-
- return NULL;
-}
-
-static int __add_job(const char *id, pid_t pid)
-{
- struct job_s *job;
- GList *list;
-
- list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
- if (list) {
- job = __find_job(list, id);
- if (job) {
- if (job->timer)
- g_source_remove(job->timer);
-
- job->timer = g_timeout_add(5000, __job_timeout_handler,
- job);
- if (job->timer == 0)
- return -1;
- } else {
- job = __create_job(id, pid);
- if (job == NULL)
- return -1;
-
- list = g_list_append(list, job);
- g_hash_table_replace(__job_table, GINT_TO_POINTER(pid),
- list);
- }
- } else {
- job = __create_job(id, pid);
- if (job == NULL)
- return -1;
-
- list = g_list_append(list, job);
- g_hash_table_insert(__job_table, GINT_TO_POINTER(pid), list);
- }
- amd_suspend_remove_timer(pid);
-
- return 0;
-}
-
-static int __remove_job(const char *id, pid_t pid)
-{
- struct job_s *job;
- GList *list;
- amd_app_status_h app_status;
- int status;
-
- list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
- if (list == NULL)
- return -1;
-
- job = __find_job(list, id);
- if (job == NULL)
- return -1;
-
- list = g_list_remove(list, job);
- if (list == NULL) {
- g_hash_table_remove(__job_table, GINT_TO_POINTER(pid));
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status) {
- status = amd_app_status_get_status(app_status);
- if (status != STATUS_DYING)
- amd_suspend_add_timer(pid);
- }
- } else {
- g_hash_table_replace(__job_table, GINT_TO_POINTER(pid), list);
- }
-
- __destroy_job(job);
-
- return 0;
-}
-
-static int __remove_all_jobs(pid_t pid)
-{
- GList *list;
-
- list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
- if (list == NULL)
- return -1;
-
- g_hash_table_remove(__job_table, GINT_TO_POINTER(pid));
- g_list_free_full(list, __destroy_job);
-
- return 0;
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- pid_t pid = amd_app_status_get_pid(app_status);
-
- __remove_all_jobs(pid);
-
- return 0;
-}
-
-static int __dispatch_job_status_update(amd_request_h req)
-{
- bundle *b = amd_request_get_bundle(req);
- pid_t pid = amd_request_get_pid(req);
- const char *job_id;
- const char *job_status_str;
- aul_job_status_e job_status;
- int r;
-
- if (b == NULL) {
- _E("Invalid parameter");
- return -1;
- }
-
- job_id = bundle_get_val(b, AUL_K_JOB_ID);
- if (job_id == NULL) {
- _E("Failed to get job - pid(%d)", pid);
- return -1;
- }
-
- job_status_str = bundle_get_val(b, AUL_K_JOB_STATUS);
- if (job_status_str == NULL) {
- _E("Failed to get job(%s) status", job_id);
- return -1;
- }
-
- if (!isdigit(*job_status_str)) {
- _E("Invalid job(%s) status(%s)", job_id, job_status_str);
- return -1;
- }
-
- job_status = strtoul(job_status_str, NULL, 10);
- switch (job_status) {
- case JOB_STATUS_START:
- r = __add_job(job_id, pid);
- if (r < 0) {
- _E("Failed to add job(%s)", job_id);
- return -1;
- }
- break;
- case JOB_STATUS_STOPPED:
- case JOB_STATUS_FINISHED:
- r = __remove_job(job_id, pid);
- if (r < 0) {
- _W("Failed to remove job(%s)", job_id);
- return -1;
- }
- break;
- default:
- _W("Unknown job status(%u)", job_status);
- break;
- }
-
- _D("job_id(%s), job_status(%u), pid(%d)", job_id, job_status, pid);
-
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = JOB_STATUS_UPDATE,
- .callback = __dispatch_job_status_update
- },
-};
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- _D("job scheduler init");
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- __job_table = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (__job_table == NULL) {
- _E("Failed to create job table");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
-
- return 0;
-}
-
-static gboolean __foreach_remove_cb(gpointer key, gpointer value,
- gpointer data)
-{
- pid_t pid = GPOINTER_TO_INT(key);
- GList *list = (GList *)value;
-
- _D("pid(%d)", pid);
- g_list_free_full(list, __destroy_job);
-
- return TRUE;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("job scheduler finish");
-
- if (__job_table) {
- g_hash_table_foreach_remove(__job_table, __foreach_remove_cb,
- NULL);
- g_hash_table_destroy(__job_table);
- }
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_LAUNCHPAD "amd-mod-launchpad")
-SET(AMD_MOD_LAUNCHPAD_DIR ${CMAKE_SOURCE_DIR}/modules/launchpad)
-PROJECT(${AMD_MOD_LAUNCHPAD} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_LAUNCHPAD_DIR}/src AMD_MOD_LAUNCHPAD_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_LAUNCHPAD_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- libsystemd
- security-manager
- libtzplatform-config
- libsmack
- tanchor
- )
-
-pkg_check_modules(amd_mod_launchpad_pkgs REQUIRED ${AMD_MOD_LAUNCHPAD_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_launchpad_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_LAUNCHPAD_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_LAUNCHPAD} ${AMD_MOD_LAUNCHPAD_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_LAUNCHPAD} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_LAUNCHPAD} ${amd_mod_launchpad_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_LAUNCHPAD} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2018 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 __LAUNCHER_INFO_H__
-#define __LAUNCHER_INFO_H__
-
-#include <glib.h>
-
-typedef struct launcher_info_s *launcher_info_h;
-
-GList *_launcher_info_load(const char *path);
-void _launcher_info_unload(GList *info);
-launcher_info_h _launcher_info_find(GList *info_list, const char *app_type);
-const char *_launcher_info_get_exe(launcher_info_h launcher_info);
-GList *_launcher_info_get_extra_args(launcher_info_h launcher_info);
-
-#endif /* __LAUNCHER_INFO_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_LAUNCHPAD"
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <unistd.h>
-#include <amd_mod_common.h>
-
-#include "launcher_info.h"
-#include "launchpad_private.h"
-
-#define FREE_AND_NULL(x) do { \
- if (x) { \
- free(x); \
- x = NULL; \
- } \
-} while (0)
-
-#define TAG_LAUNCHER "[LAUNCHER]"
-#define TAG_NAME "NAME"
-#define TAG_EXE "EXE"
-#define TAG_APP_TYPE "APP_TYPE"
-#define TAG_EXTRA_ARG "EXTRA_ARG"
-
-struct launcher_info_s {
- char *name;
- char *exe;
- GList *app_types;
- GList *extra_args;
-};
-
-static struct launcher_info_s *__create_launcher_info(void)
-{
- struct launcher_info_s *info;
-
- info = calloc(1, sizeof(struct launcher_info_s));
- if (info == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- return info;
-}
-
-static void __destroy_launcher_info(gpointer data)
-{
- struct launcher_info_s *info = (struct launcher_info_s *)data;
-
- if (info == NULL)
- return;
-
- if (info->extra_args)
- g_list_free_full(info->extra_args, free);
- if (info->app_types)
- g_list_free_full(info->app_types, free);
- if (info->exe)
- free(info->exe);
- if (info->name)
- free(info->name);
- free(info);
-}
-
-static void __parse_app_types(struct launcher_info_s *info, char *line)
-{
- char *token;
- char *saveptr = NULL;
-
- token = strtok_r(line, " |\t\r\n", &saveptr);
- while (token) {
- info->app_types = g_list_append(info->app_types, strdup(token));
- token = strtok_r(NULL, " |\t\r\n", &saveptr);
- }
-}
-
-static GList *__parse_file(GList *list, const char *path)
-{
- FILE *fp;
- char buf[LINE_MAX];
- char *tok1 = NULL;
- char *tok2 = NULL;
- struct launcher_info_s *info = NULL;
-
- fp = fopen(path, "rt");
- if (fp == NULL)
- return list;
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- FREE_AND_NULL(tok1);
- FREE_AND_NULL(tok2);
- sscanf(buf, "%ms %ms", &tok1, &tok2);
- if (tok1 && strcasecmp(TAG_LAUNCHER, tok1) == 0) {
- if (info) {
- _D("name: %s, exe: %s", info->name, info->exe);
- list = g_list_append(list, info);
- }
-
- info = __create_launcher_info();
- if (info == NULL)
- break;
-
- continue;
- }
-
- if (!tok1 || !tok2)
- continue;
- if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
- continue;
- if (info == NULL)
- continue;
-
- if (strcasecmp(TAG_NAME, tok1) == 0) {
- info->name = strdup(tok2);
- if (info->name == NULL) {
- _E("Out of memory");
- __destroy_launcher_info(info);
- info = NULL;
- break;
- }
- } else if (strcasecmp(TAG_EXE, tok1) == 0) {
- info->exe = strdup(tok2);
- if (info->exe == NULL) {
- _E("Out of memory");
- __destroy_launcher_info(info);
- info = NULL;
- break;
- }
- if (access(info->exe, F_OK | X_OK) != 0) {
- _E("Failed to access %s", info->exe);
- __destroy_launcher_info(info);
- info = NULL;
- }
- } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
- __parse_app_types(info, &buf[strlen(tok1)]);
- if (info->app_types == NULL) {
- _E("app_types is NULL");
- __destroy_launcher_info(info);
- info = NULL;
- break;
- }
- } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) {
- info->extra_args = g_list_append(info->extra_args,
- strdup(tok2));
- }
- }
- fclose(fp);
-
- if (info) {
- _D("name: %s, exe: %s", info->name, info->exe);
- list = g_list_append(list, info);
- }
-
- if (tok1)
- free(tok1);
- if (tok2)
- free(tok2);
-
- return list;
-}
-
-GList *_launcher_info_load(const char *path)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- GList *list = NULL;
- char buf[PATH_MAX];
- char *ext;
-
- if (path == NULL)
- return NULL;
-
- dp = opendir(path);
- if (dp == NULL)
- return NULL;
-
- while ((dentry = readdir(dp)) != NULL) {
- if (dentry->d_name[0] == '.')
- continue;
-
- ext = strrchr(dentry->d_name, '.');
- if (ext && strcmp(ext, ".launcher") == 0) {
- snprintf(buf, sizeof(buf), "%s/%s",
- path, dentry->d_name);
- list = __parse_file(list, buf);
- }
- }
- closedir(dp);
-
- return list;
-}
-
-void _launcher_info_unload(GList *info)
-{
- if (info == NULL)
- return;
-
- g_list_free_full(info, __destroy_launcher_info);
-}
-
-static int __comp_str(gconstpointer a, gconstpointer b)
-{
- if (a == NULL || b == NULL)
- return -1;
-
- return strcmp(a, b);
-}
-
-static int __comp_app_type(gconstpointer a, gconstpointer b)
-{
- struct launcher_info_s *info = (struct launcher_info_s *)a;
-
- if (info == NULL || info->app_types == NULL || b == NULL)
- return -1;
-
- if (g_list_find_custom(info->app_types, b, __comp_str))
- return 0;
-
- return -1;
-}
-
-launcher_info_h _launcher_info_find(GList *info_list, const char *app_type)
-{
- GList *list;
-
- if (info_list == NULL || app_type == NULL)
- return NULL;
-
- list = g_list_find_custom(info_list, app_type, __comp_app_type);
- if (list == NULL)
- return NULL;
-
- return (launcher_info_h)list->data;
-}
-
-const char *_launcher_info_get_exe(launcher_info_h info)
-{
- if (info == NULL)
- return NULL;
-
- return info->exe;
-}
-
-GList *_launcher_info_get_extra_args(launcher_info_h info)
-{
- if (info == NULL)
- return NULL;
-
- return info->extra_args;
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/signalfd.h>
-#include <sys/stat.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/smack.h>
-#include <errno.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <linux/limits.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <systemd/sd-journal.h>
-#include <amd.h>
-#include <bundle_internal.h>
-#include <security-manager.h>
-#include <tzplatform_config.h>
-#include <trust-anchor.h>
-#include <amd_mod_common.h>
-
-#include "launcher_info.h"
-#include "launchpad_private.h"
-
-#define AUL_K_EXEC "__AUL_EXEC__"
-#define AUL_K_APPID "__AUL_APPID__"
-#define AUL_K_STARTTIME "__AUL_STARTTIME__"
-#define AUL_K_HWACC "__AUL_HWACC__"
-#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__"
-#define AUL_K_PKGID "__AUL_PKGID_"
-#define AUL_K_PID "__AUL_PID__"
-#define AUL_K_ROOT_PATH "__AUL_ROOT_PATH__"
-#define AUL_K_API_VERSION "__AUL_API_VERSION__"
-#define AUL_K_APP_TYPE "__AUL_APP_TYPE__"
-#define AUL_K_IS_GLOBAL "__AUL_IS_GLOBAL__"
-
-#define FORMAT_DBUS_ADDRESS \
- "kernel:path=/sys/fs/kdbus/%u-user/bus;unix:path=/run/user/%u/bus"
-#define AUL_DBUS_PATH "/aul/dbus_handler"
-#define AUL_DBUS_INTERFACE "org.tizen.aul.signal"
-#define AUL_DBUS_APP_LAUNCH_SIGNAL "app_launch"
-#define AUL_DBUS_APP_DEAD_SIGNAL "app_dead"
-
-#define ARG_PATH 0
-#define PATH_DEV_NULL "/dev/null"
-#define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
-#define APP_STARTUP_SIGNAL 89
-#define CONNECT_RETRY_COUNT 3
-#define CONNECT_RETRY_TIME (100 * 1000)
-
-#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
-
-typedef struct _app_pkt_t {
- int cmd;
- int len;
- int opt;
- unsigned char data[1];
-} app_pkt_t;
-
-struct launch_arg {
- const char *appid;
- const char *app_path;
- const char *pkgid;
- const char *app_type;
- const char *is_global;
- bundle *b;
-};
-
-struct env_map {
- const char *key;
- const char *name;
-};
-
-struct app_arg {
- int argc;
- char **argv;
-};
-
-static struct env_map env_maps[] = {
- { AUL_K_STARTTIME, "APP_START_TIME" },
- { AUL_K_HWACC, "HWACC" },
- { AUL_K_TASKMANAGE, "TASKMANAGE" },
- { AUL_K_APPID, "AUL_APPID" },
- { AUL_K_PKGID, "AUL_PKGID" },
- { AUL_K_APP_TYPE, "RUNTIME_TYPE" },
- { AUL_K_API_VERSION, "TIZEN_API_VERSION" },
- { NULL, NULL },
-};
-
-static sigset_t old_mask;
-static guint sigchld_sid;
-static GDBusConnection *conn;
-static GList *launcher_info_list;
-
-static int __unlink_socket_path(int pid, uid_t uid);
-
-static int __send_signal(const char *path, const char *interface,
- const char *signal, GVariant *param)
-{
- GError *err = NULL;
-
- if (!conn) {
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!conn) {
- LOGE("Failed to get system bus - %s", err->message);
- g_error_free(err);
- return -1;
- }
- }
-
- if (!g_dbus_connection_emit_signal(conn, NULL, path, interface,
- signal, param, &err)) {
- LOGE("Failed to emit signal(%s) - %s", signal, err->message);
- g_error_free(err);
- return -1;
- }
-
- if (!g_dbus_connection_flush_sync(conn, NULL, &err)) {
- LOGE("Failed to flush connection - %s", err->message);
- g_error_free(err);
- return -1;
- }
-
- return 0;
-}
-
-static void __send_app_launch_signal(int pid, const char *appid)
-{
- GVariant *param;
- int r;
-
- param = g_variant_new("(us)", pid, appid);
- if (!param) {
- LOGE("Out of memory");
- return;
- }
-
- r = __send_signal(AUL_DBUS_PATH, AUL_DBUS_INTERFACE,
- AUL_DBUS_APP_LAUNCH_SIGNAL, param);
- if (r < 0)
- return;
-
- LOGD("Send app launch signal - pid(%d), appid(%s)", pid, appid);
-}
-
-static void __send_app_dead_signal(int pid)
-{
- GVariant *param;
- int r;
-
- param = g_variant_new("(u)", pid);
- if (!param) {
- LOGE("Out of memory");
- return;
- }
-
- r = __send_signal(AUL_DBUS_PATH, AUL_DBUS_INTERFACE,
- AUL_DBUS_APP_DEAD_SIGNAL, param);
- if (r < 0)
- return;
-
- LOGD("Send app dead signal - pid(%d)", pid);
-}
-
-static void __init_signal(void)
-{
- int i;
-
- for (i = 0; i < _NSIG; ++i) {
- switch (i) {
- case SIGQUIT:
- case SIGILL:
- case SIGABRT:
- case SIGBUS:
- case SIGFPE:
- case SIGSEGV:
- case SIGPIPE:
- break;
- default:
- signal(i, SIG_DFL);
- break;
- }
- }
-}
-
-static void __finish_signal(void)
-{
- int i;
-
- for (i = 0; i < _NSIG; ++i)
- signal(i, SIG_DFL);
-}
-
-static int __unblock_sigchld(void)
-{
- if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0) {
- LOGE("Failed to change blocked signal");
- return -1;
- }
-
- LOGD("Unblock SIGCHLD");
- return 0;
-}
-
-static void __process_sigchld(struct signalfd_siginfo *siginfo)
-{
- int status;
- pid_t child_pid;
- pid_t child_pgid;
-
- child_pgid = getpgid(siginfo->ssi_pid);
- LOGD("pid(%d), pgid(%d), signo(%d), status(%d)",
- siginfo->ssi_pid, child_pgid, siginfo->ssi_signo,
- siginfo->ssi_status);
-
- while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
- if (child_pid == child_pgid)
- killpg(child_pgid, SIGKILL);
-
- __send_app_dead_signal(child_pid);
- __unlink_socket_path(child_pid, siginfo->ssi_uid);
- }
-}
-
-static gboolean __handle_sigchld(GIOChannel *io, GIOCondition cond,
- gpointer data)
-{
- struct signalfd_siginfo siginfo;
- ssize_t s;
- int fd = g_io_channel_unix_get_fd(io);
- amd_app_status_h app_status;
- const char *appid;
-
- do {
- s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
- if (s == 0)
- break;
-
- if (s != sizeof(struct signalfd_siginfo))
- break;
-
- __process_sigchld(&siginfo);
- app_status = amd_app_status_find_by_pid(siginfo.ssi_pid);
- if (app_status) {
- appid = amd_app_status_get_appid(app_status);
- security_manager_cleanup_app(appid, siginfo.ssi_uid, siginfo.ssi_pid);
- }
- } while (s > 0);
-
- return G_SOURCE_CONTINUE;
-}
-
-static void __destroy_func(gpointer data)
-{
- GIOChannel *io = (GIOChannel *)data;
- gint fd;
-
- if (!io)
- return;
-
- fd = g_io_channel_unix_get_fd(io);
- if (fd > 0)
- close(fd);
-
- g_io_channel_unref(io);
-}
-
-static int __init_sigchld_fd(void)
-{
- int fd;
- sigset_t mask;
- GIOChannel *io;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
-
- if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
- LOGE("Failed to change blocked signals");
-
- fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
- if (fd < 0) {
- LOGE("Failed to create signalfd for SIGCHLD");
- return -1;
- }
-
- io = g_io_channel_unix_new(fd);
- if (!io) {
- LOGE("Failed to create g io channel");
- close(fd);
- return 0;
- }
-
- sigchld_sid = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, G_IO_IN,
- __handle_sigchld, io, __destroy_func);
- if (sigchld_sid == 0) {
- LOGE("Failed to add sigchld fd wacher");
- g_io_channel_unref(io);
- close(fd);
- return -1;
- }
-
- return 0;
-}
-
-static void __set_user_group(void)
-{
- uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
- gid_t gid = tzplatform_getgid(TZ_SYS_DEFAULT_USER);
- const char *user;
- int r;
-
- user = tzplatform_getenv(TZ_SYS_DEFAULT_USER);
- if (!user) {
- LOGE("Failed to get env - TZ_SYS_DEFAULT_USER");
- return;
- }
-
- r = initgroups(user, gid);
- if (r != 0)
- LOGE("Failed to initialize the supplementary group access list");
-
- r = setregid(gid, gid);
- if (r != 0)
- LOGE("Failed to set real and effective group id");
-
- r = setreuid(uid, uid);
- if (r != 0)
- LOGE("Failed to set real and effective user id");
-
- tzplatform_set_user(uid);
-}
-
-static void __unlink_dir(const char *path)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- struct stat statbuf;
- char buf[PATH_MAX];
- int r;
-
- dp = opendir(path);
- if (!dp)
- return;
-
- while ((dentry = readdir(dp)) != NULL) {
- if (!strcmp(dentry->d_name, ".") ||
- !strcmp(dentry->d_name, ".."))
- continue;
-
- snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
- r = stat(buf, &statbuf);
- if (r == 0) {
- if (S_ISDIR(statbuf.st_mode))
- __unlink_dir(buf);
- else
- unlink(buf);
- }
- }
-
- rmdir(path);
- closedir(dp);
-}
-
-static int __unlink_socket_path(int pid, uid_t uid)
-{
- char path[PATH_MAX];
-
- snprintf(path, sizeof(path), "/run/aul/apps/%d/%d", uid, pid);
- if (access(path, F_OK) == 0)
- __unlink_dir(path);
-
- if (access(path, F_OK) == 0)
- return -1;
-
- return 0;
-}
-
-static void __redirect_stdio(const char *ident)
-{
- int fd;
-
- /* stdin */
- fd = open(PATH_DEV_NULL, O_RDONLY | O_NOCTTY);
- if (fd < 0) {
- LOGW("Failed to open /dev/null - err(%d)", errno);
- return;
- }
- if (dup2(fd, STDIN_FILENO) < 0) {
- LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
- fd, STDIN_FILENO);
- }
- close(fd);
-
- /* stdout */
- fd = sd_journal_stream_fd(ident, LOG_INFO, false);
- if (fd < 0) {
- LOGW("Failed to connect journal socket - err(%d)", errno);
- fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
- if (fd < 0) {
- LOGW("Failed to open /dev/null - err(%d)", errno);
- return;
- }
- }
- if (dup2(fd, STDOUT_FILENO) < 0) {
- LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
- fd, STDOUT_FILENO);
- }
- close(fd);
-
- /* stderr */
- fd = sd_journal_stream_fd(ident, LOG_INFO, false);
- if (fd < 0) {
- LOGW("Failed to connect journal socket - err(%d)", errno);
- fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
- if (fd < 0) {
- LOGW("Failed to open /dev/null - err(%d)", errno);
- return;
- }
- }
-
- if (dup2(fd, STDERR_FILENO) < 0) {
- LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
- fd, STDERR_FILENO);
- }
- close(fd);
-}
-
-static void __set_env(bundle *b)
-{
- const char *val;
- char buf[PATH_MAX];
- int i;
-
- for (i = 0; env_maps[i].key; ++i) {
- val = bundle_get_val(b, env_maps[i].key);
- if (val)
- setenv(env_maps[i].name, val, 1);
- }
-
- val = bundle_get_val(b, AUL_K_ROOT_PATH);
- if (val) {
- setenv("AUL_ROOT_PATH", val, 1);
- /* for backward compatibility */
- snprintf(buf, sizeof(buf), "%s/lib/", val);
- setenv("LD_LIBRARY_PATH", buf, 1);
- }
-
- val = tzplatform_getenv(TZ_USER_HOME);
- if (val)
- setenv("HOME", val, 1);
-
- val = tzplatform_getenv(TZ_SYS_DEFAULT_USER);
- if (val) {
- setenv("LOGNAME", val, 1);
- setenv("USER", val, 1);
- }
-
- snprintf(buf, sizeof(buf), "%d", getpid());
- setenv("AUL_PID", buf, 1);
-
- snprintf(buf, sizeof(buf), "/run/user/%d", getuid());
- setenv("XDG_RUNTIME_DIR", buf, 1);
-
- snprintf(buf, sizeof(buf), FORMAT_DBUS_ADDRESS, getuid(), getuid());
- setenv("DBUS_SESSION_BUS_ADDRESS", buf, 1);
-}
-
-static int __send_cmd_to_amd(int cmd)
-{
- struct sockaddr_un addr = {0,};
- int retry = CONNECT_RETRY_COUNT;
- app_pkt_t pkt = {0,};
- int fd;
- int ret;
-
- fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
- /* support above version 2.6.27*/
- if (fd < 0) {
- if (errno == EINVAL) {
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- LOGE("second chance - socket create error");
- return -1;
- }
- } else {
- LOGE("socket error");
- return -1;
- }
- }
-
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
- while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- if (errno != ETIMEDOUT || retry <= 0) {
- LOGE("Failed to connect error(%d)", errno);
- close(fd);
- return -1;
- }
-
- usleep(CONNECT_RETRY_TIME);
- --retry;
- LOGD("re-connect to %s (%d)", addr.sun_path, retry);
- }
-
- pkt.cmd = cmd;
- ret = send(fd, &pkt, sizeof(app_pkt_t), MSG_NOSIGNAL);
- if (ret <= 0) {
- LOGE("Failed to send cmd(%d), errno(%d)", cmd, errno);
- close(fd);
- return -ECOMM;
- }
- close(fd);
-
- return 0;
-}
-
-static int __prepare_exec(struct launch_arg *arg)
-{
- char *name;
- int r;
-
- /* Set new session ID & new process group ID*/
- /* In linux, child can set new session ID without check permission */
- setsid();
-
- LOGW("trust_anchor_launch ++");
- if (arg->is_global && !strcmp(arg->is_global, "true"))
- r = trust_anchor_launch(arg->pkgid, GLOBAL_USER);
- else
- r = trust_anchor_launch(arg->pkgid, getuid());
- LOGW("trust_anchor_launch --");
- if (r != TRUST_ANCHOR_ERROR_NONE &&
- r != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
- LOGE("trust_anchor_launch() is failed. %d", r);
- return -1;
- }
-
- /* Set privileges */
- LOGW("security_manager_prepare_app ++");
- r = security_manager_prepare_app(arg->appid);
- LOGW("security_manager_prepare_app --");
- if (r != SECURITY_MANAGER_SUCCESS) {
- LOGE("Failed to set privileges");
- return -1;
- }
-
- __send_cmd_to_amd(APP_STARTUP_SIGNAL);
-
- name = basename(arg->app_path);
- if (!name) {
- LOGE("Failed to parse name");
- return -1;
- }
-
- __redirect_stdio(name);
- prctl(PR_SET_NAME, name);
- __set_env(arg->b);
-
- return 0;
-}
-
-static void __close_all_fds(void)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- int fd;
- int max_fd = sysconf(_SC_OPEN_MAX);
-
- dp = opendir("/proc/self/fd");
- if (!dp) {
- for (fd = 3; fd < max_fd; ++fd)
- close(fd);
- return;
- }
-
- while ((dentry = readdir(dp)) != NULL) {
- if (!isdigit(dentry->d_name[0]))
- continue;
-
- fd = atoi(dentry->d_name);
- if (fd < 3 || fd >= max_fd)
- continue;
-
- if (fd == dirfd(dp))
- continue;
-
- close(fd);
- }
- closedir(dp);
-}
-
-static int __create_launcher_argv(int *argc, char ***argv, const char *app_type)
-{
- int launcher_argc;
- char **launcher_argv;
- launcher_info_h launcher_info;
- const char *exe;
- const char *extra_arg;
- GList *extra_args;
- GList *iter;
- int i;
-
- launcher_info = _launcher_info_find(launcher_info_list, app_type);
- if (launcher_info == NULL)
- return 0;
-
- exe = _launcher_info_get_exe(launcher_info);
- if (exe == NULL) {
- LOGE("Failed to get launcher exe");
- return -1;
- }
-
- extra_args = _launcher_info_get_extra_args(launcher_info);
- launcher_argc = g_list_length(extra_args) + 1;
- launcher_argv = (char **)calloc(launcher_argc, sizeof(char *));
- if (launcher_argv == NULL) {
- LOGE("Out of memory");
- return -1;
- }
-
- i = ARG_PATH;
- launcher_argv[i++] = strdup(exe);
-
- iter = g_list_first(extra_args);
- while (iter) {
- extra_arg = (const char *)iter->data;
- if (extra_arg)
- launcher_argv[i++] = strdup(extra_arg);
-
- iter = g_list_next(iter);
- }
-
- *argc = launcher_argc;
- *argv = launcher_argv;
-
- return 0;
-}
-
-static void __destroy_launcher_argv(int argc, char **argv)
-{
- int i;
-
- if (argv == NULL)
- return;
-
- for (i = 0; i < argc; i++)
- free(argv[i]);
- free(argv);
-}
-
-static int __create_app_argv(int *argc, char ***argv, const char *app_path,
- bundle *b, const char *app_type)
-{
- int new_argc;
- char **new_argv;
- struct app_arg launcher_arg = { 0, };
- struct app_arg arg = { 0, };
- int i;
- int r;
- int c;
-
- r = __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv,
- app_type);
- if (r < 0) {
- LOGE("Failed to create launcher argv");
- return -1;
- }
-
- arg.argc = bundle_export_to_argv(b, &arg.argv);
- if (arg.argc <= 0) {
- LOGE("Failed to export bundle");
- __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
- return -1;
- }
-
- arg.argv[ARG_PATH] = strdup(app_path);
- if (arg.argv[ARG_PATH] == NULL) {
- LOGE("Failed to duplicate app path");
- bundle_free_exported_argv(arg.argc, &arg.argv);
- __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
- return -1;
- }
-
- new_argc = launcher_arg.argc + arg.argc;
- if (new_argc == arg.argc) {
- *argc = arg.argc;
- *argv = arg.argv;
- return 0;
- }
-
- new_argv = (char **)calloc(new_argc + 1, sizeof(char *));
- if (new_argv == NULL) {
- LOGE("Out of memory");
- free(arg.argv[ARG_PATH]);
- bundle_free_exported_argv(arg.argc, &arg.argv);
- __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
- return -1;
- }
-
- c = ARG_PATH;
- for (i = 0; i < launcher_arg.argc; i++)
- new_argv[c++] = launcher_arg.argv[i];
- for (i = 0; i < arg.argc; i++)
- new_argv[c++] = arg.argv[i];
-
- *argc = new_argc;
- *argv = new_argv;
-
- return 0;
-}
-
-static int __exec_app_process(struct launch_arg *arg)
-{
- int app_argc;
- char **app_argv = NULL;
- int i;
- int r;
-
- __unblock_sigchld();
- __finish_signal();
- __set_user_group();
-
- LOGD("appid(%s), pid(%d), uid(%d)", arg->appid, getpid(), getuid());
-
- r = __unlink_socket_path(getpid(), getuid());
- if (r < 0) {
- LOGE("Failed to delete socket path");
- return r;
- }
-
- r = __prepare_exec(arg);
- if (r < 0) {
- LOGE("Failed to prepare exec");
- return r;
- }
-
- r = __create_app_argv(&app_argc, &app_argv, arg->app_path, arg->b,
- arg->app_type);
- if (r < 0) {
- LOGE("Failed to create app arg");
- return r;
- }
-
- for (i = 0; i < app_argc; ++i)
- LOGD("input argument %d: %s##", i, app_argv[i]);
-
- __close_all_fds();
-
- r = execv(app_argv[ARG_PATH], app_argv);
- if (r < 0) {
- fprintf(stderr, "Failed to execute %s - err(%d)",
- app_argv[ARG_PATH], errno);
- }
-
- return r;
-}
-
-static int __launcher(bundle *b, uid_t uid, void *user_data)
-{
- struct launch_arg arg;
- int pid;
- int r;
- uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-
- if (!b) {
- LOGE("Invalid parameter");
- return -1;
- }
-
- if (uid != default_uid) {
- LOGE("uid(%u) is not default uid(%u)", uid, default_uid);
- return -1;
- }
-
- arg.appid = bundle_get_val(b, AUL_K_APPID);
- arg.app_path = bundle_get_val(b, AUL_K_EXEC);
- arg.pkgid = bundle_get_val(b, AUL_K_PKGID);
- arg.app_type = bundle_get_val(b, AUL_K_APP_TYPE);
- arg.is_global = bundle_get_val(b, AUL_K_IS_GLOBAL);
- arg.b = b;
-
- pid = fork();
- if (pid == 0) {
- r = __exec_app_process(&arg);
- exit(r);
- } else if (pid > 0) {
- LOGD("==> real launch pid: %d(%s)", pid, arg.app_path);
- __send_app_launch_signal(pid, arg.appid);
- } else {
- LOGE("Failed to fork process");
- }
-
- return pid;
-}
-
-static gboolean __send_startup_finished(gpointer data)
-{
- uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-
- amd_noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
- (int)uid, 0, NULL, NULL);
- return G_SOURCE_REMOVE;
-}
-
-static void __create_user_directories(void)
-{
- char buf[PATH_MAX];
- int pid;
-
- pid = fork();
- if (pid == 0) {
- __unblock_sigchld();
- __finish_signal();
- __set_user_group();
-
- snprintf(buf, sizeof(buf), "/run/aul/apps/%u", getuid());
- if (mkdir(buf, 0700) < 0)
- LOGW("Failed to create %s", buf);
- if (smack_setlabel(buf, "User", SMACK_LABEL_ACCESS))
- LOGW("Failed to change smack");
-
- snprintf(buf, sizeof(buf), "/run/aul/dbspace/%u", getuid());
- if (mkdir(buf, 0701) < 0)
- LOGW("Failed to create %s", buf);
- if (smack_setlabel(buf, "User::Home", SMACK_LABEL_ACCESS))
- LOGW("Failed to change smack");
-
- exit(EXIT_SUCCESS);
- }
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- LOGD("launchpad init");
-
- r = amd_launchpad_set_launcher(__launcher, NULL);
- if (r < 0)
- return -1;
-
- r = __init_sigchld_fd();
- if (r < 0)
- return -1;
-
- __init_signal();
- __create_user_directories();
- launcher_info_list = _launcher_info_load("/usr/share/aul");
- g_idle_add(__send_startup_finished, NULL);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- LOGD("launchpad fini");
-
- if (launcher_info_list) {
- _launcher_info_unload(launcher_info_list);
- launcher_info_list = NULL;
- }
-
- if (conn) {
- g_object_unref(conn);
- conn = NULL;
- }
-
- if (sigchld_sid > 0) {
- g_source_remove(sigchld_sid);
- sigchld_sid = 0;
- }
-
- amd_launchpad_set_launcher(NULL, NULL);
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_LOADER_MGR "amd-mod-loader-manager")
-SET(AMD_MOD_LOADER_MGR_DIR ${CMAKE_SOURCE_DIR}/modules/loader-manager)
-PROJECT(${AMD_MOD_LOADER_MGR} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_LOADER_MGR_DIR}/src AMD_MOD_LOADER_MGR_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_LOADER_MGR_PKG_CHECK_MODULES
- dlog
- glib-2.0
- bundle
- aul
- )
-
-pkg_check_modules(amd_mod_loader_mgr_pkgs REQUIRED ${AMD_MOD_LOADER_MGR_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_loader_mgr_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_LOADER_MGR_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_LOADER_MGR} ${AMD_MOD_LOADER_MGR_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_LOADER_MGR} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_LOADER_MGR} ${amd_mod_loader_mgr_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_LOADER_MGR} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <amd.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <bundle_internal.h>
-#include <glib.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_LOADER_MANAGER"
-
-#define METADATA_KEY_APP_DEFINED_LOADER \
- "http://tizen.org/metadata/app-defined-loader"
-
-static GHashTable *__loader_table;
-
-static void __loader_table_update(const char *loader_name, int loader_id)
-{
- if (g_hash_table_contains(__loader_table, loader_name)) {
- g_hash_table_replace(__loader_table, strdup(loader_name),
- GINT_TO_POINTER(loader_id));
- } else {
- g_hash_table_insert(__loader_table, strdup(loader_name),
- GINT_TO_POINTER(loader_id));
- }
-}
-
-static bool __loader_table_lookup(const char *loader_name, int *loader_id)
-{
- gpointer found;
-
- if (!g_hash_table_contains(__loader_table, loader_name)) {
- _W("loader_id(%s) doesn't exist", loader_name);
- *loader_id = -1;
- return false;
- }
-
- found = g_hash_table_lookup(__loader_table, loader_name);
- *loader_id = GPOINTER_TO_INT(found);
- return true;
-}
-
-static int __metadata_foreach_cb(const char *value, void *user_data)
-{
- int *loader_id = (int *)user_data;
-
- if (!value)
- return 0;
-
- if (__loader_table_lookup(value, loader_id))
- return -1;
-
- return 0;
-}
-
-static int __get_loader_id(const char *app_id, uid_t uid)
-{
- amd_app_property_h app_property;
- int loader_id = -1;
-
- app_property = amd_app_property_find(uid);
- if (!app_property)
- return -1;
-
- amd_app_property_metadata_foreach(app_property, app_id,
- METADATA_KEY_APP_DEFINED_LOADER,
- __metadata_foreach_cb,
- (void *)&loader_id);
-
- return loader_id;
-}
-
-static int __on_launch_prepare_end(const char *msg,
- int arg1, int arg2, void *arg3, bundle *data)
-{
- amd_appinfo_h ai = arg3;
- uid_t target_uid = (uid_t)arg2;
- const char *app_id;
- const char *loader_id_str;
- int req_loader_id;
- int loader_id;
-
- if (bundle_get_type(data, AUL_K_SDK) != BUNDLE_TYPE_NONE)
- return AMD_NOTI_CONTINUE;
-
- if (bundle_get_type(data, AUL_K_APP_DEFINED_LOADER) != BUNDLE_TYPE_NONE)
- return AMD_NOTI_CONTINUE;
-
- loader_id_str = bundle_get_val(data, AUL_K_LOADER_ID);
- if (!loader_id_str)
- return AMD_NOTI_CONTINUE;
-
- req_loader_id = atoi(loader_id_str);
-
- app_id = amd_appinfo_get_value(ai, AMD_AIT_NAME);
- if (!app_id) {
- _E("Failed to get appid");
- return AMD_NOTI_STOP;
- }
-
- loader_id = __get_loader_id(app_id, target_uid);
- if (loader_id < 0)
- return AMD_NOTI_CONTINUE;
-
- if (req_loader_id != loader_id) {
- _W("Not matched. %d:%d", req_loader_id, loader_id);
- bundle_del(data, AUL_K_LOADER_ID);
- return AMD_NOTI_CONTINUE;
- }
-
- _W("app_id(%s), loader_id(%d)", app_id, loader_id);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __dispatch_app_prepare_app_defined_loader(amd_request_h req)
-{
- const char *loader_name;
- bundle *b;
- int ret;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- loader_name = bundle_get_val(b, AUL_K_LOADER_NAME);
- if (!loader_name) {
- _E("Failed to get loader name");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- ret = amd_socket_send_cmd_to_launchpad(amd_request_get_target_uid(req),
- PAD_CMD_PREPARE_APP_DEFINED_LOADER,
- b);
- amd_request_send_result(req, ret);
- if (ret < 0) {
- _E("Failed to prepare loader process. error(%d)", ret);
- return ret;
- }
-
- __loader_table_update(loader_name, ret);
- _I("loader_name(%s), result(%d)", loader_name, ret);
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_PREPARE_APP_DEFINED_LOADER,
- .callback = __dispatch_app_prepare_app_defined_loader
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_PREPARE_APP_DEFINED_LOADER,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
-};
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int ret;
-
- _W("AMD_LOADER_MANAGER_INIT");
-
- ret = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register dispatch table");
- return -1;
- }
-
- ret = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register cynara checkers");
- return -1;
- }
-
- ret = amd_app_property_metadata_add_filter(
- METADATA_KEY_APP_DEFINED_LOADER,
- NULL);
- if (ret < 0) {
- _E("Failed to add metadata filter");
- return -1;
- }
-
- __loader_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, NULL);
- if (!__loader_table) {
- _E("Out of memory");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
- __on_launch_prepare_end);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _W("AMD_LOADER_MANAGER_FINI");
-
- if (__loader_table)
- g_hash_table_destroy(__loader_table);
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_RPC_PORT "amd-mod-rpc-port")
-SET(AMD_MOD_RPC_PORT_DIR ${CMAKE_SOURCE_DIR}/modules/rpc-port)
-PROJECT(${AMD_MOD_RPC_PORT} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_RPC_PORT_DIR}/src AMD_MOD_RPC_PORT_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_RPC_PORT_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- cert-svc-vcore
- )
-
-pkg_check_modules(amd_mod_rpc_port_pkgs REQUIRED ${AMD_MOD_RPC_PORT_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_rpc_port_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_RPC_PORT_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_RPC_PORT} ${AMD_MOD_RPC_PORT_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_RPC_PORT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_RPC_PORT} ${amd_mod_rpc_port_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_RPC_PORT} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <sys/socket.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_rpc_port.h>
-#include <aul_svc.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_RPC_PORT"
-
-#define MAX_NR_OF_DESCRIPTORS 2
-#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
-#define KEY_PRIVILEGE_CHECK_BYPASS \
- "http://tizen.org/rpc-port/privilege-check-bypass"
-
-struct metadata_info_s {
- const char *port_name;
- bool exist;
-};
-
-static GHashTable *__pid_table;
-
-static void __rpc_unref(int pid)
-{
- gpointer value;
- int count;
- amd_app_status_h app_status;
- int status;
-
- value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
- if (!value) {
- _E("Critical error");
- return;
- }
-
- count = GPOINTER_TO_INT(value);
- count--;
- if (count == 0) {
- g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
- amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status) {
- status = amd_app_status_get_status(app_status);
- if (status != STATUS_DYING)
- amd_suspend_add_timer(pid);
- }
- } else {
- g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
- GINT_TO_POINTER(count));
- }
-}
-
-static void __rpc_ref(int pid)
-{
- gpointer value;
- int count;
-
- value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
- if (value) {
- count = GPOINTER_TO_INT(value);
- count++;
- g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
- GINT_TO_POINTER(count));
- } else {
- count = 1;
- g_hash_table_insert(__pid_table, GINT_TO_POINTER(pid),
- GINT_TO_POINTER(count));
- amd_suspend_remove_timer(pid);
- amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
- }
-}
-
-static void __set_real_appid(uid_t uid, bundle *kb)
-{
- const char *alias_appid;
- const char *appid;
- const char *alias_info;
- amd_app_property_h app_property;
-
- alias_appid = bundle_get_val(kb, AUL_K_APPID);
- if (alias_appid == NULL)
- return;
-
- alias_info = bundle_get_val(kb, AUL_SVC_K_ALIAS_INFO);
- if (alias_info && strcmp(alias_info, "disable") == 0)
- return;
-
- app_property = amd_app_property_find(uid);
- if (app_property == NULL)
- return;
-
- appid = amd_app_property_get_real_appid(app_property, alias_appid);
- if (appid == NULL)
- return;
-
- _D("alias_appid(%s), appid(%s)", alias_appid, appid);
- bundle_del(kb, AUL_K_ORG_APPID);
- bundle_add(kb, AUL_K_ORG_APPID, alias_appid);
- bundle_del(kb, AUL_K_APPID);
- bundle_add(kb, AUL_K_APPID, appid);
-}
-
-static int __dispatch_rpc_port_prepare_stub(amd_request_h req)
-{
- bundle *b = amd_request_get_bundle(req);
- pid_t caller_pid = amd_request_get_pid(req);
- uid_t target_uid = amd_request_get_target_uid(req);
- amd_appinfo_h ai;
- const char *appid;
- const char *port_name;
- int pid;
- bool dummy_pending = false;
- bool dummy_bg_launch = false;
-
- if (!b) {
- _E("Invalid parameter");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- __set_real_appid(target_uid, b);
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get appid");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- port_name = bundle_get_val(b, AUL_K_RPC_PORT);
- if (!port_name) {
- _E("Failed to get port name");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- ai = amd_appinfo_find(target_uid, appid);
- if (!ai) {
- _E("Failed to find %s:%u", appid, target_uid);
- amd_request_send_result(req, -ENOENT);
- return -1;
- }
-
- amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req, b);
-
- amd_request_set_request_type(req, "rpc-port");
- amd_request_set_cmd(req, APP_START_ASYNC);
- pid = amd_launch_start_app(appid, req,
- &dummy_pending, &dummy_bg_launch,
- false);
- if (pid < 0) {
- _E("Failed to send launch request(%s:%s)",
- appid, port_name);
- amd_noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, pid, 0, NULL, NULL);
- return -1;
- }
- amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END,
- pid, dummy_bg_launch, req, b);
-
- __rpc_ref(pid);
-
- _I("[__RPC_PORT__] appid(%s), pid(%d), port_name(%s), caller_pid(%d)",
- appid, pid, port_name, caller_pid);
-
- return 0;
-}
-
-static int __pass_fds(int fd, const int (*fds)[2])
-{
- struct msghdr msg = { 0, };
- struct cmsghdr *cmsg;
- union {
- /*
- * ancillary data buffer, wrapped in a union in order to ensure
- * it is suitably aligned
- */
- char buf[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)];
- struct cmsghdr align;
- } u;
- int *fdptr;
- char iobuf[1];
- struct iovec io = {
- .iov_base = iobuf,
- .iov_len = sizeof(iobuf)
- };
- int r;
-
- msg.msg_iov = &io;
- msg.msg_iovlen = 1;
- msg.msg_control = u.buf;
- msg.msg_controllen = sizeof(u.buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- if (!cmsg) {
- _E("Failed to get the first cmsghdr");
- return -EINVAL;
- }
-
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int) * MAX_NR_OF_DESCRIPTORS);
-
- /* Initialize the payload: */
- fdptr = (int *)CMSG_DATA(cmsg);
- memcpy(fdptr, *fds, sizeof(int) * MAX_NR_OF_DESCRIPTORS);
-
- r = sendmsg(fd, &msg, 0);
- if (r < 0) {
- _E("Failed to send message. errno(%d)", errno);
- return r;
- }
-
- _D("[__RPC_PORT__] sendmsg result(%d)", r);
-
- return r;
-}
-
-static int __dispatch_rpc_port_create_socket_pair(amd_request_h req)
-{
- int fds[2] = { 0, };
- int r;
-
- r = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
- if (r != 0) {
- _E("Failed to create socket pair. err = %d", r);
- amd_request_send_result(req, -1);
- return -1;
- }
-
- if (fds[0] == -1) {
- _E("Failed to open socket");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- _I("[__RPC_PORT__] A Pair of sockets: %d:%d", fds[0], fds[1]);
-
- r = __pass_fds(amd_request_get_fd(req), &fds);
- if (r < 0) {
- _E("Failed to pass file descriptors");
- amd_request_send_result(req, r);
- }
-
- close(fds[0]);
- close(fds[1]);
-
- return 0;
-}
-
-static int __dispatch_rpc_port_notify_rpc_finished(amd_request_h req)
-{
- pid_t pid = amd_request_get_pid(req);
-
- if (pid <= 0) {
- _E("Invalid parameter");
- return -1;
- }
-
- __rpc_unref(pid);
- _I("[__RPC_PORT__] pid(%d)", pid);
-
- return 0;
-}
-
-static int __foreach_metadata_cb(const char *value, void *user_data)
-{
- struct metadata_info_s *info = (struct metadata_info_s *)user_data;
- char *str;
- char *token;
- char *saveptr = NULL;
-
- str = strdup(value);
- if (!str) {
- _E("Out of memory");
- return -1;
- }
-
- token = strtok_r(str, "|", &saveptr);
- while (token) {
- if (!strcmp(token, info->port_name)) {
- info->exist = true;
- free(str);
- return -1; /* To break metadata iteration */
- }
- token = strtok_r(NULL, "|", &saveptr);
- }
-
- free(str);
-
- return 0;
-}
-
-static int __verify_privilege_check_bypass(amd_request_h req)
-{
- int r;
- bundle *b;
- const char *appid;
- struct metadata_info_s info = { 0, };
- amd_app_property_h app_property;
- uid_t uid = amd_request_get_target_uid(req);
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Invalid request");
- return AMD_CYNARA_RET_ERROR;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get appid");
- return AMD_CYNARA_RET_ERROR;
- }
-
- info.port_name = bundle_get_val(b, AUL_K_RPC_PORT);
- if (!info.port_name) {
- _E("Failed to get port name");
- return AMD_CYNARA_RET_ERROR;
- }
-
- app_property = amd_app_property_find(uid);
- if (app_property) {
- r = amd_app_property_metadata_foreach(app_property,
- appid, KEY_PRIVILEGE_CHECK_BYPASS,
- __foreach_metadata_cb, &info);
- if (r != 0) {
- _E("Failed to retrieve metadata");
- return AMD_CYNARA_RET_ERROR;
- }
-
- if (info.exist && amd_appinfo_is_platform_app(appid, uid)) {
- SECURE_LOGD("Bypass privilege check");
- return AMD_CYNARA_RET_ALLOWED;
- }
- }
-
- return AMD_CYNARA_RET_UNKNOWN;
-}
-
-static int __prepare_stub_cynara_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- int r;
-
- r = __verify_privilege_check_bypass(req);
- if (r != AMD_CYNARA_RET_UNKNOWN)
- return r;
-
- r = amd_cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
- if (r <= AMD_CYNARA_RET_DENIED)
- return r;
-
- return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
-}
-
-static int __create_socket_pair_cynara_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- int r;
-
- r = __verify_privilege_check_bypass(req);
- if (r != AMD_CYNARA_RET_UNKNOWN)
- return r;
-
- return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- int pid = arg1;
-
- if (g_hash_table_contains(__pid_table, GINT_TO_POINTER(pid)))
- g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
-
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = RPC_PORT_PREPARE_STUB,
- .callback = __dispatch_rpc_port_prepare_stub
- },
- {
- .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
- .callback = __dispatch_rpc_port_create_socket_pair
- },
- {
- .cmd = RPC_PORT_NOTIFY_RPC_FINISHED,
- .callback = __dispatch_rpc_port_notify_rpc_finished
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = RPC_PORT_PREPARE_STUB,
- .checker = __prepare_stub_cynara_checker,
- .data = NULL,
- .priority = 10
- },
- {
- .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
- .checker = __create_socket_pair_cynara_checker,
- .data = NULL,
- .priority = 10
- },
-};
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- _D("rpc port init");
-
- r = amd_app_property_metadata_add_filter(KEY_PRIVILEGE_CHECK_BYPASS,
- NULL);
- if (r < 0) {
- _E("Failed to add metadata filter");
- return -1;
- }
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register cynara checkers");
- return -1;
- }
-
- __pid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (!__pid_table) {
- _E("Failed to create pid table");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("rpc port finish");
-
- if (__pid_table)
- g_hash_table_destroy(__pid_table);
-
- amd_app_property_metadata_remove_filter(KEY_PRIVILEGE_CHECK_BYPASS,
- NULL);
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_RUA "amd-mod-rua")
-SET(AMD_MOD_RUA_DIR ${CMAKE_SOURCE_DIR}/modules/rua)
-PROJECT(${AMD_MOD_RUA} C)
-INCLUDE_DIRECTORIES(${AMD_MOD_RUA_DIR}/inc)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_RUA_DIR}/src AMD_MOD_RUA_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_RUA_PKG_CHECK_MODULES
- dlog
- rua
- glib-2.0
- gio-2.0
- aul
- )
-
-pkg_check_modules(amd_mod_rua_pkgs REQUIRED ${AMD_MOD_RUA_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_rua_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_RUA} ${AMD_MOD_RUA_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_RUA} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_RUA} ${amd_mod_rua_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_RUA} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-/**
- * @brief Called when the image file is created.
- *
- * @param[in] image The image file
- * @param[in] user_data The user data passed from the callback registration function
- */
-typedef void (*rua_image_monitor_event_cb)(const char *image, void *user_data);
-
-/**
- * @brief Clears all image files.
- */
-void _rua_image_monitor_clear_all(void);
-
-/**
- * @brief Clears the image file.
- *
- * @param[in] image The image file
- */
-void _rua_image_monitor_clear(const char *image);
-
-/**
- * @brief Sets the event callback function.
- *
- * @param[in] callback The callback function to be called when the image file is created
- * @param[in] user_data The user data to be ppased to the callback function
- * @return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_image_monitor_set_event_cb(rua_image_monitor_event_cb callback,
- void *user_data);
-
-/**
- * @brief Initializes the image monitor.
- *
- * return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_image_monitor_init(void);
-
-/**
- * @brief Finalizes the image monitor.
- */
-void _rua_image_monitor_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <bundle.h>
-
-/**
- * @brief Intializes the RUA information.
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_info_init(void);
-
-/**
- * @brief Finalizes the RUA information.
- */
-void _rua_info_fini(void);
-
-/**
- * @brief Adds a RUA information.
- *
- * @param[in] kb The bundle object
- * @param[in] pid The process ID
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_info_add(bundle *kb, pid_t pid);
-
-/**
- * @brief Removes the RUA information.
- *
- * @param[in] kb The bundle object
- * @param[in] uid The user ID
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_info_remove(bundle *kb, uid_t uid);
-
-/**
- * @brief Updates the image path of the RUA information.
- *
- * @param[in] image The image path
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- */
-int _rua_info_update_image(const char *image);
-
-/**
- * @brief Gets the image path of the instance.
- *
- * @param[in] instance_id The ID of the instance
- *
- * @return @c the image path on success,
- * otherwise a nullptr
- */
-const char *_rua_info_get_image(const char *instance_id);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-/**
- * @brief Gets the ID of the instance.
- *
- * @return @c an instance ID on success,
- * otherwise a nullptr
- */
-const char *_rua_launch_context_get_id(void);
-
-/**
- * @brief Gets the name of the instance.
- *
- * @return @c a instance name on success,
- * otherwise a nullptr
- */
-const char *_rua_launch_context_get_name(void);
-
-/**
- * @brief Gets the icon path.
- *
- * @return @c an icon path on success,
- * otherwise a nullptr
- */
-const char *_rua_launch_context_get_icon(void);
-
-/**
- * @brief Gets the URI.
- *
- * @return @c URI on success,
- * otherwise a nullptr
- */
-const char *_rua_launch_context_get_uri(void);
-
-/**
- * @brief Releases the launch context.
- */
-void _rua_launch_context_free(void);
-
-/**
- * @brief Initialize the launch context.
- *
- * @return @c 0 on succes,
- * otherwise a negative error value
- */
-int _rua_launch_context_init(void);
-
-/**
- * @brief Finalize the launch context.
- */
-void _rua_launch_context_fini(void);
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_RUA"
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-/**
- * @brief Initializes RUA request.
- *
- * @return @c 0 on succes,
- * otherwise a negative error value
- */
-int _rua_request_init(void);
-
-/**
- * @brief Finalizes RUA request.
- */
-void _rua_request_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2017 - 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <rua_internal.h>
-#include <rua_stat_internal.h>
-#include <dlog.h>
-
-#include <amd.h>
-
-#include "amd_rua_request.h"
-#include "amd_rua_info.h"
-#include "amd_rua_launch_context.h"
-#include "amd_rua_image_monitor.h"
-#include "amd_rua_private.h"
-
-#define AUL_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
-#define RUA_TIMEOUT 1500
-
-typedef struct _rua_data_t {
- pid_t pid;
- uid_t uid;
- char *stat_tag;
- char *stat_caller;
- char *app_id;
- char *app_path;
- char *comp_id;
- char *instance_id;
- char *instance_name;
- char *icon;
- char *uri;
- bool is_group_mode;
- char *arg;
-} rua_data_t;
-
-typedef int (*rua_data_add_cb)(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status);
-typedef void (*rua_data_remove_cb)(rua_data_t *rua);
-
-typedef struct _rua_data_vft {
- rua_data_add_cb ctor;
- rua_data_remove_cb dtor;
-} rua_data_vft;
-
-struct rua_context_s {
- GList *user_list;
-};
-
-static struct rua_context_s *__get_context(void)
-{
- static struct rua_context_s context;
-
- return &context;
-}
-
-static bool __is_group_mode(bundle *kb, uid_t uid)
-{
- const char *str;
- const char *mode;
- const char *appid;
- amd_appinfo_h ai;
-
- if (kb == NULL)
- return false;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL)
- return false;
-
- ai = amd_appinfo_find(uid, appid);
- mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
- if (mode != NULL && strcmp(mode, "caller") == 0) {
- str = bundle_get_val(kb, AUL_SVC_K_LAUNCH_MODE);
- if (str != NULL && strcmp(str, "group") == 0)
- return true;
- } else if (mode != NULL && strcmp(mode, "group") == 0) {
- return true;
- }
-
- return false;
-}
-
-static void __rua_data_remove_comp_id(rua_data_t *rua)
-{
- if (!rua || !rua->comp_id)
- return;
-
- free(rua->comp_id);
- rua->comp_id = NULL;
-}
-
-static void __rua_data_remove_arg(rua_data_t *rua)
-{
- if (!rua || !rua->arg)
- return;
-
- free(rua->arg);
- rua->arg = NULL;
-}
-
-static void __rua_data_remove_uri(rua_data_t *rua)
-{
- if (!rua || !rua->uri)
- return;
-
- free(rua->uri);
- rua->uri = NULL;
-}
-
-static void __rua_data_remove_icon(rua_data_t *rua)
-{
- if (!rua || !rua->icon)
- return;
-
- free(rua->icon);
- rua->icon = NULL;
-}
-
-static void __rua_data_remove_instance_name(rua_data_t *rua)
-{
- if (!rua || !rua->instance_name)
- return;
-
- free(rua->instance_name);
- rua->instance_name = NULL;
-}
-
-static void __rua_data_remove_instance_id(rua_data_t *rua)
-{
- if (!rua || !rua->instance_id)
- return;
-
- free(rua->instance_id);
- rua->instance_id = NULL;
-}
-
-static void __rua_data_remove_app_path(rua_data_t *rua)
-{
- if (!rua || !rua->app_path)
- return;
-
- free(rua->app_path);
- rua->app_path = NULL;
-}
-
-static void __rua_data_remove_app_id(rua_data_t *rua)
-{
- if (!rua || !rua->app_id)
- return;
-
- free(rua->app_id);
- rua->app_id = NULL;
-}
-
-static void __rua_data_remove_stat_caller(rua_data_t *rua)
-{
- if (!rua || !rua->stat_caller)
- return;
-
- free(rua->stat_caller);
- rua->stat_caller = NULL;
-}
-
-static void __rua_data_remove_stat_tag(rua_data_t *rua)
-{
- if (!rua || !rua->stat_tag)
- return;
-
- free(rua->stat_tag);
- rua->stat_tag = NULL;
-}
-
-static int __rua_data_add_comp_id(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- amd_app_type_e app_type;
- const char *comp_id;
- bundle *kb;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type != AMD_AT_COMPONENT_BASED_APP)
- return 0;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Failed to get bundle");
- return -1;
- }
-
- comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- if (!comp_id) {
- _E("Failed to get component ID");
- return -1;
- }
-
- rua->comp_id = strdup(comp_id);
- if (!rua->comp_id) {
- _E("Failed to duplicate component ID");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_arg(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- if (amd_request_get_len(req) <= 0)
- return 0;
-
- rua->arg = calloc(amd_request_get_len(req) + 1, sizeof(char));
- if (!rua->arg) {
- _E("Out of memory");
- return -1;
- }
-
- memcpy(rua->arg, amd_request_get_raw(req), amd_request_get_len(req));
-
- return 0;
-}
-
-static int __rua_data_add_group_mode(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- bundle *kb = amd_request_get_bundle(req);
- uid_t uid = amd_request_get_target_uid(req);
-
- rua->is_group_mode = __is_group_mode(kb, uid);
-
- return 0;
-}
-
-static int __rua_data_add_uri(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *uri = _rua_launch_context_get_uri();
-
- if (uri == NULL)
- return 0;
-
- rua->uri = strdup(uri);
- if (!rua->uri) {
- _E("Failed to duplicate uri");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_icon(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *icon = _rua_launch_context_get_icon();
-
- if (icon == NULL)
- return 0;
-
- rua->icon = strdup(icon);
- if (!rua->icon) {
- _E("Failed to duplicate icon");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_instance_name(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *instance_name = _rua_launch_context_get_name();
-
- if (instance_name == NULL)
- return 0;
-
- rua->instance_name = strdup(instance_name);
- if (!rua->instance_name) {
- _E("Failed to duplicate instance name");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_instance_id(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *inst_id = _rua_launch_context_get_id();
- amd_appinfo_h ai;
- const char *app_id;
- const char *multiple;
- uid_t uid;
-
- if (!inst_id) {
- uid = amd_app_status_get_uid(app_status);
- app_id = amd_app_status_get_appid(app_status);
- ai = amd_appinfo_find(uid, app_id);
- if (!ai) {
- _E("Failed to find appinfo");
- return -1;
- }
-
- multiple = amd_appinfo_get_value(ai, AMD_AIT_MULTI);
- if (multiple && !strcmp(multiple, "true"))
- inst_id = amd_app_status_get_instance_id(app_status);
- }
-
- if (inst_id) {
- rua->instance_id = strdup(inst_id);
- if (!rua->instance_id) {
- _E("Failed to duplicate instance ID");
- return -1;
- }
- }
-
- return 0;
-}
-
-static int __rua_data_add_app_path(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *app_path;
-
- app_path = amd_app_status_get_app_path(app_status);
- if (!app_path) {
- _E("Failed to get application path");
- return -1;
- }
-
- rua->app_path = strdup(app_path);
- if (!rua->app_path) {
- _E("Failed to duplicate application path");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_app_id(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *app_id;
-
- app_id = amd_app_status_get_appid(app_status);
- if (!app_id) {
- _E("Failed to get application ID");
- return -1;
- }
-
- rua->app_id = strdup(app_id);
- if (!rua->app_id) {
- _E("Failed to duplicate application ID");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_stat_caller(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *stat_caller;
- bundle *kb;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Failed to get bundle");
- return -1;
- }
-
- stat_caller = bundle_get_val(kb, AUL_SVC_K_RUA_STAT_CALLER);
- if (!stat_caller)
- return 0;
-
- rua->stat_caller = strdup(stat_caller);
- if (!rua->stat_caller) {
- _E("Failed to duplicate stat caller");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_stat_tag(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- const char *stat_tag;
- bundle *kb;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Failed to get bundle");
- return -1;
- }
-
- stat_tag = bundle_get_val(kb, AUL_SVC_K_RUA_STAT_TAG);
- if (!stat_tag)
- return 0;
-
- rua->stat_tag = strdup(stat_tag);
- if (!rua->stat_tag) {
- _E("Failed to duplicate stat tag");
- return -1;
- }
-
- return 0;
-}
-
-static int __rua_data_add_uid(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- rua->uid = amd_request_get_target_uid(req);
-
- return 0;
-}
-
-static int __rua_data_add_pid(rua_data_t *rua, amd_request_h req,
- amd_app_status_h app_status)
-{
- rua->pid = amd_app_status_get_pid(app_status);
-
- return 0;
-}
-
-static rua_data_vft __rua_data_table[] = {
- { __rua_data_add_pid, NULL },
- { __rua_data_add_uid, NULL },
- { __rua_data_add_stat_tag, __rua_data_remove_stat_tag },
- { __rua_data_add_stat_caller, __rua_data_remove_stat_caller },
- { __rua_data_add_app_id, __rua_data_remove_app_id },
- { __rua_data_add_app_path, __rua_data_remove_app_path },
- { __rua_data_add_instance_id, __rua_data_remove_instance_id },
- { __rua_data_add_instance_name, __rua_data_remove_instance_name },
- { __rua_data_add_icon, __rua_data_remove_icon },
- { __rua_data_add_uri, __rua_data_remove_uri },
- { __rua_data_add_group_mode, NULL },
- { __rua_data_add_arg, __rua_data_remove_arg },
- { __rua_data_add_comp_id, __rua_data_remove_comp_id },
-};
-
-static void __destroy_rua_data(void *data)
-{
- rua_data_t *rua = data;
- int i;
-
- if (!rua)
- return;
-
- for (i = 0; i < ARRAY_SIZE(__rua_data_table); ++i) {
- if (__rua_data_table[i].dtor)
- __rua_data_table[i].dtor(rua);
- }
-
- free(rua);
-}
-
-static rua_data_t *__create_rua_data(amd_request_h req, pid_t pid)
-{
- amd_app_status_h app_status;
- rua_data_t *rua;
- int ret;
- int i;
-
- if (!req) {
- _E("Invalid parameter");
- return NULL;
- }
-
- app_status = amd_app_status_find_by_pid(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return NULL;
- }
-
- rua = calloc(1, sizeof(rua_data_t));
- if (!rua) {
- _E("Out of memory");
- return NULL;
- }
-
- for (i = 0; i < ARRAY_SIZE(__rua_data_table); ++i) {
- if (__rua_data_table[i].ctor) {
- ret = __rua_data_table[i].ctor(rua, req, app_status);
- if (ret < 0) {
- __destroy_rua_data(rua);
- return NULL;
- }
- }
- }
-
- return rua;
-}
-
-static const char *__get_instance_id(pid_t pid)
-{
- amd_app_status_h app_status;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (!app_status)
- return NULL;
-
- return amd_app_status_get_instance_id(app_status);
-}
-
-static gboolean __add_history_handler(gpointer user_data)
-{
- rua_data_t *rua = (rua_data_t *)user_data;
- struct rua_rec rec = { 0, };
- const char *image;
- const char *instance_id;
- int ret;
-
- if (!rua)
- return G_SOURCE_REMOVE;
-
- if (!rua->is_group_mode) {
- rec.pkg_name = rua->app_id;
- rec.app_path = rua->app_path;
- rec.arg = rua->arg;
- rec.launch_time = time(NULL);
- rec.instance_id = rua->instance_id;
- rec.instance_name = rua->instance_name;
- rec.icon = rua->icon;
- rec.uri = rua->uri;
-
- instance_id = rua->instance_id;
- if (!instance_id)
- instance_id = __get_instance_id(rua->pid);
-
- image = _rua_info_get_image(instance_id);
- if (image)
- rec.image = (char *)image;
-
- ret = rua_usr_db_add_history(&rec, rua->uid);
- if (ret < 0)
- _W("Failed to add rua history");
-
- SECURE_LOGD("RUA history added. app_id(%s) app_path(%s)",
- rec.pkg_name, rec.app_path);
- }
-
- if (rua->stat_caller && rua->stat_tag) {
- ret = rua_stat_usr_db_update(rua->stat_caller, rua->stat_tag,
- rua->uid);
- if (ret < 0)
- _W("Failed to update rua stat");
-
- SECURE_LOGD("RUA stat updated. caller(%s), tag(%s)",
- rua->stat_caller, rua->stat_tag);
- }
-
- __destroy_rua_data(rua);
-
- return G_SOURCE_REMOVE;
-}
-
-static bool __user_exist(uid_t uid)
-{
- struct rua_context_s *context = __get_context();
- GList *iter;
- uid_t u;
-
- iter = context->user_list;
- while (iter) {
- u = GPOINTER_TO_UINT(iter->data);
- if (u == uid)
- return true;
-
- iter = g_list_next(iter);
- }
-
- return false;
-}
-
-static void __user_add(uid_t uid)
-{
- struct rua_context_s *context = __get_context();
-
- context->user_list = g_list_append(context->user_list,
- GUINT_TO_POINTER(uid));
-}
-
-static void __user_remove(uid_t uid)
-{
- struct rua_context_s *context = __get_context();
-
- context->user_list = g_list_remove(context->user_list,
- GUINT_TO_POINTER(uid));
-}
-
-static int __reply_foreach_cb(const char *key, void *user_data)
-{
- if (key && !strcmp(key, "rua") && user_data) {
- g_timeout_add(RUA_TIMEOUT, __add_history_handler, user_data);
- return 0;
- }
-
- return -1;
-}
-
-static int __on_request_user_init(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
-
- _I("user(%u)", uid);
-
- if (__user_exist(uid))
- return AMD_NOTI_CONTINUE;
-
- rua_usr_db_delete_history(NULL, uid);
- __user_add(uid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_login_monitor_user_logout(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
-
- _I("user(%u)", uid);
-
- __user_remove(uid);
- _rua_info_remove(NULL, uid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_status(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- const char *instance_id;
- const char *comp_id = NULL;
- const char *pkg_name = NULL;
- uid_t target_uid;
- int ret;
- amd_app_status_h status = arg3;
- amd_comp_status_h comp_status;
- amd_app_type_e app_type = amd_app_status_get_app_type(status);
-
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- instance_id = amd_app_status_get_instance_id(status);
- comp_status = amd_comp_status_find_by_instance_id(instance_id);
- if (comp_status == NULL) {
- _E("Fail to get comp status (%s)", instance_id);
- return AMD_NOTI_CONTINUE;
- }
- comp_id = amd_comp_status_get_comp_id(comp_status);
- }
-
- pkg_name = amd_app_status_get_pkgid(status);
- target_uid = amd_app_status_get_uid(status);
- ret = rua_usr_db_update_history(pkg_name, comp_id, time(NULL), target_uid);
- if (ret < 0)
- _W("Failed to update rua history");
- SECURE_LOGI("[__RUA_INFO__] Updated. pkg_name(%s), comp_id(%s)",
- pkg_name, comp_id);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_app_start_pend(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- pid_t pid = (pid_t)arg1;
- bool bg_launch = (bool)arg2;
- amd_request_h req = (amd_request_h)arg3;
- amd_request_reply_h reply = (amd_request_reply_h)data;
- rua_data_t *rua = NULL;
- bundle *kb;
- int ret;
-
- if (!bg_launch) {
- kb = amd_request_get_bundle(req);
- ret = amd_noti_send(AMD_NOTI_MSG_RUA_SAVE_CRITICAL, 0, 0,
- req, kb);
- if (ret == 0) {
- rua = __create_rua_data(req, pid);
- if (rua && !rua->is_group_mode)
- _rua_info_add(kb, pid);
- }
- }
-
- _rua_launch_context_free();
- if (rua) {
- amd_request_reply_add_extra(reply, "rua",
- rua, __destroy_rua_data);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_app_start_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- pid_t pid = (pid_t)arg1;
- bool bg_launch = (bool)arg2;
- amd_request_h req = (amd_request_h)arg3;
- bundle *kb = data;
- rua_data_t *rua = NULL;
- amd_app_status_h app_status;
- int ret;
-
- if (pid > 0 && !bg_launch) {
- ret = amd_noti_send(AMD_NOTI_MSG_RUA_SAVE_CRITICAL, 0, 0,
- req, kb);
- if (ret == 0) {
- rua = __create_rua_data(req, pid);
- if (!rua) {
- _rua_launch_context_free();
- return AMD_NOTI_STOP;
- }
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status != NULL) {
- if (amd_app_status_is_running(app_status))
- __add_history_handler(rua);
- } else {
- g_timeout_add(RUA_TIMEOUT,
- __add_history_handler, rua);
- }
- }
- }
-
- _rua_launch_context_free();
-
- return AMD_NOTI_CONTINUE;
-}
-
-static void __rua_image_monitor_event_cb(const char *image, void *user_data)
-{
- _rua_info_update_image(image);
-}
-
-static int __on_launch_app_startup_signal_end(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- int pid = arg1;
-
- amd_request_reply_foreach_extra(pid, __reply_foreach_cb);
-
- return AMD_NOTI_CONTINUE;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int ret;
-
- _D("RUA Initialize");
-
- ret = _rua_launch_context_init();
- if (ret < 0)
- return ret;
-
- ret = _rua_request_init();
- if (ret < 0)
- return ret;
-
- ret = _rua_info_init();
- if (ret < 0)
- return ret;
-
- _rua_image_monitor_set_event_cb(__rua_image_monitor_event_cb, NULL);
-
- ret = _rua_image_monitor_init();
- if (ret < 0)
- return ret;
-
- amd_noti_listen(AMD_NOTI_MSG_REQUEST_USER_INIT,
- __on_request_user_init);
- amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
- __on_login_monitor_user_logout);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_PEND,
- __on_launch_app_start_pend);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_END,
- __on_launch_app_start_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END,
- __on_launch_app_startup_signal_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
- __on_launch_status);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("RUA Finalize");
-
- _rua_image_monitor_fini();
- _rua_info_fini();
- _rua_request_fini();
- _rua_launch_context_fini();
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <amd.h>
-
-#include "amd_rua_image_monitor.h"
-#include "amd_rua_private.h"
-
-#define PATH_RUN "/run"
-#define FILE_E_IMG ".e-img"
-#define PATH_RUN_E_IMG PATH_RUN "/" FILE_E_IMG
-
-struct rua_image_monitor_s {
- amd_inotify_watch_info_h directory_create;
- amd_inotify_watch_info_h image_create;
- amd_inotify_watch_info_h image_close_write;
- rua_image_monitor_event_cb callback;
- void *user_data;
-};
-
-static struct rua_image_monitor_s *__get_monitor(void)
-{
- static struct rua_image_monitor_s inst;
-
- return &inst;
-}
-
-void _rua_image_monitor_clear_all(void)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- char buf[PATH_MAX];
- struct stat statbuf;
- int r;
-
- dp = opendir(PATH_RUN_E_IMG);
- if (dp == NULL)
- return;
-
- while ((dentry = readdir(dp))) {
- if (!strcmp(dentry->d_name, ".") ||
- !strcmp(dentry->d_name, ".."))
- continue;
-
- snprintf(buf, sizeof(buf), "%s/%s",
- PATH_RUN_E_IMG, dentry->d_name);
- r = stat(buf, &statbuf);
- if (r == 0) {
- if (S_ISREG(statbuf.st_mode))
- unlink(buf);
- }
- }
-
- closedir(dp);
-}
-
-void _rua_image_monitor_clear(const char *image)
-{
- if (!image)
- return;
-
- unlink(image);
-}
-
-static void __foreach_images(void)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
- DIR *dp;
- struct dirent *dentry;
- char buf[PATH_MAX];
- struct stat statbuf;
- int r;
-
- if (!monitor->callback)
- return;
-
- dp = opendir(PATH_RUN_E_IMG);
- if (dp == NULL)
- return;
-
- while ((dentry = readdir(dp))) {
- if (!strcmp(dentry->d_name, ".") ||
- !strcmp(dentry->d_name, ".."))
- continue;
-
- snprintf(buf, sizeof(buf), "%s/%s",
- PATH_RUN_E_IMG, dentry->d_name);
- r = stat(buf, &statbuf);
- if (r == 0) {
- if (S_ISREG(statbuf.st_mode))
- monitor->callback(buf, monitor->user_data);
- }
- }
- closedir(dp);
-}
-
-static bool __on_image_create(const char *event_name, void *user_data)
-{
- if (event_name)
- _D("%s created", event_name);
-
- return true;
-}
-
-static bool __on_image_close_write(const char *event_name,
- void *user_data)
-{
- struct rua_image_monitor_s *monitor = user_data;
- char path[PATH_MAX];
-
- if (event_name) {
- snprintf(path, sizeof(path), "%s/%s",
- PATH_RUN_E_IMG, event_name);
- if (monitor->callback)
- monitor->callback(path, monitor->user_data);
-
- _D("%s opened for writing was closed ", event_name);
- }
-
- return true;
-}
-
-static void __fini_rua_image_monitor(void)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
-
- if (monitor->image_close_write) {
- amd_inotify_rm_watch(monitor->image_close_write);
- monitor->image_close_write = NULL;
- }
-
- if (monitor->image_create) {
- amd_inotify_rm_watch(monitor->image_create);
- monitor->image_create = NULL;
- }
-}
-
-static int __init_rua_image_monitor(void)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
-
- monitor->image_create = amd_inotify_add_watch(PATH_RUN_E_IMG,
- IN_CREATE, __on_image_create, monitor);
- if (!monitor->image_create)
- _W("Failed to add inotify watch %s", PATH_RUN_E_IMG);
-
- monitor->image_close_write = amd_inotify_add_watch(PATH_RUN_E_IMG,
- IN_CLOSE_WRITE, __on_image_close_write, monitor);
- if (!monitor->image_close_write) {
- _E("Failed to add inotify watch %s", PATH_RUN_E_IMG);
- return -1;
- }
-
- __foreach_images();
-
- return 0;
-}
-
-static bool __on_directory_create(const char *event_name, void *user_data)
-{
- struct rua_image_monitor_s *monitor = user_data;
-
- if (!event_name) {
- _E("Invalid parameter");
- return true;
- }
-
- if (!strcmp(event_name, FILE_E_IMG)) {
- __init_rua_image_monitor();
- monitor->directory_create = NULL;
- return false;
- }
-
- return true;
-}
-
-int _rua_image_monitor_set_event_cb(rua_image_monitor_event_cb callback,
- void *user_data)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
-
- if (!callback) {
- _E("Invalid parameter");
- return -1;
- }
-
- monitor->callback = callback;
- monitor->user_data = user_data;
-
- return 0;
-}
-
-int _rua_image_monitor_init(void)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
- int ret;
-
- _D("RUA Image Monitor Initialize");
-
- ret = access(PATH_RUN_E_IMG, F_OK);
- if (ret < 0) {
- _W("Failed to access %s", PATH_RUN_E_IMG);
- monitor->directory_create = amd_inotify_add_watch(PATH_RUN,
- IN_CREATE, __on_directory_create, monitor);
- if (!monitor->directory_create) {
- _E("Failed to add inotify watch %s", PATH_RUN);
- return -1;
- }
-
- return 0;
- }
-
- ret = __init_rua_image_monitor();
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void _rua_image_monitor_fini(void)
-{
- struct rua_image_monitor_s *monitor = __get_monitor();
-
- _D("RUA Image Monitor Finalize");
-
- __fini_rua_image_monitor();
-
- if (monitor->directory_create) {
- amd_inotify_rm_watch(monitor->directory_create);
- monitor->directory_create = NULL;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <rua_internal.h>
-#include <rua_stat_internal.h>
-#include <amd.h>
-
-#include "amd_rua_info.h"
-#include "amd_rua_image_monitor.h"
-#include "amd_rua_private.h"
-
-struct rua_info_s {
- char *key;
- pid_t pid;
- uid_t uid;
- char *app_id;
- char *app_path;
- char *instance_id;
- char *image_path;
- char *temp_path;
- char *comp_id;
- GList *wid_list;
-};
-
-struct rua_info_context_s {
- GHashTable *table;
-};
-
-typedef bool (*rua_info_foreach_remove_cb)(struct rua_info_s *info,
- void *user_data);
-
-static struct rua_info_context_s *__get_context(void)
-{
- static struct rua_info_context_s inst;
-
- return &inst;
-}
-
-static void __destroy_rua_info(gpointer data)
-{
- struct rua_info_s *info = (struct rua_info_s *)data;
-
- if (info == NULL)
- return;
-
- if (info->wid_list)
- g_list_free(info->wid_list);
-
- if (info->temp_path) {
- _rua_image_monitor_clear(info->temp_path);
- free(info->temp_path);
- }
-
- if (info->image_path) {
- _rua_image_monitor_clear(info->image_path);
- free(info->image_path);
- }
-
- if (info->comp_id)
- free(info->comp_id);
-
- if (info->instance_id)
- free(info->instance_id);
-
- if (info->app_path)
- free(info->app_path);
-
- if (info->app_id)
- free(info->app_id);
-
- if (info->key)
- free(info->key);
-
- free(info);
-}
-
-static struct rua_info_s *__create_rua_info(const char *key,
- const char *app_id, const char *app_path,
- const char *instance_id, const char *comp_id,
- pid_t pid, uid_t uid)
-{
- struct rua_info_s *info;
-
- info = calloc(1, sizeof(struct rua_info_s));
- if (info == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- info->key = strdup(key);
- if (!info->key) {
- _E("Failed to duplicate key");
- __destroy_rua_info(info);
- return NULL;
- }
-
- info->app_id = strdup(app_id);
- if (!info->app_id) {
- _E("Failed to duplicate application ID");
- __destroy_rua_info(info);
- return NULL;
- }
-
- info->app_path = strdup(app_path);
- if (!info->app_path) {
- _E("Failed to duplicate application path");
- __destroy_rua_info(info);
- return NULL;
- }
-
- if (instance_id) {
- info->instance_id = strdup(instance_id);
- if (!info->instance_id) {
- _E("Failed to duplicate instance ID");
- __destroy_rua_info(info);
- return NULL;
- }
- }
-
- if (comp_id) {
- info->comp_id = strdup(comp_id);
- if (!info->comp_id) {
- _E("Failed to duplicate component ID");
- __destroy_rua_info(info);
- return NULL;
- }
- }
-
- info->pid = pid;
- info->uid = uid;
-
- return info;
-}
-
-static gint __compare_wid(gconstpointer a, gconstpointer b)
-{
- int wid1 = GPOINTER_TO_INT(a);
- int wid2 = GPOINTER_TO_INT(b);
-
- if (wid1 == wid2)
- return 0;
-
- return -1;
-}
-
-static struct rua_info_s *__rua_info_find_by_wid(int wid)
-{
- struct rua_info_context_s *context = __get_context();
- struct rua_info_s *info;
- GHashTableIter iter;
- gpointer key;
- gpointer value;
- GList *found;
-
- g_hash_table_iter_init(&iter, context->table);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- info = (struct rua_info_s *)value;
- if (!info || !info->wid_list)
- continue;
-
- found = g_list_find_custom(info->wid_list, GINT_TO_POINTER(wid),
- __compare_wid);
- if (found)
- return info;
- }
-
- return NULL;
-}
-
-static struct rua_info_s *__rua_info_find_by_instance_id(const char *id)
-{
- struct rua_info_context_s *context = __get_context();
- struct rua_info_s *info;
-
- info = (struct rua_info_s *)g_hash_table_lookup(context->table, id);
- if (info)
- return info;
-
- return NULL;
-}
-
-static struct rua_info_s *__rua_info_find(int pid)
-{
- struct rua_info_context_s *context = __get_context();
- struct rua_info_s *info;
- GHashTableIter iter;
- gpointer key;
- gpointer value;
-
- g_hash_table_iter_init(&iter, context->table);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- info = (struct rua_info_s *)value;
- if (!info)
- continue;
-
- if (info->pid == pid)
- return info;
- }
-
- return NULL;
-}
-
-static bool __has_taskmanage(amd_app_status_h app_status, bundle *kb, uid_t uid)
-{
- amd_app_type_e app_type;
- amd_compinfo_h ci;
- amd_appinfo_h ai;
- const char *taskmanage;
- const char *comp_id;
- const char *app_id;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- if (!comp_id) {
- _E("Failed to get component ID");
- return false;
- }
-
- ci = amd_compinfo_find(uid, comp_id);
- if (!ci) {
- _E("Failed to find compinfo");
- return false;
- }
-
- taskmanage = amd_compinfo_get_value(ci,
- AMD_COMPINFO_TYPE_TASKMANAGE);
- } else {
- app_id = amd_app_status_get_appid(app_status);
- if (!app_id) {
- _E("Failed to get application ID");
- return false;
- }
-
- ai = amd_appinfo_find(uid, app_id);
- if (!ai) {
- _E("Failed to find appinfo");
- return false;
- }
-
- taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
- }
-
- if (taskmanage && !strcmp(taskmanage, "true"))
- return true;
-
- return false;
-}
-
-static bool __can_have_window(amd_app_status_h app_status,
- const char *instance_id)
-{
- amd_comp_status_h comp_status;
- amd_comp_type_e comp_type;
- amd_app_type_e app_type;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_UI_APP)
- return true;
-
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- comp_status = amd_comp_status_find_by_instance_id(instance_id);
- if (!comp_status) {
- _W("Failed to find comp status");
- return false;
- }
-
- comp_type = amd_comp_status_get_comp_type(comp_status);
- if (comp_type == AMD_CT_FRAME_COMP)
- return true;
- }
-
- return false;
-}
-
-static gboolean __foreach_remove_by_rua_info(gpointer key, gpointer value,
- gpointer user_data)
-{
- struct rua_info_s *info = (struct rua_info_s *)value;
- struct rua_info_s *new_info = (struct rua_info_s *)user_data;
-
- if (info->uid == new_info->uid &&
- !strcmp(info->app_id, new_info->app_id)) {
- if (info->instance_id && new_info->instance_id &&
- !strcmp(info->instance_id, new_info->instance_id))
- return TRUE;
- else if (!info->instance_id && !new_info->instance_id)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean __foreach_remove_by_uid(gpointer key, gpointer value,
- gpointer data)
-{
- struct rua_info_s *info = (struct rua_info_s *)value;
- uid_t uid = GPOINTER_TO_UINT(data);
-
- if (info->uid == uid)
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean __foreach_remove_by_app_id(gpointer key, gpointer value,
- gpointer data)
-{
- struct rua_info_s *info = (struct rua_info_s *)value;
- const char *app_id = (const char *)data;
-
- if (!strcmp(info->app_id, app_id))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean __foreach_remove_by_app_path(gpointer key, gpointer value,
- gpointer data)
-{
- struct rua_info_s *info = (struct rua_info_s *)value;
- const char *app_path = (const char *)data;
-
- if (!strcmp(info->app_path, app_path))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean __foreach_remove_by_instance_id(gpointer key, gpointer value,
- gpointer data)
-{
- struct rua_info_s *info = (struct rua_info_s *)value;
- const char *instance_id = (const char *)data;
-
- if (info->instance_id && !strcmp(info->instance_id, instance_id))
- return TRUE;
-
- return FALSE;
-}
-
-int _rua_info_add(bundle *kb, pid_t pid)
-{
- struct rua_info_context_s *context = __get_context();
- struct rua_info_s *info;
- amd_app_status_h app_status;
- amd_app_type_e app_type;
- const char *instance_id;
- const char *app_path;
- const char *comp_id;
- const char *app_id;
- const char *key;
- uid_t uid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return -1;
- }
-
- instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- if (instance_id)
- key = instance_id;
- else
- key = amd_app_status_get_instance_id(app_status);
-
- if (!key) {
- _E("key is nullptr");
- return -1;
- }
-
- if (!__can_have_window(app_status, instance_id)) {
- _D("The instance cannot have a window");
- return 0;
- }
-
- uid = amd_app_status_get_uid(app_status);
- if (!__has_taskmanage(app_status, kb, uid)) {
- _W("The instance isn't managed by taskmanager");
- return 0;
- }
-
- app_path = amd_app_status_get_app_path(app_status);
- app_id = amd_app_status_get_appid(app_status);
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_COMPONENT_BASED_APP)
- comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- else
- comp_id = NULL;
-
- info = __create_rua_info(key, app_id, app_path, instance_id, comp_id,
- pid, uid);
- if (!info)
- return -1;
-
- g_hash_table_foreach_remove(context->table,
- __foreach_remove_by_rua_info, info);
-
- if (g_hash_table_contains(context->table, key))
- g_hash_table_replace(context->table, info->key, info);
- else
- g_hash_table_insert(context->table, info->key, info);
-
- return 0;
-}
-
-int _rua_info_remove(bundle *kb, uid_t uid)
-{
- struct rua_info_context_s *context = __get_context();
- const char *instance_id = NULL;
- const char *app_path = NULL;
- const char *app_id = NULL;
-
- if (kb) {
- app_id = bundle_get_val(kb, AUL_K_RUA_PKGNAME);
- app_path = bundle_get_val(kb, AUL_K_RUA_APPPATH);
- instance_id = bundle_get_val(kb, AUL_K_RUA_INSTANCE_ID);
- }
-
- if (app_id) {
- g_hash_table_foreach_remove(context->table,
- __foreach_remove_by_app_id,
- (void *)app_id);
- } else if (app_path) {
- g_hash_table_foreach_remove(context->table,
- __foreach_remove_by_app_path,
- (void *)app_path);
- } else if (instance_id) {
- g_hash_table_foreach_remove(context->table,
- __foreach_remove_by_instance_id,
- (void *)instance_id);
- } else {
- g_hash_table_foreach_remove(context->table,
- __foreach_remove_by_uid,
- GUINT_TO_POINTER(uid));
- _rua_image_monitor_clear_all();
- }
-
- return 0;
-}
-
-int _rua_info_update_image(const char *image)
-{
- struct rua_info_s *info;
- char *file;
- int pid = -1;
- int wid = 0;
- int num = -1;
- int ret;
-
- file = basename(image);
- if (!file) {
- _E("Failed to get basename. image(%s)", image);
- return -1;
- }
-
- ret = sscanf(file, "win_%d_%d-%d.png", &pid, &wid, &num);
- if (ret != 3) {
- _E("Failed to parse image file");
- return -1;
- }
-
- info = __rua_info_find_by_wid(wid);
- if (!info) {
- _W("Unknown wid(%d)", wid);
- info = __rua_info_find(pid);
- }
-
- if (!info) {
- _E("Failed to find rua info. %s will be deleted", image);
- _rua_image_monitor_clear(image);
- return -1;
- }
-
- if (info->image_path) {
- if (!strcmp(info->image_path, image))
- return 0;
-
- if (info->temp_path && strcmp(info->temp_path, image) != 0) {
- _rua_image_monitor_clear(info->temp_path);
- free(info->temp_path);
- }
-
- info->temp_path = info->image_path;
- }
-
- ret = rua_usr_db_update_image(info->app_id, info->comp_id,
- info->instance_id, image, info->uid);
- if (ret < 0) {
- SECURE_LOGW("Failed to update image path(%s). instance(%s)",
- image, info->instance_id);
- }
-
- info->image_path = strdup(image);
- if (!info->image_path) {
- _E("Failed to duplicate image path(%s)", image);
- return -1;
- }
- SECURE_LOGI("[__RUA_INFO__] Updated. instance(%s), update(%s)",
- info->instance_id, info->image_path);
-
- return 0;
-}
-
-const char *_rua_info_get_image(const char *instance_id)
-{
- struct rua_info_s *info;
-
- if (!instance_id)
- return NULL;
-
- info = __rua_info_find_by_instance_id(instance_id);
- if (!info)
- return NULL;
-
- return info->image_path;
-}
-
-static int __on_app_group_window_set(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- int wid = arg2;
- const char *instance_id = (const char *)instance_id;
- amd_app_status_h app_status;
- amd_comp_status_h comp_status;
- const char *leader_id;
- struct rua_info_s *info;
-
- if (instance_id) {
- comp_status = amd_comp_status_find_by_instance_id(instance_id);
- if (!comp_status) {
- _W("Failed to find comp status");
- return AMD_NOTI_STOP;
- }
-
- leader_id = amd_comp_status_get_leader_id(comp_status);
- } else {
- app_status = amd_app_status_find_by_pid(pid);
- if (!app_status) {
- _W("Failed to find app status. pid(%d)", pid);
- return AMD_NOTI_STOP;
- }
-
- instance_id = amd_app_status_get_instance_id(app_status);
- leader_id = amd_app_status_get_leader_id(app_status);
- }
-
- if (leader_id)
- instance_id = leader_id;
-
- info = __rua_info_find_by_instance_id(instance_id);
- if (!info)
- info = __rua_info_find(pid);
-
- if (!info) {
- SECURE_LOGW("Failed to find rua info. instance(%s)",
- instance_id);
- return AMD_NOTI_CONTINUE;
- }
-
- info->wid_list = g_list_append(info->wid_list, GINT_TO_POINTER(wid));
- SECURE_LOGI("[__RUA_INFO__] instance(%s), wid(%d)", instance_id, wid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_app_group_destroy_app_group_context(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- int wid = arg2;
- struct rua_info_s *info;
-
- info = __rua_info_find_by_wid(wid);
- if (!info)
- return AMD_NOTI_CONTINUE;
-
- info->wid_list = g_list_remove(info->wid_list, GINT_TO_POINTER(wid));
-
- return AMD_NOTI_CONTINUE;
-}
-
-int _rua_info_init(void)
-{
- struct rua_info_context_s *context = __get_context();
-
- _D("RUA Info Initialize");
-
- context->table = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, __destroy_rua_info);
- if (!context->table) {
- _E("Out of memory");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET,
- __on_app_group_window_set);
- amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT,
- __on_app_group_destroy_app_group_context);
-
- return 0;
-}
-
-void _rua_info_fini(void)
-{
- struct rua_info_context_s *context = __get_context();
-
- _D("RUA Info Finalize");
-
- if (context->table) {
- g_hash_table_destroy(context->table);
- context->table = NULL;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <rua_internal.h>
-#include <rua_stat_internal.h>
-#include <aul.h>
-#include <amd.h>
-
-#include "amd_rua_launch_context.h"
-#include "amd_rua_private.h"
-
-#define MULTI_INSTANCE_SHORTCUT "multi-instance-shortcut"
-#define QUERY_KEY_ID "id="
-#define QUERY_KEY_ICON "icon="
-#define QUERY_KEY_NAME "name="
-#define AUL_SVC_K_URI "__APP_SVC_URI__"
-#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
-
-struct rua_launch_context_s {
- char *id;
- char *name;
- char *icon;
- char *uri;
-};
-
-static struct rua_launch_context_s *__get_launch_context(void)
-{
- static struct rua_launch_context_s context;
-
- return &context;
-}
-
-const char *_rua_launch_context_get_id(void)
-{
- struct rua_launch_context_s *info = __get_launch_context();
-
- return info->id;
-}
-
-const char *_rua_launch_context_get_name(void)
-{
- struct rua_launch_context_s *info = __get_launch_context();
-
- return info->name;
-}
-
-const char *_rua_launch_context_get_icon(void)
-{
- struct rua_launch_context_s *info = __get_launch_context();
-
- return info->icon;
-}
-
-const char *_rua_launch_context_get_uri(void)
-{
- struct rua_launch_context_s *info = __get_launch_context();
-
- return info->uri;
-}
-
-void _rua_launch_context_free(void)
-{
- struct rua_launch_context_s *info = __get_launch_context();
-
- if (info->uri) {
- free(info->uri);
- info->uri = NULL;
- }
-
- if (info->id) {
- free(info->id);
- info->id = NULL;
- }
-
- if (info->icon) {
- free(info->icon);
- info->icon = NULL;
- }
-
- if (info->name) {
- free(info->name);
- info->name = NULL;
- }
-}
-
-static char *__get_value_from_query(const char *src, const char *key)
-{
- int src_len = strlen(src);
- int key_len = strlen(key);
-
- if (src_len > key_len) {
- if (strncmp(src, key, key_len) == 0)
- return g_uri_unescape_string(src + key_len, NULL);
- }
-
- return NULL;
-}
-
-static int __set_launch_context(bundle *kb)
-{
- struct rua_launch_context_s *info = __get_launch_context();
- const char *uri;
- gchar *scheme;
- gchar *query;
- char *token;
- char *saveptr = NULL;
- char *dup_uri;
-
- uri = bundle_get_val(kb, AUL_SVC_K_URI);
- if (uri == NULL)
- return -1;
-
- scheme = g_uri_parse_scheme(uri);
- if (scheme == NULL)
- return -1;
-
- if (strcmp(scheme, MULTI_INSTANCE_SHORTCUT) != 0) {
- g_free(scheme);
- return -1;
- }
- g_free(scheme);
-
- dup_uri = strdup(uri);
- if (dup_uri == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- info->uri = strdup(uri);
- if (info->uri == NULL) {
- _E("Out of memory");
- free(dup_uri);
- return -1;
- }
-
- query = index(dup_uri, '?');
- if (query == NULL) {
- _rua_launch_context_free();
- free(dup_uri);
- return -1;
- }
-
- token = strtok_r(query + 1, "&", &saveptr);
- while (token != NULL) {
- if (info->id == NULL) {
- info->id = __get_value_from_query(token,
- QUERY_KEY_ID);
- }
-
- if (info->icon == NULL) {
- info->icon = __get_value_from_query(token,
- QUERY_KEY_ICON);
- }
-
- if (info->name == NULL) {
- info->name = __get_value_from_query(token,
- QUERY_KEY_NAME);
- }
-
- token = strtok_r(NULL, "&", &saveptr);
- }
- free(dup_uri);
-
- if (info->id == NULL || info->icon == NULL || info->name == NULL) {
- _W("Failed to get instance info");
- _rua_launch_context_free();
- return -1;
- }
-
- return 0;
-}
-
-int _rua_launch_context_set(bundle *kb)
-{
- struct rua_launch_context_s *info = __get_launch_context();
- const char *instance_id;
- int ret;
-
- ret = __set_launch_context(kb);
- if (ret == 0) {
- bundle_del(kb, AUL_K_INSTANCE_ID);
- bundle_add(kb, AUL_K_INSTANCE_ID, info->id);
- bundle_del(kb, AUL_K_NEW_INSTANCE);
- bundle_add(kb, AUL_K_NEW_INSTANCE, "true");
- bundle_del(kb, AUL_K_MULTI_INSTANCE_SHORTCUT);
- bundle_add(kb, AUL_K_MULTI_INSTANCE_SHORTCUT, "true");
- _D("Multiple instance launch - id(%s), name(%s), icon(%s)",
- info->id, info->name, info->icon);
- return 0;
- }
-
- instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- if (!instance_id)
- return 0;
-
- info->id = strdup(instance_id);
- if (!info->id) {
- _W("Out of memory");
- return -1;
- }
-
- _D("Multiple instance launch - id(%s)", info->id);
-
- return 0;
-}
-
-static int __on_launch_app_start_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_request_h req = (amd_request_h)arg3;
- bundle *kb = data;
- const char *launch_mode;
- uid_t uid;
-
- launch_mode = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
- if (launch_mode && strcmp(launch_mode, "single")) {
- uid = amd_request_get_target_uid(req);
- if (!amd_launch_mode_is_group_mode(kb, uid))
- bundle_del(kb, AUL_K_INSTANCE_ID);
- }
-
- _rua_launch_context_free();
- _rua_launch_context_set(data);
-
- return AMD_NOTI_CONTINUE;
-}
-
-int _rua_launch_context_init(void)
-{
- _D("RUA Launch Context Initialize");
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_START,
- __on_launch_app_start_start);
-
- return 0;
-}
-
-void _rua_launch_context_fini(void)
-{
- _D("RUA Launch Context Finalize");
-
- _rua_launch_context_free();
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <rua_internal.h>
-#include <rua_stat_internal.h>
-#include <aul.h>
-#include <amd.h>
-
-#include "amd_rua_request.h"
-#include "amd_rua_info.h"
-#include "amd_rua_private.h"
-
-static int __dispatch_update_rua_stat(amd_request_h req)
-{
- char *caller = NULL;
- char *tag = NULL;
- bundle *kb;
- uid_t uid;
- int ret;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Invalid request");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_SVC_K_RUA_STAT_CALLER, &caller);
- bundle_get_str(kb, AUL_SVC_K_RUA_STAT_TAG, &tag);
-
- uid = amd_request_get_target_uid(req);
- ret = rua_stat_usr_db_update(caller, tag, uid);
- amd_request_send_result(req, ret);
- _D("rua_stat_usr_db_update - uid(%d), result(%d)", uid, ret);
-
- return 0;
-}
-
-static int __dispatch_add_history(amd_request_h req)
-{
- struct rua_rec rec = {0,};
- char *time_str = NULL;
- bundle *kb;
- uid_t uid;
- int ret;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Invalid request");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_RUA_PKGNAME, &rec.pkg_name);
- bundle_get_str(kb, AUL_K_RUA_APPPATH, &rec.app_path);
- bundle_get_str(kb, AUL_K_RUA_ARG, &rec.arg);
- bundle_get_str(kb, AUL_K_RUA_TIME, &time_str);
- if (time_str != NULL)
- rec.launch_time = atoi(time_str);
- else
- rec.launch_time = (int)time(NULL);
- bundle_get_str(kb, AUL_K_RUA_INSTANCE_ID, &rec.instance_id);
- bundle_get_str(kb, AUL_K_RUA_INSTANCE_NAME, &rec.instance_name);
- bundle_get_str(kb, AUL_K_RUA_ICON, &rec.icon);
- bundle_get_str(kb, AUL_K_RUA_URI, &rec.uri);
-
- uid = amd_request_get_target_uid(req);
- ret = rua_usr_db_add_history(&rec, uid);
- amd_request_send_result(req, ret);
- LOGD("rua_usr_db_add_history - uid(%d), result(%d)", uid, ret);
-
- return 0;
-}
-
-static int __dispatch_remove_history(amd_request_h req)
-{
- bundle *kb;
- uid_t uid;
- int ret;
-
- kb = amd_request_get_bundle(req);
- if (!kb) {
- _E("Invalid request");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- uid = amd_request_get_target_uid(req);
- ret = rua_usr_db_delete_history(kb, uid);
- amd_request_send_result(req, ret);
-
- _rua_info_remove(kb, uid);
- LOGD("rua_usr_db_delete_history - uid(%d), result(%d)", uid, ret);
-
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_UPDATE_RUA_STAT,
- .callback = __dispatch_update_rua_stat
- },
- {
- .cmd = APP_ADD_HISTORY,
- .callback = __dispatch_add_history
- },
- {
- .cmd = APP_REMOVE_HISTORY,
- .callback = __dispatch_remove_history
- },
-
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_UPDATE_RUA_STAT,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
- {
- .cmd = APP_ADD_HISTORY,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
- {
- .cmd = APP_REMOVE_HISTORY,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
-};
-
-int _rua_request_init(void)
-{
- int ret;
-
- _D("RUA Request Initialize");
-
- ret = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- ret = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-void _rua_request_fini(void)
-{
- _D("RUA Request Finalize");
-
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_SCREEN_RESOLUTION "amd-mod-screen-resolution")
-SET(AMD_MOD_SCREEN_RESOLUTION_DIR ${CMAKE_SOURCE_DIR}/modules/screen-resolution)
-PROJECT(${AMD_MOD_SCREEN_RESOLUTION} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_SCREEN_RESOLUTION_DIR}/src AMD_MOD_SCREEN_RESOLUTION_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_SCREEN_RESOLUTION_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- bundle
- wayland-client
- tizen-extension-client
- wayland-tbm-client
- tizen-launch-client
- capi-system-info
- )
-
-pkg_check_modules(amd_mod_screen_resolution_pkgs REQUIRED ${AMD_MOD_SCREEN_RESOLUTION_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_screen_resolution_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_SCREEN_RESOLUTION_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_SCREEN_RESOLUTION} ${AMD_MOD_SCREEN_RESOLUTION_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_SCREEN_RESOLUTION} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_SCREEN_RESOLUTION} ${amd_mod_screen_resolution_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_SCREEN_RESOLUTION} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
-INSTALL(FILES ${AMD_MOD_SCREEN_RESOLUTION_DIR}/conf/amd_screen_resolution.conf DESTINATION ${AMD_MODULES_DIR}/conf)
+++ /dev/null
-[Screen Resolution]
-responsive
-4k_only
-2k_only
-1k_only
-4k
-2k
-1k
-max
-
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include <amd.h>
-#include <amd_mod_common.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <bundle_internal.h>
-#include <tizen-extension-client-protocol.h>
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-#include <tzplatform_config.h>
-#include <tizen-launch-client-protocol.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_SCREEN_RESOLUTION"
-
-struct wayland_context_s {
- struct wl_display *display;
- struct tizen_launch_appinfo *launch_appinfo;
- uint32_t launch_appinfo_id;
-};
-
-static struct wayland_context_s __context;
-
-static int __launch_appinfo_register_appid(const char *appid)
-{
- if (!__context.display) {
- __context.display = amd_wayland_get_display();
- if (!__context.display) {
- LOGW("Failed to get wayland display");
- return -1;
- }
- }
-
- if (!__context.launch_appinfo) {
- LOGW("Failed to bind tizen launch appinfo");
- return -1;
- }
-
- tizen_launch_appinfo_register_appid(__context.launch_appinfo,
- appid);
- wl_display_flush(__context.display);
- LOGI("Register appid: %s", appid);
-
- return 0;
-}
-
-static int __launch_appinfo_deregister_appid(const char *appid)
-{
- if (!__context.display) {
- __context.display = amd_wayland_get_display();
- if (!__context.display) {
- LOGW("Failed to get wayland display");
- return -1;
- }
- }
-
- if (!__context.launch_appinfo) {
- LOGW("Failed to bind tizen launch appinfo");
- return -1;
- }
-
- tizen_launch_appinfo_deregister_appid(__context.launch_appinfo, appid);
- wl_display_flush(__context.display);
- LOGI("Deregister appid: %s", appid);
-
- return 0;
-}
-
-static int __launch_appinfo_launch_app(const char *appid, int pid)
-{
- if (!appid || pid < 0) {
- LOGE("Invalid parameter");
- return -1;
- }
-
- if (!__context.display) {
- __context.display = amd_wayland_get_display();
- if (!__context.display) {
- LOGW("Failed to get wayland display");
- return -1;
- }
- }
-
- if (!__context.launch_appinfo) {
- LOGW("Failed to bind tizen launch appinfo");
- return -1;
- }
-
- tizen_launch_appinfo_set_pid(__context.launch_appinfo,
- appid, (uint32_t)pid);
- tizen_launch_appinfo_ready_metadata(__context.launch_appinfo,
- appid, (uint32_t)pid);
- wl_display_flush(__context.display);
- LOGI("Launch app. %s:%d", appid, pid);
-
- return 0;
-}
-
-static int __on_wayland_listener_tizen_launch_appinfo(const char *msg,
- int arg1, int arg2, void *arg3, bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
- struct wl_registry *registry = (struct wl_registry *)arg3;
-
- if (!__context.launch_appinfo) {
- __context.launch_appinfo_id = id;
- __context.launch_appinfo = wl_registry_bind(registry, id,
- &tizen_launch_appinfo_interface, 1);
- LOGI("tizen_launch_appinfo(%p), id(%u)",
- __context.launch_appinfo, id);
- }
-
- if (!__context.display)
- __context.display = amd_wayland_get_display();
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_wayland_listener_remove(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
-
- if (id == __context.launch_appinfo_id && __context.launch_appinfo) {
- tizen_launch_appinfo_destroy(__context.launch_appinfo);
- __context.launch_appinfo = NULL;
- __context.launch_appinfo_id = 0;
- LOGW("tizen_launch_appinfo is destroyed");
- }
-
- return AMD_NOTI_CONTINUE;
-}
-static int __on_launch_prepare_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comp_type;
- const char *appid;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
- appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
- LOGI("prepare start appid: %s", appid);
- __launch_appinfo_register_appid(appid);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- bool new_process = (bool)arg2;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comp_type;
- const char *appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
-
- if (!new_process)
- return AMD_NOTI_CONTINUE;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
- LOGI("complete start app end pid: %d", pid);
- __launch_appinfo_launch_app(appid, pid);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_main_app_dead(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_app_status_h app_status = arg3;
- const char *appid = amd_app_status_get_appid(app_status);
- int app_type = amd_app_status_get_app_type(app_status);
-
- if (app_type != AMD_AT_SERVICE_APP)
- __launch_appinfo_deregister_appid(appid);
-
- LOGI("main app dead: %s", appid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- LOGD("screen resolution init");
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_APPINFO,
- __on_wayland_listener_tizen_launch_appinfo);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
- __on_wayland_listener_remove);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
- __on_launch_prepare_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- __on_launch_complete_start);
- amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
- __on_main_app_dead);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- LOGD("screen resolution fini");
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_SHARE "amd-mod-share")
-SET(AMD_MOD_SHARE_DIR ${CMAKE_SOURCE_DIR}/modules/share)
-PROJECT(${AMD_MOD_SHARE} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_SHARE_DIR}/src AMD_MOD_SHARE_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_SHARE_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- bundle
- libtzplatform-config
- security-manager
- )
-
-pkg_check_modules(amd_mod_share_pkgs REQUIRED ${AMD_MOD_SHARE_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_share_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_SHARE_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_SHARE} ${AMD_MOD_SHARE_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_SHARE} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_SHARE} ${amd_mod_share_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_SHARE} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2016 - 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.
- */
-
-#define _GNU_SOURCE
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <linux/limits.h>
-
-#include <glib.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_svc.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <tzplatform_config.h>
-#include <security-manager.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_SHARE"
-
-#define LEGACY_APP_PATH "/opt/usr/apps/"
-#define AUL_SVC_K_URI "__APP_SVC_URI__"
-#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
-
-typedef struct _shared_info_t {
- char *owner_appid;
- private_sharing_req *handle;
-} shared_info_t;
-
-struct shared_info_main_s {
- char *appid;
- uid_t uid;
- shared_info_t *shared_info;
-};
-
-typedef struct shared_info_main_s *shared_info_h;
-
-static shared_info_h __cur_shared_info;
-static int __temporary_permission_destroy(shared_info_h handle);
-
-static int __can_share(const char *path, const char *pkgid, uid_t uid)
-{
- struct stat path_stat;
- char buf[PATH_MAX];
-
- if (stat(path, &path_stat) != 0) {
- _E("failed to stat file to share (%s, %d)", path, errno);
- return -1;
- }
-
- if (!S_ISREG(path_stat.st_mode)) {
- _E("file is not a regular file (%s)", path);
- return -1;
- }
-
- tzplatform_set_user(uid);
- snprintf(buf, sizeof(buf), "%s/%s/data/",
- tzplatform_getenv(TZ_USER_APP), pkgid);
- tzplatform_reset_user();
-
- if (strncmp(path, buf, strlen(buf)) != 0) {
- SECURE_LOGD("file is not in app's data directory (%s)", path);
- return -1;
- }
-
- return 0;
-}
-
-static int __get_owner_pid(int caller_pid, bundle *kb)
-{
- char *org_caller = NULL;
- const char *appid;
- int org_caller_pid;
- amd_app_status_h app_status;
- int ret;
-
- ret = bundle_get_str(kb, AUL_K_ORG_CALLER_PID, &org_caller);
- if (ret != BUNDLE_ERROR_NONE)
- return caller_pid;
-
- org_caller_pid = atoi(org_caller);
- app_status = amd_app_status_find_by_pid(caller_pid);
- appid = amd_app_status_get_appid(app_status);
- if (appid && (strcmp(APP_SELECTOR, appid) == 0 ||
- strcmp(SHARE_PANEL, appid) == 0))
- caller_pid = org_caller_pid;
-
- return caller_pid;
-}
-
-static const char *__get_owner_appid(int caller_pid, bundle *kb)
-{
- const char *owner_appid;
- int owner_pid = -1;
- amd_app_status_h app_status;
-
- owner_pid = __get_owner_pid(caller_pid, kb);
- owner_pid = getpgid(owner_pid); /* for webapp */
- app_status = amd_app_status_find_by_pid(owner_pid);
- owner_appid = amd_app_status_get_appid(app_status);
-
- return owner_appid;
-}
-
-static shared_info_h __new_shared_info_handle(const char *appid, uid_t uid,
- const char *owner_appid)
-{
- shared_info_h h;
- int ret;
-
- h = malloc(sizeof(struct shared_info_main_s));
- if (h == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- h->shared_info = malloc(sizeof(shared_info_t));
- if (h->shared_info == NULL) {
- _E("Out of memory");
- free(h);
- return NULL;
- }
-
- ret = security_manager_private_sharing_req_new(&h->shared_info->handle);
- if (ret != SECURITY_MANAGER_SUCCESS) {
- _E("Failed to create private sharing request handle");
- free(h->shared_info);
- free(h);
- return NULL;
- }
-
- h->shared_info->owner_appid = strdup(owner_appid);
- if (h->shared_info->owner_appid == NULL) {
- _E("Out of memory");
- security_manager_private_sharing_req_free(
- h->shared_info->handle);
- free(h->shared_info);
- free(h);
- return NULL;
- }
-
- h->appid = strdup(appid);
- if (h->appid == NULL) {
- _E("Out of memory");
- free(h->shared_info->owner_appid);
- security_manager_private_sharing_req_free(
- h->shared_info->handle);
- free(h->shared_info);
- free(h);
- return NULL;
- }
- h->uid = uid;
-
- return h;
-}
-
-static char *__convert_legacy_path(const char *path, uid_t uid)
-{
- char buf[PATH_MAX];
- int len = strlen(LEGACY_APP_PATH);
-
- if (strncmp(LEGACY_APP_PATH, path, len) == 0) {
- tzplatform_set_user(uid);
- snprintf(buf, sizeof(buf), "%s/%s",
- tzplatform_getenv(TZ_USER_APP), &path[len]);
- tzplatform_reset_user();
-
- return strdup(buf);
- }
-
- return strdup(path);
-}
-
-static GList *__add_valid_uri(GList *paths, int caller_pid, const char *appid,
- const char *owner_appid, bundle *kb, uid_t uid)
-{
- char *path = NULL;
- const char *pkgid;
- amd_appinfo_h ai;
- int ret;
-
- ret = bundle_get_str(kb, AUL_SVC_K_URI, &path);
- if (ret != BUNDLE_ERROR_NONE)
- return paths;
-
- if (!path) {
- _D("path was null");
- return paths;
- }
-
- if (strncmp(path, "file://", 7) == 0) {
- path = &path[7];
- } else {
- _E("file wasn't started with file://");
- return paths;
- }
-
- ai = amd_appinfo_find(uid, owner_appid);
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
-
- path = __convert_legacy_path(path, uid);
- if (__can_share(path, pkgid, uid) != 0) {
- _E("__can_share() returned an error");
- free(path);
- return paths;
- }
- paths = g_list_append(paths, path);
-
- return paths;
-}
-
-static GList *__add_valid_key_for_data_selected(GList *paths, int caller_pid,
- const char *appid, const char *owner_appid, bundle *kb,
- uid_t uid)
-{
- int i;
- int len = 0;
- const char **path_array = NULL;
- char *path_str;
- int type = bundle_get_type(kb, AUL_SVC_DATA_SELECTED);
- const char *pkgid = NULL;
- amd_appinfo_h ai = NULL;
-
- if (type != BUNDLE_TYPE_STR_ARRAY)
- return paths;
-
- path_array = bundle_get_str_array(kb, AUL_SVC_DATA_SELECTED, &len);
- if (!path_array || len <= 0) {
- _E("path_array was null");
- return paths;
- }
-
- ai = amd_appinfo_find(uid, owner_appid);
- if (ai == NULL) {
- _E("appinfo is NULL");
- return paths;
- }
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- if (pkgid == NULL) {
- _E("pkgid was null");
- return paths;
- }
-
- for (i = 0; i < len; i++) {
- path_str = __convert_legacy_path(path_array[i], uid);
- if (__can_share(path_str, pkgid, uid) == 0)
- paths = g_list_append(paths, path_str);
- else
- free(path_str);
- }
-
- return paths;
-}
-
-static GList *__add_valid_key_for_data_path(GList *paths, int caller_pid,
- const char *appid, const char *owner_appid, bundle *kb,
- uid_t uid)
-{
- int type = bundle_get_type(kb, AUL_SVC_DATA_PATH);
- char *path = NULL;
- const char **path_array = NULL;
- int len;
- int i;
- const char *pkgid = NULL;
- amd_appinfo_h ai = NULL;
- char *path_str;
-
- switch (type) {
- case BUNDLE_TYPE_STR:
- bundle_get_str(kb, AUL_SVC_DATA_PATH, &path);
- if (!path) {
- _E("path was null");
- break;
- }
-
- ai = amd_appinfo_find(uid, owner_appid);
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- if (pkgid == NULL) {
- _E("pkgid was null");
- break;
- }
-
- path = __convert_legacy_path(path, uid);
- if (__can_share(path, pkgid, uid) != 0) {
- _E("__can_share() returned an error");
- free(path);
- break;
- }
-
- paths = g_list_append(paths, path);
- break;
- case BUNDLE_TYPE_STR_ARRAY:
- path_array = bundle_get_str_array(kb, AUL_SVC_DATA_PATH, &len);
- if (!path_array || len <= 0) {
- _E("path_array was null");
- break;
- }
-
- ai = amd_appinfo_find(uid, owner_appid);
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- if (pkgid == NULL) {
- _E("pkgid was null");
- break;
- }
-
- for (i = 0; i < len; i++) {
- path_str = __convert_legacy_path(path_array[i], uid);
- if (__can_share(path_str, pkgid, uid) == 0)
- paths = g_list_append(paths, path_str);
- else
- free(path_str);
- }
-
- break;
- }
-
- return paths;
-}
-
-static char **__convert_list_to_array(GList *list)
-{
- int len;
- int i = 0;
- char **array;
-
- if (list == NULL)
- return NULL;
-
- len = g_list_length(list);
- if (len == 0)
- return NULL;
-
- array = (char **)g_malloc0(sizeof(char *) * (len + 1));
- if (array == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- while (list) {
- array[i] = g_strdup(list->data);
- if (array[i] == NULL) {
- _E("Out of memory");
- g_strfreev(array);
- return NULL;
- }
-
- list = g_list_next(list);
- i++;
- }
- array[len] = NULL;
-
- return array;
-}
-
-static int __destroy_status(amd_app_status_h status)
-{
- GList *list;
- GList *i;
- shared_info_t *shared_info;
-
- if (!status)
- return -1;
-
- list = amd_app_status_get_extra(status, "share");
- if (!list)
- return -1;
-
- i = list;
- while (i) {
- shared_info = (shared_info_t *)i->data;
- if (shared_info) {
- if (shared_info->owner_appid)
- free(shared_info->owner_appid);
- free(shared_info);
- }
- i = g_list_next(i);
- }
-
- g_list_free(list);
- amd_app_status_remove_extra(status, "share");
-
- return 0;
-}
-
-static shared_info_h __temporary_permission_create(int caller_pid, const char *appid,
- bundle *kb, uid_t uid)
-{
- char **path_array = NULL;
- int len;
- const char *owner_appid = NULL;
- GList *paths = NULL;
- shared_info_h h = NULL;
- int r;
-
- owner_appid = __get_owner_appid(caller_pid, kb);
- paths = __add_valid_key_for_data_path(paths, caller_pid, appid,
- owner_appid, kb, uid);
- paths = __add_valid_key_for_data_selected(paths, caller_pid, appid,
- owner_appid, kb, uid);
- paths = __add_valid_uri(paths, caller_pid, appid, owner_appid, kb, uid);
- if (!paths || !owner_appid)
- goto clear;
-
- _D("grant permission %s : %s", owner_appid, appid);
-
- h = __new_shared_info_handle(appid, uid, owner_appid);
- if (h == NULL)
- goto clear;
-
- len = g_list_length(paths);
- path_array = __convert_list_to_array(paths);
- if (path_array == NULL)
- goto clear;
-
- r = security_manager_private_sharing_req_set_owner_appid(
- h->shared_info->handle, owner_appid);
- if (r != SECURITY_MANAGER_SUCCESS)
- _E("Failed to set owner appid(%s) %d", owner_appid, r);
-
- r = security_manager_private_sharing_req_set_target_appid(
- h->shared_info->handle, appid);
- if (r != SECURITY_MANAGER_SUCCESS)
- _E("Failed to set target appid(%s) %d", appid, r);
-
- r = security_manager_private_sharing_req_add_paths(
- h->shared_info->handle, (const char **)path_array, len);
- if (r != SECURITY_MANAGER_SUCCESS)
- _E("Failed to add paths %d", r);
-
- _D("security_manager_private_sharing_apply ++");
- r = security_manager_private_sharing_apply(h->shared_info->handle);
- _D("security_manager_private_sharing_apply --");
- if (r != SECURITY_MANAGER_SUCCESS) {
- _E("Failed to apply private sharing %d", r);
- __temporary_permission_destroy(h);
- h = NULL;
- }
-
-clear:
- if (paths)
- g_list_free_full(paths, free);
-
- if (path_array)
- g_strfreev(path_array);
-
- return h;
-}
-
-static int __temporary_permission_apply(int pid, uid_t uid, shared_info_h handle)
-{
- amd_app_status_h status;
- GList *list;
-
- if (handle == NULL)
- return -1;
-
- status = amd_app_status_find_by_pid(pid);
- if (status == NULL)
- return -1;
-
- list = amd_app_status_get_extra(status, "share");
- list = g_list_append(list, handle->shared_info);
- amd_app_status_set_extra(status, "share", list);
- handle->shared_info = NULL;
-
- return 0;
-}
-
-static int __temporary_permission_destroy(shared_info_h handle)
-{
- int r;
-
- if (handle == NULL)
- return -1;
-
- if (handle->shared_info) { /* back out */
- _D("revoke permission %s : %s",
- handle->shared_info->owner_appid,
- handle->appid);
- r = security_manager_private_sharing_drop(
- handle->shared_info->handle);
- if (r != SECURITY_MANAGER_SUCCESS)
- _E("revoke error %d", r);
-
- security_manager_private_sharing_req_free(
- handle->shared_info->handle);
- free(handle->shared_info->owner_appid);
- }
-
- free(handle->appid);
- free(handle);
-
- return 0;
-}
-
-static int __temporary_permission_drop(int pid, uid_t uid)
-{
- int r;
- shared_info_t *sit;
- amd_app_status_h app_status;
- GList *list;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL)
- return -1;
-
- list = amd_app_status_get_extra(app_status, "share");
- if (!list) {
- _D("list was null");
- return -1;
- }
-
- while (list) {
- sit = (shared_info_t *)list->data;
- _D("revoke permission %s : %d", sit->owner_appid, pid);
- r = security_manager_private_sharing_drop(sit->handle);
- if (r != SECURITY_MANAGER_SUCCESS)
- _E("revoke error %d", r);
- security_manager_private_sharing_req_free(sit->handle);
- list = g_list_next(list);
- }
-
- return __destroy_status(app_status);
-}
-
-static int __temporary_permission_drop_with_owner(const char *owner_appid,
- int pid, uid_t uid)
-{
- shared_info_t *shared_info;
- amd_app_status_h app_status;
- GList *list;
- GList *iter;
- int ret;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL)
- return -1;
-
- list = amd_app_status_get_extra(app_status, "share");
- if (!list) {
- _D("list was null");
- return -1;
- }
-
- iter = list;
- while (iter) {
- shared_info = (shared_info_t *)iter->data;
- iter = g_list_next(iter);
- if (!strcmp(shared_info->owner_appid, owner_appid)) {
- list = g_list_remove(list, shared_info);
- _D("Revoke permission %s : %d",
- shared_info->owner_appid, pid);
- ret = security_manager_private_sharing_drop(shared_info->handle);
- if (ret != SECURITY_MANAGER_SUCCESS)
- _E("Revoke error %d", ret);
-
- security_manager_private_sharing_req_free(shared_info->handle);
- free(shared_info->owner_appid);
- free(shared_info);
- }
- }
-
- if (list)
- amd_app_status_set_extra(app_status, "share", list);
- else
- amd_app_status_remove_extra(app_status, "share");
-
- return 0;
-}
-
-static int __on_app_result_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- char *appid = arg3;
- int pid = arg1;
- uid_t uid = arg2;
-
- if (appid) {
- __cur_shared_info = __temporary_permission_create(pid, appid, data, uid);
- if (__cur_shared_info == NULL)
- _D("No sharable path : %d %s", pid, appid);
- }
-
- return 0;
-}
-
-static int __on_app_result_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = arg2;
- int res = GPOINTER_TO_INT(arg3);
- int ret;
-
- if (__cur_shared_info) {
- if (res >= 0) {
- ret = __temporary_permission_apply(pid, uid, __cur_shared_info);
- if (ret != 0) {
- _D("Couldn't apply temporary permission: %d",
- ret);
- }
- }
- __temporary_permission_destroy(__cur_shared_info);
- __cur_shared_info = NULL;
- }
-
- return 0;
-}
-
-static int __on_launch_prepare_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int caller_pid = arg1;
- uid_t target_uid = arg2;
- const char *appid;
- amd_appinfo_h ai = arg3;
- amd_app_status_h status;
- const char *caller_appid;
-
- appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
- status = amd_app_status_find_by_pid(caller_pid);
- caller_appid = amd_app_status_get_appid(status);
-
- if (caller_appid) {
- __cur_shared_info = __temporary_permission_create(caller_pid,
- appid, data, target_uid);
- if (__cur_shared_info == NULL)
- _W("No sharable path: %d %s", caller_pid, appid);
- }
-
- return 0;
-}
-
-static int __on_launch_complete_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t target_uid = arg2;
- int ret;
-
- if (__cur_shared_info) {
- ret = __temporary_permission_apply(pid, target_uid,
- __cur_shared_info);
- if (ret < 0)
- _D("Couldn't apply temporary permission: %d", ret);
-
- __temporary_permission_destroy(__cur_shared_info);
- __cur_shared_info = NULL;
- }
-
- return 0;
-}
-
-static int __on_launch_cancel(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- if (__cur_shared_info) {
- __temporary_permission_destroy(__cur_shared_info);
- __cur_shared_info = NULL;
- }
-
- return 0;
-}
-
-static int __on_app_status_destroy(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h status = arg3;
-
- __destroy_status(status);
-
- return 0;
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = arg2;
-
- __temporary_permission_drop(pid, uid);
-
- return 0;
-}
-
-static int __dispatch_set_private_sharing(amd_request_h req)
-{
- uid_t target_uid = amd_request_get_target_uid(req);
- int caller_pid = amd_request_get_pid(req);
- int callee_pid;
- bundle *data = amd_request_get_bundle(req);
- const char *callee_appid;
- const char *caller_appid;
- amd_app_status_h caller_app_status;
- amd_app_status_h callee_app_status;
- int ret;
-
- if (data == NULL)
- return -1;
-
- caller_app_status = amd_app_status_find_by_pid(caller_pid);
- caller_appid = amd_app_status_get_appid(caller_app_status);
- callee_appid = bundle_get_val(data, AUL_K_CALLEE_APPID);
- shared_info_h info = __temporary_permission_create(caller_pid,
- callee_appid, data, target_uid);
- if (info == NULL) {
- _W("No sharable path: %d %s", caller_pid, caller_appid);
- return -1;
- }
-
- callee_app_status = amd_app_status_find_by_appid(callee_appid, target_uid);
- callee_pid = amd_app_status_get_pid(callee_app_status);
- ret = __temporary_permission_apply(callee_pid, target_uid, info);
- if (ret != 0) {
- _E("Couldn't apply temporary permission: %d",
- ret);
- }
- __temporary_permission_destroy(info);
- _I("caller(%s), callee(%s), result(%d)",
- caller_appid, callee_appid, ret);
-
- return ret;
-}
-
-static int __dispatch_unset_private_sharing(amd_request_h req)
-{
- const char *callee_appid;
- const char *caller_appid;
- int callee_pid;
- amd_app_status_h callee_app_status;
- amd_app_status_h caller_app_status;
- int caller_pid = amd_request_get_pid(req);
- uid_t target_uid = amd_request_get_target_uid(req);
- bundle *data = amd_request_get_bundle(req);
-
- caller_app_status = amd_app_status_find_by_pid(caller_pid);
- caller_appid = amd_app_status_get_appid(caller_app_status);
- callee_appid = bundle_get_val(data, AUL_K_CALLEE_APPID);
- callee_app_status = amd_app_status_find_by_appid(callee_appid, target_uid);
- callee_pid = amd_app_status_get_pid(callee_app_status);
-
- __temporary_permission_drop_with_owner(caller_appid, callee_pid, target_uid);
-
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = SET_PRIVATE_SHARING,
- .callback = __dispatch_set_private_sharing
- },
- {
- .cmd = UNSET_PRIVATE_SHARING,
- .callback = __dispatch_unset_private_sharing
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = SET_PRIVATE_SHARING,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_DATASHARING,
- .priority = 10
- },
-};
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- _D("share init");
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register cynara checkers");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_RESULT_START,
- __on_app_result_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_RESULT_END,
- __on_app_result_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
- __on_launch_prepare_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
- __on_launch_complete_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
- __on_launch_cancel);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL,
- __on_launch_cancel);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_DESTROY,
- __on_app_status_destroy);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("share finish");
-}
-
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_SPLASH_SCREEN "amd-mod-splash-screen")
-SET(AMD_MOD_SPLASH_SCREEN_DIR ${CMAKE_SOURCE_DIR}/modules/splash-screen)
-PROJECT(${AMD_MOD_SPLASH_SCREEN} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_SPLASH_SCREEN_DIR}/src AMD_MOD_SPLASH_SCREEN_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_SPLASH_SCREEN_PKG_CHECK_MODULES
- aul
- dlog
- bundle
- sensor
- glib-2.0
- gio-2.0
- wayland-client
- wayland-tbm-client
- tizen-extension-client
- tizen-launch-client
- capi-system-info
- )
-
-PKG_CHECK_MODULES(amd_mod_splash_screen_pkgs REQUIRED ${AMD_MOD_SPLASH_SCREEN_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_splash_screen_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_SPLASH_SCREEN_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_SPLASH_SCREEN} ${AMD_MOD_SPLASH_SCREEN_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_SPLASH_SCREEN} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_SPLASH_SCREEN} ${amd_mod_splash_screen_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_SPLASH_SCREEN} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdbool.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <glib.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_svc.h>
-#include <aul_svc_priv_key.h>
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-#include <tizen-launch-client-protocol.h>
-#include <vconf.h>
-#include <sensor_internal.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_SPLASH_SCREEN"
-
-#define APP_CONTROL_OPERATION_MAIN "http://tizen.org/appcontrol/operation/main"
-#define K_FAKE_EFFECT "__FAKE_EFFECT__"
-#define SPLASH_SCREEN_INFO_PATH "/usr/share/aul"
-#define TAG_SPLASH_IMAGE "[SplashImage]"
-#define TAG_NAME "Name"
-#define TAG_FILE "File"
-#define TAG_TYPE "Type"
-#define TAG_ORIENTATION "Orientation"
-#define TAG_INDICATOR_DISPLAY "Indicator-display"
-#define TAG_COLOR_DEPTH "Color-depth"
-#define TIMEOUT_INTERVAL 10000 /* 10 sec */
-#define CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_"
-
-#define TIZEN_FEATURE_CHARGER_STATUS \
- (amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_WEARABLE))
-#define TIZEN_FEATURE_AUTO_ROTATION \
- (!(amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_TV)))
-
-#define FREE_AND_NULL(x) \
- do { \
- if (x) { \
- free(x); \
- x = NULL; \
- } \
- } while (0)
-
-struct splash_image_s {
- struct tizen_launch_splash *image;
- char *appid;
- char *src;
- int type;
- int rotation;
- int indicator;
- int color_depth;
- int pid;
- bool custom_effect;
- char *effect_type;
- char *theme_type;
- guint timer;
-};
-
-struct rotation_s {
- sensor_t sensor;
- int handle;
- int angle;
- int auto_rotate;
- int charger_status;
- bool initialized;
- guint timer;
-};
-
-struct image_info_s {
- char *name;
- char *file;
- char *type;
- char *orientation;
- char *indicator_display;
- char *color_depth;
-};
-
-typedef struct splash_image_s *splash_image_h;
-static struct wl_display *display;
-static struct tizen_launch_effect *tz_launch_effect;
-static int splash_screen_initialized;
-static struct rotation_s rotation;
-static GList *default_image_list;
-static splash_image_h splash_image;
-static splash_image_h cur_splash_image;
-static uint32_t tz_launch_effect_id;
-
-static int __init_splash_screen(void);
-static int __init_rotation(void);
-
-static splash_image_h __splash_screen_get_image(int pid)
-{
- if (splash_image == NULL)
- return NULL;
-
- if (splash_image->pid == pid)
- return splash_image;
-
- return NULL;
-}
-
-static void __set_splash_image(splash_image_h si)
-{
- splash_image = si;
-}
-
-static void __splash_screen_destroy_image(splash_image_h si)
-{
- if (si == NULL)
- return;
-
- if (si->timer)
- g_source_remove(si->timer);
- if (si->theme_type)
- free(si->theme_type);
- if (si->effect_type)
- free(si->effect_type);
- if (si->appid)
- free(si->appid);
- if (si->src)
- free(si->src);
- if (si->image) {
- tizen_launch_splash_destroy(si->image);
- wl_display_flush(display);
- }
- free(si);
- __set_splash_image(NULL);
-}
-
-static gboolean __timeout_handler(gpointer data)
-{
- splash_image_h si = (splash_image_h)data;
- amd_app_status_h app_status;
-
- if (si == NULL)
- return FALSE;
-
- app_status = amd_app_status_find_by_pid(si->pid);
- if (app_status) {
- if (amd_app_status_is_starting(app_status) == false) {
- _W("% is not starting", si->pid);
- return TRUE;
- }
- }
-
- si->timer = 0;
- __splash_screen_destroy_image(si);
-
- return FALSE;
-}
-
-static int __app_can_launch_splash_image(amd_appinfo_h ai, bundle *kb)
-{
- const char *comp_type;
- const char *fake_effect;
- int display;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type == NULL || strcmp(comp_type, APP_TYPE_UI) != 0) {
- _D("component_type: %s", comp_type);
- return -1;
- }
-
- fake_effect = bundle_get_val(kb, K_FAKE_EFFECT);
- if (fake_effect && !strcmp(fake_effect, "OFF"))
- return -1;
-
- amd_appinfo_get_int_value(ai, AMD_AIT_SPLASH_SCREEN_DISPLAY, &display);
- if (!(display & APP_ENABLEMENT_MASK_ACTIVE))
- return -1;
-
- return 0;
-}
-
-static struct appinfo_splash_image *__get_splash_image_info(
- amd_appinfo_h ai, bundle *kb, int cmd)
-{
- amd_appinfo_h caller_ai;
- amd_appinfo_splash_image_h image;
- const char *operation;
- const char *uid_str;
- const char *caller_appid;
- const char *comp_type;
- uid_t uid = 0;
- bool landscape;
-
- if ((rotation.angle == 90 || rotation.angle == 270)
- && rotation.auto_rotate == true)
- landscape = true;
- else
- landscape = false;
-
- operation = bundle_get_val(kb, AUL_SVC_K_OPERATION);
- if (cmd == APP_OPEN || (operation &&
- (!strcmp(operation, APP_CONTROL_OPERATION_MAIN) ||
- !strcmp(operation, AUL_SVC_OPERATION_DEFAULT)))) {
- image = amd_appinfo_find_splash_image(ai, "launch-effect",
- landscape);
- if (image)
- return image;
- }
-
- if (operation) {
- image = amd_appinfo_find_splash_image(ai, operation, landscape);
- if (image)
- return image;
- }
-
- caller_appid = bundle_get_val(kb, AUL_K_CALLER_APPID);
- if (caller_appid == NULL)
- return NULL;
-
- uid_str = bundle_get_val(kb, AUL_K_TARGET_UID);
- if (uid_str == NULL)
- return NULL;
-
- if (isdigit(*uid_str))
- uid = atol(uid_str);
- caller_ai = amd_appinfo_find(uid, caller_appid);
- if (caller_ai == NULL)
- return NULL;
-
- comp_type = amd_appinfo_get_value(caller_ai, AMD_AIT_COMPTYPE);
- if (comp_type == NULL)
- return NULL;
-
- if (!strcmp(comp_type, APP_TYPE_WATCH) ||
- !strcmp(comp_type, APP_TYPE_WIDGET)) {
- return amd_appinfo_find_splash_image(ai, "launch-effect",
- landscape);
- }
-
- return NULL;
-}
-
-static struct image_info_s *__get_default_image_info(bundle *kb)
-{
- struct image_info_s *info = NULL;
- const char *orientation = "portrait";
- const char *str;
- GList *list;
-
- if (default_image_list == NULL)
- return NULL;
-
- if ((rotation.angle == 90 || rotation.angle == 270) &&
- rotation.auto_rotate == true)
- orientation = "landscape";
-
- str = bundle_get_val(kb, AUL_SVC_K_SPLASH_SCREEN);
- if (str == NULL)
- str = "default";
-
- list = default_image_list;
- while (list) {
- info = (struct image_info_s *)list->data;
- if (info && strcmp(str, info->name) == 0) {
- if (!strcasecmp(info->orientation, orientation))
- return info;
- }
-
- list = g_list_next(list);
- }
-
- return NULL;
-}
-
-static splash_image_h __splash_screen_create_image(amd_appinfo_h ai,
- bundle *kb, int cmd, bool is_subapp, bool custom_effect)
-{
- amd_appinfo_splash_image_h image_info;
- struct splash_image_s *si;
- struct image_info_s *info;
- const char *appid;
- const char *src = NULL;
- const char *type;
- int file_type = 0;
- int indicator = 1;
- int color_depth = 24; /* default */
-
- if (!splash_screen_initialized) {
- if (__init_splash_screen() < 0)
- return NULL;
- }
-
- if (__app_can_launch_splash_image(ai, kb) < 0)
- return NULL;
-
- if (TIZEN_FEATURE_CHARGER_STATUS) {
- if (rotation.charger_status) {
- if (!rotation.initialized && __init_rotation() < 0)
- _W("Failed to initialize rotation");
- }
- } else {
- if (!rotation.initialized && __init_rotation() < 0)
- _W("Failed to initialize rotation");
- }
- _D("angle: %d", rotation.angle);
-
- image_info = __get_splash_image_info(ai, kb, cmd);
- if (image_info) {
- src = amd_appinfo_splash_image_get_source(image_info);
- if (access(src, F_OK) != 0)
- return NULL;
- type = amd_appinfo_splash_image_get_type(image_info);
- if (type && strcasecmp(type, "edj") == 0)
- file_type = 1;
- indicator = amd_appinfo_splash_image_get_indicator_display(
- image_info);;
- color_depth = amd_appinfo_splash_image_get_color_depth(
- image_info);
- } else {
- info = __get_default_image_info(kb);
- if (info == NULL)
- return NULL;
- src = info->file;
- if (access(src, F_OK) != 0)
- return NULL;
- if (strcasecmp(info->type, "edj") == 0)
- file_type = 1;
- if (strcmp(info->indicator_display, "false") == 0)
- indicator = 0;
- if (strcmp(info->color_depth, "32") == 0)
- color_depth = 32;
- }
-
- si = (struct splash_image_s *)calloc(1, sizeof(struct splash_image_s));
- if (si == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- si->image = tizen_launch_effect_create_splash_img(
- tz_launch_effect);
- if (si->image == NULL) {
- _E("Failed to get launch image");
- free(si);
- return NULL;
- }
- wl_display_flush(display);
-
- si->src = strdup(src);
- if (si->src == NULL) {
- _E("out of memory");
- __splash_screen_destroy_image(si);
- return NULL;
- }
-
- if (is_subapp)
- si->effect_type = strdup("depth-in");
- else
- si->effect_type = strdup("launch");
- if (si->effect_type == NULL) {
- _E("Out of memory");
- __splash_screen_destroy_image(si);
- return NULL;
- }
-
- si->theme_type = strdup("default");
- if (si->theme_type == NULL) {
- _E("Out of memory");
- __splash_screen_destroy_image(si);
- return NULL;
- }
-
- appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
- si->appid = strdup(appid);
- if (si->appid == NULL) {
- _E("out of memory");
- __splash_screen_destroy_image(si);
- return NULL;
- }
-
- si->type = file_type;
- si->rotation = rotation.angle;
- si->indicator = indicator;
- si->color_depth = color_depth;
- si->custom_effect = custom_effect;
-
- si->timer = g_timeout_add(TIMEOUT_INTERVAL, __timeout_handler, si);
- __set_splash_image(si);
-
- return si;
-}
-
-static void __set_options(struct wl_array *options, const char *app_id)
-{
- bundle *b;
- bundle_raw *raw = NULL;
- int len = 0;
- int ret;
- size_t size;
- void *data;
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return;
- }
-
- bundle_add(b, AUL_K_APPID, app_id);
- ret = bundle_encode(b, &raw, &len);
- bundle_free(b);
- if (ret != BUNDLE_ERROR_NONE) {
- _E("Failed to encode bundle. error(%d)", ret);
- return;
- }
-
- size = strlen((const char *)raw) + 1;
- data = wl_array_add(options, size);
- memcpy(data, raw, size);
- free(raw);
-}
-
-static void __set_extra_config(struct wl_array *extra_config,
- const char *app_id)
-{
- int len;
- void *data;
-
- len = strlen(CUSTOM_EFFECT_CALLEE) + 1;
- data = wl_array_add(extra_config, len);
- memcpy(data, CUSTOM_EFFECT_CALLEE, len);
-
- len = strlen(app_id) + 1;
- data = wl_array_add(extra_config, len);
- memcpy(data, app_id, len);
-}
-
-static void __splash_screen_send_image(splash_image_h si)
-{
- struct wl_array options;
- struct wl_array extra_config;
-
- if (si == NULL || si->image == NULL)
- return;
-
- wl_array_init(&options);
- __set_options(&options, si->appid);
-
- wl_array_init(&extra_config);
- __set_extra_config(&extra_config, si->appid);
-
- _D("src(%s), type(%d), color-depth(%d), rotation(%d), " \
- "indicator(%d), effect_type(%s)",
- si->src, si->type, si->color_depth, si->rotation,
- si->indicator, si->effect_type);
- tizen_launch_splash_launch_v2(si->image, si->src, si->type,
- si->color_depth, si->rotation, si->indicator,
- si->effect_type, si->theme_type, &options,
- si->custom_effect ? &extra_config : NULL);
- wl_display_flush(display);
-
- wl_array_release(&extra_config);
- wl_array_release(&options);
-}
-
-static void __splash_screen_send_pid(splash_image_h si, int pid)
-{
- if (si == NULL)
- return;
-
- _D("pid(%d)", pid);
- si->pid = pid;
- tizen_launch_splash_owner(si->image, pid);
- wl_display_flush(display);
-}
-
-static void __splash_screen_set_effect_type(int pid, const char *appid, bool is_subapp)
-{
- struct wl_array options;
- bundle *b;
- bundle_raw *raw_data = NULL;
- int len = 0;
- int ret;
- size_t size;
- void *data;
- const char *effect_type;
-
- if (!splash_screen_initialized)
- return;
-
- wl_array_init(&options);
-
- if (is_subapp)
- effect_type = "depth-in";
- else
- effect_type = "launch";
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return;
- }
-
- bundle_add(b, AUL_K_APPID, appid);
- ret = bundle_encode(b, &raw_data, &len);
- if (ret != BUNDLE_ERROR_NONE) {
- _E("Failed to encode bundle");
- bundle_free(b);
- return;
- }
- bundle_free(b);
-
- size = strlen((const char *)raw_data);
- data = wl_array_add(&options, size + 1);
- memcpy(data, raw_data, size + 1);
- free(raw_data);
-
- _D("effect_type(%s), pid(%d)", effect_type, pid);
- tizen_launch_effect_type_set(tz_launch_effect, effect_type,
- pid, &options);
- wl_display_flush(display);
-
- wl_array_release(&options);
-}
-
-static int __init_splash_screen(void)
-{
- if (!display) {
- display = amd_wayland_get_display();
- if (!display) {
- _E("Failed to get display");
- return -1;
- }
- }
-
- if (!tz_launch_effect) {
- _E("Failed to bind tizen launch screen");
- return -1;
- }
-
- splash_screen_initialized = 1;
-
- return 0;
-}
-
-static void __rotation_changed_cb(sensor_t sensor, unsigned int event_type,
- sensor_data_t *data, void *user_data)
-{
- int event;
-
- if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
- return;
-
- event = (int)data->values[0];
- switch (event) {
- case AUTO_ROTATION_DEGREE_0:
- rotation.angle = 0;
- break;
- case AUTO_ROTATION_DEGREE_90:
- rotation.angle = 90;
- break;
- case AUTO_ROTATION_DEGREE_180:
- rotation.angle = 180;
- break;
- case AUTO_ROTATION_DEGREE_270:
- rotation.angle = 270;
- break;
- default:
- break;
- }
-
- _D("angle: %d", rotation.angle);
-}
-
-static void __auto_rotate_screen_cb(keynode_t *key, void *data)
-{
- rotation.auto_rotate = vconf_keynode_get_bool(key);
- if (!rotation.auto_rotate) {
- _D("auto_rotate: %d, angle: %d",
- rotation.auto_rotate, rotation.angle);
- }
-}
-
-static void __fini_rotation(void)
-{
- if (!rotation.initialized)
- return;
-
- if (!TIZEN_FEATURE_AUTO_ROTATION)
- return;
-
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
- __auto_rotate_screen_cb);
- sensord_unregister_event(rotation.handle,
- AUTO_ROTATION_CHANGE_STATE_EVENT);
- sensord_disconnect(rotation.handle);
- rotation.angle = 0;
-
- rotation.initialized = false;
-}
-
-static int __init_rotation(void)
-{
- int ret;
- bool r;
-
- if (!TIZEN_FEATURE_AUTO_ROTATION) {
- rotation.initialized = true;
- return 0;
- }
-
- if (!rotation.sensor) {
- rotation.sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
- if (!rotation.sensor) {
- _E("Failed to get sensor. errno(%d)", errno);
- return -1;
- }
- }
-
- rotation.angle = 0;
- rotation.handle = sensord_connect(rotation.sensor);
- if (rotation.handle < 0) {
- _W("Failed to connect sensord");
- return -1;
- }
-
- r = sensord_register_event(rotation.handle,
- AUTO_ROTATION_CHANGE_STATE_EVENT,
- SENSOR_INTERVAL_NORMAL,
- 0,
- __rotation_changed_cb,
- NULL);
- if (!r) {
- _W("Failed to register event");
- sensord_disconnect(rotation.handle);
- return -1;
- }
-
- r = sensord_start(rotation.handle, 0);
- if (!r) {
- _W("Failed to start sensord");
- sensord_unregister_event(rotation.handle,
- AUTO_ROTATION_CHANGE_STATE_EVENT);
- sensord_disconnect(rotation.handle);
- return -1;
- }
-
- ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
- &rotation.auto_rotate);
- if (ret != VCONF_OK)
- rotation.auto_rotate = false;
-
- ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
- __auto_rotate_screen_cb, NULL);
- if (ret != 0) {
- _W("Failed to register callback for %s",
- VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL);
- }
- rotation.initialized = true;
-
- return 0;
-}
-
-static void __destroy_image_info(struct image_info_s *info)
-{
- if (info == NULL)
- return;
-
- if (info->color_depth)
- free(info->color_depth);
- if (info->indicator_display)
- free(info->indicator_display);
- if (info->type)
- free(info->type);
- if (info->orientation)
- free(info->orientation);
- if (info->file)
- free(info->file);
- if (info->name)
- free(info->name);
- free(info);
-}
-
-struct image_info_s *__create_image_info(void)
-{
- struct image_info_s *info;
-
- info = (struct image_info_s *)calloc(1, sizeof(struct image_info_s));
- if (info == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- return info;
-}
-
-static int __validate_image_info(struct image_info_s *info)
-{
- if (!info || !info->name || !info->file || !info->orientation)
- return -1;
-
- if (!info->type) {
- if (strstr(info->file, "edj"))
- info->type = strdup("edj");
- else
- info->type = strdup("img");
- if (info->type == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- if (!info->indicator_display) {
- info->indicator_display = strdup("true");
- if (info->indicator_display == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- if (!info->color_depth) {
- info->color_depth = strdup("24");
- if (info->color_depth == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- return 0;
-}
-
-static void __parse_file(const char *file)
-{
- FILE *fp;
- char buf[LINE_MAX];
- char *tok1 = NULL;
- char *tok2 = NULL;
- struct image_info_s *info = NULL;
-
- fp = fopen(file, "rt");
- if (fp == NULL)
- return;
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- FREE_AND_NULL(tok1);
- FREE_AND_NULL(tok2);
- sscanf(buf, "%ms %ms", &tok1, &tok2);
-
- if (tok1 && strcasecmp(TAG_SPLASH_IMAGE, tok1) == 0) {
- if (info) {
- if (__validate_image_info(info) < 0) {
- __destroy_image_info(info);
- } else {
- default_image_list = g_list_append(
- default_image_list,
- info);
- }
- }
- info = __create_image_info();
- continue;
- }
-
- if (!tok1 || !tok2 || !info)
- continue;
-
- if (strcasecmp(TAG_NAME, tok1) == 0)
- info->name = strdup(tok2);
- else if (strcasecmp(TAG_FILE, tok1) == 0)
- info->file = strdup(tok2);
- else if (strcasecmp(TAG_TYPE, tok1) == 0)
- info->type = strdup(tok2);
- else if (strcasecmp(TAG_ORIENTATION, tok1) == 0)
- info->orientation = strdup(tok2);
- else if (strcasecmp(TAG_INDICATOR_DISPLAY, tok1) == 0)
- info->indicator_display = strdup(tok2);
- else if (strcasecmp(TAG_COLOR_DEPTH, tok1) == 0)
- info->color_depth = strdup(tok2);
- }
-
- if (info) {
- if (__validate_image_info(info) < 0) {
- __destroy_image_info(info);
- } else {
- default_image_list = g_list_append(default_image_list,
- info);
- }
- }
-
- if (tok1)
- free(tok1);
- if (tok2)
- free(tok2);
-
- fclose(fp);
-}
-
-static int __load_splash_screen_info(const char *path)
-{
- DIR *dp;
- struct dirent *entry = NULL;
- char *ext;
- char buf[PATH_MAX];
-
- dp = opendir(path);
- if (dp == NULL)
- return -1;
-
- while ((entry = readdir(dp)) != NULL) {
- if (entry->d_name[0] == '.')
- continue;
-
- ext = strrchr(entry->d_name, '.');
- if (ext && !strcmp(ext, ".conf")) {
- snprintf(buf, sizeof(buf), "%s/%s",
- path, entry->d_name);
- __parse_file(buf);
- }
- }
-
- closedir(dp);
-
- return 0;
-}
-
-static int __on_launch_start(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- int cmd = arg1;
- bundle *kb = data;
- amd_launch_context_h h = arg3;
-
- cur_splash_image = NULL;
- if (bundle_get_val(kb, AUL_K_MULTI_INSTANCE_SHORTCUT)) {
- _W("Multiple instance shortcut");
- return 0;
- }
-
- if (amd_launch_context_is_bg_launch(h)) {
- _W("Background launch");
- return 0;
- }
-
- cur_splash_image = __splash_screen_create_image(
- amd_launch_context_get_appinfo(h), kb, cmd,
- amd_launch_context_is_subapp(h),
- amd_launch_context_is_custom_effect(h));
- __splash_screen_send_image(cur_splash_image);
-
- return 0;
-}
-
-static int __on_launch_end(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_launch_context_h h = arg3;
- amd_appinfo_h ai = amd_launch_context_get_appinfo(h);
- const char *comp_type;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (cur_splash_image) {
- __splash_screen_send_pid(cur_splash_image,
- amd_launch_context_get_pid(h));
- } else if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- __splash_screen_set_effect_type(amd_launch_context_get_pid(h),
- amd_launch_context_get_appid(h),
- amd_launch_context_is_subapp(h));
- }
-
- return 0;
-}
-
-static int __on_launch_cancel(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- if (cur_splash_image) {
- __splash_screen_destroy_image(cur_splash_image);
- cur_splash_image = NULL;
- }
-
- return 0;
-}
-
-static int __on_cleanup(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- int pid = arg1;
- splash_image_h si;
-
- si = __splash_screen_get_image(pid);
- if (si)
- __splash_screen_destroy_image(si);
-
- return 0;
-}
-
-static int __on_wl_listener(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
- struct wl_registry *registry = (struct wl_registry *)arg3;
-
- if (!tz_launch_effect) {
- tz_launch_effect_id = id;
- tz_launch_effect = wl_registry_bind(registry, id,
- &tizen_launch_effect_interface, 1);
- _D("tz_launch_effect(%p)", tz_launch_effect);
- }
-
- return 0;
-}
-
-static int __on_wl_listener_remove(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
-
- if (id == tz_launch_effect_id && tz_launch_effect) {
- tizen_launch_effect_destroy(tz_launch_effect);
- tz_launch_effect = NULL;
- tz_launch_effect_id = 0;
- splash_screen_initialized = 0;
- _W("tizen launch effect is destroyed");
- }
-
- return 0;
-}
-
-static void __charger_status_changed_cb(keynode_t *keynode, void *user_data)
-{
- if (TIZEN_FEATURE_CHARGER_STATUS) {
- rotation.charger_status = vconf_keynode_get_int(keynode);
- if (rotation.charger_status) {
- if (__init_rotation() < 0)
- _W("Failed to initialize rotation");
- } else {
- __fini_rotation();
- }
- _D("charger status(%d)", rotation.charger_status);
- }
-}
-
-static gboolean __rotation_init_handler(gpointer data)
-{
- int r;
-
- if (TIZEN_FEATURE_CHARGER_STATUS) {
- r = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
- &rotation.charger_status);
- if (r < 0) {
- _W("Failed to get charger status");
- return G_SOURCE_CONTINUE;
- }
-
- r = vconf_notify_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
- __charger_status_changed_cb, NULL);
- if (r < 0) {
- _W("Failed to register vconf cb");
- return G_SOURCE_CONTINUE;
- }
-
- if (rotation.charger_status) {
- if (__init_rotation() < 0)
- _W("Failed to initialize rotation");
- }
- } else {
- if (__init_rotation() < 0)
- _W("Failed to initialize rotation");
- }
-
- rotation.timer = 0;
- return G_SOURCE_REMOVE;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("splash screen init");
-
- __load_splash_screen_info(SPLASH_SCREEN_INFO_PATH);
-
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_EFFECT,
- __on_wl_listener);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
- __on_wl_listener_remove);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START,
- __on_launch_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
- __on_launch_cancel);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
- __on_launch_end);
- amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
- __on_cleanup);
-
- rotation.timer = g_timeout_add(500, __rotation_init_handler, NULL);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("splash screen finish");
-
- if (rotation.timer)
- g_source_remove(rotation.timer);
-
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
- __charger_status_changed_cb);
-
- __fini_rotation();
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_UI_CORE "amd-mod-ui-core")
-SET(AMD_MOD_UI_CORE_DIR ${CMAKE_SOURCE_DIR}/modules/ui-core)
-PROJECT(${AMD_MOD_UI_CORE} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_UI_CORE_DIR}/src AMD_MOD_UI_CORE_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_UI_CORE_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- bundle
- wayland-client
- tizen-extension-client
- wayland-tbm-client
- capi-system-info
- )
-
-pkg_check_modules(amd_mod_ui_core_pkgs REQUIRED ${AMD_MOD_UI_CORE_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_ui_core_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_UI_CORE_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_UI_CORE} ${AMD_MOD_UI_CORE_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_UI_CORE} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_UI_CORE} ${amd_mod_ui_core_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_UI_CORE} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-int _screen_connector_add_app_screen(int pid, unsigned int surf,
- const char *instance_id, uid_t uid);
-int _screen_connector_init(void);
-void _screen_connector_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2019 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <glib.h>
-
-typedef struct app_group_s *app_group_h;
-
-typedef GList *app_group_node_h;
-
-typedef void (*app_group_foreach_context_cb)(const char *id, pid_t pid,
- int wid, bool fg, void *user_data);
-
-app_group_h _app_group_find(const char *id);
-
-const char *_app_group_get_leader_id_by_window(int window);
-
-const char *_app_group_get_id(pid_t pid);
-
-void _app_group_get_group_pids(app_group_h group, int *cnt, pid_t **pids);
-
-void _app_group_get_leader_pids(int *cnt, pid_t **pids);
-
-pid_t _app_group_get_leader_pid(app_group_h h);
-
-void _app_group_get_idle_pids(int *cnt, pid_t **pids);
-
-char **_app_group_get_leader_ids(int *cnt);
-
-int _app_group_get_count(app_group_h group);
-
-int _app_group_foreach_context(app_group_h group,
- app_group_foreach_context_cb callback,
- void *user_data);
-
-int _app_group_get_idle_count(void);
-
-int _app_group_foreach_idle_context(app_group_foreach_context_cb callback,
- void *user_data);
-
-int _app_group_init(void);
-
-void _app_group_fini(void);
-
-app_group_node_h _app_group_node_find(const char *id);
-
-int _app_group_node_get_window(app_group_node_h node);
-
-void _app_group_node_lower(app_group_node_h node, bool *exit);
-
-void _app_group_node_clear_top(app_group_node_h node, uid_t uid);
-
-bool _app_group_node_get_fg_flag(app_group_node_h node);
-
-int _app_group_node_set_window(app_group_node_h node, int wid);
-
-app_group_node_h _app_group_node_find_by_wid(int wid);
-
-app_group_node_h _app_group_node_add_node(app_group_node_h node);
-
-int _app_group_node_remove_node(app_group_node_h node);
-
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "AMD_APP_GROUP"
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-int _app_group_request_init(void);
-
-void _app_group_request_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-int _app_group_wayland_lower_window(int wid);
-
-int _app_group_wayland_attach_window(int parent_wid, int child_wid);
-
-int _app_group_wayland_detach_window(int child_wid);
-
-int _app_group_wayland_activate_below(int wid, int below_wid);
-
-int _app_group_wayland_activate_above(int wid, int above_wid);
-
-int _app_group_wayland_init(void);
-
-void _app_group_wayland_fini(void);
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <unistd.h>
-
-pid_t _status_get_effective_pid(pid_t pid);
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <glib.h>
-#include <string.h>
-#include <ctype.h>
-#include <bundle_internal.h>
-#include <dlog.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <aul_screen_connector.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#include "amd_screen_connector.h"
-#include "app_group.h"
-#include "status.h"
-
-#define SUSPEND_INTERVAL 5 /* sec */
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_SCREEN_CONNECTOR"
-
-struct app_screen_s {
- char *appid;
- char *instance_id;
- int pid;
- uid_t uid;
- unsigned int surf;
- int screen_type;
- int caller_pid;
- GList *viewer_list;
-};
-
-struct viewer_info_s {
- int pid;
- int screen_type;
- bool priv;
- unsigned int ref;
- aul_screen_status_e status;
- GList *watch_list;
-};
-
-struct user_info_s {
- uid_t uid;
- struct app_screen_s *last_focused_app_screen;
- GList *screen_viewer_list;
- GList *app_screen_list;
-};
-
-static GHashTable *user_table;
-
-static struct app_screen_s *__create_app_screen(int pid, uid_t uid,
- const char *appid, unsigned int surf, const char *instance_id,
- int screen_type, int caller_pid)
-{
- struct app_screen_s *app_screen;
-
- app_screen = calloc(1, sizeof(struct app_screen_s));
- if (app_screen == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- app_screen->appid = strdup(appid);
- if (app_screen->appid == NULL) {
- _E("out of memory");
- free(app_screen);
- return NULL;
- }
-
- app_screen->instance_id = strdup(instance_id);
- if (app_screen->instance_id == NULL) {
- _E("out of memory");
- free(app_screen->appid);
- free(app_screen);
- return NULL;
- }
-
- app_screen->pid = pid;
- app_screen->uid = uid;
- app_screen->surf = surf;
- app_screen->screen_type = screen_type;
- app_screen->caller_pid = caller_pid;
-
- return app_screen;
-}
-
-static void __destroy_app_screen(gpointer data)
-{
- struct app_screen_s *app_screen = (struct app_screen_s *)data;
- struct viewer_info_s *viewer_info;
- GList *iter;
-
- if (app_screen == NULL)
- return;
-
- if (app_screen->viewer_list) {
- iter = app_screen->viewer_list;
- while (iter) {
- viewer_info = (struct viewer_info_s *)iter->data;
- viewer_info->watch_list = g_list_remove(
- viewer_info->watch_list, app_screen);
- iter = g_list_next(iter);
- }
- g_list_free(app_screen->viewer_list);
- }
-
- if (app_screen->instance_id)
- free(app_screen->instance_id);
- if (app_screen->appid)
- free(app_screen->appid);
- free(app_screen);
-}
-
-static gint __compare_instance_id(gconstpointer a, gconstpointer b)
-{
- struct app_screen_s *app_screen = (struct app_screen_s *)a;
- const char *instance_id = (const char *)b;
-
- if (app_screen == NULL || instance_id == NULL)
- return -1;
-
- if (!strcmp(app_screen->instance_id, instance_id))
- return 0;
-
- return -1;
-}
-
-static void __destroy_viewer_info(struct viewer_info_s *viewer_info)
-{
- struct app_screen_s *app_screen;
- GList *iter;
-
- if (viewer_info == NULL)
- return;
-
- if (viewer_info->watch_list) {
- iter = viewer_info->watch_list;
- while (iter) {
- app_screen = (struct app_screen_s *)iter->data;
- app_screen->viewer_list = g_list_remove(
- app_screen->viewer_list, viewer_info);
- iter = g_list_next(iter);
- }
- g_list_free(viewer_info->watch_list);
- }
-
- free(viewer_info);
-}
-
-static struct viewer_info_s *__create_viewer_info(int pid, int screen_type,
- bool priv, unsigned int ref)
-{
- struct viewer_info_s *viewer_info;
-
- viewer_info = calloc(1, sizeof(struct viewer_info_s));
- if (viewer_info == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- viewer_info->pid = pid;
- viewer_info->screen_type = screen_type;
- viewer_info->priv = priv;
- viewer_info->ref = ref;
-
- return viewer_info;
-}
-
-static void __destroy_user_info(gpointer data)
-{
- struct user_info_s *user_info = (struct user_info_s *)data;
-
- if (user_info == NULL)
- return;
-
- if (user_info->app_screen_list) {
- g_list_free_full(user_info->app_screen_list,
- __destroy_app_screen);
- }
- if (user_info->screen_viewer_list)
- g_list_free_full(user_info->screen_viewer_list, free);
- free(user_info);
-}
-
-static struct user_info_s *__create_user_info(uid_t uid)
-{
- struct user_info_s *user_info;
-
- user_info = malloc(sizeof(struct user_info_s));
- if (user_info == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- user_info->uid = uid;
- user_info->screen_viewer_list = NULL;
- user_info->app_screen_list = NULL;
- user_info->last_focused_app_screen = NULL;
-
- return user_info;
-}
-
-static bundle *__create_bundle(struct app_screen_s *app_screen,
- const char *event)
-{
- bundle *b;
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- bundle_add_str(b, "__AUL_SC_EVENT__", event);
- bundle_add_str(b, "__AUL_SC_APPID__", app_screen->appid);
- bundle_add_byte(b, "__AUL_SC_PID__", &app_screen->pid, sizeof(int));
- bundle_add_byte(b, "__AUL_SC_SURFACE__",
- &app_screen->surf, sizeof(unsigned int));
- bundle_add_str(b, "__AUL_SC_INSTANCE_ID__", app_screen->instance_id);
-
- return b;
-}
-
-static void __send_app_screen_event(struct viewer_info_s *viewer_info,
- struct app_screen_s *app_screen, const char *event)
-{
- bundle *b;
- char endpoint[128];
-
- b = __create_bundle(app_screen, event);
- if (b == NULL) {
- _E("out of memory");
- return;
- }
-
- snprintf(endpoint, sizeof(endpoint), "app_screen_event:%u:%d",
- viewer_info->ref, viewer_info->pid);
- amd_app_com_send(endpoint, app_screen->pid, b, app_screen->uid);
- bundle_free(b);
-}
-
-static void __send_app_screen_added(gpointer data, gpointer user_data)
-{
- struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
- struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
-
- if (viewer_info->pid == app_screen->pid)
- return;
- if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
- return;
- if (!(viewer_info->screen_type & app_screen->screen_type))
- return;
- __send_app_screen_event(viewer_info, app_screen, "add_screen");
-}
-
-static void __send_app_screen_removed(gpointer data, gpointer user_data)
-{
- struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
- struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
-
- if (viewer_info->pid == app_screen->pid)
- return;
- if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
- return;
- if (!(viewer_info->screen_type & app_screen->screen_type))
- return;
- __send_app_screen_event(viewer_info, app_screen, "remove_screen");
-}
-
-static void __send_app_screen_updated(gpointer data, gpointer user_data)
-{
- struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
- struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
-
- if (viewer_info->pid == app_screen->pid)
- return;
- if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
- return;
- if (!(viewer_info->screen_type & app_screen->screen_type))
- return;
- __send_app_screen_event(viewer_info, app_screen, "update_screen");
-}
-
-static void __send_app_screen_focused(gpointer data, gpointer user_data)
-{
- struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
- struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
-
- if (viewer_info->pid == app_screen->pid)
- return;
- if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
- return;
- if (!(viewer_info->screen_type & app_screen->screen_type))
- return;
- __send_app_screen_event(viewer_info, app_screen, "focus_screen");
-}
-
-static gint __compare_app_screen_instance_id(gconstpointer a, gconstpointer b)
-{
- struct app_screen_s *app_screen = (struct app_screen_s *)a;
- const char *instance_id = (const char *)b;
-
- if (strcmp(app_screen->instance_id, instance_id) == 0)
- return 0;
-
- return -1;
-}
-
-static unsigned int __screen_connector_get_surface_id(const char *instance_id,
- uid_t uid)
-{
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- GList *found;
-
- if (instance_id == NULL)
- return 0;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return 0;
-
- found = g_list_find_custom(user_info->app_screen_list,
- instance_id, __compare_app_screen_instance_id);
- if (found) {
- app_screen = (struct app_screen_s *)found->data;
- return app_screen->surf;
- }
-
- return 0;
-}
-
-static int __get_screen_type(int app_type)
-{
- switch (app_type) {
- case AMD_AT_UI_APP:
- return AUL_SCREEN_TYPE_UI;
- case AMD_AT_WIDGET_APP:
- return AUL_SCREEN_TYPE_WIDGET;
- case AMD_AT_WATCH_APP:
- return AUL_SCREEN_TYPE_WATCH;
- default:
- return -1;
- }
-}
-
-static app_group_h __find_app_group_by_pid(pid_t pid)
-{
- const char *id;
-
- id = _app_group_get_id(pid);
-
- return _app_group_find(id);
-}
-
-static app_group_node_h __find_app_group_node_by_pid(pid_t pid)
-{
- const char *id;
-
- id = _app_group_get_id(pid);
-
- return _app_group_node_find(id);
-}
-
-static int __get_pid_by_surf(int pid, unsigned int surf)
-{
- pid_t *pids = NULL;
- int cnt = 0;
- int i;
- unsigned int wid;
- app_group_h app_group;
- app_group_node_h node;
-
-
- app_group = __find_app_group_by_pid(pid);
- _app_group_get_group_pids(app_group, &cnt, &pids);
- for (i = 0; i < cnt; ++i) {
- node = __find_app_group_node_by_pid(pids[i]);
- wid = (unsigned int)_app_group_node_get_window(node);
- if (wid == surf) {
- _D("pid(%d), surf(%u)", pids[i], surf);
- pid = pids[i];
- }
- }
- free(pids);
-
- return pid;
-}
-
-static gboolean __suspend_timer(gpointer data)
-{
- int pid = GPOINTER_TO_INT(data);
- int ret;
-
- if (pid < 1)
- return FALSE;
-
- ret = amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
- _D("pid(%d), result(%d)", pid, ret);
-
- return FALSE;
-}
-
-static gint __compare_app_screen_surf(gconstpointer a, gconstpointer b)
-{
- struct app_screen_s *app_screen = (struct app_screen_s *)a;
- unsigned int surf = GPOINTER_TO_UINT(b);
-
- if (app_screen->surf == surf)
- return 0;
-
- return -1;
-}
-
-static const char *__screen_connector_get_appid_by_surface_id(unsigned int surf,
- uid_t uid)
-{
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return NULL;
-
- found = g_list_find_custom(user_info->app_screen_list,
- GUINT_TO_POINTER(surf), __compare_app_screen_surf);
- if (found) {
- app_screen = (struct app_screen_s *)found->data;
- return app_screen->appid;
- }
-
- return NULL;
-}
-
-static const char *__screen_connector_get_instance_id_by_surface_id(
- unsigned int surf, uid_t uid)
-{
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return NULL;
-
- found = g_list_find_custom(user_info->app_screen_list,
- GUINT_TO_POINTER(surf), __compare_app_screen_surf);
- if (found) {
- app_screen = (struct app_screen_s *)found->data;
- return app_screen->instance_id;
- }
-
- return NULL;
-}
-
-/* TODO: The provider_appid should be provider_instance_id. */
-static int __send_viewer_visibility_to_provider(const char *provider_appid,
- aul_screen_status_e status, int viewer_pid, uid_t viewer_uid)
-{
- bundle *b;
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return -1;
- }
-
- bundle_add_byte(b, "__AUL_SC_VIEWER_STATUS__",
- &status, sizeof(aul_screen_status_e));
- amd_app_com_send(provider_appid, viewer_pid, b, viewer_uid);
- bundle_free(b);
- _D("send viewer status to %s(%d)", provider_appid, status);
-
- return 0;
-}
-
-static gint __compare_viewer_pid(gconstpointer a, gconstpointer b)
-{
- struct viewer_info_s *viewer_info = (struct viewer_info_s *)a;
- int pid = GPOINTER_TO_INT(b);
-
- if (viewer_info->pid == pid)
- return 0;
-
- return -1;
-}
-
-static int __screen_connector_update_screen_viewer_status(int pid, int status,
- unsigned int surf, uid_t uid)
-{
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- struct viewer_info_s *viewer_info;
- bool send_pause = true;
- GList *found;
- GList *iter;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- found = g_list_find_custom(user_info->screen_viewer_list,
- GINT_TO_POINTER(pid), __compare_viewer_pid);
- if (found == NULL)
- return -1;
-
- viewer_info = (struct viewer_info_s *)found->data;
- if (status != AUL_SCREEN_STATUS_PRE_RESUME)
- viewer_info->status = status;
- else
- _W("pre resume status will not be stored as a viewer status");
-
- found = g_list_find_custom(user_info->app_screen_list,
- GUINT_TO_POINTER(surf), __compare_app_screen_surf);
- if (found == NULL)
- return -1;
-
- app_screen = (struct app_screen_s *)found->data;
- found = g_list_find(app_screen->viewer_list, viewer_info);
- if (!found) {
- app_screen->viewer_list = g_list_append(app_screen->viewer_list,
- viewer_info);
- }
-
- found = g_list_find(viewer_info->watch_list, app_screen);
- if (!found) {
- viewer_info->watch_list = g_list_append(viewer_info->watch_list,
- app_screen);
- }
-
- if (status == AUL_SCREEN_STATUS_PAUSE) {
- iter = app_screen->viewer_list;
- while (iter) {
- viewer_info = (struct viewer_info_s *)iter->data;
- if (viewer_info->status != AUL_SCREEN_STATUS_PAUSE) {
- /*
- * Every veiwer must be paused to send
- * viewer pause event to provider
- */
- send_pause = false;
- _W("Skip pause : viewer pid(%d), status(%d)",
- viewer_info->pid, viewer_info->status);
- break;
- }
- iter = g_list_next(iter);
- }
- if (send_pause) {
- __send_viewer_visibility_to_provider(app_screen->appid,
- status, pid, uid);
- }
- } else if (status == AUL_SCREEN_STATUS_RESUME ||
- status == AUL_SCREEN_STATUS_PRE_RESUME) {
- __send_viewer_visibility_to_provider(app_screen->appid, status,
- pid, uid);
- } else {
- _W("Unknown status(%d)", status);
- }
-
- return 0;
-}
-
-static int __screen_connector_send_update_request(const char *appid,
- const char *instance_id, uid_t uid)
-{
- amd_app_status_h app_status;
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- int dummy = 0;
- int pid;
- int ret;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- if (instance_id) {
- app_status = amd_app_status_find_by_instance_id(appid,
- instance_id, uid);
- } else {
- app_status = amd_app_status_find_by_appid(appid, uid);
- }
- if (app_status == NULL)
- return -1;
- if (amd_app_status_get_status(app_status) == STATUS_DYING)
- return -1;
- if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
- return -1;
- if (amd_app_status_is_home_app(app_status))
- return -1;
- if (instance_id == NULL) {
- instance_id = amd_app_status_get_instance_id(app_status);
- if (instance_id == NULL)
- return -1;
- }
-
- found = g_list_find_custom(user_info->app_screen_list, instance_id,
- __compare_instance_id);
- if (found == NULL)
- return -1;
-
- app_screen = (struct app_screen_s *)found->data;
- pid = __get_pid_by_surf(app_screen->pid, app_screen->surf);
- ret = amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
- if (ret < 0)
- return -1;
-
- ret = aul_sock_send_raw(pid, uid, APP_UPDATE_REQUESTED,
- (unsigned char *)&dummy, 0, AUL_SOCK_NOREPLY);
- if (ret < 0) {
- _E("Failed to send the update request");
- amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
- return -1;
- }
- g_timeout_add_seconds(SUSPEND_INTERVAL, __suspend_timer,
- GINT_TO_POINTER(pid));
- _D("pid(%d), uid(%d)", pid, uid);
-
- return 0;
-}
-
-int _screen_connector_add_app_screen(int pid, unsigned int surf,
- const char *instance_id, uid_t uid)
-{
- amd_app_status_h app_status;
- app_group_h app_group;
- const char *appid;
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- int caller_pid;
- int leader_pid;
- int app_type;
- int screen_type;
- int effective_pid;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- effective_pid = _status_get_effective_pid(pid);
- if (effective_pid < 0)
- return -1;
-
- if (instance_id)
- app_group = _app_group_find(instance_id);
- else
- app_group = __find_app_group_by_pid(effective_pid);
- leader_pid = _app_group_get_leader_pid(app_group);
- if (leader_pid > 0)
- pid = leader_pid;
- else
- pid = effective_pid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL) {
- _W("Failed to find app status info - pid(%d), uid(%d)",
- pid, uid);
- return -1;
- }
-
- if (amd_app_status_is_home_app(app_status))
- return 0;
-
- appid = amd_app_status_get_appid(app_status);
- if (instance_id == NULL)
- instance_id = amd_app_status_get_instance_id(app_status);
-
- found = g_list_find_custom(user_info->app_screen_list, instance_id,
- __compare_instance_id);
- if (found) {
- app_screen = (struct app_screen_s *)found->data;
- if (app_screen->surf == surf) {
- _D("Already exists");
- return 0;
- }
-
- app_screen->surf = surf;
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_updated, app_screen);
- _W("surf is changed to %u", surf);
- return 0;
- }
-
- caller_pid = amd_app_status_get_first_caller_pid(app_status);
- app_type = amd_app_status_get_app_type(app_status);
- screen_type = __get_screen_type(app_type);
- app_screen = __create_app_screen(pid, uid, appid, surf, instance_id,
- screen_type, caller_pid);
- if (app_screen == NULL)
- return -1;
-
- user_info->app_screen_list = g_list_append(user_info->app_screen_list,
- app_screen);
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_added, app_screen);
- _D("pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
-
- return 0;
-}
-
-static int __screen_connector_remove_app_screen(int pid,
- const char *instance_id, uid_t uid)
-{
- app_group_h app_group;
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- amd_app_status_h app_status;
- int leader_pid;
- int effective_pid;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- effective_pid = _status_get_effective_pid(pid);
- if (effective_pid < 0)
- return -1;
-
- if (instance_id)
- app_group = _app_group_find(instance_id);
- else
- app_group = __find_app_group_by_pid(effective_pid);
- leader_pid = _app_group_get_leader_pid(app_group);
- if (leader_pid > 0)
- pid = leader_pid;
- else
- pid = effective_pid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL) {
- _W("Failed to find app status info - pid(%d), uid(%d)",
- pid, uid);
- return -1;
- }
-
- if (amd_app_status_is_home_app(app_status))
- return 0;
-
- if (instance_id == NULL)
- instance_id = amd_app_status_get_instance_id(app_status);
-
- found = g_list_find_custom(user_info->app_screen_list, instance_id,
- __compare_instance_id);
- if (found == NULL)
- return -1;
-
- app_screen = (struct app_screen_s *)found->data;
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_removed, app_screen);
- user_info->app_screen_list = g_list_remove(user_info->app_screen_list,
- app_screen);
- __destroy_app_screen(app_screen);
- if (user_info->last_focused_app_screen == app_screen)
- user_info->last_focused_app_screen = NULL;
-
- _D("pid(%d), instance_id(%s)", pid, instance_id);
-
- return 0;
-}
-
-static gint __compare_viewers(gconstpointer a, gconstpointer b)
-{
- struct viewer_info_s *viewer_a = (struct viewer_info_s *)a;
- struct viewer_info_s *viewer_b = (struct viewer_info_s *)b;
-
- if (viewer_a->pid == viewer_b->pid &&
- viewer_a->screen_type == viewer_b->screen_type &&
- viewer_a->priv == viewer_b->priv &&
- viewer_a->ref == viewer_b->ref)
- return 0;
-
- return -1;
-}
-
-static int __screen_connector_update_app_screen(int pid, unsigned int surf,
- uid_t uid)
-{
- amd_app_status_h app_status;
- app_group_h app_group;
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- const char *appid;
- const char *instance_id;
- int leader_pid;
- int effective_pid;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- effective_pid = _status_get_effective_pid(pid);
- if (effective_pid < 0)
- return -1;
-
- app_group = __find_app_group_by_pid(effective_pid);
- leader_pid = _app_group_get_leader_pid(app_group);
- if (leader_pid > 0)
- pid = leader_pid;
- else
- pid = effective_pid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL) {
- _W("Failed to find app status info - pid(%d), uid(%d)",
- pid, uid);
- return -1;
- }
-
- if (amd_app_status_is_home_app(app_status))
- return 0;
-
- appid = amd_app_status_get_appid(app_status);
- instance_id = amd_app_status_get_instance_id(app_status);
-
- found = g_list_find_custom(user_info->app_screen_list, instance_id,
- __compare_instance_id);
- if (found == NULL)
- return -1;
-
- app_screen = (struct app_screen_s *)found->data;
- if (app_screen->surf == surf)
- return 0;
-
- app_screen->surf = surf;
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_updated, app_screen);
- _D("pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
-
- return 0;
-}
-
-static int __screen_connector_focus_app_screen(int pid, unsigned int surf,
- uid_t uid)
-{
- amd_app_status_h app_status;
- app_group_h app_group;
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- const char *appid;
- const char *instance_id;
- int leader_pid;
- int effective_pid;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- effective_pid = _status_get_effective_pid(pid);
- if (effective_pid < 0)
- return -1;
-
- app_group = __find_app_group_by_pid(effective_pid);
- leader_pid = _app_group_get_leader_pid(app_group);
- if (leader_pid > 0)
- pid = leader_pid;
- else
- pid = effective_pid;
-
- app_status = amd_app_status_find_by_pid(pid);
- if (app_status == NULL) {
- _W("Failed to find app status info - pid(%d), uid(%d)",
- pid, uid);
- return -1;
- }
-
- if (amd_app_status_is_home_app(app_status))
- return 0;
-
- appid = amd_app_status_get_appid(app_status);
- instance_id = amd_app_status_get_instance_id(app_status);
-
- found = g_list_find_custom(user_info->app_screen_list, instance_id,
- __compare_instance_id);
- if (found == NULL)
- return -1;
-
- app_screen = (struct app_screen_s *)found->data;
-
- user_info->last_focused_app_screen = app_screen;
-
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_focused, app_screen);
- _D("focus pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
-
- return 0;
-}
-
-static int __screen_connector_remove_app_screen_v2(int pid, uid_t uid)
-{
- struct user_info_s *user_info;
- struct app_screen_s *app_screen;
- GList *iter;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- iter = g_list_first(user_info->app_screen_list);
- while (iter) {
- app_screen = (struct app_screen_s *)iter->data;
- iter = g_list_next(iter);
- if (app_screen && app_screen->pid == pid) {
- _D("pid(%d), surf(%d)", pid, app_screen->surf);
- g_list_foreach(user_info->screen_viewer_list,
- __send_app_screen_removed, app_screen);
- user_info->app_screen_list = g_list_remove(
- user_info->app_screen_list,
- app_screen);
- __destroy_app_screen(app_screen);
- if (user_info->last_focused_app_screen == app_screen)
- user_info->last_focused_app_screen = NULL;
- }
- }
-
- return 0;
-}
-
-static void __foreach_app_screen_list(gpointer data, gpointer user_data)
-{
- __send_app_screen_added(user_data, data);
-}
-
-static int __screen_connector_add_screen_viewer(int pid, int screen_type,
- bool priv, unsigned int ref, uid_t uid)
-{
- struct user_info_s *user_info;
- struct viewer_info_s *viewer_info;
- GList *list;
-
- pid = _status_get_effective_pid(pid);
- if (pid < 0)
- return -1;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL) {
- _W("user info is empty");
- return -1;
- }
-
- viewer_info = __create_viewer_info(pid, screen_type, priv, ref);
- if (viewer_info == NULL)
- return -1;
-
- list = g_list_find_custom(user_info->screen_viewer_list, viewer_info,
- __compare_viewers);
- if (list) {
- _D("Already exists");
- __destroy_viewer_info(viewer_info);
- return 0;
- }
-
- user_info->screen_viewer_list = g_list_append(
- user_info->screen_viewer_list, viewer_info);
-
- g_list_foreach(user_info->app_screen_list,
- __foreach_app_screen_list, viewer_info);
- _D("pid(%d), screen_type(%d), private(%d), ref(%u), uid(%d)",
- pid, screen_type, priv, ref, uid);
-
- return 0;
-}
-
-static int __screen_connector_remove_screen_viewer(int pid, int screen_type,
- bool priv, unsigned int ref, uid_t uid)
-{
- struct user_info_s *user_info;
- struct viewer_info_s *viewer_info;
- GList *iter;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL) {
- _W("user info is empty");
- return -1;
- }
-
- pid = _status_get_effective_pid(pid);
- if (pid < 0)
- return -1;
-
- iter = g_list_first(user_info->screen_viewer_list);
- while (iter) {
- viewer_info = (struct viewer_info_s *)iter->data;
- iter = g_list_next(iter);
- if (viewer_info->pid == pid &&
- viewer_info->screen_type == screen_type &&
- viewer_info->priv == priv &&
- viewer_info->ref == ref) {
- user_info->screen_viewer_list = g_list_remove(
- user_info->screen_viewer_list,
- viewer_info);
- __destroy_viewer_info(viewer_info);
- }
- }
-
- _D("pid(%d), screen_type(%d), private(%d), ref(%u) uid(%d)",
- pid, screen_type, priv, ref, uid);
-
- return 0;
-}
-
-static int __screen_connector_remove_screen_viewer_v2(int pid, uid_t uid)
-{
- struct user_info_s *user_info;
- struct viewer_info_s *viewer_info;
- GList *iter;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL) {
- _W("user info is empty");
- return -1;
- }
-
- iter = g_list_first(user_info->screen_viewer_list);
- while (iter) {
- viewer_info = (struct viewer_info_s *)iter->data;
- iter = g_list_next(iter);
- if (viewer_info->pid == pid) {
- user_info->screen_viewer_list = g_list_remove(
- user_info->screen_viewer_list,
- viewer_info);
- __destroy_viewer_info(viewer_info);
- }
- }
-
- return 0;
-}
-
-static int __screen_connector_usr_init(uid_t uid)
-{
- struct user_info_s *user_info;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info) {
- _E("Already exists");
- return 0;
- }
-
- user_info = __create_user_info(uid);
- if (user_info == NULL)
- return -1;
-
- g_hash_table_insert(user_table, GUINT_TO_POINTER(uid), user_info);
-
- return 0;
-}
-
-static void __screen_connector_usr_fini(uid_t uid)
-{
- g_hash_table_remove(user_table, GUINT_TO_POINTER(uid));
-}
-
-static int __dispatch_add_app_screen(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *instance_id;
- const char *value;
- unsigned int surf;
- int ret;
-
- if (b == NULL)
- return -1;
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- value = bundle_get_val(b, AUL_K_WID);
- if (value == NULL)
- return -1;
-
- surf = atol(value);
- ret = _screen_connector_add_app_screen(pid, surf,
- instance_id, uid);
- _D("pid(%d), surf(%d), instance_id(%s), result(%d)",
- pid, surf, instance_id, ret);
-
- return 0;
-}
-
-static int __dispatch_remove_app_screen(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *instance_id;
- int ret;
-
- if (b == NULL)
- return -1;
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- ret = __screen_connector_remove_app_screen(pid,
- instance_id, uid);
- _D("pid(%d), instance_id(%s), result(%d)",
- pid, instance_id, ret);
-
- return 0;
-}
-
-static int __dispatch_app_update_requested(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int caller_pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *appid;
- const char *instance_id;
- int ret;
-
- if (b == NULL)
- return -1;
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (appid == NULL)
- return -1;
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- ret = __screen_connector_send_update_request(appid, instance_id, uid);
- _D("appid(%s), instance_id(%s), caller_pid(%d), result(%d)",
- appid, instance_id, caller_pid, ret);
-
- return 0;
-}
-
-static int __dispatch_add_screen_viewer(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *value;
- bool priv;
- int screen_type;
- unsigned int ref;
- int ret;
-
- if (b == NULL)
- return -1;
-
- value = bundle_get_val(b, AUL_K_SCREEN_TYPE);
- if (value == NULL)
- return -1;
- screen_type = atoi(value);
-
- value = bundle_get_val(b, AUL_K_VIEWER_REF);
- if (value == NULL)
- return -1;
- ref = atol(value);
-
- value = bundle_get_val(b, AUL_K_PRIVATE);
- if (value && strcmp(value, "true") == 0)
- priv = true;
- else
- priv = false;
-
- ret = __screen_connector_add_screen_viewer(pid, screen_type,
- priv, ref, uid);
- _D("pid(%d), screen_type(%d), private(%d), result(%d)",
- pid, screen_type, priv, ret);
-
- return 0;
-}
-
-static int __dispatch_remove_screen_viewer(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *value;
- bool priv;
- int screen_type;
- unsigned int ref;
- int ret;
-
- if (b == NULL)
- return -1;
-
- value = bundle_get_val(b, AUL_K_SCREEN_TYPE);
- if (value == NULL)
- return -1;
- screen_type = atoi(value);
-
- value = bundle_get_val(b, AUL_K_VIEWER_REF);
- if (value == NULL)
- return -1;
- ref = atol(value);
-
- value = bundle_get_val(b, AUL_K_PRIVATE);
- if (value && strcmp(value, "true") == 0)
- priv = true;
- else
- priv = false;
-
- ret = __screen_connector_remove_screen_viewer(pid, screen_type,
- priv, ref, uid);
- _D("pid(%d), screen_type(%d), private(%d), result(%d)",
- pid, screen_type, priv, ret);
-
- return 0;
-}
-
-static int __screen_connector_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- bundle *b = amd_request_get_bundle(req);
- const char *type_str;
- int type;
-
- if (b == NULL) {
- _E("Empty bundle data !!");
- return -1;
- }
-
- type_str = bundle_get_val(b, AUL_K_SCREEN_TYPE);
- if (type_str == NULL) {
- _E("Cannot get screen type !!");
- return -1;
- }
-
- type = atoi(type_str);
- if (type & AUL_SCREEN_TYPE_UI)
- return amd_cynara_simple_checker(info, req, PRIVILEGE_PLATFORM);
-
- return amd_cynara_simple_checker(info, req, PRIVILEGE_WIDGET_VIEWER);
-}
-
-static int __dispatch_app_get_appid_by_surface_id(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- bundle *b = amd_request_get_bundle(req);
- unsigned int *surf = NULL;
- const char *appid;
- size_t size;
- bundle *ret_b;
-
- if (b == NULL) {
- amd_request_send_result(req, -1);
- return -1;
- }
-
- bundle_get_byte(b, "__AUL_SC_SURFACE__", (void **)&surf, &size);
- if (surf == NULL) {
- _E("Failed to get surface");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- appid = __screen_connector_get_appid_by_surface_id(*surf, uid);
- if (appid == NULL) {
- _E("Failed to get appid");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- ret_b = bundle_create();
- if (ret_b == NULL) {
- _E("Out of memory");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- bundle_add_str(ret_b, AUL_K_APPID, appid);
- aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
- amd_request_get_cmd(req), ret_b, AUL_SOCK_NOREPLY);
- bundle_free(ret_b);
-
- return 0;
-}
-
-static int __dispatch_app_get_instance_id_by_surface_id(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- bundle *b = amd_request_get_bundle(req);
- unsigned int *surf = NULL;
- const char *instance_id;
- size_t size;
- bundle *ret_b;
-
- if (b == NULL) {
- amd_request_send_result(req, -1);
- return -1;
- }
-
- bundle_get_byte(b, "__AUL_SC_SURFACE__", (void **)&surf, &size);
- if (surf == NULL) {
- _E("Failed to get surface");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- instance_id = __screen_connector_get_instance_id_by_surface_id(*surf,
- uid);
- if (instance_id == NULL) {
- _E("Failed to get instance_id");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- ret_b = bundle_create();
- if (ret_b == NULL) {
- _E("Out of memory");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- bundle_add_str(ret_b, AUL_K_INSTANCE_ID, instance_id);
- aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
- amd_request_get_cmd(req), ret_b, AUL_SOCK_NOREPLY);
- bundle_free(ret_b);
-
- return 0;
-}
-
-static int __dispatch_trigger_focused_force(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- struct user_info_s *user_info;
- struct viewer_info_s *viewer_info;
- GList *found;
-
- user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
- if (user_info == NULL)
- return -1;
-
- if (user_info->last_focused_app_screen == NULL) {
- _E("requested bad focused screen");
- return -1;
- }
-
- found = g_list_find_custom(user_info->screen_viewer_list,
- GINT_TO_POINTER(pid), __compare_viewer_pid);
- if (found == NULL)
- return -1;
-
- viewer_info = (struct viewer_info_s *)found->data;
-
- __send_app_screen_event(viewer_info,
- user_info->last_focused_app_screen, "focus_screen");
-
- return 0;
-}
-
-static int __dispatch_update_screen_viewer_status(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- int pid = amd_request_get_pid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *val;
- aul_screen_status_e status;
- unsigned int surf;
- int r;
-
- if (b == NULL) {
- amd_request_send_result(req, -1);
- return -1;
- }
-
- val = bundle_get_val(b, "__AUL_SC_VIEWER_STATUS__");
- if (val == NULL || !isdigit(*val)) {
- _E("Failed to get viewer status");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- status = atoi(val);
-
- val = bundle_get_val(b, AUL_K_WID);
- if (val == NULL || !isdigit(*val)) {
- _E("Failed to get surface id");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- surf = strtoul(val, NULL, 10);
-
- r = __screen_connector_update_screen_viewer_status(pid, status,
- surf, uid);
- amd_request_send_result(req, r);
-
- return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = ADD_APP_SCREEN,
- .callback = __dispatch_add_app_screen
- },
- {
- .cmd = REMOVE_APP_SCREEN,
- .callback = __dispatch_remove_app_screen
- },
- {
- .cmd = APP_UPDATE_REQUESTED,
- .callback = __dispatch_app_update_requested
- },
- {
- .cmd = ADD_SCREEN_VIEWER,
- .callback = __dispatch_add_screen_viewer
- },
- {
- .cmd = REMOVE_SCREEN_VIEWER,
- .callback = __dispatch_remove_screen_viewer
- },
- {
- .cmd = APP_GET_APPID_BY_SURFACE_ID,
- .callback = __dispatch_app_get_appid_by_surface_id
- },
- {
- .cmd = APP_GET_INSTANCE_ID_BY_SURFACE_ID,
- .callback = __dispatch_app_get_instance_id_by_surface_id
- },
- {
- .cmd = UPDATE_SCREEN_VIEWER_STATUS,
- .callback = __dispatch_update_screen_viewer_status
- },
- {
- .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
- .callback = __dispatch_trigger_focused_force
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = ADD_SCREEN_VIEWER,
- .checker = __screen_connector_checker,
- .data = NULL
- },
- {
- .cmd = REMOVE_SCREEN_VIEWER,
- .checker = __screen_connector_checker,
- .data = NULL
- },
- {
- .cmd = APP_UPDATE_REQUESTED,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
- {
- .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
- .checker = __screen_connector_checker,
- .data = NULL
- }
-};
-
-static int __on_launch_status(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = arg2;
- app_group_node_h node = __find_app_group_node_by_pid(pid);
- unsigned int surf = _app_group_node_get_window(node);
-
- __screen_connector_update_app_screen(pid, surf, uid);
- amd_noti_send(AMD_NOTI_MSG_SCREEN_CONNECTOR_APP_SCREEN_UPDATE,
- pid, (int)surf, NULL, NULL);
- return 0;
-}
-
-static int __on_focus_status(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data) {
- int pid = arg1;
- uid_t uid = arg2;
- app_group_node_h node = __find_app_group_node_by_pid(pid);
- unsigned int surf = _app_group_node_get_window(node);
-
- __screen_connector_focus_app_screen(pid, surf, uid);
-
- return 0;
-}
-
-static int __on_app_status_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h h = arg3;
-
- if (amd_app_status_get_status(h) == STATUS_DYING) {
- __screen_connector_remove_app_screen_v2(
- amd_app_status_get_pid(h),
- amd_app_status_get_uid(h));
- }
-
- return 0;
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = arg2;
-
- __screen_connector_remove_app_screen_v2(pid, uid);
- __screen_connector_remove_screen_viewer_v2(pid, uid);
-
- return 0;
-}
-
-static int __on_login(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = arg1;
- int status = arg2;
-
- if (status & (AMD_UID_STATE_OPENING | AMD_UID_STATE_ONLINE |
- AMD_UID_STATE_ACTIVE))
- __screen_connector_usr_init(uid);
-
- return 0;
-}
-
-static int __on_logout(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = arg1;
- int status = arg2;
-
- if (status & (AMD_UID_STATE_CLOSING | AMD_UID_STATE_OFFLINE))
- __screen_connector_usr_fini(uid);
-
- return 0;
-}
-
-static int __on_widget_app_restart(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = (uid_t)arg2;
-
- __screen_connector_remove_app_screen_v2(pid, uid);
-
- return 0;
-}
-
-static int __on_widget_running_info(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- unsigned int *surf = GINT_TO_POINTER(arg1);
- uid_t uid = (uid_t)arg2;
- const char *instance_id = (const char *)arg3;
-
- *surf = __screen_connector_get_surface_id(instance_id, uid);
-
- return 0;
-}
-
-int _screen_connector_init(void)
-{
- int r;
-
- _D("screen connector init");
-
- user_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __destroy_user_info);
- if (user_table == NULL) {
- _E("Failed to create user table");
- return -1;
- }
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
- __on_launch_status);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
- __on_launch_status);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
- __on_focus_status);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
- __on_app_status_end);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN,
- __on_login);
- amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
- __on_logout);
- amd_noti_listen(AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART,
- __on_widget_app_restart);
- amd_noti_listen(AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND,
- __on_widget_running_info);
-
- return 0;
-}
-
-void _screen_connector_fini(void)
-{
- _D("screen connector fini");
-
- if (user_table)
- g_hash_table_destroy(user_table);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <glib.h>
-#include <dlog.h>
-#include <aul.h>
-#include <aul_svc.h>
-#include <bundle_internal.h>
-#include <aul_sock.h>
-#include <system_info.h>
-#include <aul_comp_types.h>
-#include <amd.h>
-
-#include "amd_screen_connector.h"
-#include "app_group.h"
-#include "app_group_wayland.h"
-#include "app_group_request.h"
-#include "app_group_private.h"
-
-#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
-#define STATUS_FOREGROUND "fg"
-#define STATUS_BACKGROUND "bg"
-#define TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP \
- (!(amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_TV)))
-
-#ifndef AUL_K_ORG_CALLER_INSTANCE_ID
-#define AUL_K_ORG_CALLER_INSTANCE_ID "__AUL_ORG_CALLER_INSTANCE_ID__"
-#endif
-
-#ifndef AUL_K_CALLER_INSTANCE_ID
-#define AUL_K_CALLER_INHSTANCE_ID "__AUL_CALLER_INSTANCE_ID__"
-#endif
-
-typedef enum {
- APP_GROUP_LAUNCH_MODE_SINGLE = 0,
- APP_GROUP_LAUNCH_MODE_GROUP,
- APP_GROUP_LAUNCH_MODE_CALLER,
-} app_group_launch_mode_e;
-
-struct app_group_context_s {
- char *id;
- char *caller_id;
- pid_t pid;
- pid_t caller_pid;
- int wid;
- int status;
- app_group_launch_mode_e launch_mode;
- bool fg;
- bool group_sig;
- bool can_be_leader;
- bool reroute;
- bool can_shift;
- bool recycle;
-};
-
-struct launch_context_s {
- app_group_launch_mode_e mode;
- bool can_attach;
- pid_t leader_pid;
- const char *leader_id;
- bool new_instance;
-};
-
-struct app_group_s {
- char *leader_id;
- pid_t leader_pid;
- GList *list;
-};
-
-static GList *__app_group_list;
-static GList *__recycle_bin;
-static struct launch_context_s __launch_context;
-
-static void __prepare_to_suspend(int pid, uid_t uid);
-
-static void __destroy_app_group_context(gpointer data)
-{
- struct app_group_context_s *ctx = (struct app_group_context_s *)data;
-
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT,
- ctx->pid, ctx->wid, ctx->id, NULL);
-
- if (ctx->caller_id)
- free(ctx->caller_id);
- if (ctx->id)
- free(ctx->id);
- free(ctx);
-}
-
-static struct app_group_context_s *__create_app_group_context(
- pid_t pid, const char *id,
- pid_t caller_pid, const char *caller_id,
- app_group_launch_mode_e launch_mode,
- bool can_shift, bool recycle)
-{
- struct app_group_context_s *ctx;
-
- ctx = calloc(1, sizeof(struct app_group_context_s));
- if (!ctx) {
- _E("Out of memory");
- return NULL;
- }
-
- ctx->id = strdup(id);
- if (!ctx->id) {
- _E("Failed to duplicate ID(%s)", id);
- free(ctx);
- return NULL;
- }
-
- ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
- if (!ctx->caller_id) {
- _E("Failed to duplicate caller ID(%s)", caller_id);
- __destroy_app_group_context(ctx);
- return NULL;
- }
-
- ctx->pid = pid;
- ctx->caller_pid = caller_pid;
- ctx->wid = 0;
- ctx->fg = false;
- ctx->can_be_leader = false;
- ctx->reroute = false;
- ctx->launch_mode = launch_mode;
- ctx->can_shift = can_shift;
- ctx->recycle = recycle;
-
- return ctx;
-}
-
-static void __destroy_app_group(gpointer data)
-{
- struct app_group_s *group = (struct app_group_s *)data;
-
- if (group->list)
- g_list_free_full(group->list, __destroy_app_group_context);
- if (group->leader_id)
- free(group->leader_id);
- free(group);
-}
-
-static struct app_group_s *__create_app_group(const char *leader_id,
- pid_t leader_pid)
-{
- struct app_group_s *group;
-
- group = calloc(1, sizeof(struct app_group_s));
- if (!group) {
- _E("Out of memory");
- return NULL;
- }
-
- group->leader_id = strdup(leader_id);
- if (!group->leader_id) {
- _E("Failed to duplicate leader ID");
- free(group);
- return NULL;
- }
-
- group->leader_pid = leader_pid;
-
- return group;
-}
-
-static gint __compare_context_id(gconstpointer a, gconstpointer b)
-{
- struct app_group_context_s *ctx = (struct app_group_context_s *)a;
- const char *id = (const char *)b;
-
- return strcmp(ctx->id, id);
-}
-
-static gint __compare_group_id(gconstpointer a, gconstpointer b)
-{
- app_group_h group = (app_group_h)a;
- const char *id = (const char *)b;
-
- return strcmp(group->leader_id, id);
-}
-
-const char *_app_group_get_id(pid_t pid)
-{
- amd_app_status_h app_status;
- int app_type;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return NULL;
- }
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- _E("The type of the application(%d) is component-based", pid);
- return NULL;
- }
-
- return amd_app_status_get_instance_id(app_status);
-}
-
-static pid_t __get_caller_pid(bundle *kb)
-{
- const char *pid_str;
-
- pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
- if (!pid_str) {
- pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
- if (!pid_str)
- return -1;
- }
-
- return atoi(pid_str);
-}
-
-static const char *__get_caller_id(bundle *kb)
-{
- const char *id;
-
- id = bundle_get_val(kb, AUL_K_ORG_CALLER_INSTANCE_ID);
- if (!id)
- id = bundle_get_val(kb, AUL_K_CALLER_INSTANCE_ID);
-
- return id;
-}
-
-app_group_node_h _app_group_node_find(const char *id)
-{
- app_group_h group;
- app_group_node_h node;
- GList *iter;
-
- if (!id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- node = g_list_find_custom(group->list, id,
- __compare_context_id);
- if (node)
- return node;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-app_group_h _app_group_find(const char *id)
-{
- app_group_h group;
- app_group_node_h node;
- GList *iter;
-
- if (!id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- node = g_list_find_custom(group->list, id,
- __compare_context_id);
- if (node)
- return group;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-pid_t _app_group_get_leader_pid(app_group_h h)
-{
- if (!h)
- return -1;
-
- return h->leader_pid;
-}
-
-static struct app_group_context_s *__detach_context_from_recycle_bin(
- const char *id)
-{
- struct app_group_context_s *ctx;
- GList *found;
-
- if (!id)
- return NULL;
-
- found = g_list_find_custom(__recycle_bin, id, __compare_context_id);
- if (!found)
- return NULL;
-
- ctx = (struct app_group_context_s *)found->data;
- __recycle_bin = g_list_delete_link(__recycle_bin, found);
-
- return ctx;
-}
-
-int _app_group_node_get_window(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return 0;
-
- ctx = (struct app_group_context_s *)node->data;
- if (ctx)
- return ctx->wid;
-
- return 0;
-}
-
-const char *_app_group_node_get_id(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return NULL;
-
- ctx = (struct app_group_context_s *)node->data;
- if (ctx)
- return ctx->id;
-
- return NULL;
-}
-
-int _app_group_node_set_window(app_group_node_h node, int wid)
-{
- struct app_group_context_s *ctx;
- int prev_wid = 0;
- int next_wid = 0;
- int caller_wid;
- app_group_node_h caller_node;
- amd_comp_status_h comp = NULL;
-
- if (!node) {
- _E("Invalid parameter");
- return -1;
- }
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return -1;
-
- ctx->wid = wid;
- comp = amd_comp_status_find_by_instance_id(ctx->id);
- if (comp)
- amd_comp_status_set_window(comp, wid);
-
- prev_wid = _app_group_node_get_window(g_list_previous(node));
- if (prev_wid != 0)
- _app_group_wayland_attach_window(prev_wid, wid);
-
- if (ctx->can_shift && ctx->caller_id) {
- caller_node = _app_group_node_find(ctx->caller_id);
- caller_wid = _app_group_node_get_window(caller_node);
- if (caller_wid != 0)
- _app_group_wayland_attach_window(caller_wid, wid);
- }
-
- next_wid = _app_group_node_get_window(g_list_next(node));
- if (next_wid != 0)
- _app_group_wayland_attach_window(wid, next_wid);
-
- return 0;
-}
-
-static gint __compare_window_id(gconstpointer a, gconstpointer b)
-{
- struct app_group_context_s *ctx = (struct app_group_context_s *)a;
- int wid = GPOINTER_TO_INT(b);
-
- if (ctx->wid == wid)
- return 0;
-
- return -1;
-}
-
-app_group_node_h _app_group_node_find_by_wid(int wid)
-{
- app_group_h group;
- app_group_node_h node;
- GList *iter;
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- node = g_list_find_custom(group->list,
- GINT_TO_POINTER(wid),
- __compare_window_id);
- if (node)
- return node;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-app_group_node_h _app_group_node_add_node(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
- struct app_group_context_s *new_ctx;
- app_group_h group;
-
- if (!node)
- return NULL;
-
- ctx = (struct app_group_context_s *)node->data;
- group = _app_group_find(ctx->id);
- new_ctx = __create_app_group_context(ctx->pid, ctx->id, ctx->caller_pid,
- ctx->caller_id, ctx->launch_mode, ctx->can_shift, true);
- if (!new_ctx) {
- _E("Failed to create app group context. %s:%d",
- ctx->id, ctx->pid);
- return NULL;
- }
-
- new_ctx->group_sig = ctx->group_sig;
- new_ctx->reroute = true;
- new_ctx->can_be_leader = ctx->can_be_leader;
-
- group = _app_group_find(ctx->id);
- group->list = g_list_append(group->list, new_ctx);
-
- return g_list_last(group->list);
-}
-
-int _app_group_node_remove_node(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
-
- if (!node)
- return -EINVAL;
-
- ctx = (struct app_group_context_s *)node->data;
- group = _app_group_find(ctx->id);
- group->list = g_list_remove(group->list, ctx);
- __destroy_app_group_context(ctx);
-
- return 0;
-}
-
-static bool __app_group_node_is_leader(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
-
- if (!node)
- return false;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx) {
- _E("App group context is nullptr");
- return false;
- }
-
- group = _app_group_find(ctx->id);
- if (group && g_list_first(group->list) == node)
- return true;
-
- return false;
-}
-
-static app_group_node_h __app_group_node_find_second_leader(const char *id)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
- GList *node;
-
- group = _app_group_find(id);
- if (!group)
- return NULL;
-
- node = g_list_next(group->list);
- if (node) {
- ctx = (struct app_group_context_s *)node->data;
- if (ctx && ctx->can_be_leader) {
- _W("Sencond leader. leader_id(%s), id(%s)",
- id, ctx->id);
- return node;
- }
- }
-
- return NULL;
-}
-
-static void __app_group_remove(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
-
- if (!node)
- return;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx) {
- _E("App group context is nullptr");
- return;
- }
-
- group = _app_group_find(ctx->id);
- if (!group) {
- _E("Failed to find app group. %s", ctx->id);
- return;
- }
-
- group->list = g_list_delete_link(group->list, node);
- __destroy_app_group_context(ctx);
-
- if (g_list_length(group->list) == 0) {
- __app_group_list = g_list_remove(__app_group_list, group);
- __destroy_app_group(group);
- }
-}
-
-static pid_t __app_group_node_get_pid(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return -1;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return -1;
-
- return ctx->pid;
-}
-
-static void __app_group_node_remove(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
- char id[512];
-
- if (!node)
- return;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return;
-
- snprintf(id, sizeof(id), "%s", ctx->id);
-
- __app_group_remove(node);
- ctx = __detach_context_from_recycle_bin(id);
- if (ctx)
- free(ctx);
-}
-
-static struct app_group_context_s *__detach_context_from_app_group(
- const char *id)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
- GList *found;
-
- group = _app_group_find(id);
- if (!group)
- return NULL;
-
- found = g_list_find_custom(group->list, id, __compare_context_id);
- if (!found)
- return NULL;
-
- ctx = (struct app_group_context_s *)found->data;
- group->list = g_list_delete_link(group->list, found);
-
- if (g_list_length(group->list) == 0) {
- __app_group_list = g_list_remove(__app_group_list, group);
- __destroy_app_group(group);
- }
-
- return ctx;
-}
-
-void _app_group_node_clear_top(app_group_node_h node, uid_t uid)
-{
- const char *id;
- int wid;
- pid_t pid;
- GList *iter;
- GList *curr;
-
- if (!node)
- return;
-
- iter = g_list_last(node);
- while (iter && iter != node) {
- curr = iter;
- iter = g_list_previous(iter);
- wid = _app_group_node_get_window(curr);
- _app_group_wayland_detach_window(wid);
- pid = __app_group_node_get_pid(curr);
- aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
- id = _app_group_node_get_id(curr);
- amd_launch_term_sub_inst(pid, id, uid);
- __app_group_node_remove(curr);
- }
-}
-
-static void __app_group_node_remove_leader(const char *id)
-{
- struct app_group_context_s *ctx;
- app_group_node_h node;
- app_group_h group;
- GList *found;
-
- found = g_list_find_custom(__app_group_list, id, __compare_group_id);
- if (!found)
- return;
-
- group = (app_group_h)found->data;
- if (!group)
- return;
-
- if (!g_list_next(group->list))
- return;
-
- node = group->list;
- group->list = NULL;
-
- ctx = (struct app_group_context_s *)node->data;
- if (ctx)
- __destroy_app_group_context(ctx);
-
- node = g_list_delete_link(node, node);
- ctx = (struct app_group_context_s *)node->data;
-
- __app_group_list = g_list_remove(__app_group_list, group);
- __destroy_app_group(group);
-
- group = __create_app_group(ctx->id, ctx->pid);
- if (group) {
- group->list = node;
- __app_group_list = g_list_append(__app_group_list, group);
- }
-}
-
-static const char *__app_group_node_get_next_caller_id(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return NULL;
-
- node = g_list_next(node);
- if (!node)
- return NULL;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return NULL;
-
- return ctx->caller_id;
-}
-
-static bool __app_group_node_can_reroute(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return false;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return false;
-
- return ctx->reroute;
-}
-
-static void __app_group_node_reroute(app_group_node_h node)
-{
- int prev_wid;
- int next_wid;
-
- prev_wid = _app_group_node_get_window(g_list_previous(node));
- if (!prev_wid)
- return;
-
- next_wid = _app_group_node_get_window(g_list_next(node));
- if (!next_wid)
- return;
-
- _D("Reroute");
- _app_group_wayland_attach_window(prev_wid, next_wid);
-}
-
-static bool __app_group_node_is_sub(app_group_node_h node)
-{
- if (!node)
- return false;
-
- if (g_list_previous(node))
- return true;
-
- return false;
-}
-
-static void __app_group_node_remove_full(app_group_node_h node, uid_t uid)
-{
- struct app_group_context_s *ctx;
- const char *caller_id;
-
- if (!node)
- return;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx) {
- _E("App group context is nullptr");
- return;
- }
-
- if (__app_group_node_is_leader(node)) {
- _W("App group leader. %s:%d", ctx->id, ctx->pid);
- if (!__app_group_node_find_second_leader(ctx->id)) {
- _app_group_node_clear_top(node, uid);
- __app_group_node_remove(node);
- } else {
- __app_group_node_remove_leader(ctx->id);
- }
- } else if (__app_group_node_is_sub(node)) {
- _W("App group Sub. %s:%d", ctx->id, ctx->pid);
- caller_id = __app_group_node_get_next_caller_id(node);
- if (__app_group_node_can_reroute(node) ||
- (caller_id && strcmp(caller_id, ctx->id) != 0)) {
- _W("App group reroute");
- __app_group_node_reroute(node);
- } else {
- _W("App group clear top");
- _app_group_node_clear_top(node, uid);
- }
- __app_group_node_remove(node);
- }
-}
-
-static void __app_group_remove_full(pid_t pid, uid_t uid)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
- app_group_node_h node;
- GList *iter;
- GList *iter_node;
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- iter = g_list_next(iter);
- iter_node = g_list_last(group->list);
- while (iter_node) {
- ctx = (struct app_group_context_s *)iter_node->data;
- node = iter_node;
- iter_node = g_list_previous(iter_node);
- if (ctx && ctx->pid == pid)
- __app_group_node_remove_full(node, uid);
- }
- }
-}
-
-static int __app_group_get_nth(app_group_h group, int wid)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- iter = group->list;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx->wid == wid)
- return g_list_position(group->list, iter);
-
- iter = g_list_next(iter);
- }
-
- return -1;
-}
-
-static struct app_group_context_s *__app_group_add(
- pid_t leader_pid, const char *leader_id,
- pid_t pid, const char *id,
- pid_t caller_pid, const char *caller_id,
- app_group_launch_mode_e launch_mode,
- bool can_shift, bool recycle,
- int before_wid)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
- app_group_node_h node;
- GList *found;
- int pos = -1;
-
- if (!id || !leader_id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- ctx = __detach_context_from_recycle_bin(id);
- if (!ctx) {
- ctx = __create_app_group_context(pid, id, caller_pid, caller_id,
- launch_mode, can_shift, recycle);
- if (!ctx) {
- _E("Failed to create app group context. %s:%d",
- id, pid);
- return NULL;
- }
-
- if (leader_pid == pid || ctx->recycle)
- ctx->group_sig = true;
- else
- ctx->group_sig = false;
- }
-
- found = g_list_find_custom(__app_group_list, leader_id,
- __compare_group_id);
- if (!found) {
- group = __create_app_group(leader_id, leader_pid);
- if (!group) {
- _E("Failed to create app group. %s:%d",
- leader_id, leader_pid);
- __destroy_app_group_context(ctx);
- return NULL;
- }
-
- __app_group_list = g_list_append(__app_group_list,
- group);
- found = g_list_last(__app_group_list);
- }
-
- group = (app_group_h)found->data;
-
- node = g_list_find_custom(group->list, id, __compare_context_id);
- if (node) {
- _E("Already exists. %s:%d", id, pid);
- __destroy_app_group_context(ctx);
- return NULL;
- }
-
- if (before_wid > 0)
- pos = __app_group_get_nth(group, before_wid);
-
- if (pos != -1)
- group->list = g_list_insert(group->list, ctx, pos);
- else
- group->list = g_list_append(group->list, ctx);
-
- SECURE_LOGD("[__APP_GROUP__] leader(%s:%d), length(%d)",
- leader_id, leader_pid, g_list_length(group->list));
-
- if (ctx->wid != 0) {
- node = _app_group_node_find_by_wid(ctx->wid);
- _app_group_node_set_window(node, ctx->wid);
- }
-
- return ctx;
-}
-
-static void __set_hint(struct app_group_context_s *ctx, bundle *b)
-{
- const char *str;
-
- if (!ctx || !b)
- return;
-
- str = bundle_get_val(b, AUL_SVC_K_CAN_BE_LEADER);
- if (str && !strcmp(str, "true"))
- ctx->can_be_leader = true;
- str = bundle_get_val(b, AUL_SVC_K_REROUTE);
- if (str && !strcmp(str, "true"))
- ctx->reroute = true;
-}
-
-static void __app_group_start(pid_t leader_pid, const char *leader_id,
- pid_t pid, const char *id, bundle *b, bool can_attach,
- app_group_launch_mode_e launch_mode)
-{
- bool can_shift = false;
- bool recycle = false;
- const char *str;
- const char *caller_id;
- pid_t caller_pid;
- struct app_group_context_s *ctx;
- int before_wid = 0;
-
- _D("app_group_start");
-
- caller_pid = __get_caller_pid(b);
- caller_id = __get_caller_id(b);
- if (!caller_id)
- caller_id = _app_group_get_id(caller_pid);
-
- str = bundle_get_val(b, AUL_SVC_K_SHIFT_WINDOW);
- if (str && !strcmp(str, "true"))
- can_shift = true;
-
- str = bundle_get_val(b, AUL_SVC_K_RECYCLE);
- if (str && !strcmp(str, "true"))
- recycle = true;
-
- str = bundle_get_val(b, AUL_K_INSERT_BEFORE_WINDOW);
- if (str && isdigit(str[0]))
- before_wid = atoi(str);
-
- if (can_attach) {
- ctx = __app_group_add(leader_pid, leader_id, pid, id,
- caller_pid, caller_id, launch_mode,
- false, recycle, before_wid);
- } else {
- ctx = __app_group_add(pid, id, pid, id,
- caller_pid, caller_id, launch_mode,
- can_shift, false, before_wid);
- }
- __set_hint(ctx, b);
-}
-
-static void __app_group_context_do_recycle(struct app_group_context_s *ctx)
-{
- amd_app_status_h app_status;
- const char *appid;
- const char *pkgid;
- const char *comp_type;
- amd_appinfo_h ai;
- uid_t uid;
-
- app_status = amd_app_status_find_by_pid(ctx->pid);
- uid = amd_app_status_get_uid(app_status);
-
- if (ctx->fg) {
- appid = amd_app_status_get_appid(app_status);
- ai = amd_appinfo_find(uid, appid);
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
-
- _D("Send BG signal %s:%s", appid, comp_type);
- aul_send_app_status_change_signal(ctx->pid, appid, pkgid,
- STATUS_BACKGROUND, comp_type);
- amd_app_status_find_service_apps(app_status, STATUS_BG,
- __prepare_to_suspend, true);
- ctx->fg = false;
- }
-
- __recycle_bin = g_list_append(__recycle_bin, ctx);
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END,
- ctx->pid, uid, NULL, NULL);
-}
-
-void _app_group_node_lower(app_group_node_h node, bool *exit)
-{
- struct app_group_context_s *ctx;
-
- if (!node || !exit)
- return;
-
- ctx = (struct app_group_context_s *)node->data;
- if (__app_group_node_is_sub(node)) {
- if (ctx->recycle && ctx->reroute) {
- __app_group_node_reroute(node);
- if (ctx->wid != 0)
- _app_group_wayland_detach_window(ctx->wid);
-
- ctx = __detach_context_from_app_group(ctx->id);
- __app_group_context_do_recycle(ctx);
- *exit = false;
- } else {
- *exit = true;
- }
- return;
- }
-
- *exit = false;
- if (ctx->can_shift) {
- _app_group_wayland_detach_window(ctx->wid);
- ctx->can_shift = false;
- _app_group_wayland_lower_window(ctx->wid);
- }
-}
-
-static void __app_group_restart(const char *id, bundle *b)
-{
- struct app_group_context_s *ctx;
- app_group_node_h node;
- const char *shift_window;
- int caller_wid;
- const char *caller_id;
- app_group_node_h caller_node;
-
- if (!id || !b) {
- _E("Invalid parameter");
- return;
- }
-
- node = _app_group_node_find(id);
- if (!node)
- return;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return;
-
- ctx->caller_pid = __get_caller_pid(b);
-
- if (ctx->caller_id) {
- free(ctx->caller_id);
- ctx->caller_id = NULL;
- }
-
- caller_id = __get_caller_id(b);
- if (!caller_id)
- caller_id = _app_group_get_id(ctx->caller_pid);
-
- ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
-
- if (ctx->can_shift) {
- if (ctx->wid != 0)
- _app_group_wayland_detach_window(ctx->wid);
- ctx->can_shift = false;
- }
-
- shift_window = bundle_get_val(b, AUL_SVC_K_SHIFT_WINDOW);
- if (shift_window && !strcmp(shift_window, "true")) {
- ctx->can_shift = true;
- if (ctx->wid != 0) {
- caller_node = _app_group_node_find(ctx->caller_id);
- caller_wid = _app_group_node_get_window(caller_node);
- if (caller_wid != 0) {
- _app_group_wayland_attach_window(caller_wid,
- ctx->wid);
- } else {
- _E("Invalid caller window id");
- }
- }
- }
-}
-
-static void __app_group_restart_recycle_bin(const char *leader_id,
- const char *id, bundle *b, bool can_attach)
-{
- struct app_group_context_s *ctx;
- app_group_h group;
- app_group_node_h node;
- app_group_node_h caller_node;
- const char *caller_id;
- gint caller_pos;
- GList *found;
-
- if (!id)
- return;
-
- ctx = __detach_context_from_recycle_bin(id);
- if (!ctx)
- return;
-
- ctx->caller_pid = __get_caller_pid(b);
-
- if (ctx->caller_id) {
- free(ctx->caller_id);
- ctx->caller_id = NULL;
- }
-
- caller_id = __get_caller_id(b);
- if (!caller_id)
- caller_id = _app_group_get_id(ctx->caller_pid);
-
- ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
- ctx->group_sig = true;
-
- caller_node = _app_group_node_find(ctx->caller_id);
- if (!caller_node) {
- __app_group_context_do_recycle(ctx);
- return;
- }
-
- if (can_attach) {
- found = g_list_find_custom(__app_group_list, leader_id,
- __compare_group_id);
- if (!found) {
- __app_group_context_do_recycle(ctx);
- return;
- }
-
- group = (app_group_h)found->data;
- } else {
- found = g_list_find_custom(__app_group_list, id,
- __compare_group_id);
- if (!found) {
- group = __create_app_group(ctx->id, ctx->pid);
- if (!group) {
- _E("Failed to create app group. %s:%d",
- ctx->id, ctx->pid);
- __app_group_context_do_recycle(ctx);
- return;
- }
-
- __app_group_list = g_list_append(__app_group_list,
- group);
- found = g_list_last(__app_group_list);
- }
-
- group = (app_group_h)found->data;
- }
-
- caller_pos = g_list_position(group->list, caller_node);
- group->list = g_list_insert(group->list, ctx, caller_pos + 1);
- SECURE_LOGD("[__APP_GROUP__] leader(%s:%d), length(%d)",
- group->leader_id,
- group->leader_pid,
- g_list_length(group->list));
-
- if (ctx->wid != 0) {
- node = _app_group_node_find(id);
- _app_group_node_set_window(node, ctx->wid);
- }
-}
-
-static void __prepare_to_wake(int pid, uid_t uid)
-{
- int ret;
- int dummy = 0;
-
- ret = aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
- sizeof(int), AUL_SOCK_NOREPLY);
- if (ret < 0) {
- _E("Failed to send suspend signal. pid(%d), result(%d)",
- pid, ret);
- }
-
- _D("[__APP_SUSPEND__] pid: %d, uid: %d", pid, uid);
-}
-
-static void __prepare_to_suspend(int pid, uid_t uid)
-{
- int ret;
- int dummy = 0;
-
- ret = aul_sock_send_raw(pid, uid, APP_WAKE, (unsigned char *)&dummy,
- sizeof(int), AUL_SOCK_NOREPLY);
- if (ret < 0) {
- _E("Failed to send wake signal. pid(%d), result(%d)",
- pid, ret);
- }
-
- _D("[__APP_WAKE__] pid: %d, uid: %d", pid, uid);
-}
-
-static void __app_group_send_status(pid_t pid, bool flag, bool force, bool self)
-{
- amd_app_status_h app_status;
- amd_appinfo_h ai;
- const char *appid;
- const char *pkgid;
- bool bg_allowed;
- bool excluded;
- uid_t uid;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return;
- }
-
- appid = amd_app_status_get_appid(app_status);
- uid = amd_app_status_get_uid(app_status);
-
- ai = amd_appinfo_find(uid, appid);
- if (!ai) {
- _E("Failed to find appinfo. %s:%d", appid, uid);
- return;
- }
-
- pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
- bg_allowed = amd_suspend_is_allowed_background(ai);
- excluded = amd_suspend_is_excluded(pid);
-
- _D("Send %s signal %s", flag ? "FG" : "BG", appid);
- aul_send_app_status_change_signal(pid, appid, pkgid,
- flag ? STATUS_FOREGROUND : STATUS_BACKGROUND,
- APP_TYPE_UI);
- if (!excluded && !bg_allowed) {
- amd_app_status_find_service_apps(app_status,
- flag ? STATUS_VISIBLE : STATUS_BG,
- flag ? __prepare_to_wake : __prepare_to_suspend,
- flag ? false : true);
- if (!flag && force && self) {
- __prepare_to_suspend(pid, uid);
- amd_suspend_add_timer(pid);
- }
- }
-}
-
-static void __app_group_set_flag(app_group_h group, pid_t pid, bool flag,
- bool force)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- if (!group)
- return;
-
- iter = group->list;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx && (ctx->fg != flag || force)) {
- __app_group_send_status(ctx->pid, flag, force,
- ctx->pid == pid);
- ctx->fg = flag;
- }
- iter = g_list_next(iter);
- }
-}
-
-static bool __app_group_is_visible(app_group_h group)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- if (!group)
- return false;
-
- iter = group->list;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx && ctx->status == STATUS_VISIBLE)
- return true;
-
- iter = g_list_next(iter);
- }
-
- return false;
-}
-
-static bool __app_group_can_attach_window(bundle *b, const char *appid,
- app_group_launch_mode_e *launch_mode, uid_t uid)
-{
- const char *str;
- const char *mode = NULL;
- const char *comp_type;
- const char *comp_id;
- const char *type;
- amd_appinfo_h ai;
- amd_compinfo_h ci;
-
- ai = amd_appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
- } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
- comp_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
- if (!comp_id)
- return false;
-
- ci = amd_compinfo_find(uid, comp_id);
- if (!ci)
- return false;
-
- type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
- if (!type || strcmp(type, "frame") != 0)
- return false;
-
- mode = amd_compinfo_get_value(ci,
- AMD_COMPINFO_TYPE_LAUNCH_MODE);
- }
-
- if (mode && !strcmp(mode, "caller"))
- *launch_mode = APP_GROUP_LAUNCH_MODE_CALLER;
- else if (mode && !strcmp(mode, "group"))
- *launch_mode = APP_GROUP_LAUNCH_MODE_GROUP;
- else
- *launch_mode = APP_GROUP_LAUNCH_MODE_SINGLE;
-
- switch (*launch_mode) {
- case APP_GROUP_LAUNCH_MODE_CALLER:
- _D("Launch mode is caller");
- str = bundle_get_val(b, APP_SVC_K_LAUNCH_MODE);
- if (str && !strcmp(str, "group"))
- return true;
- break;
- case APP_GROUP_LAUNCH_MODE_GROUP:
- return true;
- default:
- return false;
- }
-
- return false;
-}
-
-static bool __app_group_can_be_leader(bundle *b)
-{
- const char *str;
-
- str = bundle_get_val(b, AUL_SVC_K_CAN_BE_LEADER);
- if (str && !strcmp(str, "true"))
- return true;
-
- return false;
-}
-
-static void __app_group_context_remove_from_recycle_bin(pid_t pid)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- iter = __recycle_bin;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- iter = g_list_next(iter);
- if (ctx && ctx->pid == pid) {
- __recycle_bin = g_list_remove(__recycle_bin, ctx);
- __destroy_app_group_context(ctx);
- }
- }
-}
-
-static bool __app_group_is_group_mode(bundle *kb, uid_t uid)
-{
- const char *str;
- const char *mode = NULL;
- const char *appid;
- const char *comp_type;
- const char *comp_id;
- const char *type;
- amd_appinfo_h ai;
- amd_compinfo_h ci;
-
- if (!kb)
- return false;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (!appid)
- return false;
-
- ai = amd_appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
- } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
- comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- if (!comp_id)
- return false;
-
- ci = amd_compinfo_find(uid, comp_id);
- if (!ci)
- return false;
-
- type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
- if (!type || strcmp(type, "frame") != 0)
- return false;
-
- mode = amd_compinfo_get_value(ci,
- AMD_COMPINFO_TYPE_LAUNCH_MODE);
- }
-
- if (mode && !strcmp(mode, "caller")) {
- str = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
- if (str && !strcmp(str, "group"))
- return true;
- } else if (mode && !strcmp(mode, "group")) {
- return true;
- }
-
- return false;
-}
-
-void _app_group_get_leader_pids(int *cnt, pid_t **pids)
-{
- app_group_h group;
- GList *iter;
- pid_t *leader_pids;
- int size;
- int idx = 0;
-
-
- size = g_list_length(__app_group_list);
- if (size > 0) {
- leader_pids = (pid_t *)calloc(size, sizeof(pid_t));
- if (!leader_pids) {
- _E("Out of memory");
- return;
- }
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- if (group)
- leader_pids[idx++] = group->leader_pid;
-
- iter = g_list_next(iter);
- }
-
- *cnt = size;
- *pids = leader_pids;
- }
-}
-
-char **_app_group_get_leader_ids(int *cnt)
-{
- app_group_h group;
- GList *iter;
- char **leader_ids;
- int idx = 0;
- int size;
-
- size = g_list_length(__app_group_list);
- if (size == 0)
- return NULL;
-
- leader_ids = (char **)calloc(size + 1, sizeof(char *));
- if (!leader_ids) {
- _E("Out of memory");
- return NULL;
- }
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- if (group && group->leader_id)
- leader_ids[idx++] = strdup(group->leader_id);
-
- iter = g_list_next(iter);
- }
-
- *cnt = size;
-
- return leader_ids;
-}
-
-int _app_group_get_count(app_group_h group)
-{
- if (!group)
- return -1;
-
- return g_list_length(group->list);
-}
-
-int _app_group_foreach_context(app_group_h group,
- app_group_foreach_context_cb callback,
- void *user_data)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- if (!group)
- return -1;
-
- iter = group->list;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx) {
- callback(ctx->id, ctx->pid, ctx->wid, ctx->fg,
- user_data);
- }
- iter = g_list_next(iter);
- }
-
- return 0;
-}
-
-void _app_group_get_group_pids(app_group_h group, int *cnt, pid_t **pids)
-{
- struct app_group_context_s *ctx;
- GList *iter;
- int size;
- pid_t *group_pids;
- int idx = 0;
-
- if (!group)
- return;
-
- size = g_list_length(group->list);
- if (size == 0)
- return;
-
- group_pids = calloc(size, sizeof(pid_t));
- if (!group_pids) {
- _E("Out of memory");
- return;
- }
-
- iter = group->list;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx)
- group_pids[idx++] = ctx->pid;
- iter = g_list_next(iter);
- }
-
- *cnt = size;
- *pids = group_pids;
-}
-
-static void __app_group_context_set_status(struct app_group_context_s *ctx,
- struct app_group_context_s *last_ctx,
- pid_t leader_pid, pid_t pid,
- int status, bool force)
-{
- amd_app_status_h app_status;
- const char *pkgid;
- app_group_h group;
-
- if (status > 0)
- ctx->status = status;
-
- if ((last_ctx && last_ctx->wid != 0) ||
- status == STATUS_VISIBLE ||
- force == true) {
- group = _app_group_find(ctx->id);
- if (__app_group_is_visible(group)) {
- __app_group_set_flag(group, pid, true, force);
- if (!ctx->group_sig && leader_pid != pid) {
- app_status = amd_app_status_find_by_pid(pid);
- pkgid = amd_app_status_get_pkgid(app_status);
- _D("Send group signal %d", pid);
- aul_send_app_group_signal(leader_pid, pid,
- pkgid);
- ctx->group_sig = true;
- }
- } else {
- __app_group_set_flag(group, pid, false, force);
- }
- }
-}
-
-static int __app_group_node_set_status(app_group_node_h node, int status,
- bool force)
-{
- struct app_group_context_s *ctx;
- struct app_group_context_s *last_ctx = NULL;
- struct app_group_context_s *first_ctx = NULL;
- pid_t leader_pid = -1;
- pid_t pid;
-
- if (!node)
- return -1;
-
- ctx = (struct app_group_context_s *)node->data;
- pid = ctx->pid;
-
- node = g_list_last(node);
- if (node)
- last_ctx = (struct app_group_context_s *)node->data;
-
- node = g_list_first(node);
- if (node) {
- first_ctx = (struct app_group_context_s *)node->data;
- leader_pid = first_ctx->pid;
- }
-
- __app_group_context_set_status(ctx, last_ctx, leader_pid, pid,
- status, force);
-
- return 0;
-}
-
-bool _app_group_node_get_fg_flag(app_group_node_h node)
-{
- struct app_group_context_s *ctx;
-
- if (!node)
- return false;
-
- ctx = (struct app_group_context_s *)node->data;
- if (!ctx)
- return false;
-
- return ctx->fg;
-}
-
-static int __app_group_can_start(const char *appid, bundle *b,
- bool *can_attach, pid_t *leader_pid,
- app_group_launch_mode_e *mode, uid_t uid)
-{
- pid_t caller_pid;
- const char *caller_id;
- const char *leader_id = NULL;
- pid_t caller_wid;
- app_group_node_h node;
- app_group_h group;
- int ret = 0;
-
- if (__app_group_can_attach_window(b, appid, mode, uid)) {
- *can_attach = true;
- caller_pid = __get_caller_pid(b);
- caller_id = __get_caller_id(b);
- if (!caller_id) {
- caller_id = _app_group_get_id(caller_pid);
- if (!caller_id) {
- _E("Failed to get caller id. %d", caller_pid);
- ret = -1;
- goto end;
- }
- }
-
- group = _app_group_find(caller_id);
- *leader_pid = _app_group_get_leader_pid(group);
- if (*leader_pid != -1) {
- leader_id = group->leader_id;
- node = _app_group_node_find(caller_id);
- caller_wid = _app_group_node_get_window(node);
- if (caller_wid == 0) {
- _W("Caller(%d) window isn't ready",
- caller_pid);
- if (__app_group_can_be_leader(b))
- *can_attach = false;
- else
- *can_attach = true;
- }
- } else {
- _E("Cannot find leader pid");
- if (__app_group_can_be_leader(b)) {
- *can_attach = false;
- } else {
- ret = -1;
- goto end;
- }
- }
- }
-
-end:
- __launch_context.can_attach = *can_attach;
- __launch_context.mode = *mode;
- __launch_context.leader_pid = *leader_pid;
- __launch_context.leader_id = leader_id;
-
- _W("[__APP_GROUP__] can_attach(%d), mode(%d), leader(%s:%d)",
- __launch_context.can_attach,
- __launch_context.mode,
- __launch_context.leader_id ? __launch_context.leader_id : "null",
- __launch_context.leader_pid);
-
- return ret;
-}
-
-static int __app_group_find_pid_from_recycle_bin(const char *appid)
-{
- struct app_group_context_s *ctx;
- amd_app_status_h app_status;
- const char *appid_from_bin;
- GList *iter;
-
- if (!appid)
- return -1;
-
- iter = __recycle_bin;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx) {
- app_status = amd_app_status_find_by_pid(ctx->pid);
- appid_from_bin = amd_app_status_get_appid(app_status);
- if (appid_from_bin && !strcmp(appid_from_bin, appid))
- return ctx->pid;
- }
-
- iter = g_list_next(iter);
- }
-
- return -1;
-}
-
-void _app_group_get_idle_pids(int *cnt, pid_t **pids)
-{
- struct app_group_context_s *ctx;
- GList *iter;
- pid_t *idle_pids;
- int size;
- int idx = 0;
-
- size = g_list_length(__recycle_bin);
- if (size <= 0)
- return;
-
- idle_pids = calloc(size, sizeof(pid_t));
- if (!idle_pids) {
- _E("Out of memory");
- return;
- }
-
- iter = __recycle_bin;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx)
- idle_pids[idx++] = ctx->pid;
- iter = g_list_next(iter);
- }
-
- *cnt = size;
- *pids = idle_pids;
-}
-
-int _app_group_get_idle_count(void)
-{
- return g_list_length(__recycle_bin);
-}
-
-int _app_group_foreach_idle_context(app_group_foreach_context_cb callback,
- void *user_data)
-{
- struct app_group_context_s *ctx;
- GList *iter;
-
- iter = __recycle_bin;
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- if (ctx) {
- callback(ctx->id, ctx->pid, ctx->wid, ctx->fg,
- user_data);
- }
- iter = g_list_next(iter);
- }
-
- return 0;
-}
-
-static int __on_app_status_update_status_end(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- bool force = (bool)arg1;
- bool update_group_info = (bool)arg2;
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- app_group_node_h node;
- pid_t pid;
- int status;
- int app_type;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type != AMD_AT_UI_APP)
- return AMD_NOTI_CONTINUE;
-
- status = amd_app_status_get_status(app_status);
- if (update_group_info && status != STATUS_DYING) {
- pid = amd_app_status_get_pid(app_status);
- node = _app_group_node_find(_app_group_get_id(pid));
- __app_group_node_set_status(node, status, force);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_term_app_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- app_group_node_h node;
- app_group_h group;
- const char *id;
- pid_t pid = (pid_t)arg1;
- amd_request_h req = (amd_request_h)arg3;
- struct app_group_context_s *ctx;
- amd_app_status_h app_status;
- GList *iter;
- uid_t uid;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status)
- return AMD_NOTI_CONTINUE;
-
- if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
- return AMD_NOTI_CONTINUE;
-
- id = _app_group_get_id(pid);
- node = _app_group_node_find(id);
- if (__app_group_node_is_leader(node)) {
- group = _app_group_find(id);
- if (!group || !group->list)
- return AMD_NOTI_CONTINUE;
-
- uid = amd_request_get_target_uid(req);
- iter = g_list_last(group->list);
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- node = iter;
- iter = g_list_previous(iter);
- if (ctx) {
- if (ctx->pid != group->leader_pid) {
- amd_launch_term_sub_inst(ctx->pid,
- ctx->id, uid);
- }
- __app_group_node_remove(node);
- }
- }
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_term_bgapp_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- struct app_group_context_s *ctx;
- amd_app_status_h app_status;
- app_group_node_h node;
- app_group_h group;
- pid_t pid = (pid_t)arg1;
- amd_request_h req = (amd_request_h)arg3;
- const char *id;
- GList *iter;
- int status;
- uid_t uid;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status)
- return AMD_NOTI_CONTINUE;
-
- if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
- return AMD_NOTI_CONTINUE;
-
- id = _app_group_get_id(pid);
- node = _app_group_node_find(id);
- if (__app_group_node_is_leader(node)) {
- group = _app_group_find(id);
- if (!group || !group->list)
- return AMD_NOTI_CONTINUE;
-
- ctx = (struct app_group_context_s *)g_list_last(group->list);
- if (!ctx)
- return AMD_NOTI_CONTINUE;
-
- app_status = amd_app_status_find_by_pid(ctx->pid);
- status = amd_app_status_get_status(app_status);
- if (status != STATUS_BG)
- return AMD_NOTI_CONTINUE;
-
- uid = amd_request_get_target_uid(req);
- iter = g_list_last(group->list);
- while (iter) {
- ctx = (struct app_group_context_s *)iter->data;
- node = iter;
- iter = g_list_previous(iter);
- if (ctx) {
- if (ctx->pid != group->leader_pid) {
- amd_launch_term_sub_inst(ctx->pid,
- ctx->id, uid);
- }
- __app_group_node_remove(node);
- }
- }
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __app_group_prepare(int status, uid_t uid, amd_launch_context_h h,
- bundle *kb)
-{
- app_group_launch_mode_e launch_mode = APP_GROUP_LAUNCH_MODE_SINGLE;
- bool can_attach = false;
- pid_t leader_pid = -1;
- const char *appid;
- pid_t pid;
- int ret;
-
- appid = amd_launch_context_get_appid(h);
- pid = amd_launch_context_get_pid(h);
- if (pid <= 0 || status == STATUS_DYING) {
- ret = __app_group_can_start(appid, kb, &can_attach,
- &leader_pid, &launch_mode, uid);
- if (ret != 0) {
- _E("Can't make group info");
- return -1;
- }
-
- if (can_attach && leader_pid == -1) {
- _E("Can't launch singleton app in the same group");
- return -1;
- }
- }
-
- if (pid == -1 && can_attach) {
- pid = __app_group_find_pid_from_recycle_bin(appid);
- amd_launch_context_set_pid(h, pid);
- }
-
- return 0;
-}
-
-static int __on_launch_prepare_ui_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int status = arg1;
- uid_t uid = (uid_t)arg2;
- amd_launch_context_h h = (amd_launch_context_h)arg3;
- bundle *kb = data;
- int ret;
-
- if (__app_group_is_group_mode(kb, uid)) {
- amd_launch_context_set_pid(h, -1);
- amd_launch_context_set_subapp(h, true);
- amd_launch_context_set_app_status(h, NULL);
- } else {
- if (amd_launch_context_is_new_instance(h))
- amd_launch_context_set_subapp(h, true);
- else
- amd_launch_context_set_subapp(h, false);
- }
-
- ret = __app_group_prepare(status, uid, h, data);
- if (ret < 0)
- return AMD_NOTI_STOP;
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_prepare_component_based_start(const char *msg,
- int arg1, int arg2, void *arg3, bundle *data)
-{
- int status = arg1;
- uid_t uid = (uid_t)arg2;
- amd_launch_context_h h = (amd_launch_context_h)arg3;
- bundle *kb = data;
- amd_comp_status_h comp_status = NULL;
- const char *id;
- int ret;
-
- id = amd_launch_context_get_instance_id(h);
- if (status != COMP_STATUS_DESTROYED) {
- comp_status = amd_comp_status_find_by_instance_id(id);
- if (comp_status)
- status = amd_comp_status_get_status(comp_status);
- else
- status = COMP_STATUS_DESTROYED;
- }
-
- if (__app_group_is_group_mode(kb, uid)) {
- amd_launch_context_set_subapp(h, true);
- amd_launch_context_set_comp_status(h, NULL);
- __launch_context.new_instance = true;
- } else {
- if (!comp_status || status == COMP_STATUS_DESTROYED) {
- __launch_context.new_instance = true;
- } else {
- __launch_context.new_instance =
- amd_launch_context_is_new_instance(h);
- }
- }
-
- ret = __app_group_prepare(status, uid, h, data);
- if (ret < 0)
- return AMD_NOTI_STOP;
-
- return AMD_NOTI_CONTINUE;
-}
-
-static void __terminate_unmanageable_app(amd_app_status_h app_status)
-{
- app_group_h group;
- amd_app_status_h leader_status;
- amd_appinfo_h ai;
- const char *taskmanage;
- const char *appid;
- bool bg_allowed;
- bool excluded;
- GList *iter;
- uid_t uid;
-
- if (!amd_app_status_is_home_app(app_status))
- return;
-
- iter = __app_group_list;
- while (iter) {
- group = (app_group_h)iter->data;
- iter = g_list_next(iter);
- if (!group)
- continue;
-
- leader_status = amd_app_status_find_by_pid(group->leader_pid);
- if (!leader_status)
- continue;
-
- if (amd_app_status_is_home_app(leader_status))
- continue;
-
- if (amd_app_status_get_status(leader_status) != STATUS_BG)
- continue;
-
- appid = amd_app_status_get_appid(leader_status);
- uid = amd_app_status_get_uid(leader_status);
-
- ai = amd_appinfo_find(uid, appid);
- taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
- bg_allowed = amd_suspend_is_allowed_background(ai);
- excluded = amd_suspend_is_excluded(group->leader_pid);
- if (taskmanage && !strcmp(taskmanage, "false") &&
- !bg_allowed && !excluded) {
- SECURE_LOGW("Terminate leader app(%s:%d)",
- appid, group->leader_pid);
- aul_send_app_terminate_request_signal(group->leader_pid,
- NULL, NULL, NULL);
- amd_launch_term_sub_inst(group->leader_pid,
- group->leader_id, uid);
- }
- }
-}
-
-static int __on_launch_status_fg(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
-
- if (TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP)
- __terminate_unmanageable_app(app_status);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static gint __compare_app_status_for_sorting(gconstpointer p1, gconstpointer p2)
-{
- amd_app_status_h app_status1 = (amd_app_status_h)p1;
- amd_app_status_h app_status2 = (amd_app_status_h)p2;
- int app_group_cnt1;
- int app_group_cnt2;
- int *app_group_pids1;
- int *app_group_pids2;
- int fg_cnt1;
- int fg_cnt2;
- int timestamp1;
- int timestamp2;
- const char *id1;
- const char *id2;
- app_group_h app_group1;
- app_group_h app_group2;
-
- if (amd_app_status_get_app_type(app_status1) != AMD_AT_UI_APP ||
- amd_app_status_get_app_type(app_status2) != AMD_AT_UI_APP)
- return 0;
-
- timestamp1 = amd_app_status_get_timestamp(app_status1);
- timestamp2 = amd_app_status_get_timestamp(app_status2);
- if (timestamp1 > timestamp2)
- return 1;
- else if (timestamp1 < timestamp2)
- return -1;
-
- id1 = amd_app_status_get_leader_id(app_status1);
- app_group1 = _app_group_find(id1);
- _app_group_get_group_pids(app_group1, &app_group_cnt1,
- &app_group_pids1);
- id2 = amd_app_status_get_leader_id(app_status2);
- app_group2 = _app_group_find(id2);
- _app_group_get_group_pids(app_group2, &app_group_cnt2,
- &app_group_pids2);
- free(app_group_pids1);
- free(app_group_pids2);
-
- if (app_group_cnt1 < app_group_cnt2)
- return 1;
- else if (app_group_cnt1 > app_group_cnt2)
- return -1;
-
- fg_cnt1 = amd_app_status_get_fg_cnt(app_status1);
- fg_cnt2 = amd_app_status_get_fg_cnt(app_status2);
- if (fg_cnt1 > fg_cnt2)
- return 1;
- else if (fg_cnt1 < fg_cnt2)
- return -1;
-
- return 0;
-}
-
-static int __on_app_status_term_bg_apps(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_term_bg_apps(__compare_app_status_for_sorting);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_comp_status_notify_exit(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg2;
- const char *id = (const char *)arg3;
- app_group_node_h node;
-
- node = _app_group_node_find(id);
- if (!node)
- return AMD_NOTI_CONTINUE;
-
- __app_group_node_remove_full(node, uid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_comp_status_update_status_end(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- bool update_group_info = (bool)arg2;
- amd_comp_status_h comp_status = (amd_comp_status_h)arg3;
- app_group_node_h node;
- const char *id;
- int status;
-
- status = amd_comp_status_get_status(comp_status);
- if (update_group_info && status != COMP_STATUS_DESTROYED) {
- id = amd_comp_status_get_instance_id(comp_status);
- node = _app_group_node_find(id);
-
- if (status == COMP_STATUS_RESUMED)
- status = STATUS_VISIBLE;
- else
- status = STATUS_BG;
-
- __app_group_node_set_status(node, status, false);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_app_status_app_register_pid(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- pid_t pid = (pid_t)arg1;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comp_type;
- const char *id;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- id = _app_group_get_id(pid);
- __app_group_start(pid, id, pid, id, data, false,
- APP_GROUP_LAUNCH_MODE_SINGLE);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- bool new_process = (bool)arg2;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comp_type;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI))
- __launch_context.new_instance = new_process;
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_launch_complete_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- pid_t pid = (pid_t)arg1;
- uid_t uid = (uid_t)arg2;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- amd_appinfo_h ci;
- const char *comp_type;
- const char *comp_id;
- const char *type;
- const char *id = NULL;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- id = _app_group_get_id(pid);
- } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
- comp_id = bundle_get_val(data, AUL_K_COMPONENT_ID);
- if (!comp_id)
- return AMD_NOTI_CONTINUE;
-
- ci = amd_compinfo_find(uid, comp_id);
- if (!ci)
- return AMD_NOTI_CONTINUE;
-
- type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
- if (!type || strcmp(type, "frame") != 0)
- return AMD_NOTI_CONTINUE;
-
- id = bundle_get_val(data, AUL_K_INSTANCE_ID);
- } else {
- return AMD_NOTI_CONTINUE;
- }
-
- if (!id) {
- _E("Failed to get id. pid(%d)", pid);
- return AMD_NOTI_CONTINUE;
- }
-
- if (__launch_context.new_instance) {
- __app_group_start(__launch_context.leader_pid,
- __launch_context.leader_id,
- pid, id, data,
- __launch_context.can_attach,
- __launch_context.mode);
- SECURE_LOGI("Add app group %s:%d", id, pid);
- } else {
- __app_group_restart(id, data);
- __app_group_restart_recycle_bin(__launch_context.leader_id, id,
- data, __launch_context.can_attach);
- SECURE_LOGI("Restart app group %s:%d", id, pid);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_app_status_add(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- int app_type;
-
- if (__launch_context.leader_id == NULL)
- return AMD_NOTI_CONTINUE;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_UI_APP) {
- amd_app_status_set_leader_id(app_status,
- __launch_context.leader_id);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_comp_status_add(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int ret;
- amd_comp_status_h comp_status = (amd_comp_status_h)arg3;
- amd_comp_type_e comp_type;
-
- if (__launch_context.leader_id == NULL)
- return AMD_NOTI_CONTINUE;
-
- comp_type = amd_comp_status_get_comp_type(comp_status);
- if (comp_type == AMD_CT_FRAME_COMP) {
- ret = amd_comp_status_set_leader_id(comp_status,
- __launch_context.leader_id);
- if (ret < 0) {
- _E("Fail to set leader id (%s)",
- __launch_context.leader_id);
- }
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- pid_t pid;
- uid_t uid;
-
- if (!app_status)
- return AMD_NOTI_STOP;
-
- pid = amd_app_status_get_pid(app_status);
- uid = amd_app_status_get_uid(app_status);
-
- __app_group_remove_full(pid, uid);
- __app_group_context_remove_from_recycle_bin(pid);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static bool __is_running_instance(bundle *kb, uid_t uid)
-{
- amd_app_status_h app_status;
- amd_comp_status_h comp_status;
- const char *instance_id;
- const char *app_id;
- int status;
-
- app_id = bundle_get_val(kb, AUL_K_APPID);
- instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- app_status = amd_app_status_find_by_instance_id(app_id,
- instance_id, uid);
- if (app_status) {
- if (amd_app_status_get_status(app_status) != STATUS_DYING)
- return true;
-
- return false;
- }
-
- comp_status = amd_comp_status_find_by_instance_id(instance_id);
- if (comp_status) {
- status = amd_comp_status_get_status(comp_status);
- if (status != COMP_STATUS_DESTROYED)
- return true;
-
- return false;
- }
-
- return false;
-}
-
-static int __on_launch_app_start_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_request_h req = (amd_request_h)arg3;
- bundle *kb = data;
- const char *instance_id;
- const char *launch_mode;
- uid_t uid;
-
- instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- if (!instance_id)
- return AMD_NOTI_CONTINUE;
-
- launch_mode = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
- if (!launch_mode || !strcmp(launch_mode, "single"))
- return AMD_NOTI_CONTINUE;
-
- uid = amd_request_get_target_uid(req);
- if (__app_group_is_group_mode(kb, uid)) {
- if (!__is_running_instance(kb, uid)) {
- bundle_del(kb, AUL_K_NEW_INSTANCE);
- bundle_add(kb, AUL_K_NEW_INSTANCE, "true");
- }
- } else {
- _W("Wrong request");
- bundle_del(kb, AUL_K_INSTANCE_ID);
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-int _app_group_init(void)
-{
- int r;
-
- _D("app group init");
- r = _app_group_wayland_init();
- if (r < 0) {
- _E("Failed to initialize app group wayland");
- return -1;
- }
-
- r = _app_group_request_init();
- if (r < 0) {
- _E("Failed to initialize app group request");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
- __on_app_status_add);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID,
- __on_app_status_app_register_pid);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
- __on_app_status_update_status_end);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS,
- __on_app_status_term_bg_apps);
- amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_ADD,
- __on_comp_status_add);
- amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT,
- __on_comp_status_notify_exit);
- amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END,
- __on_comp_status_update_status_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- __on_launch_complete_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
- __on_launch_complete_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
- __on_launch_status_fg);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_TERM_APP_START,
- __on_launch_term_app_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START,
- __on_launch_term_bgapp_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
- __on_launch_prepare_ui_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
- __on_launch_prepare_component_based_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_START,
- __on_launch_app_start_start);
-
- return 0;
-}
-
-void _app_group_fini(void)
-{
- _app_group_request_fini();
- _app_group_wayland_fini();
-
- if (__app_group_list)
- g_list_free_full(__app_group_list, __destroy_app_group);
-
- if (__recycle_bin)
- g_list_free_full(__recycle_bin, __destroy_app_group_context);
-
- _D("app group fini");
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <glib.h>
-#include <dlog.h>
-#include <aul.h>
-#include <aul_svc.h>
-#include <bundle_internal.h>
-#include <aul_sock.h>
-#include <system_info.h>
-#include <amd.h>
-
-#include "amd_screen_connector.h"
-#include "app_group.h"
-#include "app_group_request.h"
-#include "app_group_wayland.h"
-#include "app_group_private.h"
-
-static app_group_h __find_app_group_by_pid(pid_t pid)
-{
- const char *id;
-
- id = _app_group_get_id(pid);
-
- return _app_group_find(id);
-}
-
-static app_group_node_h __find_app_group_node_by_pid(pid_t pid)
-{
- const char *id;
-
- id = _app_group_get_id(pid);
-
- return _app_group_node_find(id);
-}
-
-static int __get_window_by_pid(pid_t pid)
-{
- app_group_node_h node;
-
- node = __find_app_group_node_by_pid(pid);
-
- return _app_group_node_get_window(node);
-}
-
-static int __get_window_by_appid(const char *appid, uid_t uid)
-{
- amd_app_status_h app_status;
- pid_t pid;
-
- app_status = amd_app_status_find_by_appid(appid, uid);
- if (!app_status) {
- _E("Failed to find app status. appid(%s)", appid);
- return 0;
- }
-
- pid = amd_app_status_get_pid(app_status);
-
- return __get_window_by_pid(pid);
-}
-
-static int __dispatch_app_group_get_window(amd_request_h req)
-{
- app_group_node_h node;
- const char *pid_str;
- pid_t pid = -1;
- int wid;
- bundle *b;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str && isdigit(pid_str[0]))
- pid = atoi(pid_str);
-
- if (pid <= 1) {
- _E("Invalid process ID(%d)", pid);
- amd_request_send_result(req, -1);
- return -1;
- }
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- amd_request_send_result(req, -1);
- return -1;
- }
-
- wid = _app_group_node_get_window(node);
- if (wid <= 0)
- _E("Failed to get window");
-
- amd_request_send_result(req, wid);
-
- _I("pid(%d), wid(%u)", pid, wid);
-
- return 0;
-}
-
-static int __dispatch_app_group_set_window(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- pid_t pid = amd_request_get_pid(req);
- app_group_node_h node;
- const char *wid_str;
- int wid = -1;
- bundle *b;
- int ret;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- return -1;
- }
-
- wid_str = bundle_get_val(b, AUL_K_WID);
- if (wid_str && isdigit(wid_str[0]))
- wid = atoi(wid_str);
-
- if (wid <= 0) {
- _E("Failed to get window ID");
- return -1;
- }
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- return -1;
- }
-
- ret = _app_group_node_set_window(node, wid);
- if (ret < 0) {
- _E("Failed to set window. pid(%d), wid(%d)",
- pid, wid);
- return -1;
- }
-
- _screen_connector_add_app_screen(pid, wid, NULL, uid);
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET, pid, wid, NULL, NULL);
- _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
-
- return ret;
-}
-
-static int __dispatch_app_group_get_fg_flag(amd_request_h req)
-{
- app_group_node_h node;
- const char *pid_str;
- pid_t pid = -1;
- bundle *b;
- bool fg;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, 0);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str && isdigit(pid_str[0]))
- pid = atoi(pid_str);
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- amd_request_send_result(req, 0);
- return -1;
- }
-
- fg = _app_group_node_get_fg_flag(node);
- amd_request_send_result(req, (int)fg);
-
- _I("pid(%d), fg(%s)", pid, fg ? "true" : "false");
-
- return 0;
-}
-
-static int __dispatch_app_group_clear_top(amd_request_h req)
-{
- pid_t pid = amd_request_get_pid(req);
- uid_t uid = amd_request_get_target_uid(req);
- app_group_node_h node;
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- amd_request_send_result(req, 0);
- return -1;
- }
-
- _app_group_node_clear_top(node, uid);
- amd_request_send_result(req, 0);
-
- _I("pid(%d)", pid);
-
- return 0;
-}
-
-static int __dispatch_app_group_get_leader_pid(amd_request_h req)
-{
- app_group_h app_group;
- const char *pid_str;
- pid_t leader_pid;
- pid_t pid = -1;
- bundle *b;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str && isdigit(pid_str[0]))
- pid = atoi(pid_str);
-
- app_group = __find_app_group_by_pid(pid);
- if (!app_group) {
- _E("Failed to find app group. pid(%d)", pid);
- amd_request_send_result(req, -1);
- return -1;
- }
-
- leader_pid = _app_group_get_leader_pid(app_group);
- amd_request_send_result(req, leader_pid);
- _I("pid(%d), leader_pid(%d)", pid, leader_pid);
-
- return 0;
-}
-
-static int __dispatch_app_group_get_leader_pids(amd_request_h req)
-{
- unsigned char empty[1] = { 0, };
- pid_t *pids = NULL;
- int cnt = 0;
-
- _app_group_get_leader_pids(&cnt, &pids);
-
- if (pids == NULL || cnt == 0) {
- amd_request_send_raw(req, APP_GROUP_GET_LEADER_PIDS, empty, 0);
- } else {
- amd_request_send_raw(req, APP_GROUP_GET_LEADER_PIDS,
- (unsigned char *)pids, cnt * sizeof(int));
- }
-
- if (pids != NULL)
- free(pids);
-
- _I("count(%d)", cnt);
-
- return 0;
-}
-
-static int __dispatch_app_group_get_idle_pids(amd_request_h req)
-{
- unsigned char empty[1] = { 0, };
- pid_t *pids = NULL;
- int cnt = 0;
-
- _app_group_get_idle_pids(&cnt, &pids);
- if (pids == NULL || cnt == 0) {
- amd_request_send_raw(req, APP_GROUP_GET_IDLE_PIDS, empty, 0);
- } else {
- amd_request_send_raw(req, APP_GROUP_GET_IDLE_PIDS,
- (unsigned char *)pids, cnt * sizeof(int));
- }
-
- if (pids != NULL)
- free(pids);
-
- _I("count(%d)", cnt);
-
- return 0;
-}
-
-static int __dispatch_app_group_get_group_pids(amd_request_h req)
-{
- unsigned char empty[1] = { 0 };
- app_group_h app_group;
- pid_t leader_pid = -1;
- pid_t *pids = NULL;
- int cnt = 0;
- char *buf;
- bundle *b;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
- return -1;
- }
-
- bundle_get_str(b, AUL_K_LEADER_PID, &buf);
- if (buf && isdigit(buf[0]))
- leader_pid = atoi(buf);
-
- if (leader_pid <= 1) {
- _E("Failed to get leader process ID");
- amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
- return -1;
- }
-
- app_group = __find_app_group_by_pid(leader_pid);
- _app_group_get_group_pids(app_group, &cnt, &pids);
- if (pids == NULL || cnt == 0) {
- amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
- } else {
- amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS,
- (unsigned char *)pids, cnt * sizeof(int));
- }
-
- if (pids != NULL)
- free(pids);
-
- _I("leader_pid(%d), count(%d)", leader_pid, cnt);
-
- return 0;
-}
-
-static int __dispatch_app_group_lower(amd_request_h req)
-{
- pid_t pid = amd_request_get_pid(req);
- app_group_node_h node;
- bool exit = false;
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- amd_request_send_result(req, 0);
- return -1;
- }
-
- _app_group_node_lower(node, &exit);
- amd_request_send_result(req, (int)exit);
- _I("pid(%d), exit(%s)", pid, exit ? "true" : "false");
-
- return 0;
-}
-
-static int __app_group_activate_below(pid_t pid, uid_t uid,
- const char *below_appid)
-{
- int below_wid;
- int wid;
-
- if (!below_appid) {
- _E("Invalid parameter");
- return -1;
- }
-
- wid = __get_window_by_pid(pid);
- if (wid == 0) {
- _E("Caller(%d) window is not ready", pid);
- return -1;
- }
-
- below_wid = __get_window_by_appid(below_appid, uid);
- if (below_wid == 0) {
- _E("Below app(%s) window is not ready", below_appid);
- return -1;
- }
-
- _app_group_wayland_activate_below(wid, below_wid);
-
- return 0;
-}
-
-static int __dispatch_app_group_activate_below(amd_request_h req)
-{
- const char *appid;
- int ret;
- bundle *b;
- pid_t pid;
- uid_t uid;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get appid");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- pid = amd_request_get_pid(req);
- uid = amd_request_get_target_uid(req);
-
- ret = __app_group_activate_below(pid, uid, appid);
- amd_request_send_result(req, ret);
- _I("pid(%d), appid(%s), result(%d)", pid, appid, ret);
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_ACTIVATE_BELOW, pid, (int)uid,
- (void *)appid, b);
-
- return 0;
-}
-
-static int __app_group_activate_above(pid_t pid, uid_t uid,
- const char *above_appid)
-{
- int above_wid;
- int wid;
-
- if (!above_appid) {
- _E("Invalid parameter");
- return -1;
- }
-
- wid = __get_window_by_pid(pid);
- if (wid == 0) {
- _E("Caller(%d) window is not ready", pid);
- return -1;
- }
-
- above_wid = __get_window_by_appid(above_appid, uid);
- if (above_wid == 0) {
- _E("Above app(%s) window is not ready", above_appid);
- return -1;
- }
-
- _app_group_wayland_activate_above(wid, above_wid);
-
- return 0;
-}
-
-static int __dispatch_app_group_activate_above(amd_request_h req)
-{
- const char *appid;
- int ret;
- bundle *b;
- pid_t pid;
- uid_t uid;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get appid");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- pid = amd_request_get_pid(req);
- uid = amd_request_get_target_uid(req);
-
- ret = __app_group_activate_above(pid, uid, appid);
- amd_request_send_result(req, ret);
- _I("pid(%d), appid(%s), result(%d)", pid, appid, ret);
-
- return 0;
-}
-
-static int __app_window_attach(const char *parent_appid,
- const char *child_appid, uid_t uid)
-{
- int parent_wid;
- int child_wid;
-
- parent_wid = __get_window_by_appid(parent_appid, uid);
- if (parent_wid == 0) {
- _E("Parent(%s) window is not ready", parent_appid);
- return -ENOENT;
- }
-
- child_wid = __get_window_by_appid(child_appid, uid);
- if (child_wid == 0) {
- _E("Child(%s) window is not ready", child_appid);
- return -ENOENT;
- }
-
- _app_group_wayland_attach_window(parent_wid, child_wid);
-
- return 0;
-}
-
-static int __dispatch_app_window_attach(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *parent_appid;
- const char *child_appid;
- int ret;
-
- if (!b) {
- _E("Invalid bundle");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- parent_appid = bundle_get_val(b, AUL_K_PARENT_APPID);
- if (!parent_appid) {
- _E("Invalid parameters");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- child_appid = bundle_get_val(b, AUL_K_CHILD_APPID);
- if (!child_appid) {
- _E("Invalid parameters");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- ret = __app_window_attach(parent_appid, child_appid, uid);
- amd_request_send_result(req, ret);
- _I("parent appid(%s), child appid(%s), result(%d)",
- parent_appid, child_appid, ret);
-
- return ret;
-}
-
-static int __app_window_detach(const char *appid, uid_t uid)
-{
- int wid;
-
- wid = __get_window_by_appid(appid, uid);
- if (wid == 0) {
- _E("%s window(%u) is invalid", appid, wid);
- return -ENOENT;
- }
-
- _app_group_wayland_detach_window(wid);
-
- return 0;
-}
-
-static int __dispatch_app_window_detach(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- bundle *b = amd_request_get_bundle(req);
- const char *child_appid;
- int ret;
-
- if (!b) {
- _E("Invalid bundle");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- child_appid = bundle_get_val(b, AUL_K_CHILD_APPID);
- if (!child_appid) {
- _E("Invalid parameters");
- amd_request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- ret = __app_window_detach(child_appid, uid);
- amd_request_send_result(req, ret);
- _I("child appid(%s), result(%d)", child_appid, ret);
-
- return ret;
-}
-
-static int __dispatch_app_group_set_window_v2(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- pid_t pid = amd_request_get_pid(req);
- app_group_node_h node;
- const char *id;
- const char *wid_str;
- int wid = 0;
- bundle *b;
- int ret;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- return -1;
- }
-
- id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!id) {
- _E("Failed to get instance ID");
- return -1;
- }
-
- wid_str = bundle_get_val(b, AUL_K_WID);
- if (wid_str && isdigit(wid_str[0]))
- wid = (uint32_t)atoi(wid_str);
-
- if (wid <= 0) {
- _E("Failed to get window ID");
- return -1;
- }
-
- node = _app_group_node_find(id);
- if (!node) {
- _E("Failed to find app group node. id(%s)", id);
- return -1;
- }
-
- ret = _app_group_node_set_window(node, wid);
- if (ret < 0) {
- _E("Failed to set window. id(%s), wid(%u)",
- id, wid);
- return -1;
- }
-
- _screen_connector_add_app_screen(pid, wid, id, uid);
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET,
- pid, wid, (void *)id, NULL);
- _I("id(%s), wid(%u), result(%d)", id, wid, ret);
-
- return ret;
-}
-
-static int __dispatch_app_group_lower_v2(amd_request_h req)
-{
- app_group_node_h node;
- const char *id;
- bool exit = false;
- bundle *b;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, 0);
- return -1;
- }
-
- id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!id) {
- _E("Failed to get instance ID");
- amd_request_send_result(req, 0);
- return -1;
- }
-
- node = _app_group_node_find(id);
- if (!node) {
- _E("Failed to find app group node. id(%s)", id);
- amd_request_send_result(req, 0);
- return -1;
- }
-
- _app_group_node_lower(node, &exit);
- amd_request_send_result(req, (int)exit);
- _I("id(%s), exit(%s)", id, exit ? "true" : "false");
-
- return 0;
-}
-
-static int __dispatch_app_group_get_leader_ids(amd_request_h req)
-{
- char **leader_ids;
- int cnt = 0;
- bundle *b;
- int ret;
- int i;
-
- b = bundle_create();
- if (!b) {
- amd_request_send_result(req, -1);
- return -1;
- }
-
- leader_ids = _app_group_get_leader_ids(&cnt);
- if (!leader_ids) {
- amd_request_send_result(req, -1);
- bundle_free(b);
- return -1;
- }
-
- bundle_add_str_array(b, AUL_K_LEADER_IDS,
- (const char **)leader_ids, cnt);
- for (i = 0; i < cnt; i++) {
- if (leader_ids[i])
- free(leader_ids[i]);
- }
- free(leader_ids);
-
- ret = aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
- APP_GET_INFO_OK, b, AUL_SOCK_NOREPLY);
- bundle_free(b);
-
- _I("count(%d), result(%d)", cnt, ret);
-
- return 0;
-}
-
-static void __foreach_group_info(const char *id, pid_t pid, int wid,
- bool fg, void *user_data)
-{
- amd_request_h req = (amd_request_h)user_data;
- int fd = amd_request_get_fd(req);
- amd_app_status_h app_status;
- amd_comp_status_h comp_status;
- int app_type;
- int status;
- char buf[32];
- bundle *b;
- int ret;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status) {
- _E("Failed to get app status");
- return;
- }
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return;
- }
-
- bundle_add(b, AUL_K_INSTANCE_ID, id);
- snprintf(buf, sizeof(buf), "%d", pid);
- bundle_add(b, AUL_K_PID, buf);
- bundle_add(b, AUL_K_APPID, amd_app_status_get_appid(app_status));
- bundle_add(b, AUL_K_PKGID, amd_app_status_get_pkgid(app_status));
- snprintf(buf, sizeof(buf), "%d", (int)wid);
- bundle_add(b, AUL_K_WID, buf);
- snprintf(buf, sizeof(buf), "%d", (int)fg);
- bundle_add(b, AUL_K_FG_FLAG, buf);
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- comp_status = amd_comp_status_find_by_instance_id(id);
- status = amd_comp_status_get_status(comp_status);
- } else {
- status = amd_app_status_get_status(app_status);
- }
- snprintf(buf, sizeof(buf), "%d", status);
- bundle_add(b, AUL_K_STATUS, buf);
-
- ret = aul_sock_send_bundle_with_fd(fd, APP_GET_INFO_OK, b,
- AUL_SOCK_ASYNC);
- if (ret < 0)
- _E("Failed to send bundle. result(%d)", ret);
- bundle_free(b);
-}
-
-static int __dispatch_app_group_get_group_info(amd_request_h req)
-{
- app_group_h group;
- int group_count;
- const char *id;
- bundle *b;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- id = bundle_get_val(b, AUL_K_LEADER_ID);
- if (!id) {
- _E("Failed to get leader id");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- group = _app_group_find(id);
- if (!group) {
- SECURE_LOGE("Failed to find app group. id(%s)", id);
- amd_request_send_result(req, -1);
- return -1;
- }
-
- group_count = _app_group_get_count(group);
- amd_socket_send_result(amd_request_get_fd(req), group_count, false);
-
- _app_group_foreach_context(group, __foreach_group_info, req);
-
- _I("leader(%s), count(%d)", id, group_count);
-
- return 0;
-}
-
-static int __dispatch_app_group_get_idle_info(amd_request_h req)
-{
- int idle_count;
-
- idle_count = _app_group_get_idle_count();
- amd_socket_send_result(amd_request_get_fd(req), idle_count, false);
-
- _app_group_foreach_idle_context(__foreach_group_info, req);
-
- _I("count(%d)", idle_count);
-
- return 0;
-}
-
-static int __dispatch_app_group_add(amd_request_h req)
-{
- uid_t uid = amd_request_get_target_uid(req);
- pid_t pid = amd_request_get_pid(req);
- app_group_node_h node;
- app_group_node_h new_node;
- const char *wid_str;
- int wid = -1;
- bundle *b;
- int ret;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- return -EINVAL;
- }
-
- wid_str = bundle_get_val(b, AUL_K_WID);
- if (wid_str && isdigit(wid_str[0]))
- wid = atoi(wid_str);
-
- if (wid <= 0) {
- _E("Failed to get window ID");
- return -EINVAL;
- }
-
- node = _app_group_node_find_by_wid(wid);
- if (node) {
- _E("Already exists. wid(%d)", wid);
- return -EALREADY;
- }
-
- node = __find_app_group_node_by_pid(pid);
- if (!node) {
- _E("Failed to find app group node. pid(%d)", pid);
- return -EINVAL;
- }
-
- new_node = _app_group_node_add_node(node);
- if (!new_node) {
- _E("Failed to add new node. pid(%d), wid(%d)", pid, wid);
- return -ENOMEM;
- }
-
- ret = _app_group_node_set_window(new_node, wid);
- if (ret < 0)
- _E("Failed to set window. pid(%d), wid(%d)", pid, wid);
-
- _screen_connector_add_app_screen(pid, wid, NULL, uid);
- amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET, pid, wid, NULL, NULL);
- _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
-
- return ret;
-}
-
-static int __dispatch_app_group_remove(amd_request_h req)
-{
- pid_t pid = amd_request_get_pid(req);
- app_group_node_h node;
- const char *wid_str;
- int wid = -1;
- bundle *b;
- int ret;
-
- b = amd_request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- return -EINVAL;
- }
-
- wid_str = bundle_get_val(b, AUL_K_WID);
- if (wid_str && isdigit(wid_str[0]))
- wid = atoi(wid_str);
-
- if (wid <= 0) {
- _E("Failed to get window ID");
- return -EINVAL;
- }
-
- node = _app_group_node_find_by_wid(wid);
- if (!node) {
- _E("Failed to find node. pid(%d), wid(%d)", pid, wid);
- return -EINVAL;
- }
-
- ret = _app_group_node_remove_node(node);
- if (ret < 0)
- _E("Failed to remove node. pid(%d), wid(%d)", pid, wid);
-
- _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
-
- return ret;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_GROUP_GET_WINDOW,
- .callback = __dispatch_app_group_get_window
- },
- {
- .cmd = APP_GROUP_SET_WINDOW,
- .callback = __dispatch_app_group_set_window
- },
- {
- .cmd = APP_GROUP_GET_FG,
- .callback = __dispatch_app_group_get_fg_flag
- },
- {
- .cmd = APP_GROUP_GET_LEADER_PID,
- .callback = __dispatch_app_group_get_leader_pid
- },
- {
- .cmd = APP_GROUP_GET_LEADER_PIDS,
- .callback = __dispatch_app_group_get_leader_pids
- },
- {
- .cmd = APP_GROUP_GET_GROUP_PIDS,
- .callback = __dispatch_app_group_get_group_pids
- },
- {
- .cmd = APP_GROUP_GET_IDLE_PIDS,
- .callback = __dispatch_app_group_get_idle_pids
- },
- {
- .cmd = APP_GROUP_LOWER,
- .callback = __dispatch_app_group_lower
- },
- { .cmd = APP_GROUP_CLEAR_TOP,
- .callback = __dispatch_app_group_clear_top
- },
- {
- .cmd = APP_GROUP_ACTIVATE_BELOW,
- .callback = __dispatch_app_group_activate_below
- },
- {
- .cmd = APP_GROUP_ACTIVATE_ABOVE,
- .callback = __dispatch_app_group_activate_above
- },
- {
- .cmd = APP_WINDOW_ATTACH,
- .callback = __dispatch_app_window_attach
- },
- { .cmd = APP_WINDOW_DETACH,
- .callback = __dispatch_app_window_detach
- },
- {
- .cmd = APP_GROUP_SET_WINDOW_V2,
- .callback = __dispatch_app_group_set_window_v2
- },
- {
- .cmd = APP_GROUP_LOWER_V2,
- .callback = __dispatch_app_group_lower_v2
- },
- {
- .cmd = APP_GROUP_GET_LEADER_IDS,
- .callback = __dispatch_app_group_get_leader_ids
- },
- {
- .cmd = APP_GROUP_GET_GROUP_INFO,
- .callback = __dispatch_app_group_get_group_info
- },
- {
- .cmd = APP_GROUP_GET_IDLE_INFO,
- .callback = __dispatch_app_group_get_idle_info
- },
- {
- .cmd = APP_GROUP_ADD,
- .callback = __dispatch_app_group_add
- },
- {
- .cmd = APP_GROUP_REMOVE,
- .callback = __dispatch_app_group_remove
- },
-};
-
-static int __verify_instance_cynara_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- bundle *b = amd_request_get_bundle(req);
- pid_t pid = amd_request_get_pid(req);
- amd_app_status_h app_status;
- amd_comp_status_h comp_status;
- const char *inst_id;
- const char *id;
- int app_type;
-
- if (!b) {
- _E("Failed to get bundle");
- return AMD_CYNARA_RET_DENIED;
- }
-
- id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!id) {
- _E("Failed to get instance ID");
- return AMD_CYNARA_RET_DENIED;
- }
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return AMD_CYNARA_RET_DENIED;
- }
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type == AMD_AT_COMPONENT_BASED_APP) {
- comp_status = amd_comp_status_find_by_instance_id(id);
- if (!comp_status) {
- _E("Failed to find comp status. instance(%s)", id);
- return AMD_CYNARA_RET_DENIED;
- }
-
- if (amd_comp_status_get_pid(comp_status) != pid) {
- _E("Reject request! instance(%s:%d) doesn't exist",
- id, pid);
- return AMD_CYNARA_RET_DENIED;
- }
- } else {
- inst_id = amd_app_status_get_instance_id(app_status);
- if (!inst_id || strcmp(inst_id, id) != 0) {
- _E("Reject request! instance(%s:%d) doesn't exist",
- id, pid);
- return AMD_CYNARA_RET_DENIED;
- }
- }
-
- return AMD_CYNARA_RET_ALLOWED;
-}
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_WINDOW_ATTACH,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
- {
- .cmd = APP_WINDOW_DETACH,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
- {
- .cmd = APP_GROUP_SET_WINDOW_V2,
- .checker = __verify_instance_cynara_checker,
- .data = NULL,
- .priority = 10
- },
- {
- .cmd = APP_GROUP_LOWER_V2,
- .checker = __verify_instance_cynara_checker,
- .data = NULL,
- .priority = 10
- },
- {
- .cmd = APP_GROUP_GET_LEADER_IDS,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
- {
- .cmd = APP_GROUP_GET_IDLE_INFO,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
-};
-
-int _app_group_request_init(void)
-{
- int r;
-
- _D("app group request init");
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-void _app_group_request_fini(void)
-{
- _D("app group request fini");
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <amd.h>
-#include <dlog.h>
-#include <tizen-extension-client-protocol.h>
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-
-#include "app_group_private.h"
-
-struct wayland_context_s {
- struct wl_display *display;
- struct tizen_policy *tizen_policy;
- uint32_t tizen_policy_id;
- bool tizen_policy_initialized;
-};
-
-static struct wayland_context_s __context;
-
-int _app_group_wayland_lower_window(int wid)
-{
- if (!__context.tizen_policy_initialized) {
- _E("tizen_policy is not initialized");
- return -1;
- }
-
- tizen_policy_lower_by_res_id(__context.tizen_policy, wid);
- wl_display_roundtrip(__context.display);
-
- return 0;
-}
-
-int _app_group_wayland_attach_window(int parent_wid, int child_wid)
-{
- if (!__context.tizen_policy_initialized) {
- _E("tizen_policy is not initialized");
- return -1;
- }
-
- tizen_policy_set_transient_for(__context.tizen_policy,
- child_wid, parent_wid);
- wl_display_roundtrip(__context.display);
- _W("[__ATTACH__] parent_wid(%d), child_wid(%d)",
- parent_wid, child_wid);
-
- return 0;
-}
-
-int _app_group_wayland_detach_window(int child_wid)
-{
- if (!__context.tizen_policy_initialized) {
- _E("tizen_policy is not initialized");
- return -1;
- }
-
- tizen_policy_unset_transient_for(__context.tizen_policy, child_wid);
- wl_display_roundtrip(__context.display);
- _W("[__DETACH__] child_wid(%d)", child_wid);
-
- return 0;
-}
-
-int _app_group_wayland_activate_below(int wid, int below_wid)
-{
- if (!__context.tizen_policy_initialized) {
- _E("tizen_policy is not initialized");
- return -1;
- }
-
- tizen_policy_activate_below_by_res_id(__context.tizen_policy,
- below_wid, wid);
- wl_display_roundtrip(__context.display);
-
- return 0;
-}
-
-int _app_group_wayland_activate_above(int wid, int above_wid)
-{
- if (!__context.tizen_policy_initialized) {
- _E("tizen_policy is not initialized");
- return -1;
- }
-
- tizen_policy_activate_above_by_res_id(__context.tizen_policy,
- above_wid, wid);
- wl_display_roundtrip(__context.display);
-
- return 0;
-}
-
-static void __wl_conformant(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- uint32_t is_conformant)
-{
-}
-
-static void __wl_conformant_area(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- uint32_t conformant_part,
- uint32_t state,
- int32_t x, int32_t y, int32_t w, int32_t h)
-{
-}
-
-static void __wl_notification_done(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface,
- int32_t level,
- uint32_t state)
-{
-}
-
-static void __wl_transient_for_done(void *data,
- struct tizen_policy *tizen_policy,
- uint32_t child_id)
-{
-}
-
-static void __wl_scr_mode_done(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface,
- uint32_t mode,
- uint32_t state)
-{
-}
-
-static void __wl_iconify_state_changed(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- uint32_t iconified,
- uint32_t force)
-{
-}
-
-static void __wl_supported_aux_hints(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- struct wl_array *hints,
- uint32_t num_hints)
-{
-}
-
-static void __wl_allowed_aux_hint(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- int id)
-{
-}
-
-static void __wl_aux_message(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface_resource,
- const char *key,
- const char *val,
- struct wl_array *options)
-{
-}
-
-static void __wl_conformant_region(void *data,
- struct tizen_policy *tizen_policy,
- struct wl_surface *surface,
- uint32_t conformant_part,
- uint32_t state,
- int32_t x, int32_t y, int32_t w, int32_t h,
- uint32_t serial)
-{
-}
-
-static const struct tizen_policy_listener __tizen_policy_listener = {
- __wl_conformant,
- __wl_conformant_area,
- __wl_notification_done,
- __wl_transient_for_done,
- __wl_scr_mode_done,
- __wl_iconify_state_changed,
- __wl_supported_aux_hints,
- __wl_allowed_aux_hint,
- __wl_aux_message,
- __wl_conformant_region,
-};
-
-static int __on_wayland_listener_tizen_policy(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
- struct wl_registry *reg = (struct wl_registry *)arg3;
-
- if (!__context.tizen_policy) {
- __context.display = amd_wayland_get_display();
- __context.tizen_policy_id = id;
- __context.tizen_policy = wl_registry_bind(reg, id,
- &tizen_policy_interface, 7);
- if (__context.tizen_policy) {
- tizen_policy_add_listener(__context.tizen_policy,
- &__tizen_policy_listener,
- __context.display);
- amd_wayland_set_tizen_policy(__context.tizen_policy);
- __context.tizen_policy_initialized = true;
- }
- _D("tizen_policy(%p)", __context.tizen_policy);
- }
-
- return 0;
-}
-
-static int __on_wayland_listener_listener_remove(const char *msg, int arg1,
- int arg2, void *arg3, bundle *data)
-{
- uint32_t id = (uint32_t)arg1;
-
- if (__context.tizen_policy_id == id && __context.tizen_policy) {
- tizen_policy_destroy(__context.tizen_policy);
- __context.tizen_policy = NULL;
- __context.tizen_policy_id = 0;
- __context.tizen_policy_initialized = false;
- amd_wayland_set_tizen_policy(__context.tizen_policy);
- _W("tizen policy is destroyed");
- }
-
- return 0;
-}
-
-int _app_group_wayland_init(void)
-{
- _D("app group wayland init");
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_POLICY,
- __on_wayland_listener_tizen_policy);
- amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
- __on_wayland_listener_listener_remove);
-
- return 0;
-}
-
-void _app_group_wayland_fini(void)
-{
- _D("app group wayland fini");
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <dlog.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#include "status.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_UI_CORE"
-
-pid_t _status_get_effective_pid(pid_t pid)
-{
- amd_app_status_h app_status;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (!app_status) {
- _W("Failed to find app status info. pid(%d)", pid);
- return -1;
- }
-
- return amd_app_status_get_pid(app_status);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include <dlog.h>
-
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#include "amd_screen_connector.h"
-#include "app_group.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_UI_CORE"
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("ui-core init");
- if (_app_group_init() < 0)
- return -1;
-
- if (_screen_connector_init() < 0)
- return -1;
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("ui-core fini");
- _screen_connector_fini();
- _app_group_fini();
-}
-
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_WATCH "amd-mod-watch")
-SET(AMD_MOD_WATCH_DIR ${CMAKE_SOURCE_DIR}/modules/watch)
-PROJECT(${AMD_MOD_WATCH} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_WATCH_DIR}/src AMD_MOD_WATCH_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_WATCH_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- bundle
- )
-
-pkg_check_modules(amd_mod_watch_pkgs REQUIRED ${AMD_MOD_WATCH_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_watch_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_WATCH_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_WATCH} ${AMD_MOD_WATCH_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_WATCH} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_WATCH} ${amd_mod_watch_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_WATCH} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * 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_WATCH_LOGGER_H__
-#define __AMD_WATCH_LOGGER_H__
-
-int _watch_logger_init(void);
-
-void _watch_logger_fini(void);
-
-int _watch_logger_print(const char *tag, const char *format, ...);
-
-#endif /* __AMD_WATCH_LOGGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_WATCH"
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <glib.h>
-#include <aul.h>
-#include <bundle_internal.h>
-#include <amd.h>
-
-#include "amd_watch_logger.h"
-#include "amd_watch_private.h"
-
-struct watch_info {
- char *appid;
- char *pkgid;
- int pid;
- uid_t uid;
- bool is_faulted;
-};
-
-static GList *__update_list;
-
-static void __send_dead_signal(const char *appid, pid_t pid, uid_t uid,
- bool is_faulted)
-{
- char buf[32];
- bundle *envelope;
-
- envelope = bundle_create();
- if (envelope == NULL) {
- _E("Out of memory");
- return;
- }
-
- snprintf(buf, sizeof(buf), "%d", pid);
- bundle_add(envelope, AUL_K_PID, buf);
- bundle_add(envelope, AUL_K_APPID, appid);
- bundle_add(envelope, AUL_K_IS_FAULT, is_faulted ? "true" : "false");
-
- amd_app_com_send("watch.dead", pid, envelope, uid);
- bundle_free(envelope);
- _I("Send dead signal %s:%d:%u:%d", appid, pid, uid, is_faulted);
- _watch_logger_print("Send Dead", "appid(%s), pid(%d) "
- "uid(%d), is_faulted(%d)", appid, pid, uid, is_faulted);
-}
-
-static void __send_launch_signal(const char *appid, const char *viewer,
- pid_t pid, uid_t uid)
-{
- char buf[32];
- bundle *envelope;
-
- envelope = bundle_create();
- if (envelope == NULL) {
- _E("Out of memory");
- return;
- }
-
- snprintf(buf, sizeof(buf), "%d", pid);
- bundle_add(envelope, AUL_K_PID, buf);
- bundle_add(envelope, AUL_K_APPID, appid);
- bundle_add(envelope, AUL_K_WIDGET_VIEWER, viewer);
-
- amd_app_com_send("watch.launch", pid, envelope, uid);
- bundle_free(envelope);
- _I("Send launch signal %s:%d:%u", appid, pid, uid);
- _watch_logger_print("Send Launch", "appid(%s), pid(%d) "
- "uid(%d)", appid, pid, uid);
-}
-
-static void __destroy_watch_info(gpointer data)
-{
- struct watch_info *info = (struct watch_info *)data;
-
- if (info == NULL)
- return;
-
- if (info->pkgid)
- free(info->pkgid);
- if (info->appid)
- free(info->appid);
- free(info);
-}
-
-static struct watch_info *__create_watch_info(const char *appid,
- const char *pkgid, bool is_faulted, pid_t pid, uid_t uid)
-{
- struct watch_info *info;
-
- info = malloc(sizeof(struct watch_info));
- if (info == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- info->appid = strdup(appid);
- if (info->appid == NULL) {
- _E("Out of memory");
- free(info);
- return NULL;
- }
-
- info->pkgid = strdup(pkgid);
- if (info->pkgid == NULL) {
- _E("Out of memory");
- free(info->appid);
- free(info);
- return NULL;
- }
-
- info->is_faulted = is_faulted;
- info->pid = pid;
- info->uid = uid;
-
- return info;
-}
-
-static void __watch_flush_update_list(const char *pkgid, uid_t uid)
-{
- struct watch_info *info;
- GList *iter;
-
- if (__update_list == NULL)
- return;
-
- iter = __update_list;
- while (iter) {
- info = (struct watch_info *)iter->data;
- iter = g_list_next(iter);
- if ((uid < REGULAR_UID_MIN || info->uid == uid) &&
- !strcmp(info->pkgid, pkgid)) {
- __update_list = g_list_remove(__update_list, info);
- __send_dead_signal(info->appid, info->pid, info->uid,
- true);
- __destroy_watch_info(info);
- }
- }
-}
-
-static struct watch_info *__find_watch_info(GList *list, const char *appid,
- uid_t uid)
-{
- struct watch_info *info;
- GList *iter;
-
- iter = list;
- while (iter) {
- info = (struct watch_info *)iter->data;
- if (!strcmp(info->appid, appid) && info->uid == uid)
- return info;
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static int __update_watch_info(const char *appid, const char *pkgid,
- bool is_faulted, pid_t pid, uid_t uid, GList **list)
-{
- struct watch_info *info;
-
- info = __find_watch_info(*list, appid, uid);
- if (info) {
- info->pid = pid;
- info->is_faulted = is_faulted;
- return 0;
- }
-
- info = __create_watch_info(appid, pkgid, is_faulted, pid, uid);
- if (info == NULL)
- return -1;
-
- *list = g_list_append(*list, info);
-
- return 0;
-}
-
-static int __on_app_dead(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = arg3;
- int pid = arg1;
- uid_t uid = (uid_t)arg2;
- const char *appid;
- const char *pkgid;
- bool is_faulted;
- int r;
- int app_type;
-
- if (app_status == NULL)
- return 0;
-
- app_type = amd_app_status_get_app_type(app_status);
- if (app_type != AMD_AT_WATCH_APP)
- return 0;
-
- appid = amd_app_status_get_appid(app_status);
- pkgid = amd_app_status_get_pkgid(app_status);
- is_faulted = !amd_app_status_is_exiting(app_status);
-
- if (amd_appinfo_is_pkg_updating(pkgid)) {
- r = __update_watch_info(appid, pkgid, is_faulted, pid, uid,
- &__update_list);
- if (r == 0)
- return 0;
- }
-
- __send_dead_signal(appid, pid, uid, is_faulted);
-
- return 0;
-}
-
-static int __on_package_update_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- const char *pkgid = (const char *)arg3;
-
- __watch_flush_update_list(pkgid, uid);
-
- return 0;
-}
-
-static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comptype;
- const char *appid;
- const char *viewer;
- const char *val;
- uid_t uid;
-
- comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comptype && !strcmp(comptype, APP_TYPE_WATCH)) {
- appid = bundle_get_val(data, AUL_K_APPID);
- if (appid == NULL)
- return 0;
-
- viewer = bundle_get_val(data, AUL_K_WIDGET_VIEWER);
- if (viewer == NULL)
- return 0;
-
- val = bundle_get_val(data, AUL_K_TARGET_UID);
- if (!val || !isdigit(*val))
- return 0;
-
- uid = strtoul(val, NULL, 10);
- __send_launch_signal(appid, viewer, pid, uid);
- }
-
- return 0;
-}
-
-static int __on_package_update_error(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- const char *pkgid = (const char *)arg3;
-
- __watch_flush_update_list(pkgid, uid);
-
- return 0;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("watch init");
- _watch_logger_init();
-
- amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
- __on_app_dead);
- amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
- __on_package_update_end);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- __on_launch_complete_start);
- amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
- __on_package_update_error);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("watch finish");
-
- if (__update_list)
- g_list_free_full(__update_list, __destroy_watch_info);
- _watch_logger_fini();
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdarg.h>
-#include <amd.h>
-
-#include "amd_logger.h"
-#include "amd_watch_private.h"
-
-#define LOG_FILE "amd_watch.log"
-#define LOG_PATH LOGGER_PATH "/" LOG_FILE
-
-static amd_logger_h __logger;
-
-int _watch_logger_print(const char *tag, const char *format, ...)
-{
- char format_buf[LOG_MAX_STRING_SIZE];
- va_list ap;
-
- va_start(ap, format);
- vsnprintf(format_buf, sizeof(format_buf), format, ap);
- va_end(ap);
-
- return amd_logger_print(__logger, tag, format_buf);
-}
-
-int _watch_logger_init(void)
-{
- int ret;
-
- _D("watch logger init");
- ret = amd_logger_create(LOG_PATH, &__logger);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void _watch_logger_fini(void)
-{
- _D("watch logger fini");
- amd_logger_destroy(__logger);
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_WATCHDOG "amd-mod-watchdog")
-SET(AMD_MOD_WATCHDOG_DIR ${CMAKE_SOURCE_DIR}/modules/watchdog)
-PROJECT(${AMD_MOD_WATCHDOG} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_WATCHDOG_DIR}/src AMD_MOD_WATCHDOG_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_WATCHDOG_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- iniparser
- )
-
-pkg_check_modules(amd_mod_watchdog_pkgs REQUIRED ${AMD_MOD_WATCHDOG_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_rpc_port_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_WATCHDOG_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_WATCHDOG} ${AMD_MOD_WATCHDOG_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_WATCHDOG} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_WATCHDOG} ${amd_mod_watchdog_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_WATCHDOG} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
-INSTALL(FILES ${AMD_MOD_WATCHDOG_DIR}/conf/amd_watchdog.conf DESTINATION ${AMD_MODULES_DIR}/conf)
+++ /dev/null
-[Setting]
-# Watchdog timer: "enable-by-default" or "enable-on-demand"(default)
-Watchdog=enable-on-demand
-# Watchdog timer interval: 10 seconds (default)
-WatchdogInterval=10000
-# Watchdog timer maximum retry count: 1 (default)
-WatchdogMaxRetryCount=1
+++ /dev/null
-/*
- * Copyright (c) 2018 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_WATCHDOG_CONFIG_H__
-#define __AMD_WATCHDOG_CONFIG_H__
-
-#include <stdbool.h>
-
-enum watchdog_operation_state_e {
- WATCHDOG_ENABLE_BY_DEFAULT,
- WATCHDOG_ENABLE_ON_DEMAND
-};
-
-int _watchdog_config_init(void);
-
-void _watchdog_config_fini(void);
-
-int _watchdog_config_get_operation_state(void);
-
-unsigned int _watchdog_config_get_interval(void);
-
-unsigned int _watchdog_config_get_max_retry_count(void);
-
-#endif /* __AMD_WATCHDOG_CONFIG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2018 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_WATCHDOG_LOGGER_H__
-#define __AMD_WATCHDOG_LOGGER_H__
-
-int _watchdog_logger_init(void);
-
-void _watchdog_logger_fini(void);
-
-int _watchdog_logger_print(const char *tag, const char *format, ...);
-
-#endif /* __AMD_WATCHDOG_LOGGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_WATCHDOG"
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_watchdog.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-#include <amd.h>
-
-#include "amd_watchdog_config.h"
-#include "amd_watchdog_logger.h"
-#include "amd_watchdog_private.h"
-
-#define RESOURCED_FREEZER_PATH "/Org/Tizen/ResourceD/Freezer"
-#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
-#define RESOURCED_FREEZER_SIGNAL "FreezerState"
-
-typedef struct watchdog_s {
- GDBusConnection *conn;
- guint listener;
- guint retry_handler;
- unsigned int interval;
- int max_retry_count;
- GList *proc_contexts;
-} watchdog;
-
-typedef struct proc_context_s {
- pid_t pid;
- uid_t uid;
- bool frozen;
- bool watchdog_enable;
- guint timer;
- int retry_count;
- int kick_count;
- struct timespec resp_time;
-} proc_context;
-
-static watchdog __watchdog;
-
-static proc_context *__create_proc_context(pid_t pid, uid_t uid)
-{
- proc_context *ctx;
-
- ctx = calloc(1, sizeof(proc_context));
- if (!ctx) {
- _E("Out of memory");
- return NULL;
- }
-
- ctx->pid = pid;
- ctx->uid = uid;
-
- return ctx;
-}
-
-static void __destroy_proc_context(gpointer data)
-{
- proc_context *ctx = (proc_context *)data;
-
- if (ctx->timer > 0)
- g_source_remove(ctx->timer);
-
- free(ctx);
-}
-
-static proc_context *__find_proc_context(pid_t pid)
-{
- proc_context *ctx;
- GList *iter;
-
- iter = __watchdog.proc_contexts;
- while (iter) {
- ctx = (proc_context *)iter->data;
- if (ctx && ctx->pid == pid)
- return ctx;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static const char *__get_appid(pid_t pid)
-{
- amd_app_status_h app_status;
- const char *appid = NULL;
-
- app_status = amd_app_status_find_by_effective_pid(pid);
- if (app_status)
- appid = amd_app_status_get_appid(app_status);
-
- return appid ? appid : "Unknown";
-}
-
-static bundle *__create_bundle(unsigned int interval)
-{
- char buf[32];
- bundle *b;
- int ret;
-
- b = bundle_create();
- if (!b) {
- _E("Failed to create bundle");
- return NULL;
- }
-
- if (interval != 0) {
- snprintf(buf, sizeof(buf), "%u", interval);
- ret = bundle_add(b, AUL_K_INTERVAL, buf);
- if (ret != BUNDLE_ERROR_NONE) {
- _E("Failed to add interval(%s)", buf);
- bundle_free(b);
- return NULL;
- }
- }
-
- return b;
-}
-
-static int __send_request(proc_context *ctx, int cmd, unsigned int interval)
-{
- bundle *b;
- int ret;
-
- b = __create_bundle(interval);
- if (!b)
- return -ENOMEM;
-
- ret = aul_sock_send_bundle(ctx->pid, ctx->uid, cmd, b,
- AUL_SOCK_NOREPLY);
- bundle_free(b);
- if (ret < 0) {
- _E("Failed to send request(%d), pid(%d)", cmd, ctx->pid);
- return ret;
- }
-
- return 0;
-}
-
-static gboolean __timeout_handler(gpointer data)
-{
- proc_context *ctx = (proc_context *)data;
-
- _E("Timer expired. pid(%d), resp_time(%ld.%ld)",
- ctx->pid,
- ctx->resp_time.tv_sec,
- ctx->resp_time.tv_nsec);
-
- if (ctx->retry_count < __watchdog.max_retry_count) {
- ctx->retry_count++;
- return G_SOURCE_CONTINUE;
- }
-
- _E("pid(%d) will be terminated", ctx->pid);
- amd_signal_send_watchdog(ctx->pid, SIGKILL);
- _watchdog_logger_print("SIGKILL", "pid(%d), appid(%s)",
- ctx->pid, __get_appid(ctx->pid));
-
- return G_SOURCE_REMOVE;
-}
-
-static void __watchdog_set_timer(proc_context *ctx)
-{
- if (!ctx->timer) {
- ctx->timer = g_timeout_add(__watchdog.interval + 1000,
- __timeout_handler, ctx);
- }
-}
-
-static void __watchdog_unset_timer(proc_context *ctx)
-{
- if (ctx->timer) {
- g_source_remove(ctx->timer);
- ctx->timer = 0;
- }
-}
-
-static int __dispatch_watchdog_enable(amd_request_h req)
-{
- int pid = amd_request_get_pid(req);
- proc_context *ctx;
- int ret;
-
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _E("Failed to find process(%d) context", pid);
- return -1;
- }
-
- if (ctx->watchdog_enable) {
- _W("Watchdog timer is already enabled. pid(%d)", pid);
- return 0;
- }
-
- if (!ctx->frozen)
- __watchdog_set_timer(ctx);
-
- ctx->watchdog_enable = true;
-
- ret = __send_request(ctx, WATCHDOG_ENABLE, __watchdog.interval);
-
- _I("pid(%d), result(%d)", pid, ret);
- _watchdog_logger_print("ENABLE", "pid(%d), appid(%s)",
- pid, __get_appid(pid));
-
- return 0;
-}
-
-static int __dispatch_watchdog_disable(amd_request_h req)
-{
- int pid = amd_request_get_pid(req);
- proc_context *ctx;
- int ret;
-
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _E("Failed to find process(%d) context", pid);
- return -1;
- }
-
- if (!ctx->watchdog_enable) {
- _W("Watchdog timer is already disabled. pid(%d)", pid);
- return 0;
-
- }
-
- __watchdog_unset_timer(ctx);
-
- ctx->watchdog_enable = false;
- ctx->retry_count = 0;
- ctx->kick_count = 0;
- ctx->resp_time.tv_sec = 0;
- ctx->resp_time.tv_nsec = 0;
-
- ret = __send_request(ctx, WATCHDOG_DISABLE, 0);
-
- _I("pid(%d), result(%d)", pid, ret);
- _watchdog_logger_print("DISABLE", "pid(%d), appid(%s)",
- pid, __get_appid(pid));
-
- return 0;
-}
-
-static int __dispatch_watchdog_kick(amd_request_h req)
-{
- int pid = amd_request_get_pid(req);
- proc_context *ctx;
-
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _E("Failed to find process(%d) context", pid);
- return -1;
- }
-
- if (!ctx->watchdog_enable) {
- _W("watchdog timer is not enabled. pid(%d)", pid);
- return -1;
- }
-
- __watchdog_unset_timer(ctx);
- __watchdog_set_timer(ctx);
-
- ctx->kick_count++;
-
- _I("pid(%d), kick count(%d)", pid, ctx->kick_count);
- _watchdog_logger_print("KICK", "count(%d), pid(%d), appid(%s)",
- ctx->kick_count, pid, __get_appid(pid));
-
- return 0;
-}
-
-static int __dispatch_watchdog_ping(amd_request_h req)
-{
- int pid = amd_request_get_pid(req);
- proc_context *ctx;
-
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _E("Failed to find process(%d) context", pid);
- return -1;
- }
-
- if (!ctx->watchdog_enable) {
- _W("watchdog timer is not enabled. pid(%d)", pid);
- return -1;
- }
-
- __watchdog_unset_timer(ctx);
- __watchdog_set_timer(ctx);
- clock_gettime(CLOCK_MONOTONIC, &ctx->resp_time);
- ctx->retry_count = 0;
-
- _I("pid(%d), resp_time(%ld.%ld)",
- pid, ctx->resp_time.tv_sec, ctx->resp_time.tv_nsec);
- _watchdog_logger_print("PING", "pid(%d), appid(%s)",
- pid, __get_appid(pid));
-
- return 0;
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- int pid = arg1;
- proc_context *ctx;
-
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _W("Failed to find process(%d) context", pid);
- return AMD_NOTI_CONTINUE;
- }
-
- __watchdog.proc_contexts = g_list_remove(__watchdog.proc_contexts, ctx);
- __destroy_proc_context(ctx);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_app_status_add(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- amd_app_status_h app_status = (amd_app_status_h)arg3;
- int pid = amd_app_status_get_pid(app_status);
- uid_t uid;
- proc_context *ctx;
- int operation_state;
-
- ctx = __find_proc_context(pid);
- if (ctx) {
- _W("Process(%d) context already exists", pid);
- return AMD_NOTI_CONTINUE;
- }
-
- uid = amd_app_status_get_uid(app_status);
- ctx = __create_proc_context(pid, uid);
- if (!ctx) {
- _E("Failed to create process(%d) context", pid);
- return AMD_NOTI_CONTINUE;
- }
-
- __watchdog.proc_contexts = g_list_append(__watchdog.proc_contexts, ctx);
-
- operation_state = _watchdog_config_get_operation_state();
- if (operation_state == WATCHDOG_ENABLE_BY_DEFAULT) {
- __watchdog_set_timer(ctx);
- ctx->watchdog_enable = true;
- _watchdog_logger_print("ENABLE", "pid(%d), appid(%s)",
- pid, amd_app_status_get_appid(app_status));
- }
-
- return AMD_NOTI_CONTINUE;
-}
-
-static int __on_signal_send_watchdog_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- int pid = arg1;
- proc_context *ctx;
-
- _W("Watchdog pid(%d)", pid);
- ctx = __find_proc_context(pid);
- if (!ctx)
- return AMD_NOTI_CONTINUE;
-
- __watchdog_unset_timer(ctx);
-
- return AMD_NOTI_CONTINUE;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = WATCHDOG_ENABLE,
- .callback = __dispatch_watchdog_enable
- },
- {
- .cmd = WATCHDOG_DISABLE,
- .callback = __dispatch_watchdog_disable
- },
- {
- .cmd = WATCHDOG_KICK,
- .callback = __dispatch_watchdog_kick
- },
- {
- .cmd = WATCHDOG_PING,
- .callback = __dispatch_watchdog_ping
- },
-};
-
-static void __on_freezer_state_changed(GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- gint pid = -1;
- gint status = -1;
- proc_context *ctx;
-
- if (!g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL)) {
- g_variant_get(parameters, "(ii)", &status, &pid);
- ctx = __find_proc_context(pid);
- if (!ctx) {
- _E("Failed to find process(%d) context", pid);
- return;
- }
-
- /* 0: SET_FOREGRD, 1: SET_BACKGRD, */
- ctx->frozen = (bool)status;
- if (ctx->frozen) {
- __watchdog_unset_timer(ctx);
- } else {
- if (ctx->watchdog_enable)
- __watchdog_set_timer(ctx);
- }
-
- _W("pid(%d), freezer state(%s)",
- pid, status ? "BACKGRD" : "FOREGRD");
- _watchdog_logger_print("FREEZER",
- "state(%s), pid(%d), appid(%s)",
- status ? "BACKGRD" : "FOREGRD",
- pid, __get_appid(pid));
- }
-}
-
-static int __listen_freezer_state(void *user_data)
-{
- GError *err = NULL;
-
- if (__watchdog.listener)
- return 0;
-
- if (!__watchdog.conn) {
- __watchdog.conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!__watchdog.conn) {
- _E("Failed to connecto D-Bus daemon. err(%s)",
- err->message);
- g_error_free(err);
- return -1;
- }
- }
-
- __watchdog.listener = g_dbus_connection_signal_subscribe(
- __watchdog.conn,
- NULL,
- RESOURCED_FREEZER_INTERFACE,
- RESOURCED_FREEZER_SIGNAL,
- RESOURCED_FREEZER_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- __on_freezer_state_changed,
- NULL,
- NULL);
- if (!__watchdog.listener) {
- _E("Failed to subscribe freezer state");
- return -1;
- }
-
- _I("%s is subscribed", RESOURCED_FREEZER_SIGNAL);
-
- return 0;
-}
-
-static void __ignore_freezer_state(void)
-{
- if (!__watchdog.conn)
- return;
-
- if (__watchdog.listener) {
- g_dbus_connection_signal_unsubscribe(__watchdog.conn,
- __watchdog.listener);
- __watchdog.listener = 0;
- }
-
- g_object_unref(__watchdog.conn);
- __watchdog.conn = NULL;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- _D("init");
-
- _watchdog_logger_init();
- _watchdog_config_init();
-
- __watchdog.interval = _watchdog_config_get_interval();
- __watchdog.max_retry_count = _watchdog_config_get_max_retry_count();
-
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
- __on_app_status_add);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
- __on_app_status_cleanup);
- amd_noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
- __on_signal_send_watchdog_start);
-
- amd_signal_add_ready_cb(__listen_freezer_state, NULL);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("fini");
-
- if (__watchdog.retry_handler)
- g_source_remove(__watchdog.retry_handler);
-
- __ignore_freezer_state();
-
- if (__watchdog.proc_contexts) {
- g_list_free_full(__watchdog.proc_contexts,
- __destroy_proc_context);
- }
-
- _watchdog_config_fini();
- _watchdog_logger_fini();
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <iniparser.h>
-
-#include "amd_watchdog_config.h"
-#include "amd_watchdog_private.h"
-
-#define CONFIG_PATH "/usr/share/amd/conf/amd_watchdog.conf"
-#define CONFIG_SECTION_NAME "Setting"
-#define CONFIG_KEY_WATCHDOG "Watchdog"
-#define CONFIG_KEY_INTERVAL "WatchdogInterval"
-#define CONFIG_KEY_MAX_RETRY_COUNT "WatchdogMaxRetryCount"
-
-struct watchdog_config_s {
- int state;
- unsigned int interval;
- unsigned int max_retry_count;
-};
-
-static struct watchdog_config_s __config;
-
-static int __watchdog_config_get_int(dictionary *d,
- const char *section, const char *key)
-{
- char buf[512];
-
- snprintf(buf, sizeof(buf), "%s:%s", section, key);
-
- return iniparser_getint(d, buf, -1);
-}
-
-static const char *__watchdog_config_get_string(dictionary *d,
- const char *section, const char *key)
-{
- char buf[512];
-
- snprintf(buf, sizeof(buf), "%s:%s", section, key);
-
- return iniparser_getstring(d, buf, NULL);
-}
-
-static int __watchdog_config_load(const char *path)
-{
- dictionary *d;
- const char *str;
- int r;
-
- r = access(path, R_OK);
- if (r != 0) {
- _E("Failed to access %s. errno(%d)", path, errno);
- return -1;
- }
-
- d = iniparser_load(path);
- if (!d) {
- _E("Failed to load %s by iniparser", path);
- return -1;
- }
-
- str = __watchdog_config_get_string(d, CONFIG_SECTION_NAME,
- CONFIG_KEY_WATCHDOG);
- if (str && !strcmp(str, "enable-by-default"))
- __config.state = WATCHDOG_ENABLE_BY_DEFAULT;
- _W("Operation state: %s", str);
-
- r = __watchdog_config_get_int(d, CONFIG_SECTION_NAME,
- CONFIG_KEY_INTERVAL);
- if (r > 0) {
- __config.interval = r;
- _W("Interval: %u", __config.interval);
- }
-
- r = __watchdog_config_get_int(d, CONFIG_SECTION_NAME,
- CONFIG_KEY_MAX_RETRY_COUNT);
- if (r > 0) {
- __config.max_retry_count = r;
- _W("Maximum retry count: %u", __config.max_retry_count);
- }
-
- iniparser_freedict(d);
-
- return 0;
-}
-
-int _watchdog_config_get_operation_state(void)
-{
- return __config.state;
-}
-
-unsigned int _watchdog_config_get_interval(void)
-{
- return __config.interval;
-}
-
-unsigned int _watchdog_config_get_max_retry_count(void)
-{
- return __config.max_retry_count;
-}
-
-int _watchdog_config_init(void)
-{
- _D("Watchdog config init");
-
- __config.state = WATCHDOG_ENABLE_ON_DEMAND;
- __config.interval = 10000; /* 10 secdons */
- __config.max_retry_count = 1;
-
- if (__watchdog_config_load(CONFIG_PATH) < 0)
- _W("Failed to load watchdog config");
-
- return 0;
-}
-
-void _watchdog_config_fini(void)
-{
- _D("Watchdog config fini");
- __config.state = WATCHDOG_ENABLE_ON_DEMAND;
- __config.interval = 0;
- __config.max_retry_count = 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdarg.h>
-#include <amd.h>
-
-#include "amd_watchdog_logger.h"
-#include "amd_watchdog_private.h"
-
-#define LOG_FILE "amd_watchdog.log"
-#define LOG_PATH LOGGER_PATH "/" LOG_FILE
-
-static amd_logger_h __logger;
-
-int _watchdog_logger_print(const char *tag, const char *format, ...)
-{
- char format_buf[256];
- va_list ap;
-
- va_start(ap, format);
- vsnprintf(format_buf, sizeof(format_buf), format, ap);
- va_end(ap);
-
- return amd_logger_print(__logger, tag, format_buf);
-}
-
-int _watchdog_logger_init(void)
-{
- int ret;
-
- _D("Watchdog logger init");
- ret = amd_logger_create(LOG_PATH, &__logger);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void _watchdog_logger_fini(void)
-{
- _D("Watchdog logger fini");
- amd_logger_destroy(__logger);
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_WAYLAND_CORE "amd-mod-wayland-core")
-SET(AMD_MOD_WAYLAND_CORE_DIR ${CMAKE_SOURCE_DIR}/modules/wayland-core)
-PROJECT(${AMD_MOD_WAYLAND_CORE} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_WAYLAND_CORE_DIR}/src AMD_MOD_WAYLAND_CORE_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_WAYLAND_CORE_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- wayland-client
- wayland-tbm-client
- tizen-extension-client
- )
-
-pkg_check_modules(amd_mod_wayland_core_pkgs REQUIRED ${AMD_MOD_WAYLAND_CORE_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_wayland_core_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_WAYLAND_CORE_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_WAYLAND_CORE} ${AMD_MOD_WAYLAND_CORE_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_WAYLAND_CORE} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_WAYLAND_CORE} ${amd_mod_wayland_core_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_WAYLAND_CORE} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2017 - 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-#include <tizen-extension-client-protocol.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_WAYLAND_CORE"
-
-#define PATH_RUN_WAYLAND "/run/wayland-0"
-#define PATH_RUN_WMREADY "/run/.wm_ready"
-#define PATH_RUN "/run"
-
-struct file_monitor_s {
- bool wl_ready;
- bool wm_ready;
- amd_inotify_watch_info_h handle;
-};
-
-struct wl_source_s {
- struct wl_display *display;
- struct wl_registry *registry;
- GSource *gsource;
- GPollFD *gfd;
- bool prepared;
-};
-
-static struct file_monitor_s __file_monitor;
-static struct wl_source_s __wl_source;
-static int __retry_cnt;
-
-static void __wl_listener_cb(void *data, struct wl_registry *reg,
- unsigned int id, const char *interface, unsigned int version)
-{
- char buf[512];
-
- if (!interface)
- return;
-
- _W("interface(%s), id(%u), version(%u)", interface, id, version);
- snprintf(buf, sizeof(buf), "wayland.listener.%s", interface);
- amd_noti_send(buf, (int)id, (int)version, reg, NULL);
-}
-
-static void __wl_listener_remove_cb(void *data, struct wl_registry *reg,
- unsigned int id)
-{
- _W("id(%u)", id);
- amd_noti_send(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
- (int)id, 0, reg, NULL);
-}
-
-static const struct wl_registry_listener __registry_listener = {
- __wl_listener_cb,
- __wl_listener_remove_cb
-};
-
-static gboolean __wl_source_prepare(GSource *source, gint *timeout)
-{
- if (__wl_source.prepared)
- return FALSE;
-
- while (wl_display_prepare_read(__wl_source.display) != 0) {
- if (wl_display_dispatch_pending(__wl_source.display) < 0)
- _W("Failed to dispatch queue pending");
- }
-
- __wl_source.prepared = true;
-
- wl_display_flush(__wl_source.display);
- *timeout = -1;
-
- return FALSE;
-}
-
-static gboolean __wl_source_check(GSource *source)
-{
- if (g_source_is_destroyed(source)) {
- if (__wl_source.display && __wl_source.prepared)
- wl_display_cancel_read(__wl_source.display);
- _E("Display source(%p) already destroyed", source);
- return FALSE;
- }
-
- if (!__wl_source.prepared)
- return FALSE;
-
- if (__wl_source.gfd->revents & (G_IO_HUP | G_IO_ERR)) {
- wl_display_cancel_read(__wl_source.display);
- _E("Error: revents(%x)", __wl_source.gfd->revents);
- __wl_source.prepared = false;
- g_source_destroy(source);
- abort();
- return FALSE;
- }
-
- if (__wl_source.gfd->revents & G_IO_IN) {
- if (wl_display_read_events(__wl_source.display) < 0)
- _W("Failed to read events");
- __wl_source.prepared = false;
- return TRUE;
- }
-
- wl_display_cancel_read(__wl_source.display);
- __wl_source.prepared = false;
-
- return FALSE;
-}
-
-static gboolean __wl_source_dispatch(GSource *source, GSourceFunc callback,
- gpointer data)
-{
- if (g_source_is_destroyed(source)) {
- _E("Source(%p) is already destroyed", source);
- return G_SOURCE_REMOVE;
- }
-
- if (__wl_source.gfd->revents & (G_IO_HUP | G_IO_ERR)) {
- _E("Error: revents(%x)", __wl_source.gfd->revents);
- g_source_destroy(source);
- abort();
- return G_SOURCE_REMOVE;
- }
-
- if (__wl_source.gfd->revents & G_IO_IN) {
- if (wl_display_dispatch_pending(__wl_source.display) < 0)
- _W("Failed to dispatch queue pending");
- }
-
- wl_display_flush(__wl_source.display);
-
- return G_SOURCE_CONTINUE;
-}
-
-static GSourceFuncs __wl_source_funcs = {
- .prepare = __wl_source_prepare,
- .check = __wl_source_check,
- .dispatch = __wl_source_dispatch,
- .finalize = NULL
-};
-
-static void __wl_source_fini(void)
-{
- if (__wl_source.gfd) {
- g_source_remove_poll(__wl_source.gsource, __wl_source.gfd);
- g_free(__wl_source.gfd);
- __wl_source.gfd = NULL;
- }
-
- if (__wl_source.gsource != NULL &&
- !g_source_is_destroyed(__wl_source.gsource)) {
- g_source_destroy(__wl_source.gsource);
- g_source_unref(__wl_source.gsource);
- __wl_source.gsource = NULL;
- }
-
- if (__wl_source.registry) {
- wl_registry_destroy(__wl_source.registry);
- __wl_source.registry = NULL;
- }
-
- if (__wl_source.display) {
- wl_display_disconnect(__wl_source.display);
- __wl_source.display = NULL;
- amd_wayland_set_display(NULL);
- }
-}
-
-static int __wl_source_init(void)
-{
- int r;
-
- __wl_source.display = wl_display_connect(NULL);
- if (!__wl_source.display) {
- _E("Failed to connect wayland display");
- return -1;
- }
- amd_wayland_set_display(__wl_source.display);
-
- __wl_source.registry = wl_display_get_registry(__wl_source.display);
- if (!__wl_source.registry) {
- _E("Failed to get wayland registry");
- return -1;
- }
-
- wl_registry_add_listener(__wl_source.registry,
- &__registry_listener, NULL);
- wl_display_flush(__wl_source.display);
-
- r = wl_display_roundtrip(__wl_source.display);
- if (r < 0)
- _W("wl_display_roundtrip() is failed. result(%d)", r);
-
- __wl_source.gsource = g_source_new(&__wl_source_funcs, sizeof(GSource));
- if (!__wl_source.gsource) {
- _E("Failed to create GSource");
- return -1;
- }
-
- __wl_source.gfd = (GPollFD *)g_malloc(sizeof(GPollFD));
- if (!__wl_source.gfd) {
- _E("Failed to create GPollFD");
- return -1;
- }
-
- __wl_source.gfd->fd = wl_display_get_fd(__wl_source.display);
- __wl_source.gfd->events = G_IO_IN | G_IO_ERR;
- __wl_source.gfd->revents = 0;
-
- g_source_add_poll(__wl_source.gsource, __wl_source.gfd);
- g_source_set_callback(__wl_source.gsource, NULL,
- __wl_source.display, NULL);
- g_source_set_priority(__wl_source.gsource, G_PRIORITY_DEFAULT);
- g_source_attach(__wl_source.gsource, NULL);
-
- return 0;
-}
-
-static gboolean __init_wl(gpointer data)
-{
- _I("Initialize Wayland");
- if (__wl_source_init() < 0) {
- __retry_cnt++;
- if (__retry_cnt > 10) {
- _E("Failed to initialize wayland: Retry(%d)", __retry_cnt);
- __wl_source_fini();
- g_timeout_add_seconds(1, __init_wl, NULL);
- return G_SOURCE_REMOVE;
- }
- __wl_source_fini();
- return G_SOURCE_CONTINUE;
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static bool __wayland_monitor_cb(const char *event_name, void *data)
-{
- if (event_name == NULL)
- return true;
-
- if (strcmp(event_name, "wayland-0") == 0) {
- _D("%s is created", event_name);
- __file_monitor.wl_ready = true;
- } else if (strcmp(event_name, ".wm_ready") == 0) {
- _D("%s is created", event_name);
- __file_monitor.wm_ready = true;
- }
-
- if (__file_monitor.wm_ready && __file_monitor.wl_ready) {
- g_idle_add(__init_wl, NULL);
- __file_monitor.handle = NULL;
- return false;
- }
-
- return true;
-}
-
-static int __file_monitor_init(void)
-{
- if (!__file_monitor.wl_ready) {
- if (access(PATH_RUN_WAYLAND, F_OK) == 0) {
- _D("%s exists", PATH_RUN_WAYLAND);
- __file_monitor.wl_ready = true;
- }
- }
-
- if (!__file_monitor.wm_ready) {
- if (access(PATH_RUN_WMREADY, F_OK) == 0) {
- _D("%s exists", PATH_RUN_WMREADY);
- __file_monitor.wm_ready = true;
- }
- }
-
- if (__file_monitor.wl_ready && __file_monitor.wm_ready) {
- g_idle_add(__init_wl, NULL);
- return 0;
- }
-
- __file_monitor.handle = amd_inotify_add_watch(PATH_RUN, IN_CREATE,
- __wayland_monitor_cb, NULL);
- if (__file_monitor.handle == NULL) {
- _E("Failed to add inotify watch");
- return -1;
- }
-
- return 0;
-}
-
-static void __file_monitor_fini(void)
-{
- if (__file_monitor.handle)
- amd_inotify_rm_watch(__file_monitor.handle);
-}
-
-static gboolean __idle_cb(gpointer data)
-{
- _D("wayland core init");
-
- if (__file_monitor_init() < 0)
- return G_SOURCE_CONTINUE;
-
- return G_SOURCE_REMOVE;
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- _D("wayland core init");
-
- g_idle_add(__idle_cb, NULL);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- _D("wayland core finish");
-
- __file_monitor_fini();
- __wl_source_fini();
- __retry_cnt = 0;
-}
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
-
-SET(AMD_MOD_WIDGET "amd-mod-widget")
-SET(AMD_MOD_WIDGET_DIR ${CMAKE_SOURCE_DIR}/modules/widget)
-PROJECT(${AMD_MOD_WIDGET} C)
-AUX_SOURCE_DIRECTORY(${AMD_MOD_WIDGET_DIR}/src AMD_MOD_WIDGET_SOURCES)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-
-SET(AMD_MOD_WIDGET_PKG_CHECK_MODULES
- dlog
- glib-2.0
- gio-2.0
- aul
- bundle
- pkgmgr-info
- )
-
-pkg_check_modules(amd_mod_widget_pkgs REQUIRED ${AMD_MOD_WIDGET_PKG_CHECK_MODULES})
-
-FOREACH(flag ${amd_mod_widget_pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-# Compiler flags
-INCLUDE_DIRECTORIES(${AMD_MOD_WIDGET_DIR}/inc)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-SET(CMAKE_SKIP_BUILD_RPATH true)
-SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AMD_MOD_WIDGET} ${AMD_MOD_WIDGET_SOURCES})
-SET_TARGET_PROPERTIES(${AMD_MOD_WIDGET} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${AMD_MOD_WIDGET} ${amd_mod_widget_pkgs_LDFLAGS} libamd)
-
-INSTALL(TARGETS ${AMD_MOD_WIDGET} DESTINATION ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * Copyright (c) 2018 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_WIDGET_LOGGER_H__
-#define __AMD_WIDGET_LOGGER_H__
-
-int _widget_logger_init(void);
-
-void _widget_logger_fini(void);
-
-int _widget_logger_print(const char *tag, const char *format, ...);
-
-#endif /* __AMD_WIDGET_LOGGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#pragma once
-
-#include <amd_mod_common.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_WIDGET"
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_svc.h>
-#include <aul_svc_priv_key.h>
-#include <aul_sock.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-#include <aul_widget.h>
-#include <amd.h>
-
-#include "amd_widget_logger.h"
-#include "amd_widget_private.h"
-
-#ifndef AUL_K_WIDGET_OPERATION
-#define AUL_K_WIDGET_OPERATION "__WIDGET_OP__"
-#endif
-#define MAX_NR_OF_DESCRIPTORS 2
-#define MAX_PID_STR_BUFSZ 20
-#define DISABLE_ENDPOINT "widget.disable"
-
-typedef struct _widget_t {
- char *pkg_id;
- char *widget_id;
- int pid;
- pid_t viewer_pid;
- uid_t uid;
- GList *instances;
-} widget_t;
-
-struct restart_widget_info {
- char *appid;
- char *pkgid;
- GList *widget_list;
- bool is_faulted;
- int status;
- pid_t pid;
- uid_t uid;
- pid_t viewer_pid;
- int count;
- guint timer;
-};
-
-struct restart_info {
- char *appid;
- int count;
- guint timer;
-};
-
-struct widget_status_info {
- const char *endpoint;
- const char *widget_id;
- const char *instance_id;
- const char *pkg_id;
- const char *is_fault;
- int status;
- int pid;
- uid_t uid;
-};
-
-static GList *__widgets;
-static GList *__update_widgets;
-static GList *__oom_restart_widgets;
-static GList *__restart_widgets;
-
-static widget_t *__create_widget(const char *widget_id, const char *pkgid,
- pid_t pid, uid_t uid);
-static void __free_widget(gpointer data);
-
-static int __send_status_info(struct widget_status_info *info)
-{
- char buf[MAX_PID_STR_BUFSZ];
- bundle *envelope;
- int r;
-
- envelope = bundle_create();
- if (envelope == NULL) {
- LOGE("Out of memory");
- return -1;
- }
-
- snprintf(buf, sizeof(buf), "%d", info->pid);
- bundle_add(envelope, AUL_K_COM_SENDER_PID, buf);
- bundle_add(envelope, AUL_K_WIDGET_ID, info->widget_id);
- bundle_add_byte(envelope, AUL_K_WIDGET_STATUS,
- &info->status, sizeof(int));
-
- if (info->instance_id) {
- bundle_add(envelope, AUL_K_WIDGET_INSTANCE_ID,
- info->instance_id);
- }
- if (info->pkg_id)
- bundle_add(envelope, AUL_K_PKGID, info->pkg_id);
- if (info->is_fault)
- bundle_add(envelope, AUL_K_IS_FAULT, info->is_fault);
-
- r = amd_app_com_send(info->endpoint, info->pid, envelope, info->uid);
- bundle_free(envelope);
- LOGW("endpoint(%s), widget(%s:%d), status(%d), is_faulted(%s)",
- info->endpoint, info->widget_id,
- info->pid, info->status,
- info->is_fault);
- _widget_logger_print("SEND_STATUS", "widget(%s), pid(%d) "
- "status(%d), is_faulted(%s)",
- info->widget_id, info->pid,
- info->status, info->is_fault);
- return r;
-}
-
-static void __free_widget(gpointer data)
-{
- widget_t *widget = (widget_t *)data;
-
- if (widget->pkg_id)
- free(widget->pkg_id);
- if (widget->widget_id)
- free(widget->widget_id);
- if (widget->instances)
- g_list_free_full(widget->instances, free);
- free(widget);
-}
-
-static widget_t *__create_widget(const char *widget_id, const char *pkgid,
- pid_t pid, uid_t uid)
-{
- widget_t *widget;
-
- widget = (widget_t *)calloc(1, sizeof(widget_t));
- if (widget == NULL) {
- LOGE("Out of memory");
- return NULL;
- }
-
- widget->widget_id = strdup(widget_id);
- if (widget->widget_id == NULL) {
- LOGE("Out of memory");
- free(widget);
- return NULL;
- }
-
- if (pkgid) {
- widget->pkg_id = strdup(pkgid);
- if (widget->pkg_id == NULL) {
- LOGE("Out of memory");
- free(widget->widget_id);
- free(widget);
- return NULL;
- }
- }
-
- widget->pid = pid;
- widget->uid = uid;
-
- return widget;
-}
-
-static widget_t *__find_widget(const char *widget_id, int pid, uid_t uid)
-{
- GList *widget_list = __widgets;
- widget_t *widget;
-
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (strcmp(widget->widget_id, widget_id) == 0) {
- if (widget->pid == pid && widget->uid == uid)
- return widget;
- }
-
- widget_list = widget_list->next;
- }
-
- return NULL;
-}
-
-static widget_t *__find_instance(const char *widget_id, const char *instance_id)
-{
- GList *widget_list = __widgets;
- GList *instance_list;
- widget_t *widget;
-
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (strcmp(widget->widget_id, widget_id) == 0
- && widget->instances) {
- instance_list = g_list_find_custom(widget->instances,
- instance_id, (GCompareFunc)g_strcmp0);
-
- if (instance_list)
- return widget;
- }
-
- widget_list = widget_list->next;
- }
-
- return NULL;
-}
-
-static bool __widget_exist(int pid, uid_t uid)
-{
- GList *widget_list = __widgets;
- widget_t *widget;
-
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (widget->pid == pid && widget->uid == uid)
- return true;
-
- widget_list = widget_list->next;
- }
- return false;
-}
-
-static int __get_viewer_pid(bundle *kb)
-{
- const char *pid_str;
- int pid;
-
- pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
- if (pid_str == NULL)
- pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
-
- if (pid_str == NULL)
- return -1;
-
- pid = atoi(pid_str);
- if (pid <= 1)
- return -1;
- return pid;
-}
-
-static int __widget_pre_add(bundle *kb, int pid, uid_t uid)
-{
- widget_t *widget;
- const char *widget_id;
- const char *instance_id;
- const char *operation;
- pid_t viewer_pid;
- char *error_desc;
-
- if (!kb) {
- LOGE("Invalid parameter");
- error_desc = "bundle NULL";
- goto error;
- }
-
- operation = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
- if (!operation || strcmp(operation, "create") != 0) {
- error_desc = "operation";
- goto error;
- }
-
- widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
- if (!widget_id) {
- error_desc = "widget id";
- goto error;
- }
-
- instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
- if (!instance_id) {
- error_desc = "instance id";
- goto error;
- }
-
- widget = __find_instance(widget_id, instance_id);
- if (!widget) {
- widget = __find_widget(widget_id, pid, uid);
- if (!widget) {
- widget = __create_widget(widget_id, NULL, pid, uid);
- if (!widget) {
- error_desc = "create widget";
- goto error;
- }
-
- __widgets = g_list_append(__widgets, widget);
- }
- } else {
- if (widget->pid != pid) {
- LOGW("Process ID(%d) of %s is changed to %d",
- widget->pid, widget_id, pid);
- widget->pid = pid;
- }
- }
-
- viewer_pid = __get_viewer_pid(kb);
- widget->viewer_pid = viewer_pid;
- _widget_logger_print("PRE_ADD", "instance(%s), pid(%d), viewer_pid(%d)",
- instance_id, pid, viewer_pid);
-
- return 0;
-error:
- _widget_logger_print(
- "PRE_ADD", "Fail to PRE_ADD REASON(%s)", error_desc);
- return -1;
-}
-
-static int __widget_add(const char *widget_id, const char *instance_id,
- int pid, uid_t uid)
-{
- widget_t *widget;
- char *id;
- char *error_desc;
-
- if (!widget_id || !instance_id) {
- if (!widget_id)
- error_desc = "widget id";
- else
- error_desc = "instance id";
- goto error;
- }
-
- id = strdup(instance_id);
- if (!id) {
- error_desc = "instance_id dup";
- goto error;
- }
-
- widget = __find_instance(widget_id, instance_id);
- if (!widget) {
- widget = __find_widget(widget_id, pid, uid);
- if (!widget) {
- widget = __create_widget(widget_id, NULL, pid, uid);
- if (!widget) {
- LOGE("out of memory");
- free(id);
- error_desc = "create widget";
- goto error;
- }
-
- __widgets = g_list_append(__widgets, widget);
- }
- widget->pid = pid;
- widget->instances = g_list_append(widget->instances, id);
- } else {
- LOGW("instance recovery: %s - %s(%d)",
- widget_id, instance_id, pid);
- if (widget->pid != pid) {
- LOGW("Process ID(%d) of %s is changed to %d",
- widget->pid, widget_id, pid);
- widget->pid = pid;
- }
- free(id);
- }
-
- LOGD("widget instance added: %s - %s (%d:%d)", widget_id, instance_id,
- uid, pid);
- return 0;
-error:
- _widget_logger_print(
- "ADD", "Fail to ADD REASON(%s)", error_desc);
- return -1;
-}
-
-static int __widget_del(const char *widget_id, const char *instance_id)
-{
- widget_t *widget;
- GList *stored_list;
-
- if (!widget_id || !instance_id)
- return -1;
-
- widget = __find_instance(widget_id, instance_id);
- if (!widget) {
- LOGE("Failed to find instance(%s) of widget(%s)",
- instance_id, widget_id);
- return -1;
- }
- stored_list = g_list_find_custom(widget->instances, instance_id,
- (GCompareFunc)g_strcmp0);
-
- if (stored_list) {
- LOGW("widget instace deleted: %s - %s (%d:%d)",
- widget->widget_id,
- instance_id,
- widget->uid,
- widget->pid);
- widget->instances = g_list_remove_link(widget->instances,
- stored_list);
- if (!widget->instances) {
- __widgets = g_list_remove(__widgets, widget);
- __free_widget(widget);
- }
-
- free(stored_list->data);
- g_list_free(stored_list);
- return 0;
- }
-
- return -1;
-}
-
-static int __widget_list(const char *widget_id, amd_request_h req)
-{
- bundle *rvalue;
- widget_t *widget;
- GList *widget_list = __widgets;
- GList *instance_list;
- char pid_buf[10];
- int fd;
-
- if (!widget_id)
- return -1;
-
- rvalue = bundle_create();
- if (!rvalue) {
- LOGE("out of memory");
- return -1;
- }
-
- LOGD("start instance list");
-
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (strcmp(widget->widget_id, widget_id) == 0) {
- instance_list = widget->instances;
- snprintf(pid_buf, sizeof(pid_buf), "%d", widget->pid);
- while (instance_list) {
- LOGD("%s - %s", widget_id,
- (const char *)instance_list->data);
- bundle_add_str(rvalue, instance_list->data,
- pid_buf);
- instance_list = instance_list->next;
- }
- }
- widget_list = widget_list->next;
- }
-
- LOGD("end instance list");
-
- fd = amd_request_remove_fd(req);
- aul_sock_send_bundle_with_fd(fd, 0, rvalue, AUL_SOCK_NOREPLY);
- bundle_free(rvalue);
-
- return 0;
-}
-
-static int __widget_update(const char *widget_id, amd_request_h req)
-{
- char *instance_id = NULL;
- char *appid = NULL;
- bundle *kb = amd_request_get_bundle(req);
- int ret = -1;
- widget_t *widget;
- GList *widget_list = __widgets;
- bool dummy;
- bool dummy_mode;
-
- if (!kb || !widget_id) {
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_APPID, &appid);
- if (!appid) {
- LOGE("missing appid:%s", widget_id);
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
- if (!instance_id) { /* all instances */
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (strcmp(widget->widget_id, widget_id) == 0
- && widget->pid > 0) {
- bundle_del(kb, AUL_K_TARGET_PID);
- bundle_add_byte(kb, AUL_K_TARGET_PID,
- (void *)&widget->pid,
- sizeof(widget->pid));
-
- ret = amd_launch_start_app(appid, req, &dummy,
- &dummy_mode, false);
- LOGD("update widget: %s(%d)", widget->widget_id,
- widget->pid);
- }
- widget_list = widget_list->next;
- }
- } else {
- widget = __find_instance(widget_id, instance_id);
- if (widget) {
- if (widget->pid == -1) {
- LOGW("widget process is not running: %s",
- widget->widget_id);
- return ret;
- }
- bundle_del(kb, AUL_K_TARGET_PID);
- bundle_add_byte(kb, AUL_K_TARGET_PID,
- (void *)&widget->pid, sizeof(widget->pid));
- }
- ret = amd_launch_start_app(appid, req, &dummy, &dummy_mode, false);
- LOGD("update widget: %s", widget_id);
- }
-
- return ret;
-}
-
-static int __widget_cleanup(int pid, uid_t uid, int viewer_pid)
-{
- GList *widget_list = __widgets;
- widget_t *widget;
- amd_app_status_h viewer_status;
-
- LOGD("viewer pid %d", viewer_pid);
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- widget_list = widget_list->next;
- if (widget->pid == pid && widget->uid == uid) {
- viewer_status = amd_app_status_find_by_pid(viewer_pid);
- if (viewer_status == NULL) {
- __widgets = g_list_remove(__widgets, widget);
- __free_widget(widget);
- LOGW("remove widget(%d) from list", pid);
- } else {
- LOGW("viewer pid(%d), widget pid(%d)",
- viewer_pid, pid);
- widget->pid = -1;
- }
- }
- }
-
- LOGW("cleanup widget %d:%d", pid, uid);
-
- return 0;
-}
-
-static int __viewer_widget_cleanup(int viewer_pid, uid_t uid)
-{
- GList *widget_list = __widgets;
- widget_t *widget;
-
- LOGD("viewer pid %d", viewer_pid);
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- widget_list = widget_list->next;
- if (widget->viewer_pid == viewer_pid) {
- __widgets = g_list_remove(__widgets, widget);
- LOGW("remove widget(%s) from list", widget->widget_id);
- __free_widget(widget);
- }
- }
- LOGW("cleanup widget from viewer %d:%d", viewer_pid, uid);
-
- return 0;
-}
-
-static int __widget_get_pid(const char *widget_id, const char *instance_id)
-{
- widget_t *widget;
-
- widget = __find_instance(widget_id, instance_id);
- if (!widget)
- return -1;
-
- return widget->pid;
-}
-
-static int __widget_count(const char *widget_id, uid_t uid)
-{
- widget_t *widget;
- GList *widget_list = __widgets;
- GList *instance_list;
- int count = 0;
-
- if (!widget_id)
- return -1;
-
- while (widget_list) {
- widget = (widget_t *)widget_list->data;
- if (strcmp(widget->widget_id, widget_id) == 0 &&
- widget->uid == uid) {
- instance_list = widget->instances;
- if (instance_list)
- count += g_list_length(instance_list);
- }
- widget_list = widget_list->next;
- }
- LOGW("widget(%s) count: %d", widget_id, count);
-
- return count;
-}
-
-static int __widget_verify_cmd(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- const char *command;
- const char *instance_id;
- const char *widget_id;
- widget_t *widget;
- char *error_desc;
-
- if (!kb) {
- LOGE("invalid argument");
- error_desc = "bundle NULL";
- goto error;
- }
-
- widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
- if (!widget_id) {
- LOGE("widget id is NULL");
- error_desc = "widget id";
- goto error;
- }
-
- instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
- if (!instance_id) {
- LOGE("widget instance is NULL");
- error_desc = "instance id";
- goto error;
- }
-
- command = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
- if (!command) {
- LOGE("widget command is NULL");
- error_desc = "command is null";
- goto error;
- }
-
- if (strcmp(command, "create") == 0)
- return 0;
-
- widget = __find_instance(widget_id, instance_id);
- if (!widget) {
- LOGE("invalid command: %s - target instance %s is not exist",
- command, instance_id);
- error_desc = "invalid command";
- goto error;
- }
-
- return 0;
-error:
- _widget_logger_print(
- "VERIFY_CMD", "Fail to PRE_ADD REASON(%s)", error_desc);
- return -1;
-}
-
-static int __validate_widget_owner(amd_request_h req)
-{
- amd_app_status_h status;
- const char *appid;
- char *widget_id = NULL;
- const char *appid_part = NULL;
- bundle *kb = amd_request_get_bundle(req);
-
- status = amd_app_status_find_by_pid(amd_request_get_pid(req));
- if (!status)
- return -1;
-
- appid = amd_app_status_get_appid(status);
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- if (!widget_id || !appid)
- return -1;
-
- appid_part = g_strstr_len(widget_id, strlen(widget_id), "@");
- if (appid_part)
- appid_part = appid_part + 1;
- else
- appid_part = widget_id;
-
- return strcmp(appid_part, appid);
-}
-
-static int __dispatch_widget_change_status(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- amd_app_status_h caller_status;
- const char *caller_pkgid;
- const char *caller_appid = NULL;
- const char *status;
- int pid;
-
- if (__validate_widget_owner(req) < 0) {
- LOGE("Invalid sender");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- status = bundle_get_val(kb, AUL_K_STATUS);
- if (status == NULL) {
- LOGE("Failed to get status");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- pid = amd_request_get_pid(req);
- caller_status = amd_app_status_find_by_pid(pid);
- if (!caller_status)
- return 0; /* not app? */
-
- caller_pkgid = amd_app_status_get_pkgid(caller_status);
- if (!caller_pkgid) {
- LOGE("can not get caller pkgid");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- caller_appid = amd_app_status_get_appid(caller_status);
- if (!caller_appid) {
- LOGE("can not get caller appid");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- LOGI("send status %d, %s, %s, %s", pid, caller_appid,
- caller_pkgid, status);
-
- aul_send_app_status_change_signal(pid,
- caller_appid,
- caller_pkgid,
- status,
- APP_TYPE_WIDGET);
- _widget_logger_print("CHANGE_STATUS", "widget_id(%s), status(%s)",
- caller_appid, status);
- return amd_request_send_result(req, 0);
-}
-
-static int __dispatch_widget_add_del(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *widget_id = NULL;
- char *instance_id = NULL;
- int ret;
- int cmd = amd_request_get_cmd(req);
- const char *tag;
-
- if (cmd == WIDGET_ADD && __validate_widget_owner(req) != 0) {
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- if (!widget_id) {
- LOGE("Failed to get widget id");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
- if (!instance_id) {
- LOGE("Failed to get instance id");
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- if (amd_request_get_cmd(req) == WIDGET_ADD) {
- ret = __widget_add(widget_id, instance_id,
- amd_request_get_pid(req),
- amd_request_get_uid(req));
- tag = "ADD";
- } else {
- ret = __widget_del(widget_id, instance_id);
- tag = "DEL";
- }
-
- amd_request_send_result(req, ret);
- LOGW("[%s:%d] Instance ID(%s), Result(%d)",
- aul_cmd_convert_to_string(cmd),
- cmd, instance_id, ret);
- _widget_logger_print(tag, "instance(%s), result(%d)",
- instance_id, ret);
- return ret;
-}
-
-static int __validate_widget_caller(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *appid = NULL;
- amd_appinfo_h target;
- const char *target_pkgid;
- amd_app_status_h caller_status;
- const char *caller_pkgid;
- pid_t caller_pid = amd_request_get_pid(req);
- char attr[512] = { 0, };
- int r;
-
- if (amd_request_get_uid(req) < REGULAR_UID_MIN) {
- LOGD("bypass caller package check");
- return 0;
- }
-
- bundle_get_str(kb, AUL_K_APPID, &appid);
- if (!appid) {
- LOGE("no appid provided");
- return -1;
- }
-
- target = amd_appinfo_find(amd_request_get_uid(req), appid);
- if (!target) {
- LOGE("can not find appinfo of %s", appid);
- return -1;
- }
-
- target_pkgid = amd_appinfo_get_value(target, AMD_AIT_PKGID);
- if (!target_pkgid) {
- LOGE("can not get pkgid of %s", appid);
- return -1;
- }
-
- caller_status = amd_app_status_find_by_effective_pid(caller_pid);
- if (!caller_status) {
- r = amd_proc_get_attr(caller_pid, attr, sizeof(attr));
- if (r != 0) {
- LOGE("Failed to get attr. caller(%d)", caller_pid);
- return -1;
- }
-
- if (!strcmp(attr, "User"))
- return 0;
-
- LOGE("Reject request. caller(%d)", caller_pid);
- return -1;
- }
-
- caller_pkgid = amd_app_status_get_pkgid(caller_status);
- if (!caller_pkgid) {
- LOGE("can not get caller pkgid");
- return -1;
- }
-
- LOGD("compare pkgid %s:%s", caller_pkgid, target_pkgid);
- if (strcmp(caller_pkgid, target_pkgid) == 0)
- return 0;
-
- return -1;
-}
-
-static int __send_message(int sock, const struct iovec *vec, int vec_size,
- const int *desc, int nr_desc)
-{
- struct msghdr msg = {0,};
- int sndret;
- int desclen = 0;
- struct cmsghdr *cmsg = NULL;
- char buff[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)] = {0,};
-
- if (vec == NULL || vec_size < 1)
- return -EINVAL;
- if (nr_desc < 0 || nr_desc > MAX_NR_OF_DESCRIPTORS)
- return -EINVAL;
- if (desc == NULL)
- nr_desc = 0;
-
- msg.msg_iov = (struct iovec *)vec;
- msg.msg_iovlen = vec_size;
-
- /* sending ancillary data */
- if (nr_desc > 0) {
- msg.msg_control = buff;
- msg.msg_controllen = sizeof(buff);
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg == NULL)
- return -EINVAL;
-
- /* packing files descriptors */
- if (nr_desc > 0) {
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- desclen = cmsg->cmsg_len =
- CMSG_LEN(sizeof(int) * nr_desc);
- memcpy((int *)CMSG_DATA(cmsg), desc,
- sizeof(int) * nr_desc);
- cmsg = CMSG_NXTHDR(&msg, cmsg);
- LOGD("packing file descriptors done");
- }
-
- /* finished packing updating the corect length */
- msg.msg_controllen = desclen;
- } else {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- }
-
- sndret = sendmsg(sock, &msg, 0);
- LOGD("sendmsg ret : %d", sndret);
- if (sndret < 0)
- return -errno;
-
- return sndret;
-}
-
-static int __dispatch_widget_get_content(amd_request_h req)
-{
- int handles[2] = {0,};
- char iobuf[1];
- struct iovec vec = {
- .iov_base = iobuf,
- .iov_len = sizeof(iobuf)
- };
- int msglen = 0;
- int ret;
- bundle *kb = amd_request_get_bundle(req);
- struct timeval tv;
- int pid;
- char *widget_id = NULL;
- char *instance_id = NULL;
-
- if (__validate_widget_caller(req) != 0) {
- amd_request_send_result(req, -EILLEGALACCESS);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
-
- pid = __widget_get_pid(widget_id, instance_id);
- if (pid < 0) {
- LOGE("can not find widget");
- amd_request_send_result(req, -ENOENT);
- return -1;
- }
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) {
- LOGE("error create socket pair");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- if (handles[0] == -1) {
- LOGE("error socket open");
- amd_request_send_result(req, -1);
- return -1;
- }
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- ret = setsockopt(handles[1], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- if (ret < 0) {
- LOGE("cannot set SO_RCVTIMEO for socket %d", handles[0]);
- amd_request_send_result(req, -1);
- goto out;
- }
-
- ret = aul_sock_send_bundle(pid, amd_request_get_target_uid(req),
- amd_request_get_cmd(req), amd_request_get_bundle(req),
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- LOGE("error while sending bundle");
- amd_request_send_result(req, -1);
- goto out;
- }
-
- msglen = __send_message(ret, &vec, 1, &(handles[0]), 1);
- if (msglen < 0) {
- LOGE("Error[%d]: while sending message to widget", -msglen);
- amd_request_send_result(req, -1);
- ret = -1;
- goto out;
- }
-
- msglen = __send_message(amd_request_get_fd(req), &vec, 1,
- &(handles[1]), 1);
- if (msglen < 0) {
- LOGE("Error[%d]: while sending message to caller", -msglen);
- amd_request_send_result(req, -1);
- ret = -1;
- }
-
-out:
- close(handles[0]);
- close(handles[1]);
-
- return ret;
-}
-
-static int __dispatch_widget_list(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *widget_id = NULL;
- int ret;
-
- if (__validate_widget_caller(req) < 0) {
- amd_request_send_result(req, -EILLEGALACCESS);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- if (!widget_id) {
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- ret = __widget_list(widget_id, req);
-
- return ret;
-}
-
-static int __dispatch_widget_update(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *widget_id = NULL;
- int ret;
-
- if (__validate_widget_caller(req) < 0) {
- amd_request_send_result(req, -EILLEGALACCESS);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- if (!widget_id) {
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
-
- /* update will pass bundle by app_control */
- amd_request_set_cmd(req, APP_START_ASYNC);
-
- ret = __widget_update(widget_id, req);
- if (ret < 0)
- return -1;
-
- _widget_logger_print("UPDATE", "widget_id(%s), result(%d)",
- widget_id, ret);
-
- return 0;
-}
-
-static int __dispatch_widget_count(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *widget_id = NULL;
- int count;
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- if (!widget_id) {
- LOGE("Failed to get widget id. caller(%d)",
- amd_request_get_pid(req));
- amd_request_send_result(req, -EINVAL);
- return -1;
- }
- count = __widget_count(widget_id, amd_request_get_uid(req));
- LOGD("dispatch widget count %d", count);
- amd_request_send_result(req, count);
-
- _widget_logger_print("COUNT", "widget_id(%s), count(%d)",
- widget_id, count);
-
- return 0;
-}
-
-static bundle *__create_bundle(widget_t *widget)
-{
- char buf[MAX_PID_STR_BUFSZ];
- amd_app_status_h app_status;
- bundle *b;
-
- app_status = amd_app_status_find_by_pid(widget->pid);
- if (app_status == NULL)
- return NULL;
-
- b = bundle_create();
- if (b == NULL) {
- LOGE("Out of memory");
- return NULL;
- }
-
- snprintf(buf, sizeof(buf), "%d", widget->pid);
- bundle_add_str(b, AUL_K_PID, buf);
- bundle_add_str(b, AUL_K_APPID, amd_app_status_get_appid(app_status));
- bundle_add_str(b, AUL_K_PKGID, amd_app_status_get_pkgid(app_status));
- bundle_add_str(b, AUL_K_EXEC, amd_app_status_get_app_path(app_status));
- bundle_add_str(b, AUL_K_WIDGET_ID, widget->widget_id);
-
- return b;
-}
-
-static int __send_running_info(widget_t *widget, int fd)
-{
- char buf[MAX_PID_STR_BUFSZ];
- const char *instance_id;
- unsigned int surf;
- bundle_raw *b_raw = NULL;
- int len = 0;
- GList *iter;
- bundle *b;
- int r;
-
- b = __create_bundle(widget);
- if (b == NULL) {
- LOGE("Failed to create bundle");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- iter = widget->instances;
- while (iter) {
- instance_id = (const char *)iter->data;
- surf = 0;
- amd_noti_send(AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND,
- GPOINTER_TO_INT(&surf), (int)widget->uid,
- (void *)instance_id, NULL);
- snprintf(buf, sizeof(buf), "%u", surf);
- bundle_del(b, AUL_K_WID);
- bundle_add_str(b, AUL_K_WID, buf);
- bundle_del(b, AUL_K_WIDGET_INSTANCE_ID);
- bundle_add_str(b, AUL_K_WIDGET_INSTANCE_ID, instance_id);
-
- bundle_encode(b, &b_raw, &len);
- if (b_raw == NULL) {
- LOGE("Failed to encode bundle");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_NOREPLY);
- bundle_free(b);
- return -1;
- }
-
- r = aul_sock_send_raw_with_fd(fd, APP_GET_INFO_OK,
- (unsigned char *)b_raw, len,
- AUL_SOCK_ASYNC | AUL_SOCK_BUNDLE);
- if (r < 0) {
- LOGE("Failed to send raw data: %d", r);
- free(b_raw);
- bundle_free(b);
- return -1;
- }
- free(b_raw);
- b_raw = NULL;
-
- iter = g_list_next(iter);
- }
- free(b_raw);
- bundle_free(b);
-
- return 0;
-}
-
-static int __dispatch_widget_running_info(amd_request_h req)
-{
- uid_t target_uid = amd_request_get_target_uid(req);
- int fd = amd_request_remove_fd(req);
- widget_t *widget;
- GList *iter;
- int count = 0;
- int r;
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- if (widget && widget->uid == target_uid)
- count += g_list_length(widget->instances);
-
- iter = g_list_next(iter);
- }
-
- if (count == 0) {
- LOGE("Widget doesn't exist");
- amd_socket_send_result(fd, -1, true);
- return -1;
- }
- amd_socket_send_result(fd, count, false);
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- if (widget && widget->uid == target_uid) {
- r = __send_running_info(widget, fd);
- if (r < 0)
- break;
- }
- iter = g_list_next(iter);
- }
- close(fd);
-
- return 0;
-}
-
-static int __app_term_by_pid_async_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- int pid;
- char *term_pid;
- bundle *kb;
- amd_app_status_h status;
- amd_appinfo_h ai;
- const char *comp_type;
-
- kb = amd_request_get_bundle(req);
- if (kb == NULL) {
- LOGE("Failed to get bundle");
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_APPID, &term_pid);
- if (term_pid == NULL) {
- LOGE("Failed to get process id");
- return -1;
- }
-
- pid = atoi(term_pid);
- status = amd_app_status_find_by_pid(pid);
- if (!status) {
- LOGE("Failed to find app status. pid(%d)", pid);
- return -1;
- }
-
- ai = amd_appinfo_find(amd_request_get_target_uid(req),
- amd_app_status_get_appid(status));
- if (!ai) {
- LOGE("Failed to find appinfo");
- return -1;
- }
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (!comp_type)
- return -1;
-
- if (strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
- return amd_cynara_simple_checker(info, req,
- PRIVILEGE_WIDGET_VIEWER);
- }
-
- return amd_cynara_simple_checker(info, req, data);
-}
-
-static int __dispatch_widget_disable(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- char *widget_id = NULL;
- char *ambient = NULL;
- int ret;
- int sender_pid = amd_request_get_pid(req);
- uid_t sender_uid = amd_request_get_uid(req);
-
- if (__validate_widget_caller(req) < 0) {
- LOGE("widget dispatch validate error");
- amd_request_send_result(req, -EILLEGALACCESS);
- return -1;
- }
-
- bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
- bundle_get_str(kb, AUL_K_WIDGET_DISABLE, &ambient);
-
- ret = aul_widget_service_set_disable_db(widget_id, (bool)atoi(ambient));
- if (ret) {
- LOGE("widget set disable db error");
- amd_request_send_result(req, ret);
- return -1;
- }
-
- ret = amd_app_com_send(DISABLE_ENDPOINT, getpgid(sender_pid), kb, sender_uid);
- if (ret < 0) {
- _E("send disable error:%d", ret);
- amd_request_send_result(req, -ECOMM);
- return -1;
- }
- amd_request_send_result(req, 0);
-
- return 0;
-}
-
-static int __dispatch_widget_event(amd_request_h req)
-{
- bundle *kb = amd_request_get_bundle(req);
- uid_t target_uid = amd_request_get_target_uid(req);
- int ret;
-
- if (!kb) {
- _E("Invalid request");
- return -EINVAL;
- }
-
- ret = amd_app_com_send("widget.event", getpid(), kb, target_uid);
-
- _W("[__WIDGET_EVENT__] caller(%d), result(%d)",
- amd_request_get_pid(req), ret);
- return ret;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = WIDGET_ADD,
- .callback = __dispatch_widget_add_del
- },
- {
- .cmd = WIDGET_DEL,
- .callback = __dispatch_widget_add_del
- },
- {
- .cmd = WIDGET_LIST,
- .callback = __dispatch_widget_list
- },
- {
- .cmd = WIDGET_UPDATE,
- .callback = __dispatch_widget_update
- },
- {
- .cmd = WIDGET_COUNT,
- .callback = __dispatch_widget_count
- },
- {
- .cmd = WIDGET_GET_CONTENT,
- .callback = __dispatch_widget_get_content
- },
- {
- .cmd = WIDGET_RUNNING_INFO,
- .callback = __dispatch_widget_running_info
- },
- {
- .cmd = WIDGET_CHANGE_STATUS,
- .callback = __dispatch_widget_change_status
- },
- {
- .cmd = WIDGET_DISABLE,
- .callback = __dispatch_widget_disable
- },
- {
- .cmd = WIDGET_EVENT,
- .callback = __dispatch_widget_event
- },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_TERM_BY_PID_ASYNC,
- .checker = __app_term_by_pid_async_checker,
- .data = PRIVILEGE_APPMANAGER_KILL,
- .priority = 10
- },
- {
- .cmd = WIDGET_RUNNING_INFO,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
- {
- .cmd = WIDGET_DISABLE,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PACKAGEMANAGER_ADMIN,
- .priority = 10
- },
- {
- .cmd = WIDGET_EVENT,
- .checker = amd_cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM,
- .priority = 10
- },
-};
-
-static void __destroy_restart_widget_info(gpointer data)
-{
- struct restart_widget_info *info = (struct restart_widget_info *)data;
-
- if (info == NULL)
- return;
-
- if (info->timer > 0)
- g_source_remove(info->timer);
- if (info->widget_list)
- g_list_free_full(info->widget_list, free);
- if (info->pkgid)
- free(info->pkgid);
- if (info->appid)
- free(info->appid);
- free(info);
-}
-
-static struct restart_widget_info *__create_restart_widget_info(
- amd_app_status_h app_status)
-{
- struct restart_widget_info *info;
- const char *appid = amd_app_status_get_appid(app_status);
- const char *pkgid = amd_app_status_get_pkgid(app_status);
- widget_t *widget;
- char *widget_id;
- GList *iter;
-
- info = calloc(1, sizeof(struct restart_widget_info));
- if (info == NULL) {
- LOGE("Out of memory");
- return NULL;
- }
-
- info->appid = strdup(appid);
- if (info->appid == NULL) {
- LOGE("Out of memory");
- free(info);
- return NULL;
- }
-
- info->pkgid = strdup(pkgid);
- if (info->pkgid == NULL) {
- LOGE("Out of memory");
- free(info->appid);
- free(info);
- return NULL;
- }
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- iter = g_list_next(iter);
-
- widget_id = strdup(widget->widget_id);
- if (widget_id == NULL) {
- LOGE("Out of memory");
- __destroy_restart_widget_info(info);
- return NULL;
- }
-
- info->widget_list = g_list_append(info->widget_list, widget_id);
- }
-
- info->is_faulted = !amd_app_status_is_exiting(app_status);
- info->pid = amd_app_status_get_pid(app_status);
- info->uid = amd_app_status_get_uid(app_status);
- info->viewer_pid = amd_app_status_get_first_caller_pid(app_status);
- info->count = 1;
-
- return info;
-}
-
-static struct restart_widget_info *__find_restart_widget_info(const char *appid,
- uid_t uid)
-{
- struct restart_widget_info *info;
- GList *iter;
-
- iter = __restart_widgets;
- while (iter) {
- info = (struct restart_widget_info *)iter->data;
- if (!strcmp(info->appid, appid) && info->uid == uid)
- return info;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static gboolean __restart_timeout_handler(void *data)
-{
- struct restart_widget_info *info = (struct restart_widget_info *)data;
-
- LOGW("appid (%s)", info->appid);
- __restart_widgets = g_list_remove(__restart_widgets, info);
- /* timer source will be removed after returing this callback */
- info->timer = 0;
- __destroy_restart_widget_info(info);
-
- return G_SOURCE_REMOVE;
-}
-
-static bool __check_restart(amd_app_status_h app_status)
-{
- struct restart_widget_info *info;
- const char *appid = amd_app_status_get_appid(app_status);;
- uid_t uid = amd_app_status_get_uid(app_status);
-
- info = __find_restart_widget_info(appid, uid);
- if (info == NULL) {
- info = __create_restart_widget_info(app_status);
- if (info == NULL)
- return false;
-
- __restart_widgets = g_list_append(__restart_widgets, info);
- info->timer = g_timeout_add(10 * 1000,
- __restart_timeout_handler, info);
- } else {
- info->count++;
- if (info->count > 5) {
- LOGW("Failed to recover the widget(%s:%u)",
- info->appid, info->uid);
- __restart_widgets = g_list_remove(__restart_widgets,
- info);
- __destroy_restart_widget_info(info);
- return false;
- }
-
- if (info->timer > 0) {
- g_source_remove(info->timer);
- info->timer = g_timeout_add(10 * 1000,
- __restart_timeout_handler, info);
- }
- }
-
- LOGD("appid(%s), uid(%u), count(%d)", appid, uid, info->count);
-
- return true;
-}
-
-static void __widget_send_dead_signal(pid_t pid, uid_t uid, const char *pkgid,
- bool is_faulted)
-{
- widget_t *widget;
- GList *iter;
- struct widget_status_info info = {
- .endpoint = "widget.status",
- .widget_id = NULL,
- .instance_id = NULL,
- .pkg_id = pkgid,
- .is_fault = is_faulted ? "true" : "false",
- .status = AUL_WIDGET_LIFE_CYCLE_EVENT_APP_DEAD,
- .pid = pid,
- .uid = uid
- };
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- if (widget->pid == pid && widget->uid == uid) {
- info.widget_id = widget->widget_id;
- __send_status_info(&info);
- }
- iter = g_list_next(iter);
- }
-}
-
-static void __widget_send_restart_signal(pid_t pid, uid_t uid, pid_t viewer_pid,
- const char *pkgid, bool is_faulted)
-{
- widget_t *widget;
- GList *iter;
- amd_app_status_h app_status;
- struct widget_status_info info;
-
- app_status = amd_app_status_find_by_pid(viewer_pid);
- if (app_status == NULL)
- return;
-
- info.endpoint = amd_app_status_get_appid(app_status);
- info.widget_id = NULL;
- info.instance_id = NULL;
- info.pkg_id = pkgid;
- info.is_fault = is_faulted ? "true" : "false";
- info.status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST;
- info.pid = pid;
- info.uid = uid;
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- if (widget->pid == pid && widget->uid == uid) {
- info.widget_id = widget->widget_id;
- __send_status_info(&info);
- }
- iter = g_list_next(iter);
- }
-}
-
-static widget_t *__find_pending_restart_widget(const char *widget_id, pid_t pid,
- uid_t uid, GList *pending_list)
-{
- widget_t *widget;
- GList *iter;
-
- iter = pending_list;
- while (iter) {
- widget = (widget_t *)iter->data;
- if (!strcmp(widget->widget_id, widget_id) &&
- widget->uid == uid &&
- widget->pid == pid)
- return widget;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static int __add_pending_restart_info(pid_t pid, uid_t uid,
- const char *pkgid, GList **pending_list)
-{
- widget_t *widget;
- widget_t *pending_info;
- GList *iter;
-
- iter = __widgets;
- while (iter) {
- widget = (widget_t *)iter->data;
- iter = g_list_next(iter);
-
- pending_info = __find_pending_restart_widget(widget->widget_id,
- pid, widget->uid, *pending_list);
- if (pending_info == NULL && widget->pid == pid) {
- pending_info = __create_widget(widget->widget_id,
- pkgid, widget->pid, widget->uid);
- if (pending_info == NULL)
- return -1;
- *pending_list = g_list_append(*pending_list,
- pending_info);
- LOGW("adding pending restart info: %s, %d, %d",
- widget->widget_id, widget->pid,
- widget->uid);
- }
- }
-
- return 0;
-}
-
-static void __flush_pending_restart_list(const char *pkgid, uid_t uid,
- GList **pending_list)
-{
- widget_t *widget;
- GList *iter;
- struct widget_status_info info = {
- .endpoint = "widget.status",
- .widget_id = NULL,
- .instance_id = NULL,
- .pkg_id = NULL,
- .is_fault = "true",
- .status = AUL_WIDGET_LIFE_CYCLE_EVENT_APP_DEAD,
- .pid = -1,
- .uid = 0
- };
-
- if (pending_list == NULL || *pending_list == NULL)
- return;
-
- iter = *pending_list;
- while (iter) {
- widget = (widget_t *)iter->data;
- iter = g_list_next(iter);
- if ((uid < REGULAR_UID_MIN || uid == widget->uid) &&
- (pkgid == NULL ||
- !strcmp(widget->pkg_id, pkgid))) {
- *pending_list = g_list_remove(*pending_list, widget);
- info.widget_id = widget->widget_id;
- info.pkg_id = widget->pkg_id;
- info.pid = widget->pid;
- info.uid = widget->uid;
- LOGW("sending pending restart status: %s, %d, %d",
- info.widget_id, info.pid, info.uid);
- __send_status_info(&info);
- __free_widget(widget);
- }
- }
-}
-
-static void __widget_flush_oom_restart_list(void)
-{
- __flush_pending_restart_list(NULL, 0, &__oom_restart_widgets);
-}
-
-static void __widget_flush_update_list(const char *pkgid, uid_t uid)
-{
- __flush_pending_restart_list(pkgid, uid, &__update_widgets);
-}
-
-static int __on_app_dead(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- amd_app_status_h app_status = arg3;
- int pid = arg1;
- uid_t uid = arg2;
- widget_t *info;
- pid_t viewer_pid = amd_app_status_get_first_caller_pid(app_status);
- bool is_faulted = !amd_app_status_is_exiting(app_status);
- const char *appid = amd_app_status_get_appid(app_status);
- const char *pkgid = amd_app_status_get_pkgid(app_status);
- bool can_restart;
- bool is_widget;
- int r;
-
- is_widget = __widget_exist(pid, uid);
- if (!is_widget)
- return 0;
-
- can_restart = __check_restart(app_status);
- if (!can_restart || !is_faulted) {
- __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
- return 0;
- }
-
- /*
- * Screen info should be removed before send dead signal
- * If not, _app_status_cleanup will send
- * AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE
- * event to the viewer and recreated instance with same
- * instance id info will be removed by
- * AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE event.
- */
- amd_noti_send(AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART,
- pid, (int)uid, NULL, NULL);
- if (amd_util_check_oom()) {
- info = __find_pending_restart_widget(appid, pid, uid,
- __oom_restart_widgets);
- if (info)
- return 0;
-
- r = __add_pending_restart_info(pid, uid, pkgid,
- &__oom_restart_widgets);
- if (r == 0) {
- LOGW("%s:%d is added on pending list", appid, pid);
- __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
- return 0;
- }
- } else if (amd_appinfo_is_pkg_updating(pkgid)) {
- LOGW("%s:%d is updating", appid, pid);
- /*
- * If widget package is in update process
- * widget dead signal will be sent after
- * update process is completed so that
- * viewer can restart widget at that time.
- */
- __widget_send_restart_signal(pid, uid, viewer_pid, pkgid,
- is_faulted);
-
- r = __add_pending_restart_info(pid, uid, pkgid,
- &__update_widgets);
- if (r == 0)
- return 0;
-
- __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
- return 0;
- }
-
- __widget_send_restart_signal(pid, uid, viewer_pid, pkgid,
- is_faulted);
- __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
- LOGW("Sent widget(%s:%d) dead signal", appid, pid);
-
- return 0;
-}
-
-static int __on_app_status_destroy(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_app_status_h app_status = arg3;
-
- if (amd_app_status_get_app_type(app_status) == AMD_AT_WIDGET_APP) {
- __widget_cleanup(amd_app_status_get_pid(app_status),
- amd_app_status_get_uid(app_status),
- amd_app_status_get_first_caller_pid(app_status));
- } else {
- LOGW("cleanup viewer start");
- __viewer_widget_cleanup(amd_app_status_get_pid(app_status),
- amd_app_status_get_uid(app_status));
- }
-
- return 0;
-}
-
-static int __on_launching_widget(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- amd_request_h req = arg3;
-
- if (__widget_verify_cmd(req) < 0)
- return -1;
-
- return 0;
-}
-
-static int __on_package_update_end(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- const char *pkgid = (const char *)arg3;
-
- __widget_flush_update_list(pkgid, uid);
-
- return 0;
-}
-
-static int __on_low_memory_normal(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- __widget_flush_oom_restart_list();
-
- return 0;
-}
-
-static void __widget_verify_instance(bundle *kb, int pid, uid_t uid)
-{
- const char *operation;
- const char *instance_id;
- const char *widget_id;
- widget_t *widget;
- struct widget_status_info info;
-
- if (kb == NULL)
- return;
-
- operation = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
- if (operation == NULL)
- return;
-
- if (strcmp(operation, "create") != 0)
- return;
-
- widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
- if (widget_id == NULL)
- return;
-
- instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
- if (instance_id == NULL)
- return;
-
- widget = __find_instance(widget_id, instance_id);
- if (widget)
- return;
-
- info.endpoint = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
- if (info.endpoint == NULL)
- return;
-
- info.widget_id = widget_id;
- info.instance_id = instance_id;
- info.pkg_id = NULL;
- info.is_fault = NULL;
- info.status = AUL_WIDGET_INSTANCE_EVENT_CREATE_ABORTED;
- info.pid = pid;
- info.uid = uid;
-
- LOGW("Send create aborted event %s:%s:%s",
- info.endpoint, info.widget_id, info.instance_id);
- __send_status_info(&info);
-}
-
-static int __on_launch_recv_timeout(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = (uid_t)arg2;
-
- __widget_verify_instance(data, pid, uid);
-
- return 0;
-}
-
-static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = (int)arg1;
- amd_appinfo_h ai = (amd_appinfo_h)arg3;
- const char *comptype;
- const char *val;
- uid_t uid;
-
- comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comptype && !strcmp(comptype, APP_TYPE_WIDGET)) {
- val = bundle_get_val(data, AUL_K_TARGET_UID);
- if (!val || !isdigit(*val))
- return 0;
-
- uid = strtoul(val, NULL, 10);
- __widget_pre_add(data, pid, uid);
- }
-
-
- return 0;
-}
-
-static int __on_launch_recv_error(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
- uid_t uid = (uid_t)arg2;
-
- __widget_verify_instance(data, pid, uid);
-
- return 0;
-}
-
-static int __on_package_update_error(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- const char *pkgid = (const char *)arg3;
-
- __widget_flush_update_list(pkgid, uid);
-
- return 0;
-}
-
-static void __check_disabled_appinfo(const char *appid, uid_t uid)
-{
- pkgmgrinfo_appinfo_h handle = NULL;
- int ret;
-
- ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(appid, uid, &handle);
- if (ret != PMINFO_R_OK) {
- LOGE("Failed to get disabled appinfo. appid(%s), uid(%u)",
- appid, uid);
- return;
- }
- pkgmgrinfo_appinfo_destroy_appinfo(handle);
-
- LOGW("[__WIDGET__] widget(%s) is disabled", appid);
-}
-
-static int __widget_viewer_checker(amd_cynara_caller_info_h info, amd_request_h req)
-{
- char *appid = NULL;
- const char *apptype;
- amd_appinfo_h appinfo;
- bundle *appcontrol = amd_request_get_bundle(req);
- uid_t target_uid = amd_request_get_target_uid(req);
-
- if (!appcontrol) {
- LOGE("wrong argument");
- return AMD_CYNARA_RET_ERROR;
- }
-
- bundle_get_str(appcontrol, AUL_K_APPID, &appid);
- if (!appid) {
- LOGE("can not resolve appid. request denied.");
- return AMD_CYNARA_RET_ERROR;
- }
-
- appinfo = amd_appinfo_find(target_uid, appid);
- if (!appinfo) {
- LOGE("can not resolve appinfo of %s. request denied.", appid);
- __check_disabled_appinfo(appid, target_uid);
- return AMD_CYNARA_RET_ERROR;
- }
-
- apptype = amd_appinfo_get_value(appinfo, AMD_AIT_COMPTYPE);
- if (!apptype) {
- LOGE("can not resolve apptype of %s. request denied.", appid);
- return AMD_CYNARA_RET_ERROR;
- }
-
- if (!strcmp(apptype, APP_TYPE_WIDGET) ||
- !strcmp(apptype, APP_TYPE_WATCH))
- return amd_cynara_simple_checker(info, req, PRIVILEGE_WIDGET_VIEWER);
-
- LOGE("illegal app type of request: %s - " \
- "only widget or watch apps are allowed", apptype);
-
- return AMD_CYNARA_RET_ERROR;
-}
-
-static int __appcontrol_sub_checker(amd_cynara_caller_info_h info, amd_request_h req)
-{
- bundle *appcontrol;
- char *op = NULL;
- int ret;
-
- appcontrol = amd_request_get_bundle(req);
- if (!appcontrol)
- return AMD_CYNARA_RET_CONTINUE;
-
- ret = bundle_get_str(appcontrol, AUL_SVC_K_OPERATION, &op);
- if (ret != BUNDLE_ERROR_NONE)
- return AMD_CYNARA_RET_CONTINUE;
-
- if (!op || strcmp(op, AUL_SVC_OPERATION_LAUNCH_WIDGET))
- return AMD_CYNARA_RET_CONTINUE;
-
- return __widget_viewer_checker(info, req);
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
- int r;
-
- LOGD("widget init");
- _widget_logger_init();
- r = amd_request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- LOGE("Failed to register cmds");
- return -1;
- }
-
- r = amd_cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- LOGE("Failed to register checkers");
- return -1;
- }
-
- amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
- __on_app_dead);
- amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_DESTROY,
- __on_app_status_destroy);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET,
- __on_launching_widget);
- amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
- __on_package_update_end);
- amd_noti_listen(AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL,
- __on_low_memory_normal);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT,
- __on_launch_recv_timeout);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- __on_launch_complete_start);
- amd_noti_listen(AMD_NOTI_MSG_LAUNCH_RECV_ERROR,
- __on_launch_recv_error);
- amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
- __on_package_update_error);
-
- amd_cynara_sub_checker_add("appcontrol", __appcontrol_sub_checker);
-
- return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
- LOGD("widget fini");
-
- if (__restart_widgets) {
- g_list_free_full(__restart_widgets,
- __destroy_restart_widget_info);
- }
-
- if (__update_widgets)
- g_list_free_full(__update_widgets, __free_widget);
-
- if (__widgets)
- g_list_free_full(__widgets, __free_widget);
-
- _widget_logger_fini();
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdarg.h>
-#include <amd.h>
-
-#include "amd_logger.h"
-#include "amd_widget_logger.h"
-#include "amd_widget_private.h"
-
-#define LOG_FILE "amd_widget.log"
-#define LOG_PATH LOGGER_PATH "/" LOG_FILE
-
-static amd_logger_h __logger;
-
-int _widget_logger_print(const char *tag, const char *format, ...)
-{
- char format_buf[LOG_MAX_STRING_SIZE];
- va_list ap;
-
- va_start(ap, format);
- vsnprintf(format_buf, sizeof(format_buf), format, ap);
- va_end(ap);
-
- return amd_logger_print(__logger, tag, format_buf);
-}
-
-int _widget_logger_init(void)
-{
- int ret;
-
- _D("widget logger init");
- ret = amd_logger_create(LOG_PATH, &__logger);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void _widget_logger_fini(void)
-{
- _D("widget logger fini");
- amd_logger_destroy(__logger);
-}
%{_unitdir}/sockets.target.wants/ac.socket
%{_bindir}/amd
%{_libdir}/libamd.so.*
-%{_moddir}/libamd.so
%{_moddir}/conf/amd.conf
%files devel
--- /dev/null
+ADD_SUBDIRECTORY(amd)
+ADD_SUBDIRECTORY(lib)
+ADD_SUBDIRECTORY(modules)
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} AMD_SRCS)
+
+ADD_EXECUTABLE(${TARGET_AMD} ${AMD_SRCS})
+
+IF(_TIZEN_FEATURE_PRELINK)
+MESSAGE(STATUS "prelink enable")
+SET_TARGET_PROPERTIES(${TARGET_AMD} PROPERTIES COMPILE_FLAGS ${CFLAGS})
+SET_TARGET_PROPERTIES(${TARGET_AMD} PROPERTIES LINK_FLAGS "-Wl,-z,relro")
+ELSE(_TIZEN_FEATURE_PRELINK)
+MESSAGE(STATUS "prelink disable")
+SET_TARGET_PROPERTIES(${TARGET_AMD} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_AMD} PROPERTIES LINK_FLAGS
+ "-pie -Wl,-z,relro")
+ENDIF(_TIZEN_FEATURE_PRELINK)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD} PRIVATE ${TARGET_LIB_AMD})
+
+INSTALL(TARGETS ${TARGET_AMD} DESTINATION bin)
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <dlfcn.h>
-
-#define PATH_LIB_AMD "/usr/share/amd/libamd.so"
-
-int main(int argc, char *argv[])
-{
- void *handle;
- int (*dl_main)(int, char **);
-
- handle = dlopen(PATH_LIB_AMD, RTLD_LAZY | RTLD_GLOBAL);
- if (!handle) {
- fprintf(stderr, "Failed to load - %s", dlerror());
- return -1;
- }
-
- dl_main = dlsym(handle, "main");
- if (!dl_main) {
- fprintf(stderr, "Failed to find main function");
- dlclose(handle);
- return -1;
- }
-
- return dl_main(argc, argv);
-}
--- /dev/null
+/*
+ * 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 <amd_main.h>
+
+int main(int argc, char** argv) {
+ return amd_main(argc, argv);
+}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <glib.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <bundle_internal.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-
-#include "amd_api_noti.h"
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_signal.h"
-#include "amd_anr_monitor.h"
-#include "amd_app_status.h"
-#include "amd_app_property.h"
-#include "amd_appinfo.h"
-#include "amd_noti.h"
-#include "amd_request.h"
-#include "amd_launch.h"
-
-#define MAX_TIMEOUT 5000
-#define METADATA_ANR_CHECK_BYPASS \
- "http://tizen.org/metadata/appmanager/anr_check_bypass"
-
-typedef struct proc_info_s {
- pid_t pid;
- int ref;
- guint timer;
-} proc_info_t;
-
-static GHashTable *__proc_tbl;
-
-static proc_info_t *__find_proc_info(pid_t pid);
-static void __remove_proc_info(pid_t pid);
-
-static bool __is_managed_by_taskmgr(app_status_h app_status)
-{
- struct appinfo *ai;
- const char *taskmanage;
- const char *appid;
- uid_t uid;
-
- appid = _app_status_get_appid(app_status);
- uid = _app_status_get_uid(app_status);
- ai = _appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- taskmanage = _appinfo_get_value(ai, AIT_TASKMANAGE);
- if (!strcmp(taskmanage, "true"))
- return true;
-
- return false;
-}
-
-static bool __can_ignore_anr_policy(app_status_h app_status)
-{
- app_property_h app_property;
- const char *appid;
- bool ignore;
- uid_t uid;
-
- appid = _app_status_get_appid(app_status);
- uid = _app_status_get_uid(app_status);
- if (!_appinfo_is_platform_app(appid, uid))
- return false;
-
- app_property = _app_property_find(uid);
- ignore = _app_property_metadata_match(app_property,
- appid, METADATA_ANR_CHECK_BYPASS, "yes");
- if (ignore)
- return true;
-
- return false;
-}
-
-static gboolean __timeout_handler(gpointer data)
-{
- pid_t pid = GPOINTER_TO_INT(data);
- app_status_h app_status;
- proc_info_t *ctx;
-
- ctx = __find_proc_info(pid);
- if (!ctx)
- return G_SOURCE_REMOVE;
-
- ctx->timer = 0;
-
- app_status = _app_status_find_v2(pid);
- if (!app_status) {
- _W("Failed to find app status. pid(%d)", pid);
- __remove_proc_info(pid);
- return G_SOURCE_REMOVE;
- }
-
- if (_app_status_get_status(app_status) == STATUS_DYING) {
- _W("%d is dying", pid);
- __remove_proc_info(pid);
- return G_SOURCE_REMOVE;
- }
-
- _W("Application(%d) Not Responding", pid);
- if (__can_ignore_anr_policy(app_status)) {
- _W("Ignore ANR policy. pid(%d)", pid);
- return G_SOURCE_REMOVE;
- }
-
- if (!__is_managed_by_taskmgr(app_status)) {
- _W("The process(%d) is not managed by task-manager", pid);
- return G_SOURCE_REMOVE;
- }
-
- __remove_proc_info(pid);
- _signal_send_watchdog(pid, SIGKILL);
-
- return G_SOURCE_REMOVE;
-}
-
-static proc_info_t *__create_proc_info(pid_t pid)
-{
- proc_info_t *ctx;
-
- ctx = calloc(1, sizeof(proc_info_t));
- if (!ctx) {
- _E("Out of memory");
- return NULL;
- }
-
- ctx->pid = pid;
- ctx->ref = 1;
-
- ctx->timer = g_timeout_add(MAX_TIMEOUT, __timeout_handler,
- GINT_TO_POINTER(pid));
- if (ctx->timer == 0)
- _E("Failed to add timer");
-
- return ctx;
-}
-
-static void __destroy_proc_info(gpointer data)
-{
- proc_info_t *ctx = (proc_info_t *)data;
-
- if (!ctx) {
- _E("Critical error");
- return;
- }
-
- if (ctx->timer > 0)
- g_source_remove(ctx->timer);
-
- free(ctx);
-}
-
-static proc_info_t *__find_proc_info(pid_t pid)
-{
- if (!g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(pid)))
- return NULL;
-
- return g_hash_table_lookup(__proc_tbl, GINT_TO_POINTER(pid));
-}
-
-static void __add_proc_info(proc_info_t *ctx)
-{
- if (g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(ctx->pid)))
- return;
-
- g_hash_table_insert(__proc_tbl, GINT_TO_POINTER(ctx->pid), ctx);
-}
-
-static void __remove_proc_info(pid_t pid)
-{
- if (!g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(pid)))
- return;
-
- g_hash_table_remove(__proc_tbl, GINT_TO_POINTER(pid));
-}
-
-static void __reset_timer(proc_info_t *ctx)
-{
- if (ctx->timer > 0)
- g_source_remove(ctx->timer);
-
- ctx->timer = g_timeout_add(MAX_TIMEOUT, __timeout_handler,
- GINT_TO_POINTER(ctx->pid));
- if (ctx->timer == 0)
- _E("Failed to add timer. pid(%d)", ctx->pid);
-
- _W("Reset timer. pid(%d)", ctx->pid);
-}
-
-int _anr_monitor_add_timer(pid_t pid)
-{
- proc_info_t *ctx;
-
- _W("Add timer. pid(%d)", pid);
- ctx = __find_proc_info(pid);
- if (ctx) {
- __reset_timer(ctx);
- ctx->ref++;
- return 0;
- }
-
- ctx = __create_proc_info(pid);
- if (!ctx) {
- _E("Failed to create process(%d) info", pid);
- return -1;
- }
-
- __add_proc_info(ctx);
-
- return 0;
-}
-
-int _anr_monitor_remove_timer(pid_t pid)
-{
- proc_info_t *ctx;
-
- _W("Remove timer. pid(%d)", pid);
- ctx = __find_proc_info(pid);
- if (!ctx) {
- _E("Failed to find process(%d) info", pid);
- return -1;
- }
-
- ctx->ref--;
- if (ctx->ref > 0)
- return 0;
-
- __remove_proc_info(pid);
-
- return 0;
-}
-
-static int __dispatch_anr_notify(request_h req)
-{
- bundle *b = _request_get_bundle(req);
- uid_t uid = _request_get_uid(req);
- int pid = _request_get_pid(req);
- app_status_h app_status;
- const char *cmd_str;
- int cmd;
-
- cmd_str = bundle_get_val(b, AUL_K_COMMAND);
- if (cmd_str)
- cmd = atoi(cmd_str);
- else
- cmd = -1;
-
- _E("Application(%d) Not Responding. cmd(%d)", pid, cmd);
-
- app_status = _app_status_find_v2(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return -1;
- }
-
- switch (cmd) {
- case APP_OPEN:
- case APP_RESUME:
- case APP_START:
- case APP_START_RES:
- case APP_START_ASYNC:
- case APP_START_RES_ASYNC:
- case APP_SEND_LAUNCH_REQUEST:
- case APP_SEND_LAUNCH_REQUEST_SYNC:
- case APP_SEND_RESUME_REQUEST:
- if (!_app_status_is_debug_mode(app_status) &&
- !__can_ignore_anr_policy(app_status) &&
- __is_managed_by_taskmgr(app_status))
- _signal_send_watchdog(pid, SIGKILL);
- break;
- case APP_TERM_BY_PID:
- case APP_TERM_REQ_BY_PID:
- case APP_TERM_BY_PID_ASYNC:
- case APP_TERM_BGAPP_BY_PID:
- case APP_TERM_INSTANCE_ASYNC:
- case APP_TERM_BG_INSTANCE:
- _launch_send_sigkill(pid, uid);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = ANR_NOTIFY,
- .callback = __dispatch_anr_notify
- },
-};
-
-static int __on_signal_send_watchdog_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- int pid = arg1;
-
- _W("Watchdog pid(%d)", pid);
- _anr_monitor_remove_timer(pid);
-
- return 0;
-}
-
-int _anr_monitor_init(void)
-{
- int ret;
-
- _D("[__ANR_MONITOR__] init");
-
- __proc_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __destroy_proc_info);
- if (!__proc_tbl) {
- _E("Failed to create proc table");
- return -1;
- }
-
- ret = _app_property_metadata_add_filter(METADATA_ANR_CHECK_BYPASS,
- NULL);
- if (ret < 0)
- return -1;
-
- ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0)
- return -1;
-
- _noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
- __on_signal_send_watchdog_start);
-
- return 0;
-}
-
-void _anr_monitor_fini(void)
-{
- _D("[__ANR_MONITOR__] fini");
-
- _app_property_metadata_remove_filter(METADATA_ANR_CHECK_BYPASS, NULL);
-
- if (__proc_tbl) {
- g_hash_table_destroy(__proc_tbl);
- __proc_tbl = NULL;
- }
-}
+++ /dev/null
-/*
- * 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_app_com.h>
-#include <aul_cmd.h>
-#include <bundle.h>
-#include <bundle_cpp.h>
-#include <bundle_internal.h>
-
-#include "amd_app_com.h"
-#include "amd_cynara.h"
-#include "amd_request.h"
-
-#include "core/app_com/app_com_broker.hh"
-#include "core/common/key_private.hh"
-#include "core/common/log_private.hh"
-
-using namespace amd;
-
-const char* _app_com_get_privilege(const char* endpoint) {
- auto& inst = AppComBroker::GetInst();
- if (!inst.Exist(endpoint))
- return nullptr;
-
- return inst.GetPrivilege(endpoint).c_str();
-}
-
-int _app_com_send(const char* endpoint, int cpid, bundle* envelope, uid_t uid) {
- auto& inst = AppComBroker::GetInst();
- if (!inst.Exist(endpoint)) {
- _E("Endpoint(%s) does not exist", endpoint);
- return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
- }
-
- _D("endpoint=%s cpid=%d", endpoint, cpid);
- std::string endpoint_str(endpoint);
- bundle_del(envelope, AUL_K_COM_ENDPOINT);
- bundle_add_str(envelope, AUL_K_COM_ENDPOINT, endpoint_str.c_str());
- int result = AUL_APP_COM_R_OK;
- bundle_add_byte(envelope, AUL_K_COM_RESULT, &result, sizeof(result));
-
- std::shared_ptr<tizen_base::Bundle> envelope_ptr(
- new (std::nothrow) tizen_base::Bundle(envelope));
- if (envelope_ptr.get() == nullptr) {
- _E("Out of memory");
- return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
- }
-
- return inst.Send(endpoint_str, envelope_ptr, cpid, uid);
-}
-
-int _app_com_client_remove(int cpid) {
- AppComBroker::GetInst().Remove(cpid);
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-bool _app_com_endpoint_exists(const char* endpoint) {
- return AppComBroker::GetInst().Exist(endpoint);
-}
-
-static int __dispatch_app_com_create(request_h req) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
- if (endpoint == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- const char* privilege = bundle_get_val(kb, AUL_K_COM_PRIVILEGE);
- if (privilege == nullptr) {
- _D("Non-privileged endpoint: %s", endpoint);
- privilege = "";
- }
-
- unsigned int propagate;
- unsigned int* prop;
- size_t propagate_size;
- int ret = bundle_get_byte(kb, AUL_K_COM_PROPAGATE, (void **)&prop,
- &propagate_size);
- if (ret == BUNDLE_ERROR_NONE)
- propagate = *prop;
- else
- propagate = 0;
-
- _D("endpoint=%s propagate=%x privilege=%s",
- endpoint, propagate, privilege);
-
- ret = AppComBroker::GetInst().Create(endpoint, propagate, privilege);
- if (ret == AUL_APP_COM_R_ERROR_OK ||
- ret == AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS) {
- int pid = _request_get_pid(req);
- uid_t uid = _request_get_uid(req);
- ret = AppComBroker::GetInst().Join(endpoint, "", getpgid(pid), uid);
- if (ret == AUL_APP_COM_R_ERROR_ILLEGAL_ACCESS) {
- _E("Illegal access: remove endpoint");
- AppComBroker::GetInst().Destroy(endpoint);
- }
- }
- _request_send_result(req, ret);
- return ret;
-}
-
-static int __dispatch_app_com_join(request_h req) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
- if (endpoint == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- const char* filter = bundle_get_val(kb, AUL_K_COM_FILTER);
- int pid = _request_get_pid(req);
- uid_t uid = _request_get_uid(req);
- int ret = AppComBroker::GetInst().Join(endpoint, filter ? filter : "",
- getpgid(pid), uid);
- _request_send_result(req, ret);
- return ret;
-}
-
-static int __dispatch_app_com_send(request_h req) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- int sender_pid = _request_get_pid(req);
- bundle_del(kb, AUL_K_COM_SENDER_PID);
- bundle_add(kb, AUL_K_COM_SENDER_PID, std::to_string(sender_pid).c_str());
-
- const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
- if (endpoint == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- uid_t sender_uid = _request_get_uid(req);
- int ret = _app_com_send(endpoint, getpgid(sender_pid), kb, sender_uid);
- _request_send_result(req, ret);
- return ret;
-}
-
-static int __dispatch_app_com_leave(request_h req) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
- if (endpoint == nullptr) {
- _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
- return -EINVAL;
- }
-
- int pid = _request_get_pid(req);
- int ret = AppComBroker::GetInst().Leave(endpoint, getpgid(pid));
- _request_send_result(req, ret);
- return ret;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_COM_CREATE,
- .callback = __dispatch_app_com_create
- },
- {
- .cmd = APP_COM_JOIN,
- .callback = __dispatch_app_com_join
- },
- {
- .cmd = APP_COM_SEND,
- .callback = __dispatch_app_com_send
- },
- {
- .cmd = APP_COM_LEAVE,
- .callback = __dispatch_app_com_leave
- },
-};
-
-static int __com_create_checker(caller_info_h info, request_h req, void* data) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- char* privilege = nullptr;
- bundle_get_str(kb, AUL_K_COM_PRIVILEGE, &privilege);
- if (privilege == nullptr)
- return 0;
-
- return _cynara_simple_checker(info, req, reinterpret_cast<void*>(privilege));
-}
-
-static int __com_join_checker(caller_info_h info, request_h req, void* data) {
- bundle* kb = _request_get_bundle(req);
- if (kb == nullptr) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- char* endpoint = nullptr;
- bundle_get_str(kb, AUL_K_COM_ENDPOINT, &endpoint);
- if (endpoint == nullptr)
- return -EINVAL;
-
- const char* privilege = _app_com_get_privilege(endpoint);
- if (privilege == nullptr)
- return 0;
-
- return _cynara_simple_checker(info, req,
- static_cast<void*>(const_cast<char*>(privilege)));
-}
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_COM_JOIN,
- .checker = __com_join_checker,
- .data = NULL
- },
- {
- .cmd = APP_COM_CREATE,
- .checker = __com_create_checker,
- .data = NULL
- },
-};
-
-int _app_com_broker_init(void) {
- _W("APP_COM_BROKER_INIT");
- AppComBroker::GetInst();
- int ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- ret = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-int _app_com_broker_fini(void) {
- _W("APP_COM_BROKER_FINI");
- AppComBroker::GetInst().Dispose();
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <glib.h>
-#include <string.h>
-#include <ctype.h>
-#include <gio/gio.h>
-#include <aul_svc.h>
-#include <pkgmgr-info.h>
-#include <aul_sock.h>
-#include <aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-
-#include "amd_util.h"
-#include "amd_app_property.h"
-#include "amd_request.h"
-#include "amd_appinfo.h"
-#include "amd_cynara.h"
-
-struct metadata_filter {
- char *key;
- char *value; /* Could be NULL */
-};
-
-struct metadata_entity {
- char *appid;
- char *key;
- char *value;
-};
-
-struct app_property_s {
- uid_t uid;
- GHashTable *alias_info_table;
- GHashTable *allowed_info_table;
- GHashTable *appid_cache_table;
- GList *metadata_list;
-};
-
-static GHashTable *user_prop_table;
-static GList *metadata_filters;
-
-static int __foreach_allowed_info(const char *appid, const char *allowed_appid,
- void *data);
-static int __foreach_metadata_info(const pkgmgrinfo_appinfo_h handle,
- void *data);
-static void __free_metadata_entity(gpointer data);
-
-static int __add_alias_info(const char *alias_appid,
- const char *appid, void *user_data)
-{
- GHashTable *alias_info_table = (GHashTable *)user_data;
- char *key;
- char *value;
- char *id;
-
- if (alias_appid == NULL || appid == NULL || alias_info_table == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- key = strdup(alias_appid);
- if (key == NULL) {
- _E("out of memory");
- return -1;
- }
-
- value = strdup(appid);
- if (value == NULL) {
- _E("out of memory");
- free(key);
- return -1;
- }
-
- id = g_hash_table_lookup(alias_info_table, key);
- if (id) {
- _D("Replace alias info - alias_appid(%s), appid(%s)",
- key, value);
- g_hash_table_replace(alias_info_table, key, value);
- } else {
- g_hash_table_insert(alias_info_table, key, value);
- }
-
- return 0;
-}
-
-int _app_property_add_alias_info(app_property_h app_property,
- const char *alias_appid, const char *appid)
-{
- int ret;
-
- if (app_property == NULL || appid == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- if (alias_appid && appid) {
- ret = __add_alias_info(alias_appid, appid,
- app_property->alias_info_table);
- if (ret < 0) {
- _W("Failed to add alias info");
- return -1;
- }
- } else if (appid) {
- ret = aul_svc_foreach_alias_info_by_appid_for_uid(
- __add_alias_info, appid,
- app_property->uid,
- app_property->alias_info_table);
- if (ret < 0) {
- _W("Failed to retrive alias info - appid(%s)", appid);
- return -1;
- }
- }
-
- return 0;
-}
-
-static gboolean __remove_alias_info(gpointer key, gpointer value,
- gpointer user_data)
-{
- if (value == NULL || user_data == NULL) {
- _W("Invalid parameter");
- return FALSE;
- }
-
- if (strcmp(value, user_data) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-int _app_property_remove_alias_info(app_property_h app_property,
- const char *alias_appid, const char *appid)
-{
- const char *id;
-
- if (app_property == NULL || (alias_appid == NULL && appid == NULL)) {
- _W("Invalid parameter");
- return -1;
- }
-
- if (alias_appid) {
- id = g_hash_table_lookup(app_property->alias_info_table,
- alias_appid);
- if (id) {
- g_hash_table_remove(app_property->alias_info_table,
- alias_appid);
- }
- } else {
- g_hash_table_foreach_remove(app_property->alias_info_table,
- __remove_alias_info, (gpointer)appid);
- }
-
- return 0;
-}
-
-const char *_app_property_get_real_appid(app_property_h app_property,
- const char *alias_appid)
-{
- if (app_property == NULL || alias_appid == NULL) {
- _W("Invalid parameter");
- return NULL;
- }
-
- return g_hash_table_lookup(app_property->alias_info_table, alias_appid);
-}
-
-GList *_app_property_get_allowed_app_list(app_property_h app_property,
- const char *appid)
-{
- if (app_property == NULL || appid == NULL) {
- _W("Invalid parameter");
- return NULL;
- }
-
- return g_hash_table_lookup(app_property->allowed_info_table, appid);
-}
-
-app_property_h _app_property_find(uid_t uid)
-{
- if (user_prop_table == NULL)
- return NULL;
-
- return g_hash_table_lookup(user_prop_table, GUINT_TO_POINTER(uid));
-}
-
-int _app_property_insert(uid_t uid, const char *appid,
- const pkgmgrinfo_appinfo_h handle)
-{
- int ret;
- app_property_h app_property;
-
- if (appid == NULL || handle == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL)
- return -1;
-
- g_hash_table_remove_all(app_property->appid_cache_table);
-
- ret = aul_svc_foreach_alias_info_by_appid_for_uid(__add_alias_info,
- appid, app_property->uid,
- app_property->alias_info_table);
- if (ret < 0) {
- _E("Failed to retrieve alias info - %s:%u:%d",
- appid, uid, ret);
- return -1;
- }
-
- ret = aul_svc_foreach_allowed_info_by_appid_for_uid(
- __foreach_allowed_info, appid,
- app_property->uid, app_property->allowed_info_table);
- if (ret < 0) {
- _E("Failed to retrieve allowed info - %s:%u:%d",
- appid, uid, ret);
- return -1;
- }
-
- ret = __foreach_metadata_info(handle, app_property);
- if (ret < 0) {
- _E("Failed to retrieve metadata info - %s:%u:%d",
- appid, uid, ret);
- return -1;
- }
-
- _D("uid(%d), appid(%s)", uid, appid);
-
- return 0;
-}
-
-int _app_property_delete(uid_t uid, const char *appid)
-{
- app_property_h app_property;
- struct metadata_entity *entity;
- GList *iter;
-
- if (appid == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL)
- return -1;
-
- iter = app_property->metadata_list;
- while (iter) {
- entity = (struct metadata_entity *)iter->data;
- iter = g_list_next(iter);
- if (strcmp(entity->appid, appid) == 0) {
- app_property->metadata_list = g_list_remove(
- app_property->metadata_list,
- entity);
- __free_metadata_entity(entity);
- }
- }
-
- g_hash_table_remove_all(app_property->appid_cache_table);
-
- g_hash_table_foreach_remove(app_property->alias_info_table,
- __remove_alias_info, (gpointer)appid);
-
- g_hash_table_remove(app_property->allowed_info_table, appid);
- _D("uid(%d), appid(%s)", uid, appid);
-
- return 0;
-}
-
-static void __foreach_alias_info(const char *alias_appid, const char *appid,
- void *data)
-{
- GHashTable *alias_info_table = (GHashTable *)data;
- char *key;
- char *value;
-
- if (alias_appid == NULL || appid == NULL || alias_info_table == NULL) {
- _W("Invalid parameter");
- return;
- }
-
- key = strdup(alias_appid);
- if (key == NULL) {
- _E("out of memory");
- return;
- }
-
- value = strdup(appid);
- if (value == NULL) {
- _E("out of memory");
- free(key);
- return;
- }
-
- g_hash_table_insert(alias_info_table, key, value);
-}
-
-static int __foreach_allowed_info(const char *appid, const char *allowed_appid,
- void *data)
-{
- GHashTable *allowed_info_table = (GHashTable *)data;
- char *key;
- char *value;
- GList *list;
-
- if (appid == NULL || allowed_appid == NULL ||
- allowed_info_table == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- value = strdup(allowed_appid);
- if (value == NULL) {
- _E("out of memory");
- return -1;
- }
-
- list = g_hash_table_lookup(allowed_info_table, appid);
- if (list) {
- list = g_list_append(list, value);
- } else {
- key = strdup(appid);
- if (key == NULL) {
- _E("out of memory");
- free(value);
- return -1;
- }
-
- list = g_list_append(list, value);
- g_hash_table_insert(allowed_info_table, key, list);
- }
-
- return 0;
-}
-
-static void __destroy_allowed_info_list(gpointer data)
-{
- GList *list = (GList *)data;
-
- if (list == NULL)
- return;
-
- g_list_free_full(list, free);
-}
-
-static struct app_property_s *__create_app_property(uid_t uid)
-{
- struct app_property_s *prop;
-
- prop = calloc(1, sizeof(struct app_property_s));
- if (prop == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- prop->uid = uid;
- prop->alias_info_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free);
- if (prop->alias_info_table == NULL) {
- _E("Failed to create alias info table");
- free(prop);
- return NULL;
- }
-
- prop->allowed_info_table = g_hash_table_new_full(g_str_hash,
- g_str_equal, free, __destroy_allowed_info_list);
- if (prop->allowed_info_table == NULL) {
- _E("Failed to create allowed info table");
- g_hash_table_destroy(prop->alias_info_table);
- free(prop);
- return NULL;
- }
-
- prop->appid_cache_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free);
- if (prop->appid_cache_table == NULL) {
- _E("Failed to create appid cache table");
- g_hash_table_destroy(prop->allowed_info_table);
- g_hash_table_destroy(prop->alias_info_table);
- free(prop);
- return NULL;
- }
-
- prop->metadata_list = NULL;
-
- return prop;
-}
-
-static void __free_metadata_entity(gpointer data)
-{
- struct metadata_entity *entity = data;
-
- if (!entity)
- return;
-
- if (entity->appid)
- free(entity->appid);
- if (entity->key)
- free(entity->key);
- if (entity->value)
- free(entity->value);
- free(entity);
-}
-
-static void __destroy_app_property(gpointer data)
-{
- struct app_property_s *prop = (struct app_property_s *)data;
-
- if (prop == NULL)
- return;
-
- if (prop->allowed_info_table)
- g_hash_table_destroy(prop->allowed_info_table);
- if (prop->alias_info_table)
- g_hash_table_destroy(prop->alias_info_table);
- if (prop->appid_cache_table)
- g_hash_table_destroy(prop->appid_cache_table);
- if (prop->metadata_list)
- g_list_free_full(prop->metadata_list, __free_metadata_entity);
-
- free(prop);
-}
-
-static gint __comp_metadata_list(gconstpointer a, gconstpointer b)
-{
- const struct metadata_entity *entity1 = a;
- const struct metadata_entity *entity2 = b;
-
- if (!a || !b)
- return -1;
-
- if (!strcmp(entity1->appid, entity2->appid) &&
- !strcmp(entity1->key, entity2->key) &&
- !strcmp(entity1->value, entity2->value))
- return 0;
-
- return -1;
-}
-
-static void __add_metadata_info(const char *appid, const char *key,
- const char *val, struct app_property_s *prop)
-{
- struct metadata_entity *entity;
- GList *found;
-
- if (appid == NULL || key == NULL || val == NULL) {
- _W("Invalid parameter");
- return;
- }
-
- entity = calloc(1, sizeof(struct metadata_entity));
- if (entity == NULL) {
- _E("out of memory");
- return;
- }
-
- entity->appid = strdup(appid);
- if (!entity->appid) {
- _E("out of memory");
- __free_metadata_entity(entity);
- return;
- }
-
- entity->key = strdup(key);
- if (!entity->key) {
- _E("out of memory");
- __free_metadata_entity(entity);
- return;
- }
-
- entity->value = strdup(val);
- if (!entity->value) {
- _E("out of memory");
- __free_metadata_entity(entity);
- return;
- }
-
- found = g_list_find_custom(prop->metadata_list, entity,
- __comp_metadata_list);
- if (found) {
- __free_metadata_entity(entity);
- return;
- }
-
- prop->metadata_list = g_list_append(prop->metadata_list, entity);
-}
-
-static int __foreach_metadata_info(const pkgmgrinfo_appinfo_h handle,
- void *user_data)
-{
- struct app_property_s *prop = user_data;
- char *appid = NULL;
- char *val;
- int ret;
- GList *iter;
- struct metadata_filter *filter;
-
- ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
- if (ret < 0 || !appid)
- return -1;
-
- for (iter = metadata_filters; iter; iter = g_list_next(iter)) {
- filter = (struct metadata_filter *)iter->data;
- val = NULL;
- ret = pkgmgrinfo_appinfo_get_metadata_value(handle,
- filter->key, &val);
- if (ret == PMINFO_R_OK)
- __add_metadata_info(appid, filter->key, val, prop);
- }
-
- return 0;
-}
-
-static int __load_metadata(struct app_property_s *prop)
-{
- pkgmgrinfo_appinfo_metadata_filter_h handle;
- int ret;
- GList *iter;
- struct metadata_filter *filter;
-
- ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
- if (ret != PMINFO_R_OK)
- return -1;
-
- for (iter = metadata_filters; iter; iter = g_list_next(iter)) {
- filter = (struct metadata_filter *)iter->data;
- ret = pkgmgrinfo_appinfo_metadata_filter_add(handle,
- filter->key, filter->value);
- if (ret != PMINFO_R_OK) {
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
- }
- }
-
- ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle,
- __foreach_metadata_info, prop, prop->uid);
- if (ret != PMINFO_R_OK) {
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle,
- __foreach_metadata_info, prop, GLOBAL_USER);
- if (ret != PMINFO_R_OK) {
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
- }
-
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-
- return 0;
-}
-
-static int __load_app_property(struct app_property_s *prop)
-{
- int ret;
-
- if (prop == NULL) {
- _W("Invalid parameter");
- return -1;
- }
-
- ret = aul_svc_foreach_alias_info_for_uid(__foreach_alias_info,
- prop->uid, prop->alias_info_table);
- if (ret < 0) {
- _E("Failed to retrieve alias info uid(%d) - ret(%d)",
- prop->uid, ret);
- return -1;
- }
-
- ret = aul_svc_foreach_allowed_info_for_uid(__foreach_allowed_info,
- prop->uid, prop->allowed_info_table);
- if (ret < 0) {
- _E("Failed to retrieve allowed info uid(%d) - ret(%d)",
- prop->uid, ret);
- return -1;
- }
-
- ret = __load_metadata(prop);
- if (ret < 0) {
- _E("Failed to retrieve metadata info uid(%d) - ret(%d)",
- prop->uid, ret);
- return -1;
- }
-
- return 0;
-}
-
-int _app_property_load(uid_t uid)
-{
- int ret;
- struct app_property_s *prop;
-
- prop = __create_app_property(uid);
- if (prop == NULL)
- return -1;
-
- ret = __load_app_property(prop);
- if (ret < 0) {
- _E("Failed to load properties - ret(%d)", ret);
- __destroy_app_property(prop);
- return -1;
- }
-
- g_hash_table_insert(user_prop_table, GUINT_TO_POINTER(uid), prop);
-
- return 0;
-}
-
-void _app_property_unload(uid_t uid)
-{
- g_hash_table_remove(user_prop_table, GUINT_TO_POINTER(uid));
-}
-
-static void __app_property_cache_put(app_property_h app_property,
- const char *checksum, const char *appid)
-{
- if (!app_property || !checksum || !appid)
- return;
-
- g_hash_table_replace(app_property->appid_cache_table, strdup(checksum),
- strdup(appid));
-}
-
-static const char *__app_property_cache_get(app_property_h app_property,
- const char *checksum)
-{
- if (!app_property || !checksum)
- return NULL;
-
- return g_hash_table_lookup(app_property->appid_cache_table, checksum);
-}
-
-void _app_property_cache_invalidate(app_property_h app_property)
-{
- if (!app_property)
- return;
-
- g_hash_table_remove_all(app_property->appid_cache_table);
-}
-
-bool _app_property_metadata_query_bool(app_property_h app_property,
- const char *appid, const char *key)
-{
- return _app_property_metadata_match(app_property, appid, key, "true");
-}
-
-int _app_property_metadata_foreach(app_property_h app_property,
- const char *appid, const char *key,
- int (*callback)(const char *value, void *data),
- void *user_data)
-{
- struct metadata_entity *ret;
- GList *i;
-
- if (!app_property || !appid || !key)
- return -1;
-
- i = app_property->metadata_list;
- while (i) {
- ret = i->data;
-
- if (!strcmp(ret->appid, appid) &&
- !strcmp(ret->key, key)) {
- if (callback(ret->value, user_data) < 0)
- break;
- }
-
- i = g_list_next(i);
- }
-
- return 0;
-}
-
-bool _app_property_metadata_match(app_property_h app_property,
- const char *appid, const char *key, const char *value)
-{
- struct metadata_entity entity;
- GList *i;
-
- if (!app_property || !appid || !key || !value)
- return false;
-
- entity.appid = (char *)appid;
- entity.key = (char *)key;
- entity.value = (char *)value;
- i = g_list_find_custom(app_property->metadata_list,
- &entity, __comp_metadata_list);
- if (!i)
- return false;
-
- return true;
-}
-
-static gint __comp_key(gconstpointer a, gconstpointer b)
-{
- const struct metadata_entity *entity1 = a;
- const struct metadata_entity *entity2 = b;
-
- if (!a || !b)
- return -1;
-
- if (!strcmp(entity1->appid, entity2->appid) &&
- !strcmp(entity1->key, entity2->key)) {
- if (entity1->value && !strcmp(entity1->value, "false"))
- return -1;
-
- return 0;
- }
-
- return -1;
-}
-
-bool _app_property_metadata_query_activation(app_property_h app_property,
- const char *appid, const char *key)
-{
- struct metadata_entity entity;
- GList *i;
-
- if (!app_property || !appid || !key)
- return false;
-
- entity.appid = (char *)appid;
- entity.key = (char *)key;
- entity.value = NULL;
-
- i = g_list_find_custom(app_property->metadata_list,
- &entity, __comp_key);
- if (!i)
- return false;
-
- return true;
-}
-
-static struct metadata_filter *__create_metadata_filter(const char *key,
- const char *value)
-{
- struct metadata_filter *filter;
-
- filter = calloc(1, sizeof(struct metadata_filter));
- if (!filter) {
- _E("Out of memory");
- return NULL;
- }
-
- filter->key = strdup(key);
- if (!filter->key) {
- _E("Failed to duplicate key");
- free(filter);
- return NULL;
- }
-
- if (value) {
- filter->value = strdup(value);
- if (!filter->value) {
- _E("Failed to duplicate value");
- free(filter->key);
- free(filter);
- return NULL;
- }
- }
-
- return filter;
-}
-
-static void __destroy_metadata_filter(gpointer data)
-{
- struct metadata_filter *filter = (struct metadata_filter *)data;
-
- if (!filter)
- return;
-
- if (filter->value)
- free(filter->value);
- if (filter->key)
- free(filter->key);
- free(filter);
-}
-
-static struct metadata_filter *__find_metadata_filter(const char *key,
- const char *value)
-{
- struct metadata_filter *filter;
- GList *iter;
-
- iter = metadata_filters;
- while (iter) {
- filter = (struct metadata_filter *)iter->data;
- if (!strcmp(filter->key, key)) {
- if (value && filter->value &&
- !strcmp(filter->value, value))
- return filter;
- else if (!value && !filter->value)
- return filter;
- }
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-int _app_property_metadata_add_filter(const char *key, const char *value)
-{
- struct metadata_filter *filter;
-
- if (!key) {
- _E("Invalid parameter");
- return -1;
- }
-
- filter = __find_metadata_filter(key, value);
- if (filter) {
- _W("Already exists");
- return -1;
- }
-
- filter = __create_metadata_filter(key, value);
- if (!filter)
- return -1;
-
- metadata_filters = g_list_append(metadata_filters, filter);
-
- return 0;
-}
-
-int _app_property_metadata_remove_filter(const char *key, const char *value)
-{
- struct metadata_filter *filter;
-
- if (!key) {
- _E("Invalid parameter");
- return -1;
- }
-
- filter = __find_metadata_filter(key, value);
- if (!filter) {
- _E("Failed to find metadata filter(%s:%s)", key, value);
- return -1;
- }
-
- metadata_filters = g_list_remove(metadata_filters, filter);
- __destroy_metadata_filter(filter);
-
- return 0;
-}
-
-static int __dispatch_app_set_alias_appid(request_h req)
-{
- int ret;
- const char *appid;
- const char *alias_appid;
- const struct appinfo *ai;
- bundle *kb;
- uid_t uid = _request_get_target_uid(req);
- app_property_h app_property;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- alias_appid = bundle_get_val(kb, AUL_K_ALIAS_APPID);
- if (alias_appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ai = _appinfo_find(uid, appid);
- if (ai == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_svc_set_alias_appid_for_uid(alias_appid, appid, uid);
- if (ret < 0) {
- _E("Failed to set alias appid - alias_appid(%s), appid(%s)",
- alias_appid, appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL) {
- _E("Failed to find app property - uid(%d)", uid);
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _app_property_add_alias_info(app_property, alias_appid, appid);
- if (ret < 0) {
- _E("Failed to add alias info - %s:%s", alias_appid, appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- _request_send_result(req, 0);
-
- return 0;
-}
-
-static int __dispatch_app_unset_alias_appid(request_h req)
-{
- int ret;
- const char *alias_appid;
- bundle *kb;
- uid_t uid = _request_get_target_uid(req);
- app_property_h app_property;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- alias_appid = bundle_get_val(kb, AUL_K_ALIAS_APPID);
- if (alias_appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_svc_unset_alias_appid_for_uid(alias_appid, uid);
- if (ret < 0) {
- _E("Failed to unset alias appid - alias_appid(%s)",
- alias_appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL) {
- _E("Failed to find app property - uid(%d)", uid);
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _app_property_remove_alias_info(app_property, alias_appid, NULL);
- if (ret < 0) {
- _E("Failed to remove alias info - %s", alias_appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- _request_send_result(req, 0);
-
- return 0;
-}
-
-static int __dispatch_app_enable_alias_info(request_h req)
-{
- int ret;
- const char *appid;
- bundle *kb;
- uid_t uid = _request_get_target_uid(req);
- app_property_h app_property;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_svc_enable_alias_info_for_uid(appid, uid);
- if (ret < 0) {
- _E("Failed to activate alias info - appid(%s)", appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL) {
- _E("Failed to find app property - uid(%d)", uid);
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _app_property_add_alias_info(app_property, NULL, appid);
- if (ret < 0) {
- _E("Failed to add alias info - %s", appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- _request_send_result(req, 0);
-
- return 0;
-}
-
-static int __dispatch_app_disable_alias_info(request_h req)
-{
- int ret;
- const char *appid;
- bundle *kb;
- uid_t uid = _request_get_target_uid(req);
- app_property_h app_property;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_svc_disable_alias_info_for_uid(appid, uid);
- if (ret < 0) {
- _E("Failed to deactivate alias info - appid(%s)", appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- app_property = _app_property_find(uid);
- if (app_property == NULL) {
- _E("Failed to find app property - uid(%d)", uid);
- _request_send_result(req, -1);
- }
-
- ret = _app_property_remove_alias_info(app_property, NULL, appid);
- if (ret < 0) {
- _E("Failed to remove alias info - appid(%s)", appid);
- _request_send_result(req, ret);
- return -1;
- }
-
- _request_send_result(req, 0);
-
- return 0;
-}
-
-static int __dispatch_app_set_app_control_default_app(request_h req)
-{
- bundle *kb = NULL;
- const char *op;
- const char *mime_type;
- const char *uri;
- const char *appid;
- int ret;
- app_property_h prop;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- op = aul_svc_get_operation(kb);
- appid = aul_svc_get_appid(kb);
- if (op == NULL || appid == NULL) {
- _E("Invalid operation, appid");
- _request_send_result(req, -1);
- return -1;
- }
-
- mime_type = aul_svc_get_mime(kb);
- uri = aul_svc_get_uri(kb);
-
- ret = aul_svc_set_defapp_for_uid(op, mime_type, uri,
- appid, _request_get_target_uid(req));
- if (ret < 0) {
- _E("Error[%d], aul_svc_set_defapp", ret);
- _request_send_result(req, -1);
- return -1;
- }
-
- prop = _app_property_find(_request_get_target_uid(req));
- _app_property_cache_invalidate(prop);
- _request_send_result(req, 0);
- return 0;
-}
-
-static int __dispatch_app_unset_app_control_default_app(request_h req)
-{
- char appid[MAX_PACKAGE_STR_SIZE];
- int ret;
- app_property_h prop;
-
- snprintf(appid, MAX_PACKAGE_STR_SIZE - 1, "%s",
- (const char *)_request_get_raw(req));
-
- ret = aul_svc_unset_defapp_for_uid(appid, _request_get_target_uid(req));
- if (ret < 0) {
- _E("Error[%d], aul_svc_unset_defapp", ret);
- _request_send_result(req, -1);
- return -1;
- }
-
- prop = _app_property_find(_request_get_target_uid(req));
- _app_property_cache_invalidate(prop);
- _request_send_result(req, 0);
- return 0;
-}
-
-static int __dispatch_app_get_appid_from_cache(request_h req)
-{
- const char *checksum;
- const char *appid;
- bundle *b = _request_get_bundle(req);
- app_property_h prop = _app_property_find(_request_get_target_uid(req));
-
- checksum = bundle_get_val(b, AUL_K_CHECKSUM);
- appid = __app_property_cache_get(prop, checksum);
-
- if (!appid) {
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_APPID_FROM_CACHE, NULL, 0,
- AUL_SOCK_NOREPLY);
- return 0;
- }
-
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_APPID_FROM_CACHE, (unsigned char *)appid,
- strlen(appid), AUL_SOCK_NOREPLY);
-
- return 0;
-}
-
-static int __dispatch_app_set_cache(request_h req)
-{
- const char *appid;
- const char *checksum;
- bundle *b = _request_get_bundle(req);
- app_property_h prop = _app_property_find(_request_get_target_uid(req));
-
- appid = bundle_get_val(b, AUL_K_APPID);
- checksum = bundle_get_val(b, AUL_K_CHECKSUM);
-
- if (!appid || !checksum) {
- _request_send_result(req, -1);
- return -1;
- }
-
- __app_property_cache_put(prop, checksum, appid);
- _request_send_result(req, 0);
- return 0;
-}
-
-static int __dispatch_app_invalidate_cache(request_h req)
-{
- app_property_h prop = _app_property_find(_request_get_target_uid(req));
-
- _app_property_cache_invalidate(prop);
- _request_send_result(req, 0);
- return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_SET_ALIAS_APPID,
- .callback = __dispatch_app_set_alias_appid
- },
- {
- .cmd = APP_UNSET_ALIAS_APPID,
- .callback = __dispatch_app_unset_alias_appid
- },
- {
- .cmd = APP_ENABLE_ALIAS_INFO,
- .callback = __dispatch_app_enable_alias_info
- },
- {
- .cmd = APP_DISABLE_ALIAS_INFO,
- .callback = __dispatch_app_disable_alias_info
- },
- {
- .cmd = APP_SET_APP_CONTROL_DEFAULT_APP,
- .callback = __dispatch_app_set_app_control_default_app
- },
- {
- .cmd = APP_UNSET_APP_CONTROL_DEFAULT_APP,
- .callback = __dispatch_app_unset_app_control_default_app
- },
- {
- .cmd = APP_GET_APPID_FROM_CACHE,
- .callback = __dispatch_app_get_appid_from_cache
- },
- {
- .cmd = APP_SET_CACHE,
- .callback = __dispatch_app_set_cache
- },
- {
- .cmd = APP_INVALIDATE_CACHE,
- .callback = __dispatch_app_invalidate_cache
- },
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_SET_APP_CONTROL_DEFAULT_APP,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
- {
- .cmd = APP_UNSET_APP_CONTROL_DEFAULT_APP,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
- {
- .cmd = APP_SET_ALIAS_APPID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
- {
- .cmd = APP_UNSET_ALIAS_APPID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
- {
- .cmd = APP_ENABLE_ALIAS_INFO,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
- {
- .cmd = APP_DISABLE_ALIAS_INFO,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_SYSTEM_SETTING
- },
-};
-
-int _app_property_init(void)
-{
- struct metadata_filter metadata_table[] = {
- { METADATA_LARGEMEMORY, NULL },
- { METADATA_OOMTERMINATION, NULL },
- { METADATA_VIPAPP, NULL },
- };
- int r;
- int i;
-
- _D("app property init");
-
- user_prop_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __destroy_app_property);
- if (user_prop_table == NULL) {
- _E("Failed to create user prop table");
- return -1;
- }
-
- for (i = 0; i < ARRAY_SIZE(metadata_table); i++) {
- r = _app_property_metadata_add_filter(metadata_table[i].key,
- metadata_table[i].value);
- if (r != 0)
- return -1;
- }
-
- r = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-void _app_property_fini(void)
-{
- _D("app property fini");
-
- if (metadata_filters)
- g_list_free_full(metadata_filters, __destroy_metadata_filter);
-
- if (user_prop_table)
- g_hash_table_destroy(user_prop_table);
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <uuid/uuid.h>
-#include <glib.h>
-#include <aul.h>
-#include <string.h>
-#include <linux/limits.h>
-#include <vconf.h>
-#include <time.h>
-#include <aul_sock.h>
-#include <aul_proc.h>
-#include <ctype.h>
-#include <gio/gio.h>
-#include <bundle_internal.h>
-
-#include "amd_api_noti.h"
-#include "amd_app_status.h"
-#include "amd_appinfo.h"
-#include "amd_request.h"
-#include "amd_launch.h"
-#include "amd_util.h"
-#include "amd_suspend.h"
-#include "amd_socket.h"
-#include "amd_app_com.h"
-#include "amd_signal.h"
-#include "amd_noti.h"
-#include "amd_inotify.h"
-#include "amd_proc.h"
-#include "amd_cynara.h"
-
-#define PATH_AUL_APPS "/run/aul/apps"
-
-struct pkg_status_s {
- char *pkgid;
- int status;
- GSList *ui_list;
- GSList *svc_list;
-};
-
-struct app_status_s {
- char *appid;
- char *app_path;
- char *pkgid;
- char *instance_id;
- int app_type;
- int pid;
- uid_t uid;
- int status;
- bool is_subapp;
- char *leader_id;
- int timestamp;
- int fg_count;
- bool managed;
- int org_caller_pid;
- int last_caller_pid;
- struct pkg_status_s *pkg_status;
- bool bg_launch;
- bool socket_exists;
- bool starting;
- GHashTable *extras;
- bool exiting;
- bool debug_mode;
- guint timer;
-};
-
-struct fault_app_s {
- int pid;
- int uid;
- char *appid;
- char *pkgid;
- int type;
-};
-
-struct vconf_context_s {
- bool initialized;
- guint timer;
-};
-
-static GSList *app_status_list;
-static GHashTable *pkg_status_table;
-static int limit_bg_uiapps;
-static char *home_appid;
-static GHashTable *__wd_table;
-static inotify_watch_info_h __wh;
-static struct vconf_context_s __vconf;
-
-static int __get_managed_uiapp_cnt(void)
-{
- GSList *iter;
- struct app_status_s *app_status;
- int cnt = 0;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->managed &&
- app_status->app_type == AT_UI_APP)
- cnt++;
- }
-
- return cnt;
-}
-
-static void __cleanup_bg_uiapps(int n)
-{
- GSList *iter;
- GSList *iter_next;
- struct app_status_s *app_status;
- int i = 0;
- int ret;
-
- GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
- if (i == n)
- break;
-
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->status != STATUS_VISIBLE) {
- ret = _terminate_app_local(app_status->uid,
- app_status->pid);
- if (ret < 0) {
- _E("Failed to terminate app(%d)",
- app_status->pid);
- continue;
- }
- i++;
- }
- }
-}
-
-static void __check_running_uiapp_list(void)
-{
- _noti_send(AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS, 0, 0, NULL, NULL);
-}
-
-int _app_status_term_bg_apps(GCompareFunc func)
-{
- int len;
- int n;
-
- len = __get_managed_uiapp_cnt();
- if (len <= 0)
- return -1;
-
- n = len - limit_bg_uiapps;
- if (n <= 0)
- return -1;
-
- app_status_list = g_slist_sort(app_status_list, func);
- __cleanup_bg_uiapps(n);
-
- return 0;
-}
-
-static void __vconf_cb(keynode_t *key, void *data)
-{
- const char *name;
-
- name = vconf_keynode_get_name(key);
- if (name && strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) == 0) {
- limit_bg_uiapps = vconf_keynode_get_int(key);
- if (limit_bg_uiapps > 0)
- __check_running_uiapp_list();
- }
-}
-
-static void __update_leader_app_status(const char *leader_id)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- if (!leader_id)
- return;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && !strcmp(app_status->instance_id, leader_id)) {
- app_status->timestamp = time(NULL) / 10;
- app_status->fg_count++;
- break;
- }
- }
-}
-
-static void __add_pkg_status(struct app_status_s *app_status)
-{
- struct pkg_status_s *pkg_status;
-
- if (app_status == NULL) {
- _E("Invalid parameter");
- return;
- }
-
- if (app_status->app_type != AT_SERVICE_APP &&
- app_status->app_type != AT_UI_APP)
- return;
-
- if (pkg_status_table == NULL) {
- pkg_status_table = g_hash_table_new(g_str_hash, g_str_equal);
- if (pkg_status_table == NULL) {
- _E("out of memory");
- return;
- }
- }
-
- pkg_status = g_hash_table_lookup(pkg_status_table, app_status->pkgid);
- if (pkg_status == NULL) {
- pkg_status = (struct pkg_status_s *)calloc(1,
- sizeof(struct pkg_status_s));
- if (pkg_status == NULL) {
- _E("out of memory");
- return;
- }
-
- pkg_status->pkgid = strdup(app_status->pkgid);
- if (pkg_status->pkgid == NULL) {
- _E("out of memory");
- free(pkg_status);
- return;
- }
-
- g_hash_table_insert(pkg_status_table, pkg_status->pkgid,
- pkg_status);
- }
-
- pkg_status->status = app_status->status;
- app_status->pkg_status = pkg_status;
-
- if (app_status->app_type == AT_SERVICE_APP) {
- pkg_status->svc_list = g_slist_append(pkg_status->svc_list,
- app_status);
- } else {
- pkg_status->ui_list = g_slist_append(pkg_status->ui_list,
- app_status);
- }
-}
-
-static int __get_ui_app_status_pkg_status(struct pkg_status_s *pkg_status)
-{
- struct app_status_s *app_status;
- GSList *iter;
-
- for (iter = pkg_status->ui_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status->status != STATUS_BG)
- return app_status->status;
- }
-
- return STATUS_BG;
-}
-
-static int __update_pkg_status(struct app_status_s *app_status)
-{
- struct pkg_status_s *pkg_status;
- int ret;
-
- if (app_status == NULL)
- return -1;
-
- if (pkg_status_table == NULL)
- return -1;
-
- pkg_status = (struct pkg_status_s *)g_hash_table_lookup(
- pkg_status_table, app_status->pkgid);
- if (pkg_status == NULL) {
- _E("pkgid(%s) is not on list", app_status->pkgid);
- return -1;
- }
-
- if (pkg_status->ui_list) {
- ret = __get_ui_app_status_pkg_status(pkg_status);
- if (ret > -1)
- pkg_status->status = ret;
- } else {
- pkg_status->status = STATUS_SERVICE;
- }
-
- return 0;
-}
-
-static void __remove_pkg_status(struct app_status_s *app_status)
-{
- struct pkg_status_s *pkg_status;
-
- if (app_status == NULL) {
- _E("Invalid parameter");
- return;
- }
-
- pkg_status = g_hash_table_lookup(pkg_status_table, app_status->pkgid);
- if (pkg_status == NULL)
- return;
-
- if (app_status->app_type == AT_SERVICE_APP) {
- pkg_status->svc_list = g_slist_remove(pkg_status->svc_list,
- app_status);
- _D("STATUS_SERVICE: appid(%s)", app_status->appid);
- } else {
- pkg_status->ui_list = g_slist_remove(pkg_status->ui_list,
- app_status);
- _D("~STATUS_SERVICE: appid(%s)", app_status->appid);
- }
-
- if (!pkg_status->svc_list && !pkg_status->ui_list) {
- g_hash_table_remove(pkg_status_table, pkg_status->pkgid);
- if (pkg_status->pkgid)
- free(pkg_status->pkgid);
- free(pkg_status);
- }
-}
-
-static void __destroy_app_status(struct app_status_s *app_status)
-{
- if (app_status == NULL)
- return;
-
- _noti_send(AMD_NOTI_MSG_APP_STATUS_DESTROY, 0, 0, app_status, NULL);
-
- if (app_status->leader_id)
- free(app_status->leader_id);
- if (app_status->instance_id)
- free(app_status->instance_id);
- if (app_status->pkgid)
- free(app_status->pkgid);
- if (app_status->app_path)
- free(app_status->app_path);
- if (app_status->appid)
- free(app_status->appid);
- if (app_status->extras)
- g_hash_table_destroy(app_status->extras);
- if (app_status->timer)
- g_source_remove(app_status->timer);
-
- free(app_status);
-}
-
-static int __get_app_type(const char *comp_type)
-{
- if (comp_type == NULL)
- return -1;
-
- if (strcmp(comp_type, APP_TYPE_SERVICE) == 0)
- return AT_SERVICE_APP;
- else if (strcmp(comp_type, APP_TYPE_UI) == 0)
- return AT_UI_APP;
- else if (strcmp(comp_type, APP_TYPE_WIDGET) == 0)
- return AT_WIDGET_APP;
- else if (strcmp(comp_type, APP_TYPE_WATCH) == 0)
- return AT_WATCH_APP;
- else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0)
- return AT_COMPONENT_BASED_APP;
-
- return -1;
-}
-
-static int __app_status_set_app_info(struct app_status_s *app_status,
- const struct appinfo *ai, int pid,
- bool is_subapp, uid_t uid, int caller_pid,
- bool bg_launch, const char *instance_id,
- bool debug_mode)
-{
- const char *appid;
- const char *app_path;
- const char *pkgid;
- const char *comp_type;
- const char *taskmanage;
- char buf[MAX_PACKAGE_STR_SIZE];
- char uuid[37];
- uuid_t u;
-
- appid = _appinfo_get_value(ai, AIT_NAME);
- if (appid == NULL)
- return -1;
-
- app_status->appid = strdup(appid);
- if (app_status->appid == NULL) {
- _E("out of memory");
- return -1;
- }
-
- app_path = _appinfo_get_value(ai, AIT_EXEC);
- if (app_path == NULL)
- return -1;
-
- app_status->app_path = strdup(app_path);
- if (app_status->app_path == NULL) {
- _E("out of memory");
- return -1;
- }
-
- pkgid = _appinfo_get_value(ai, AIT_PKGID);
- if (pkgid == NULL)
- return -1;
-
- app_status->pkgid = strdup(pkgid);
- if (app_status->pkgid == NULL) {
- _E("out of memory");
- return -1;
- }
-
- comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp_type == NULL)
- return -1;
-
- app_status->app_type = __get_app_type(comp_type);
- if (app_status->app_type == -1) {
- _E("Unknown component type: %s", comp_type);
- return -1;
- }
-
- if (app_status->app_type == AT_SERVICE_APP)
- app_status->status = STATUS_SERVICE;
- else
- app_status->status = STATUS_LAUNCHING;
-
- if (instance_id) {
- app_status->instance_id = strdup(instance_id);
- if (app_status->instance_id == NULL) {
- _E("out of memory");
- return -1;
- }
- } else {
- uuid_generate(u);
- uuid_unparse(u, uuid);
-
- snprintf(buf, sizeof(buf), "%s:%s", uuid, appid);
- app_status->instance_id = strdup(buf);
- if (app_status->instance_id == NULL) {
- _E("out of memory");
- return -1;
- }
- }
-
- app_status->pid = pid;
- app_status->uid = uid;
-
- if (app_status->app_type == AT_COMPONENT_BASED_APP)
- app_status->is_subapp = false;
- else
- app_status->is_subapp = is_subapp;
-
- app_status->timestamp = time(NULL) / 10;
- app_status->org_caller_pid = caller_pid;
- app_status->last_caller_pid = caller_pid;
-
- taskmanage = _appinfo_get_value(ai, AIT_TASKMANAGE);
- if (taskmanage && !strcmp(taskmanage, "true") && !app_status->is_subapp)
- app_status->managed = true;
-
- app_status->bg_launch = bg_launch;
- app_status->socket_exists = false;
- app_status->starting = false;
-
- app_status->extras = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, NULL);
-
- app_status->debug_mode = debug_mode;
- app_status->exiting = false;
-
- return 0;
-}
-
-int _app_status_set_extra(app_status_h app_status, const char *key, void *data)
-{
- char *name;
-
- if (!app_status || !app_status->extras)
- return -1;
-
- name = strdup(key);
- if (!name)
- return -1;
-
- _app_status_remove_extra(app_status, key);
- if (g_hash_table_insert(app_status->extras, name, data) == TRUE)
- return 0;
-
- return -1;
-}
-
-int _app_status_remove_extra(app_status_h app_status, const char *key)
-{
- if (!app_status || !app_status->extras)
- return -1;
-
- if (g_hash_table_remove(app_status->extras, key) == TRUE)
- return 0;
-
- return -1;
-}
-
-void *_app_status_get_extra(app_status_h app_status, const char *key)
-{
- if (!app_status || !app_status->extras)
- return NULL;
-
- return g_hash_table_lookup(app_status->extras, key);
-}
-
-int _app_status_add_app_info(const struct appinfo *ai, int pid,
- bool is_subapp, uid_t uid, int caller_pid,
- bool bg_launch, const char *instance_id,
- bool debug_mode)
-{
- GSList *iter;
- GSList *iter_next;
- struct app_status_s *app_status;
- int r;
-
- if (ai == NULL)
- return -1;
-
- GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->pid == pid) {
- if (app_status->uid == uid)
- return 0;
-
- app_status_list = g_slist_remove(app_status_list,
- app_status);
- __remove_pkg_status(app_status);
- __destroy_app_status(app_status);
- break;
- }
- }
-
- app_status = (struct app_status_s *)calloc(1,
- sizeof(struct app_status_s));
- if (app_status == NULL) {
- _E("out of memory");
- return -1;
- }
-
- r = __app_status_set_app_info(app_status, ai, pid, is_subapp, uid,
- caller_pid, bg_launch, instance_id, debug_mode);
- if (r < 0) {
- __destroy_app_status(app_status);
- return -1;
- }
-
- _noti_send(AMD_NOTI_MSG_APP_STATUS_ADD, 0, 0, app_status, NULL);
- app_status_list = g_slist_append(app_status_list, app_status);
- __add_pkg_status(app_status);
-
- return 0;
-}
-
-int _app_status_remove_all_app_info_with_uid(uid_t uid)
-{
- GSList *iter;
- GSList *iter_next;
- struct app_status_s *app_status;
-
- GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->uid == uid) {
- app_status_list = g_slist_remove(app_status_list,
- app_status);
- __destroy_app_status(app_status);
- }
- }
-
- return 0;
-}
-
-int _app_status_remove(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- app_status_list = g_slist_remove(app_status_list, app_status);
- __remove_pkg_status(app_status);
- __destroy_app_status(app_status);
-
- return 0;
-}
-
-static gboolean __terminate_timer_cb(gpointer data)
-{
- int pid = GPOINTER_TO_INT(data);
- app_status_h app_status;
- int r;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return G_SOURCE_REMOVE;
-
- _E("pid(%d)", pid);
- r = kill(pid, SIGKILL);
- if (r < 0)
- _W("Failed to send SIGKILL, pid(%d), errno(%d)", pid, errno);
-
- app_status->timer = 0;
-
- return G_SOURCE_REMOVE;
-}
-
-int _app_status_update_status(app_status_h app_status, int status, bool force,
- bool update_group_info)
-{
- if (app_status == NULL || status < 0)
- return -1;
-
- _D("pid: %d, status: %d", app_status->pid, status);
- _noti_send(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START,
- status, 0, app_status, NULL);
- if (app_status->status == STATUS_DYING) {
- _E("%s is STATUS_DYING", app_status->appid);
- return -1;
- }
-
- app_status->status = status;
- if (app_status->status == STATUS_VISIBLE) {
- app_status->timestamp = time(NULL) / 10;
- app_status->fg_count++;
- if (!app_status->managed)
- __update_leader_app_status(app_status->leader_id);
- if (app_status->fg_count == 1 && limit_bg_uiapps > 0)
- __check_running_uiapp_list();
- } else if (app_status->status == STATUS_DYING) {
- _suspend_remove_timer(app_status->pid);
- if (!app_status->debug_mode) {
- app_status->timer = g_timeout_add_seconds(5,
- __terminate_timer_cb,
- GINT_TO_POINTER(app_status->pid));
- }
- aul_send_app_terminate_request_signal(app_status->pid,
- NULL, NULL, NULL);
- }
-
- __update_pkg_status(app_status);
- _W("pid: %d, appid: %s, pkgid: %s, status: %s(%d)",
- app_status->pid, app_status->appid, app_status->pkgid,
- aul_app_status_convert_to_string(app_status->status),
- app_status->status);
- _noti_send(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
- force, update_group_info, app_status, NULL);
-
- return 0;
-}
-
-int _app_status_update_last_caller_pid(app_status_h app_status, int caller_pid)
-{
- if (app_status == NULL)
- return -1;
-
- app_status->last_caller_pid = caller_pid;
-
- return 0;
-}
-
-int _app_status_update_bg_launch(app_status_h app_status, bool bg_launch)
-{
- if (app_status == NULL)
- return -1;
-
- if (!app_status->bg_launch)
- return 0;
-
- app_status->bg_launch = bg_launch;
-
- return 0;
-}
-
-int _app_status_get_process_cnt(const char *appid)
-{
- GSList *iter;
- struct app_status_s *app_status;
- int cnt = 0;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->appid &&
- strcmp(app_status->appid, appid) == 0)
- cnt++;
- }
-
- return cnt;
-}
-
-bool _app_status_is_home_app(app_status_h app_status)
-{
- const char *appid = _app_status_get_appid(app_status);
-
- if (!appid)
- return false;
- if (!home_appid)
- return false;
-
- if (strcmp(home_appid, appid) == 0)
- return true;
-
- return false;
-}
-
-int _app_status_get_pid(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- return app_status->pid;
-}
-
-int _app_status_get_org_caller_pid(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- return app_status->org_caller_pid;
-}
-
-int _app_status_get_last_caller_pid(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- return app_status->last_caller_pid;
-}
-
-int _app_status_is_running(app_status_h app_status)
-{
- if (app_status == NULL ||
- (app_status->app_type == AT_UI_APP && app_status->is_subapp) ||
- app_status->status == STATUS_DYING)
- return -1;
-
- return app_status->pid;
-}
-
-int _app_status_get_status(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- return app_status->status;
-}
-
-uid_t _app_status_get_uid(app_status_h app_status)
-{
- if (app_status == NULL)
- return (uid_t)-1;
-
- return app_status->uid;
-}
-
-const char *_app_status_get_appid(app_status_h app_status)
-{
- if (app_status == NULL)
- return NULL;
-
- return app_status->appid;
-}
-
-const char *_app_status_get_pkgid(app_status_h app_status)
-{
- if (app_status == NULL)
- return NULL;
-
- return app_status->pkgid;
-}
-
-bool _app_status_get_bg_launch(app_status_h app_status)
-{
- if (app_status == NULL)
- return false;
-
- return app_status->bg_launch;
-}
-
-const char *_app_status_get_instance_id(app_status_h app_status)
-{
- if (app_status == NULL)
- return NULL;
-
- return app_status->instance_id;
-}
-
-int _app_status_get_app_type(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
- return app_status->app_type;
-}
-
-bool _app_status_socket_exists(app_status_h app_status)
-{
- if (app_status == NULL)
- return false;
-
- return app_status->socket_exists;
-}
-
-bool _app_status_is_starting(app_status_h app_status)
-{
- if (app_status == NULL)
- return false;
-
- return app_status->starting;
-}
-
-int _app_status_update_is_starting(app_status_h app_status, bool is_starting)
-{
- if (app_status == NULL)
- return -1;
-
- app_status->starting = is_starting;
-
- return 0;
-}
-
-bool _app_status_is_exiting(app_status_h app_status)
-{
- if (app_status == NULL)
- return false;
-
- return app_status->exiting;
-}
-
-int _app_status_update_is_exiting(app_status_h app_status, bool is_exiting)
-{
- if (app_status == NULL)
- return -1;
-
- app_status->exiting = is_exiting;
-
- return 0;
-}
-
-const char *_app_status_get_app_path(app_status_h app_status)
-{
- if (app_status == NULL)
- return NULL;
-
- return app_status->app_path;
-}
-
-app_status_h _app_status_find(int pid)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->pid == pid)
- return app_status;
- }
-
- return NULL;
-}
-
-static int __read_ppid_from_proc(const char *path, int *ppid)
-{
- FILE *fp;
- int ret;
- int result = -1;
- char *buf = NULL;
- int val;
-
- if (path == NULL)
- return -1;
-
- fp = fopen(path, "r");
- if (fp == NULL)
- return -1;
-
- ret = fscanf(fp, "%ms %d\n", &buf, &val);
- while (ret != EOF) {
- if (ret == 2) {
- if (buf && strcmp(buf, "PPid:") == 0) {
- *ppid = val;
- result = 0;
- _D("ppid : %d", *ppid);
- break;
- }
- }
-
- free(buf);
- buf = NULL;
- ret = fscanf(fp, "%ms %d\n", &buf, &val);
- }
-
- fclose(fp);
- free(buf);
-
- return result;
-}
-
-int __proc_get_ppid_by_pid(int pid)
-{
- char path[PATH_MAX] = { 0, };
- int ret = 0;
- int ppid;
-
- snprintf(path, sizeof(path), "/proc/%d/status", pid);
- ret = __read_ppid_from_proc(path, &ppid);
- if (ret < 0)
- return -1;
-
- return ppid;
-}
-
-app_status_h _app_status_find_v2(int pid)
-{
- int ppid;
- int pgid;
- struct app_status_s *app_status;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- pgid = getpgid(pid);
- if (pgid > 0)
- app_status = _app_status_find(pgid);
- }
-
- if (app_status == NULL) {
- ppid = __proc_get_ppid_by_pid(pid);
- app_status = _app_status_find(ppid);
- }
-
- return app_status;
-}
-
-app_status_h _app_status_find_by_appid(const char *appid, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->appid &&
- strcmp(app_status->appid, appid) == 0 &&
- app_status->uid == uid &&
- (app_status->is_subapp == false ||
- app_status->app_type == AT_WATCH_APP ||
- app_status->app_type == AT_WIDGET_APP))
- return app_status;
- }
-
- return NULL;
-}
-
-app_status_h _app_status_find_by_appid_v2(const char *appid, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->appid &&
- strcmp(app_status->appid, appid) == 0 &&
- app_status->uid == uid)
- return app_status;
- }
-
- return NULL;
-}
-
-app_status_h _app_status_find_with_org_caller(const char *appid, uid_t uid,
- int caller_pid)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->appid &&
- strcmp(app_status->appid, appid) == 0 &&
- app_status->uid == uid &&
- app_status->org_caller_pid == caller_pid)
- return app_status;
- }
-
- return NULL;
-}
-
-app_status_h _app_status_find_by_instance_id(const char *appid,
- const char *instance_id, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->instance_id &&
- app_status->uid == uid &&
- !strcmp(app_status->instance_id, instance_id) &&
- !strcmp(app_status->appid, appid))
- return app_status;
- }
-
- return NULL;
-}
-
-void _app_status_find_service_apps(app_status_h app_status, int status,
- void (*send_event_to_svc_core)(int, uid_t), bool suspend)
-{
- GSList *iter;
- GSList *svc_list = NULL;
- const struct appinfo *ai;
- struct app_status_s *svc_status;
- bool bg_allowed;
- bool excluded;
- uid_t uid;
-
- if (app_status == NULL) {
- _E("Invalid parameter");
- return;
- }
-
- uid = _app_status_get_uid(app_status);
- if (app_status->pkg_status && app_status->pkg_status->status == status)
- svc_list = app_status->pkg_status->svc_list;
-
- for (iter = svc_list; iter; iter = g_slist_next(iter)) {
- svc_status = (struct app_status_s *)iter->data;
- if (svc_status && svc_status->uid == uid) {
- ai = _appinfo_find(uid, svc_status->appid);
- bg_allowed = _suspend_is_allowed_background(ai);
- excluded = _suspend_is_excluded(svc_status->pid);
- if (!excluded && !bg_allowed) {
- send_event_to_svc_core(svc_status->pid, uid);
- if (svc_status->status != STATUS_DYING &&
- suspend)
- _suspend_add_timer(svc_status->pid);
- else
- _suspend_remove_timer(svc_status->pid);
- }
- }
- }
-}
-
-void _app_status_check_service_only(app_status_h app_status,
- void (*send_event_to_svc_core)(int, uid_t))
-{
- GSList *iter;
- GSList *ui_list = NULL;
- struct app_status_s *ui_status;
- int ui_cnt = 0;
- bool bg_allowed;
- bool excluded;
- const char *appid;
- const struct appinfo *ai;
- uid_t uid;
- int status;
-
- if (app_status == NULL) {
- _E("Invalid parameter");
- return;
- }
-
- uid = _app_status_get_uid(app_status);
- if (app_status->pkg_status && app_status->pkg_status->ui_list)
- ui_list = app_status->pkg_status->ui_list;
-
- for (iter = ui_list; iter; iter = g_slist_next(iter)) {
- ui_status = (struct app_status_s *)iter->data;
- if (_app_status_get_status(ui_status) != STATUS_DYING)
- ui_cnt++;
- }
-
- if (ui_cnt == 0) {
- appid = _app_status_get_appid(app_status);
- status = _app_status_get_status(app_status);
- ai = _appinfo_find(uid, appid);
- bg_allowed = _suspend_is_allowed_background(ai);
- excluded = _suspend_is_excluded(app_status->pid);
- if (!excluded && !bg_allowed && status != STATUS_DYING) {
- send_event_to_svc_core(app_status->pid, uid);
- _suspend_add_timer(app_status->pid);
- }
- }
-}
-
-static bundle *__create_appinfo_bundle(app_status_h app_status)
-{
- bundle *b;
- char tmp_str[MAX_PID_STR_BUFSZ];
-
- b = bundle_create();
- if (b == NULL)
- return NULL;
-
- snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->pid);
- bundle_add(b, AUL_K_PID, tmp_str);
- bundle_add(b, AUL_K_APPID, app_status->appid);
- bundle_add(b, AUL_K_EXEC, app_status->app_path);
- bundle_add(b, AUL_K_PKGID, app_status->pkgid);
- snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->status);
- bundle_add(b, AUL_K_STATUS, tmp_str);
- snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->is_subapp);
- bundle_add(b, AUL_K_IS_SUBAPP, tmp_str);
- if (app_status->instance_id)
- bundle_add(b, AUL_K_INSTANCE_ID, app_status->instance_id);
-
- return b;
-}
-
-static int __send_running_appinfo(app_status_h app_status, int fd)
-{
- int ret;
- bundle *b;
- bundle_raw *raw = NULL;
- int len = 0;
-
- b = __create_appinfo_bundle(app_status);
- if (b == NULL) {
- _E("out of memory");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- ret = bundle_encode(b, &raw, &len);
- bundle_free(b);
- if (ret != BUNDLE_ERROR_NONE) {
- _E("Failed to encode bundle");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR, NULL,
- 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- ret = aul_sock_send_raw_with_fd(fd, APP_GET_INFO_OK,
- (unsigned char *)raw, len,
- AUL_SOCK_ASYNC | AUL_SOCK_BUNDLE);
- if (ret < 0) {
- _E("Failed to send raw data: %s", raw);
- free(raw);
- return ret;
- }
- free(raw);
-
- return 0;
-}
-
-int _app_status_send_running_appinfo(int fd, int cmd, uid_t uid)
-{
- GSList *list = NULL;
- GSList *iter;
- struct app_status_s *app_status;
- int ret;
- int count;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status->uid != uid ||
- app_status->status == STATUS_DYING)
- continue;
- if (cmd != APP_ALL_RUNNING_INFO &&
- cmd != APP_RUNNING_INSTANCE_INFO &&
- (app_status->app_type == AT_UI_APP &&
- app_status->is_subapp))
- continue;
- if (cmd == APP_RUNNING_INSTANCE_INFO &&
- app_status->instance_id == NULL)
- continue;
-
- list = g_slist_append(list, app_status);
- }
-
- count = g_slist_length(list);
- if (count == 0) {
- _E("Applications are not running");
- _send_result_to_client(fd, -1);
- return -1;
- }
- _send_result_to_client_v2(fd, count);
-
- for (iter = list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status == NULL)
- continue;
-
- ret = __send_running_appinfo(app_status, fd);
- if (ret < 0) {
- g_slist_free(list);
- return -1;
- }
- }
- close(fd);
- g_slist_free(list);
-
- return 0;
-}
-
-int _app_status_foreach_running_appinfo(void (*callback)(app_status_h, void *),
- void *data)
-{
- GSList *iter;
- struct app_status_s *app_status;
-
- if (callback == NULL)
- return -1;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status->status == STATUS_DYING ||
- app_status->is_subapp)
- continue;
- callback(app_status, data);
- }
-
- return 0;
-}
-
-int _app_status_terminate_apps(const char *appid, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
- int ret;
-
- if (appid == NULL)
- return -1;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status->uid == uid &&
- strcmp(app_status->appid, appid) == 0 &&
- app_status->status != STATUS_DYING) {
- ret = _terminate_app_local(app_status->uid,
- app_status->pid);
- if (ret < 0) {
- _E("Failed to terminate app(%d)",
- app_status->pid);
- }
-
- _app_status_update_status(app_status, STATUS_DYING,
- false, true);
- }
- }
-
- return 0;
-}
-
-static void __delete_socket_path(pid_t pid, uid_t uid)
-{
- char buf[PATH_MAX];
- int ret;
-
- snprintf(buf, sizeof(buf), "/run/aul/apps/%u/%d", uid, pid);
- ret = _util_unlink(buf);
- if (ret != 0)
- _W("Failed to delete socket path(%s)", buf);
-}
-
-int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
- int ret;
-
- if (pkgid == NULL)
- return -1;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status->uid == uid &&
- strcmp(app_status->pkgid, pkgid) == 0 &&
- app_status->status != STATUS_DYING) {
- ret = _terminate_app_local(app_status->uid,
- app_status->pid);
- if (ret < 0) {
- _E("Failed to terminate app(%d)",
- app_status->pid);
- }
-
- _app_status_update_status(app_status, STATUS_DYING,
- false, true);
- __delete_socket_path(app_status->pid, app_status->uid);
- }
- }
-
- return 0;
-}
-
-int _app_status_get_appid_bypid(int fd, int pid)
-{
- int cmd = APP_GET_INFO_ERROR;
- int len = 0;
- int pgid;
- int ppid;
- int ret;
- char appid[MAX_PACKAGE_STR_SIZE] = {0,};
- app_status_h app_status;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- pgid = getpgid(pid);
- if (pgid > 0) {
- app_status = _app_status_find(pgid);
- if (app_status == NULL) {
- ppid = __proc_get_ppid_by_pid(pid);
- app_status = _app_status_find(ppid);
- }
- }
- }
-
- if (app_status) {
- snprintf(appid, sizeof(appid), "%s",
- _app_status_get_appid(app_status));
- SECURE_LOGD("appid for %d is %s", pid, appid);
- len = strlen(appid);
- cmd = APP_GET_INFO_OK;
- }
-
- ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)appid,
- len, AUL_SOCK_NOREPLY);
-
- return ret;
-}
-
-int _app_status_get_pkgid_bypid(int fd, int pid)
-{
- int cmd = APP_GET_INFO_ERROR;
- int len = 0;
- int pgid;
- int ppid;
- int ret;
- char pkgid[MAX_PACKAGE_STR_SIZE] = {0,};
- app_status_h app_status;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- pgid = getpgid(pid);
- if (pgid > 0) {
- app_status = _app_status_find(pgid);
- if (app_status == NULL) {
- ppid = __proc_get_ppid_by_pid(pid);
- app_status = _app_status_find(ppid);
- }
- }
- }
-
- if (app_status) {
- snprintf(pkgid, sizeof(pkgid), "%s",
- _app_status_get_pkgid(app_status));
- SECURE_LOGD("pkgid for %d is %s", pid, pkgid);
- len = strlen(pkgid);
- cmd = APP_GET_INFO_OK;
- }
-
- ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)pkgid,
- len, AUL_SOCK_NOREPLY);
-
- return ret;
-}
-
-int _app_status_get_instance_id_bypid(int fd, int pid)
-{
- int cmd = APP_GET_INFO_ERROR;
- int len = 0;
- int ret;
- const char *instance_id;
- char buf[MAX_PACKAGE_STR_SIZE] = {0,};
- app_status_h app_status;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- app_status = _app_status_find(getpgid(pid));
- if (app_status == NULL) {
- app_status = _app_status_find(
- __proc_get_ppid_by_pid(pid));
- }
- }
-
- instance_id = _app_status_get_instance_id(app_status);
- if (instance_id) {
- snprintf(buf, sizeof(buf), "%s", instance_id);
- SECURE_LOGD("pid(%d), instance-id(%s)", pid, instance_id);
- len = strlen(buf);
- cmd = APP_GET_INFO_OK;
- }
-
- ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)buf, len,
- AUL_SOCK_NOREPLY);
-
- return ret;
-}
-
-int _app_status_set_leader_id(app_status_h app_status, const char *id)
-{
- if (app_status == NULL || id == NULL)
- return -1;
-
- if (app_status->leader_id)
- free(app_status->leader_id);
-
- app_status->leader_id = strdup(id);
- if (!app_status->leader_id) {
- _E("Failed to duplicate leader ID(%s)", id);
- return -1;
- }
-
- return 0;
-}
-
-const char *_app_status_get_leader_id(app_status_h app_status)
-{
- if (app_status == NULL)
- return NULL;
-
-
- return app_status->leader_id;
-}
-
-int _app_status_get_fg_cnt(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
-
- return app_status->fg_count;
-}
-
-int _app_status_get_timestamp(app_status_h app_status)
-{
- if (app_status == NULL)
- return -1;
-
-
- return app_status->timestamp;
-}
-
-static void __home_appid_vconf_cb(keynode_t *key, void *data)
-{
- char *tmpstr;
-
- tmpstr = vconf_keynode_get_str(key);
- if (tmpstr == NULL)
- return;
-
- if (home_appid)
- free(home_appid);
- home_appid = strdup(tmpstr);
-}
-
-int _app_status_publish_status(int pid, int context_status)
-{
-#define APP_STATUS_EVENT "app_status_event"
- bundle *b;
- char endpoint_system[MAX_LOCAL_BUFSZ];
- char endpoint_user[MAX_LOCAL_BUFSZ];
- char endpoint_system2[MAX_LOCAL_BUFSZ];
- char endpoint_user2[MAX_LOCAL_BUFSZ];
- bool endpoint_system_exists;
- bool endpoint_user_exists;
- bool endpoint_system2_exists;
- bool endpoint_user2_exists;
- char buf[MAX_PID_STR_BUFSZ];
- app_status_h app_status;
- const char *appid;
- uid_t uid;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return -1;
-
- appid = _app_status_get_appid(app_status);
- uid = _app_status_get_uid(app_status);
- snprintf(endpoint_user, sizeof(endpoint_user), "%s:%s:%u",
- APP_STATUS_EVENT, appid, uid);
- snprintf(endpoint_system, sizeof(endpoint_system), "%s:%s",
- APP_STATUS_EVENT, appid);
- snprintf(endpoint_user2, sizeof(endpoint_user2), "%s:%u",
- APP_STATUS_EVENT, uid);
- snprintf(endpoint_system2, sizeof(endpoint_system2), "%s",
- APP_STATUS_EVENT);
- endpoint_system_exists = _app_com_endpoint_exists(endpoint_system);
- endpoint_user_exists = _app_com_endpoint_exists(endpoint_user);
- endpoint_system2_exists = _app_com_endpoint_exists(endpoint_system2);
- endpoint_user2_exists = _app_com_endpoint_exists(endpoint_user2);
- if (!endpoint_system_exists && !endpoint_user_exists &&
- !endpoint_system2_exists && !endpoint_user2_exists)
- return -1;
-
- b = __create_appinfo_bundle(app_status);
- if (b == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- snprintf(buf, sizeof(buf), "%d", context_status);
- bundle_add(b, "__CONTEXT_STATUS__", buf);
- if (endpoint_system_exists)
- _app_com_send(endpoint_system, pid, b, uid);
- if (endpoint_user_exists)
- _app_com_send(endpoint_user, pid, b, uid);
- if (endpoint_system2_exists)
- _app_com_send(endpoint_system2, pid, b, uid);
- if (endpoint_user2_exists)
- _app_com_send(endpoint_user2, pid, b, uid);
- bundle_free(b);
-
- return 0;
-}
-
-static void __terminate_widget_apps_by_org_caller(int caller_pid, uid_t uid)
-{
- GSList *iter;
- struct app_status_s *app_status;
- int ret;
-
- for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
- app_status = (struct app_status_s *)iter->data;
- if ((app_status->app_type == AT_WIDGET_APP ||
- app_status->app_type == AT_WATCH_APP) &&
- app_status->uid == uid &&
- app_status->org_caller_pid == caller_pid &&
- app_status->status != STATUS_DYING) {
- ret = _terminate_app_local(app_status->uid,
- app_status->pid);
- if (ret < 0) {
- _E("Failed to terminate app(%d)",
- app_status->pid);
- }
- }
- }
-}
-
-void _app_status_cleanup(app_status_h app_status)
-{
- int pid;
- const char *instance_id;
- uid_t uid;
-
- if (app_status == NULL)
- return;
-
- pid = _app_status_get_pid(app_status);
- uid = _app_status_get_uid(app_status);
- _D("pid: %d, uid: %d", pid, uid);
-
- _noti_send(AMD_NOTI_MSG_APP_STATUS_CLEANUP, pid, uid, app_status, NULL);
-
- instance_id = _app_status_get_instance_id(app_status);
- if (instance_id == NULL)
- instance_id = _app_status_get_appid(app_status);
-
- __terminate_widget_apps_by_org_caller(pid, uid);
- _app_com_client_remove(pid);
- _suspend_remove_proc(pid);
- _app_status_remove(app_status);
- aul_send_app_terminated_signal(pid);
-}
-
-static bool __socket_monitor_cb(const char *event_name, void *data)
-{
- int pid = -1;
-
- if (event_name == NULL)
- return true;
-
- if (isdigit(*event_name))
- pid = atoi(event_name);
-
- if (pid > 1)
- _I("Socket(%d) is created.", pid);
-
- return true;
-}
-
-static bool __dir_monitor_cb(const char *event_name, void *data)
-{
- uid_t uid;
- inotify_watch_info_h handle;
- char path[PATH_MAX];
-
- if (event_name == NULL)
- return true;
-
- uid = strtol(event_name, NULL, 10);
- handle = g_hash_table_lookup(__wd_table, GUINT_TO_POINTER(uid));
- if (!handle) {
- snprintf(path, sizeof(path), "%s/%u", PATH_AUL_APPS, uid);
- handle = _inotify_add_watch(path, IN_CREATE,
- __socket_monitor_cb, NULL);
- if (handle == NULL) {
- _E("Failed to add a watch - uid(%d)", uid);
- return true;;
- }
-
- g_hash_table_insert(__wd_table, GUINT_TO_POINTER(uid), handle);
- }
-
- return true;
-}
-
-int _app_status_usr_init(uid_t uid)
-{
- inotify_watch_info_h handle;
- char buf[PATH_MAX];
-
- handle = g_hash_table_lookup(__wd_table, GUINT_TO_POINTER(uid));
- if (handle) {
- _D("Already exists. uid(%u)", uid);
- return 0;
- }
-
- snprintf(buf, sizeof(buf), "/run/aul/apps/%d", uid);
- if (access(buf, F_OK) == 0) {
- handle = _inotify_add_watch(buf, IN_CREATE, __socket_monitor_cb,
- NULL);
- if (handle == NULL) {
- _E("Failed to add a watch - uid(%d)", uid);
- return -1;
- }
-
- g_hash_table_insert(__wd_table, GUINT_TO_POINTER(uid), handle);
- }
-
- return 0;
-}
-
-void _app_status_usr_fini(uid_t uid)
-{
- GSList *iter;
- GSList *iter_next;
- app_status_h app_status;
-
- if (g_hash_table_contains(__wd_table, GUINT_TO_POINTER(uid)))
- g_hash_table_remove(__wd_table, GUINT_TO_POINTER(uid));
- else
- _D("Watch fd doesn't exist - uid(%d)", uid);
-
- GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
- app_status = (struct app_status_s *)iter->data;
- if (app_status && app_status->uid == uid)
- _app_status_cleanup(app_status);
- }
-}
-
-static void __remove_inotify_watch(gpointer data)
-{
- inotify_watch_info_h handle = data;
-
- if (handle == NULL)
- return;
-
- _inotify_rm_watch(handle);
-}
-
-static int __dispatch_app_running_info(request_h req)
-{
- int ret;
-
- ret = _app_status_send_running_appinfo(_request_remove_fd(req),
- _request_get_cmd(req), _request_get_target_uid(req));
- return ret;
-}
-
-static int __dispatch_app_all_running_info(request_h req)
-{
- int ret;
-
- ret = _app_status_send_running_appinfo(_request_remove_fd(req),
- _request_get_cmd(req), _request_get_target_uid(req));
- return ret;
-}
-
-static int __dispatch_app_is_running(request_h req)
-{
- const char *appid;
- int ret;
- app_status_h app_status;
- bundle *b = _request_get_bundle(req);
-
- if (b == NULL) {
- _E("Failed to get bundle");
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (appid == NULL) {
- _E("Failed to get appid");
- _request_send_result(req, -1);
- return -1;
- }
-
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- ret = _app_status_is_running(app_status);
- SECURE_LOGD("APP_IS_RUNNING : %s : %d", appid, ret);
- _request_send_result(req, ret);
-
- return 0;
-}
-
-static int __dispatch_app_get_pid(request_h req)
-{
- const char *appid;
- int ret;
- app_status_h app_status;
- bundle *b;
-
- b = _request_get_bundle(req);
- if (b == NULL) {
- _E("Failed to get bundle");
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (appid == NULL) {
- _E("Failed to get appid");
- _request_send_result(req, -1);
- return -1;
- }
-
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- ret = _app_status_get_pid(app_status);
- SECURE_LOGD("APP_GET_PID : %s : %d", appid, ret);
- _request_send_result(req, ret);
-
- return 0;
-}
-
-static int __dispatch_app_get_appid_by_pid(request_h req)
-{
- int pid;
- int ret;
- const char *pid_str;
- bundle *b = _request_get_bundle(req);
-
- if (b == NULL) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str == NULL || !isdigit(pid_str[0])) {
- _E("Failed to get pid");
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid = atoi(pid_str);
- ret = _app_status_get_appid_bypid(_request_remove_fd(req), pid);
- _D("app_status_get_appid_bypid : %d : %d", pid, ret);
-
- return 0;
-}
-
-static int __dispatch_app_get_pkgid_by_pid(request_h req)
-{
- int pid;
- int ret;
- const char *pid_str;
- bundle *b = _request_get_bundle(req);
-
- if (b == NULL) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str == NULL || !isdigit(pid_str[0])) {
- _E("Failed to get pid");
- aul_sock_send_raw_with_fd(_request_remove_fd(req),
- APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid = atoi(pid_str);
- ret = _app_status_get_pkgid_bypid(_request_remove_fd(req), pid);
- _D("APP_GET_PKGID_BYPID : %d : %d", pid, ret);
-
- return 0;
-}
-
-static int __dispatch_app_status_update(request_h req)
-{
- int *status;
- const char *appid;
- struct appinfo *ai;
- app_status_h app_status;
-
- app_status = _app_status_find(_request_get_pid(req));
- if (app_status == NULL)
- return -1;
-
- status = (int *)_request_get_raw(req);
- switch (*status) {
- case STATUS_NORESTART:
- appid = _app_status_get_appid(app_status);
- ai = _appinfo_find(_request_get_target_uid(req), appid);
- _appinfo_set_value((struct appinfo *)ai, AIT_STATUS,
- "norestart");
- break;
- case STATUS_VISIBLE:
- case STATUS_BG:
- break;
- default:
- _app_status_update_status(app_status, *status, false, true);
- break;
- }
-
- return 0;
-}
-
-static int __dispatch_app_get_status(request_h req)
-{
- int pid;
- int status;
- app_status_h app_status;
- const char *pid_str;
- bundle *b;
-
- b = _request_get_bundle(req);
- if (b == NULL) {
- _E("Failed to get bundle");
- _request_send_result(req, -1);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str == NULL || !isdigit(pid_str[0])) {
- _E("Falied to get pid");
- _request_send_result(req, -1);
- return -1;
- }
-
- pid = atoi(pid_str);
- app_status = _app_status_find(pid);
- status = _app_status_get_status(app_status);
- _request_send_result(req, status);
-
- return 0;
-}
-
-static int __dispatch_app_get_status_by_appid(request_h req)
-{
- int status;
- int pid;
- uid_t uid;
- const char *appid;
- bundle *kb;
- app_status_h app_status;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- uid = _request_get_target_uid(req);
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- app_status = _app_status_find_by_appid(appid, uid);
- pid = _app_status_is_running(app_status);
- status = _app_status_get_status(app_status);
- if (status == STATUS_VISIBLE) {
- if (_launch_get_focused_pid() == pid)
- status = STATUS_FOCUS;
- }
-
- _request_send_result(req, status);
- _D("appid: %s, pid: %d, status: %d", appid, pid, status);
-
- return 0;
-}
-
-static int __dispatch_app_get_last_caller_pid(request_h req)
-{
- int pid;
- int ret;
- app_status_h app_status;
- const char *pid_str;
- bundle *b = _request_get_bundle(req);
-
- if (b == NULL) {
- _E("Failed to get bundle");
- _request_send_result(req, -1);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str == NULL || !isdigit(pid_str[0])) {
- _E("Failed to get pid");
- _request_send_result(req, -1);
- return -1;
- }
-
- pid = atoi(pid_str);
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- _E("Failed to get app status info(%d)", pid);
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _app_status_get_last_caller_pid(app_status);
- _D("app_get_last_caller_pid: %d : %d", pid, ret);
- _request_send_result(req, ret);
-
- return 0;
-}
-
-static int __verify_app_process(pid_t pid, const char *pkgid)
-{
- char attr[PATH_MAX] = { 0, };
- char buf[PATH_MAX];
- int r;
-
- r = _proc_get_attr(pid, attr, sizeof(attr));
- if (r < 0)
- return -1;
-
- snprintf(buf, sizeof(buf), "User::Pkg::%s", pkgid);
- if (!strcmp(buf, attr))
- return 0;
-
- SECURE_LOGD("attr:%s, package:%s", attr, pkgid);
- return -1;
-}
-
-static void __update_proc_status(int pid, int status, int focused, void *data)
-{
- app_status_h app_status;
-
- if (focused == 1)
- _launch_set_focused_pid(pid);
-
- if (status == PROC_STATUS_FG)
- status = STATUS_VISIBLE;
- else if (status == PROC_STATUS_BG)
- status = STATUS_BG;
- else
- return;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return;
-
- _app_status_update_status(app_status, status, false, true);
-}
-
-int _app_status_register_pid(int pid, const char *appid, uid_t uid)
-{
- struct appinfo *ai;
- const char *component_type;
- const char *pkgid;
- int ret;
- app_status_h app_status;
-
- ai = _appinfo_find(uid, appid);
- if (!ai)
- return -1;
-
- pkgid = _appinfo_get_value(ai, AIT_PKGID);
- if (__verify_app_process(pid, pkgid) < 0)
- return -1;
-
- app_status = _app_status_find_by_appid(appid, uid);
- ret = _app_status_is_running(app_status);
- if (ret > 0) {
- _W("status info is already exist: %s", appid);
- if (ret == pid)
- return 0;
- _W("Running process: %d, request process:%d", ret, pid);
- return -1;
- }
- _D("appid: %s, pid: %d", appid, pid);
-
- component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- _app_status_add_app_info(ai, pid, false, uid, getpid(),
- false, NULL, false);
- _noti_send(AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID, pid, 0, ai, NULL);
- if (component_type && strcmp(component_type, APP_TYPE_SERVICE) != 0) {
- ret = _signal_get_proc_status_async(pid,
- __update_proc_status, NULL);
- if (ret < 0)
- return 0;
- }
-
- return 0;
-}
-
-static int __dispatch_app_register_pid(request_h req)
-{
- uid_t target_uid = _request_get_target_uid(req);
- const char *appid;
- const char *pid_str;
- bundle *kb;
- int pid;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL)
- return -1;
-
- pid_str = bundle_get_val(kb, AUL_K_PID);
- if (pid_str == NULL)
- return -1;
-
- pid = atoi(pid_str);
- if (pid <= 1)
- return -1;
-
- return _app_status_register_pid(pid, appid, target_uid);
-}
-
-static int __dispatch_app_running_instance_info(request_h req)
-{
- int fd = _request_remove_fd(req);
- int cmd = _request_get_cmd(req);
- uid_t target_uid = _request_get_target_uid(req);
-
- return _app_status_send_running_appinfo(fd, cmd, target_uid);
-}
-
-static int __dispatch_app_get_instance_id_by_pid(request_h req)
-{
- int pid;
- int ret;
- const char *pid_str;
- int fd = _request_remove_fd(req);
- bundle *b = _request_get_bundle(req);
-
- if (b == NULL) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (pid_str == NULL || !isdigit(pid_str[0])) {
- _E("Failed to get pid");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -1;
- }
-
- pid = atoi(pid_str);
- ret = _app_status_get_instance_id_bypid(fd, pid);
- _D("app get instance-id by pid - pid(%d), ret(%d)", pid, ret);
-
- return ret;
-}
-
-static int __dispatch_app_notify_exit(request_h req)
-{
- int pid = _request_get_pid(req);
- int ret;
- app_status_h app_status;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- _E("pid(%d) is not an application", pid);
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _app_status_update_is_exiting(app_status, true);
- _D("[APP_NOTIFY_EXIT] result(%d)", ret);
-
- return 0;
-}
-
-static int __dispatch_app_notify_start(request_h req)
-{
- int pid = _request_get_pid(req);
- app_status_h app_status;
-
- _request_reply_for_pending_request(pid);
- app_status = _app_status_find(pid);
- if (app_status) {
- app_status->socket_exists = true;
- app_status->starting = true;
- }
-
- _W("[APP_NOTIFY_START] pid(%d)", pid);
-
- return 0;
-}
-
-static int __dispatch_app_is_running_v2(request_h req)
-{
- app_status_h app_status;
- const char *instance_id;
- const char *appid;
- bundle *b;
- int ret;
-
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- _request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get application ID");
- _request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!instance_id) {
- _E("Failed to get instance ID");
- _request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- app_status = _app_status_find_by_instance_id(appid,
- instance_id, _request_get_target_uid(req));
- ret = _app_status_is_running(app_status);
- _request_send_result(req, ret > 0 ? ret : 0);
- SECURE_LOGD("APP_IS_RUNNING_V2 : %s : %s : %d",
- appid, instance_id, ret);
-
- return 0;
-}
-
-static int __dispatch_app_get_running_context(request_h req)
-{
- comp_status_h comp_status = NULL;
- app_status_h app_status = NULL;
- const char *component_id;
- const char *instance_id;
- const char *appid;
- char buf[12];
- int pid;
- bundle *b;
- int ret;
-
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(_request_remove_fd(req), -EINVAL,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get application ID");
- aul_sock_send_raw_with_fd(_request_remove_fd(req), -EINVAL,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- component_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
- if (component_id && instance_id) {
- comp_status = _comp_status_find_by_instance_id(instance_id);
- } else if (component_id) {
- comp_status = _comp_status_find(component_id);
- } else if (appid && instance_id) {
- app_status = _app_status_find_by_instance_id(appid,
- instance_id, _request_get_target_uid(req));
- } else {
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- }
-
- if (_comp_status_is_running(comp_status)) {
- instance_id = _comp_status_get_instance_id(comp_status);
- pid = _comp_status_get_pid(comp_status);
- } else if (_app_status_is_running(app_status) > 0) {
- instance_id = _app_status_get_instance_id(app_status);
- pid = _app_status_get_pid(app_status);
- } else {
- _E("Failed to find information");
- aul_sock_send_raw_with_fd(_request_remove_fd(req), -ENOENT,
- NULL, 0, AUL_SOCK_NOREPLY);
- return -ENOENT;
- }
-
- bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
- snprintf(buf, sizeof(buf), "%d", pid);
- bundle_add(b, AUL_K_PID, buf);
-
- ret = aul_sock_send_bundle_with_fd(_request_remove_fd(req),
- APP_GET_INFO_OK, b, AUL_SOCK_NOREPLY);
- _I("[APP_GET_RUNNING_CONTEXT] result: %d", ret);
-
- return 0;
-}
-
-static int __dispatch_app_context_get(request_h req)
-{
- app_status_h app_status;
- const char *appid;
- int s_pid;
- int c_pid;
- bundle *b;
- int ret;
- int fd;
-
- fd = _request_remove_fd(req);
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get application ID");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- if (_app_status_is_running(app_status) < 0) {
- s_pid = _app_status_get_pid(app_status);
- c_pid = _request_get_pid(req);
- if (s_pid != c_pid)
- app_status = NULL;
- }
-
- if (!app_status) {
- _E("Failed to find app status. appid(%s)", appid);
- aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -ENOENT;
- }
-
- ret = __send_running_appinfo(app_status, fd);
- if (ret < 0)
- return ret;
-
- close(fd);
- _I("[APP_CONTEXT_GET] result: %d", ret);
- return 0;
-}
-
-static int __dispatch_app_context_get_by_instance_id(request_h req)
-{
- app_status_h app_status;
- const char *instance_id;
- const char *appid;
- int status;
- int s_pid;
- bundle *b;
- int pid;
- int ret;
- int fd;
-
- fd = _request_remove_fd(req);
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- appid = bundle_get_val(b, AUL_K_APPID);
- if (!appid) {
- _E("Failed to get application ID");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!instance_id) {
- _E("Failed to get instance ID");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- pid = _request_get_pid(req);
- app_status = _app_status_find_by_instance_id(appid, instance_id,
- _request_get_target_uid(req));
- if (app_status) {
- status = _app_status_get_status(app_status);
- if (status == STATUS_DYING) {
- s_pid = _app_status_get_pid(app_status);
- _W("%d is dying", s_pid);
- if (s_pid != pid)
- app_status = NULL;
- }
- }
-
- if (!app_status) {
- _E("Failed to find app status. appid(%s), inst_id(%s)",
- appid, instance_id);
- aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -ENOENT;
- }
-
- ret = __send_running_appinfo(app_status, fd);
- if (ret < 0)
- return ret;
-
- close(fd);
- _I("[APP_CONTEXT_GET_BY_INSTANCE_ID] result: %d", ret);
- return 0;
-}
-
-static int __dispatch_app_context_get_by_pid(request_h req)
-{
- app_status_h app_status;
- const char *pid_str;
- int status;
- int c_pid;
- bundle *b;
- int pid;
- int ret;
- int fd;
-
- fd = _request_remove_fd(req);
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
-
- pid_str = bundle_get_val(b, AUL_K_PID);
- if (!pid_str) {
- _E("Failed to get process ID");
- aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -EINVAL;
- }
- pid = atoi(pid_str);
-
- app_status = _app_status_find_v2(pid);
- if (app_status) {
- status = _app_status_get_status(app_status);
- if (status == STATUS_DYING) {
- _W("%d is dying", pid);
- c_pid = _request_get_pid(req);
- if (c_pid != pid)
- app_status = NULL;
- }
- }
-
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -ENOENT;
- }
-
- ret = __send_running_appinfo(app_status, fd);
- if (ret < 0)
- return ret;
-
- close(fd);
- _I("[APP_CONTEXT_GET_BY_PID] result: %d", ret);
- return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_RUNNING_INFO,
- .callback = __dispatch_app_running_info
- },
- {
- .cmd = APP_ALL_RUNNING_INFO,
- .callback = __dispatch_app_all_running_info
- },
- {
- .cmd = APP_IS_RUNNING,
- .callback = __dispatch_app_is_running
- },
- {
- .cmd = APP_GET_PID,
- .callback = __dispatch_app_get_pid
- },
- {
- .cmd = APP_GET_APPID_BYPID,
- .callback = __dispatch_app_get_appid_by_pid
- },
- {
- .cmd = APP_GET_PKGID_BYPID,
- .callback = __dispatch_app_get_pkgid_by_pid
- },
- {
- .cmd = APP_STATUS_UPDATE,
- .callback = __dispatch_app_status_update
- },
- {
- .cmd = APP_GET_STATUS,
- .callback = __dispatch_app_get_status
- },
- {
- .cmd = APP_GET_STATUS_BY_APPID,
- .callback = __dispatch_app_get_status_by_appid
- },
- {
- .cmd = APP_GET_LAST_CALLER_PID,
- .callback = __dispatch_app_get_last_caller_pid
- },
- {
- .cmd = APP_REGISTER_PID,
- .callback = __dispatch_app_register_pid
- },
- {
- .cmd = APP_RUNNING_INSTANCE_INFO,
- .callback = __dispatch_app_running_instance_info
- },
- {
- .cmd = APP_GET_INSTANCE_ID_BYPID,
- .callback = __dispatch_app_get_instance_id_by_pid
- },
- {
- .cmd = APP_NOTIFY_EXIT,
- .callback = __dispatch_app_notify_exit
- },
- {
- .cmd = APP_NOTIFY_START,
- .callback = __dispatch_app_notify_start
- },
- {
- .cmd = APP_IS_RUNNING_V2,
- .callback = __dispatch_app_is_running_v2
- },
- {
- .cmd = APP_GET_RUNNING_CONTEXT,
- .callback = __dispatch_app_get_running_context
- },
- {
- .cmd = APP_CONTEXT_GET,
- .callback = __dispatch_app_context_get
- },
- {
- .cmd = APP_CONTEXT_GET_BY_INSTANCE_ID,
- .callback = __dispatch_app_context_get_by_instance_id
- },
- {
- .cmd = APP_CONTEXT_GET_BY_PID,
- .callback = __dispatch_app_context_get_by_pid
- },
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_GET_RUNNING_CONTEXT,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
-};
-
-static int __init_vconf(void)
-{
- int r;
-
- r = vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
- &limit_bg_uiapps);
- if (r != VCONF_OK)
- _W("Failed to get %s", VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS);
-
- r = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
- __vconf_cb, NULL);
- if (r != VCONF_OK) {
- _E("Failed to register callback for %s",
- VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS);
- return -1;
- }
-
- home_appid = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
- r = vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME,
- __home_appid_vconf_cb, NULL);
- if (r != VCONF_OK) {
- _E("Failed to register callback for %s",
- VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
- __vconf_cb);
- return -1;
- }
-
- __vconf.initialized = true;
-
- return 0;
-}
-
-static void __finish_vconf(void)
-{
- if (!__vconf.initialized)
- return;
-
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
- __vconf_cb);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME,
- __home_appid_vconf_cb);
-
- __vconf.initialized = false;
-}
-
-static gboolean __vconf_init_handler(gpointer data)
-{
- static int retry_count;
-
- retry_count++;
- if (__init_vconf() < 0 && retry_count <= 10) {
- _W("Retry count(%d)", retry_count);
- return G_SOURCE_CONTINUE;
- }
-
- __vconf.timer = 0;
- return G_SOURCE_REMOVE;
-}
-
-int _app_status_init(void)
-{
- int ret;
-
- __wd_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __remove_inotify_watch);
- if (__wd_table == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- __wh = _inotify_add_watch(PATH_AUL_APPS, IN_CREATE, __dir_monitor_cb, NULL);
- if (!__wh) {
- _E("Failed to add watch(%s)", PATH_AUL_APPS);
- return -1;
- }
-
- ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- ret = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- __vconf.timer = g_timeout_add(500, __vconf_init_handler, NULL);
-
- return 0;
-}
-
-int _app_status_finish(void)
-{
- GSList *iter;
- GSList *iter_next;
- app_status_h app_status;
-
- GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
- app_status = (app_status_h)iter->data;
- _app_status_cleanup(app_status);
- }
-
- if (__vconf.timer)
- g_source_remove(__vconf.timer);
-
- __finish_vconf();
-
- free(home_appid);
-
- if (__wh)
- _inotify_rm_watch(__wh);
-
- if (__wd_table)
- g_hash_table_destroy(__wd_table);
-
- return 0;
-}
-
-bool _app_status_is_debug_mode(app_status_h app_status)
-{
- return app_status->debug_mode;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <glib.h>
-#include <dirent.h>
-#include <package-manager.h>
-#include <pkgmgr-info.h>
-#include <vconf.h>
-#include <aul_sock.h>
-#include <aul.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-
-#include "amd_api_noti.h"
-#include "amd_util.h"
-#include "amd_appinfo.h"
-#include "amd_launch.h"
-#include "amd_app_status.h"
-#include "amd_signal.h"
-#include "amd_app_property.h"
-#include "amd_suspend.h"
-#include "amd_login_monitor.h"
-#include "amd_noti.h"
-
-#define CATEGORY_IME "http://tizen.org/category/ime"
-
-typedef int (*appinfo_handler_add_cb)(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data);
-typedef void (*appinfo_handler_remove_cb)(void *data);
-
-typedef struct _appinfo_vft {
- appinfo_handler_add_cb constructor;
- appinfo_handler_remove_cb destructor;
-} appinfo_vft;
-
-struct user_appinfo {
- uid_t uid;
- GHashTable *tbl; /* key is appid, value is struct appinfo */
-};
-
-struct app_event_info {
- int req_id;
- int type;
- uid_t uid;
-};
-
-struct pkg_event_info {
- uid_t target_uid;
- uid_t uid;
- const char *pkgid;
-};
-
-struct callback_info {
- appinfo_iter_callback cb;
- void *user_data;
-};
-
-static pkgmgr_client *pc;
-static GHashTable *user_tbl;
-static GHashTable *pkg_pending;
-static GList *app_event_list;
-static int gles = 1;
-
-static void __free_appinfo_splash_image(gpointer data)
-{
- struct appinfo_splash_image *splash_image = data;
-
- if (splash_image == NULL)
- return;
-
- if (splash_image->color_depth)
- free(splash_image->color_depth);
- if (splash_image->indicatordisplay)
- free(splash_image->indicatordisplay);
- if (splash_image->type)
- free(splash_image->type);
- if (splash_image->src)
- free(splash_image->src);
- free(splash_image);
-}
-
-static void __free_user_appinfo(gpointer data)
-{
- struct user_appinfo *info = (struct user_appinfo *)data;
-
- g_hash_table_destroy(info->tbl);
- free(info);
-}
-
-static int __read_background_category(const char *category_name,
- void *user_data)
-{
- struct appinfo *c = user_data;
- int category = (intptr_t)(c->val[AIT_BG_CATEGORY]);
-
- if (!category_name)
- return 0;
-
- if (strcmp(category_name, "disable") == 0) {
- c->val[AIT_BG_CATEGORY] = 0x00;
- return -1;
- }
-
- if (strcmp(category_name, "media") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_MEDIA));
- } else if (strcmp(category_name, "download") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_DOWNLOAD));
- } else if (strcmp(category_name, "background-network") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_BACKGROUND_NETWORK));
- } else if (strcmp(category_name, "location") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_LOCATION));
- } else if (strcmp(category_name, "sensor") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_SENSOR));
- } else if (strcmp(category_name, "iot-communication") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_IOT_COMMUNICATION));
- } else if (strcmp(category_name, "system") == 0) {
- c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
- BACKGROUND_CATEGORY_SYSTEM));
- }
-
- return 0;
-}
-
-static void __appinfo_remove_splash_screen(void *data)
-{
- struct appinfo_splash_screen *splash_screen =
- (struct appinfo_splash_screen *)data;
-
- if (splash_screen == NULL)
- return;
-
- if (splash_screen->portrait)
- g_hash_table_destroy(splash_screen->portrait);
- if (splash_screen->landscape)
- g_hash_table_destroy(splash_screen->landscape);
- free(splash_screen);
-}
-
-static int __appinfo_add_exec(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *exec = NULL;
-
- ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get exec");
- return -1;
- }
-
- info->val[AIT_EXEC] = strdup(exec);
- if (info->val[AIT_EXEC] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_pkgtype(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *pkgtype = NULL;
-
- ret = pkgmgrinfo_appinfo_get_pkgtype(handle, &pkgtype);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get pkgtype");
- return -1;
- }
-
- info->val[AIT_PKGTYPE] = strdup(pkgtype);
- if (info->val[AIT_PKGTYPE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_onboot(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool onboot = false;
-
- ret = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get onboot");
- return -1;
- }
-
- info->val[AIT_ONBOOT] = strdup(onboot ? "true" : "false");
- if (info->val[AIT_ONBOOT] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_restart(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool restart = false;
-
- ret = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get restart");
- return -1;
- }
-
- info->val[AIT_RESTART] = GINT_TO_POINTER(restart ? 1 : 0);
-
- return 0;
-}
-
-static int __appinfo_add_multi(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool multiple = false;
-
- ret = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get multiple");
- return -1;
- }
-
- info->val[AIT_MULTI] = strdup(multiple ? "true" : "false");
- if (info->val[AIT_MULTI] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_hwacc(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- pkgmgrinfo_app_hwacceleration hwacc;
-
- ret = pkgmgrinfo_appinfo_get_hwacceleration(handle, &hwacc);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get hwacc");
- return -1;
- }
-
- info->val[AIT_HWACC] = strdup(
- (gles == 0 ||
- hwacc == PMINFO_HWACCELERATION_OFF) ?
- "NOT_USE" :
- (hwacc == PMINFO_HWACCELERATION_ON) ?
- "USE" :
- "SYS");
- if (info->val[AIT_HWACC] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_perm(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- pkgmgrinfo_permission_type permission;
-
- ret = pkgmgrinfo_appinfo_get_permission_type(handle, &permission);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get permission type");
- return -1;
- }
-
- info->val[AIT_PERM] = strdup(
- (permission == PMINFO_PERMISSION_SIGNATURE) ?
- "signature" :
- (permission == PMINFO_PERMISSION_PRIVILEGE) ?
- "privilege" :
- "normal");
- if (info->val[AIT_PERM] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_pkgid(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *pkgid = NULL;
-
- ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get pkgid");
- return -1;
- }
-
- info->val[AIT_PKGID] = strdup(pkgid);
- if (info->val[AIT_PKGID] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_preload(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool preload = false;
-
- ret = pkgmgrinfo_appinfo_is_preload(handle, &preload);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get preload");
- return -1;
- }
-
- info->val[AIT_PRELOAD] = strdup(preload ? "true" : "false");
- if (info->val[AIT_PRELOAD] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_status(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- info->val[AIT_STATUS] = strdup("installed");
- if (info->val[AIT_STATUS] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_pool(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool process_pool = false;
-
- ret = pkgmgrinfo_appinfo_is_process_pool(handle, &process_pool);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get process_pool");
- return -1;
- }
-
- info->val[AIT_POOL] = strdup(process_pool ? "true" : "false");
- if (info->val[AIT_POOL] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_comptype(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *component_type = NULL;
-
- ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get component type");
- return -1;
- }
-
- info->val[AIT_COMPTYPE] = strdup(component_type);
- if (info->val[AIT_COMPTYPE] == NULL) {
- _E("Ouf ot memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_tep(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- char *tep_name = NULL;
-
- pkgmgrinfo_appinfo_get_tep_name(handle, &tep_name);
- if (tep_name && strlen(tep_name) > 0) {
- info->val[AIT_TEP] = strdup(tep_name);
- if (info->val[AIT_TEP] == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- return 0;
-}
-
-static int __appinfo_add_mountable_pkg(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- char *tpk_name = NULL;
-
- pkgmgrinfo_appinfo_get_zip_mount_file(handle, &tpk_name);
- if (tpk_name && strlen(tpk_name) > 0) {
- info->val[AIT_MOUNTABLE_PKG] = strdup(tpk_name);
- if (info->val[AIT_MOUNTABLE_PKG] == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- return 0;
-}
-
-static int __appinfo_add_storage_type(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- pkgmgrinfo_installed_storage installed_storage;
-
- ret = pkgmgrinfo_appinfo_get_installed_storage_location(handle,
- &installed_storage);
- if (ret == PMINFO_R_OK) {
- if (installed_storage == PMINFO_INTERNAL_STORAGE)
- info->val[AIT_STORAGE_TYPE] = strdup("internal");
- else if (installed_storage == PMINFO_EXTERNAL_STORAGE)
- info->val[AIT_STORAGE_TYPE] = strdup("external");
- } else {
- info->val[AIT_STORAGE_TYPE] = strdup("internal");
- }
-
- if (info->val[AIT_STORAGE_TYPE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_bg_category(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
-
- ret = pkgmgrinfo_appinfo_foreach_background_category(handle,
- __read_background_category, info);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get background category");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_launch_mode(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *mode = NULL;
-
- ret = pkgmgrinfo_appinfo_get_launch_mode(handle, &mode);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get launch_mode");
- return -1;
- }
-
- info->val[AIT_LAUNCH_MODE] = strdup(mode ? mode : "single");
- if (info->val[AIT_LAUNCH_MODE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_global(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool is_global = false;
-
- ret = pkgmgrinfo_appinfo_is_global(handle, &is_global);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get is_global info");
- return -1;
- }
-
- info->val[AIT_GLOBAL] = strdup(is_global ? "true" : "false");
- if (info->val[AIT_GLOBAL] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_effective_appid(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- char *effective_appid = NULL;
-
- pkgmgrinfo_appinfo_get_effective_appid(handle, &effective_appid);
- if (effective_appid && strlen(effective_appid) > 0) {
- info->val[AIT_EFFECTIVE_APPID] = strdup(effective_appid);
- if (info->val[AIT_EFFECTIVE_APPID] == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- return 0;
-}
-
-static int __appinfo_add_taskmanage(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool taskmanage = false;
-
- ret = pkgmgrinfo_appinfo_is_taskmanage(handle, &taskmanage);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get taskmanage");
- return -1;
- }
-
- info->val[AIT_TASKMANAGE] = strdup(taskmanage ? "true" : "false");
- if (info->val[AIT_TASKMANAGE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_apptype(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *apptype = NULL;
-
- ret = pkgmgrinfo_appinfo_get_apptype(handle, &apptype);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get apptype");
- return -1;
- }
-
- info->val[AIT_APPTYPE] = strdup(apptype);
- if (info->val[AIT_APPTYPE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_root_path(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *path = NULL;
-
- ret = pkgmgrinfo_appinfo_get_root_path(handle, &path);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get root path");
- return -1;
- }
-
- if (path) {
- info->val[AIT_ROOT_PATH] = strdup(path);
- if (info->val[AIT_ROOT_PATH] == NULL) {
- _E("Out of memory");
- return -1;
- }
- }
-
- return 0;
-}
-
-static int __add_splash_screen_list_cb(const char *src, const char *type,
- const char *orientation, const char *indicatordisplay,
- const char *operation, const char *color_depth, void *user_data)
-{
- struct appinfo *info = (struct appinfo *)user_data;
- struct appinfo_splash_screen *splash_screen;
- struct appinfo_splash_image *splash_image;
- char *key;
-
- splash_image = (struct appinfo_splash_image *)calloc(1,
- sizeof(struct appinfo_splash_image));
- if (splash_image == NULL) {
- _E("out of memory");
- return -1;
- }
-
- splash_image->src = strdup(src);
- if (splash_image->src == NULL) {
- _E("Out of memory");
- free(splash_image);
- return -1;
- }
-
- splash_image->type = strdup(type);
- if (splash_image->type == NULL) {
- _E("Out of memory");
- __free_appinfo_splash_image(splash_image);
- return -1;
- }
-
- splash_image->indicatordisplay = strdup(indicatordisplay);
- if (splash_image->indicatordisplay == NULL) {
- _E("Out of memory");
- __free_appinfo_splash_image(splash_image);
- return -1;
- }
-
- splash_image->color_depth = strdup(color_depth);
- if (splash_image->color_depth == NULL) {
- _E("Out of memory");
- __free_appinfo_splash_image(splash_image);
- return -1;
- }
-
- key = strdup(operation);
- if (key == NULL) {
- _E("Out of memory");
- __free_appinfo_splash_image(splash_image);
- return -1;
- }
-
- splash_screen = (struct appinfo_splash_screen *)
- info->val[AIT_SPLASH_SCREEN];
- if (splash_screen == NULL) {
- splash_screen = (struct appinfo_splash_screen *)calloc(1,
- sizeof(struct appinfo_splash_screen));
- if (splash_screen == NULL) {
- _E("out of memory");
- __free_appinfo_splash_image(splash_image);
- free(key);
- return -1;
- }
- info->val[AIT_SPLASH_SCREEN] = (char *)splash_screen;
- }
-
- if (strcasecmp(orientation, "portrait") == 0) {
- if (splash_screen->portrait == NULL) {
- splash_screen->portrait = g_hash_table_new_full(
- g_str_hash, g_str_equal, free,
- __free_appinfo_splash_image);
- }
- g_hash_table_insert(splash_screen->portrait, key, splash_image);
- } else if (strcasecmp(orientation, "landscape") == 0) {
- if (splash_screen->landscape == NULL) {
- splash_screen->landscape = g_hash_table_new_full(
- g_str_hash, g_str_equal, free,
- __free_appinfo_splash_image);
- }
- g_hash_table_insert(splash_screen->landscape, key,
- splash_image);
- } else {
- __free_appinfo_splash_image(splash_image);
- free(key);
- }
-
- return 0;
-}
-
-static int __appinfo_add_splash_screens(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
-
- ret = pkgmgrinfo_appinfo_foreach_splash_screen(handle,
- __add_splash_screen_list_cb, info);
- if (ret < 0) {
- _E("Failed to get splash screen");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_splash_screen_display(
- const pkgmgrinfo_appinfo_h handle, struct appinfo *info,
- void *data)
-{
- bool splash_screen_display = true;
- int ret;
-
- ret = pkgmgrinfo_appinfo_get_splash_screen_display(handle,
- &splash_screen_display);
- if (ret < 0)
- _D("Failed to get splash screen display");
-
- info->val[AIT_SPLASH_SCREEN_DISPLAY] =
- GINT_TO_POINTER(splash_screen_display ? 1 : 0);
-
- return 0;
-}
-
-static int __appinfo_add_api_version(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- char *api_version;
-
- ret = pkgmgrinfo_appinfo_get_api_version(handle, &api_version);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get api version");
- return -1;
- }
-
- info->val[AIT_API_VERSION] = strdup(api_version);
- if (info->val[AIT_API_VERSION] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_enablement(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool disabled = false;
-
- ret = pkgmgrinfo_appinfo_is_disabled(handle, &disabled);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get enablement");
- return -1;
- }
-
- info->val[AIT_ENABLEMENT] = GINT_TO_POINTER(disabled ? 0 : 1);
-
- return 0;
-}
-
-static int __appinfo_add_cooldown_mode(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- int support_mode = 0;
-
- ret = pkgmgrinfo_appinfo_get_support_mode(handle, &support_mode);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get support mode value");
- return -1;
- }
-
- if (support_mode & APP_SUPPORT_MODE_COOL_DOWN_VAL)
- info->val[AIT_COOLDOWN] = strdup("true");
- else
- info->val[AIT_COOLDOWN] = strdup("false");
- if (info->val[AIT_COOLDOWN] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_system(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool system = false;
-
- ret = pkgmgrinfo_appinfo_is_system(handle, &system);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get support mode value");
- return -1;
- }
-
- if (system)
- info->val[AIT_SYSTEM] = strdup("true");
- else
- info->val[AIT_SYSTEM] = strdup("false");
- if (info->val[AIT_SYSTEM] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_ime(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- int ret;
- bool exist = false;
-
- ret = pkgmgrinfo_appinfo_is_category_exist(handle, CATEGORY_IME,
- &exist);
- if (ret != PMINFO_R_OK) {
- _E("Failed to check ime category");
- return -1;
- }
-
- info->val[AIT_IME] = strdup(exist ? "true" : "false");
- if (info->val[AIT_IME] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __appinfo_add_ignore(const pkgmgrinfo_appinfo_h handle,
- struct appinfo *info, void *data)
-{
- /*
- * The default value of the ignore flag is "false".
- * If the flag is 'true', AMD doesn't block the launch request.
- */
- info->val[AIT_IGNORE] = strdup("false");
- if (info->val[AIT_IGNORE] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static appinfo_vft appinfo_table[AIT_MAX] = {
- [AIT_NAME] = {
- .constructor = NULL,
- .destructor = NULL
- },
- [AIT_EXEC] = {
- .constructor = __appinfo_add_exec,
- .destructor = free
- },
- [AIT_PKGTYPE] = {
- .constructor = __appinfo_add_pkgtype,
- .destructor = free
- },
- [AIT_ONBOOT] = {
- .constructor = __appinfo_add_onboot,
- .destructor = free
- },
- [AIT_RESTART] = {
- .constructor = __appinfo_add_restart,
- .destructor = NULL
- },
- [AIT_MULTI] = {
- .constructor = __appinfo_add_multi,
- .destructor = free
- },
- [AIT_HWACC] = {
- .constructor = __appinfo_add_hwacc,
- .destructor = free
- },
- [AIT_PERM] = {
- .constructor = __appinfo_add_perm,
- .destructor = free
- },
- [AIT_PKGID] = {
- .constructor = __appinfo_add_pkgid,
- .destructor = free
- },
- [AIT_PRELOAD] = {
- .constructor = __appinfo_add_preload,
- .destructor = free
- },
- [AIT_STATUS] = {
- .constructor = __appinfo_add_status,
- .destructor = free
- },
- [AIT_POOL] = {
- .constructor = __appinfo_add_pool,
- .destructor = free
- },
- [AIT_COMPTYPE] = {
- .constructor = __appinfo_add_comptype,
- .destructor = free
- },
- [AIT_TEP] = {
- .constructor = __appinfo_add_tep,
- .destructor = free
- },
- [AIT_MOUNTABLE_PKG] = {
- .constructor = __appinfo_add_mountable_pkg,
- .destructor = free
- },
- [AIT_STORAGE_TYPE] = {
- .constructor = __appinfo_add_storage_type,
- .destructor = free
- },
- [AIT_BG_CATEGORY] = {
- .constructor = __appinfo_add_bg_category,
- .destructor = NULL
- },
- [AIT_LAUNCH_MODE] = {
- .constructor = __appinfo_add_launch_mode,
- .destructor = free
- },
- [AIT_GLOBAL] = {
- .constructor = __appinfo_add_global,
- .destructor = free
- },
- [AIT_EFFECTIVE_APPID] = {
- .constructor = __appinfo_add_effective_appid,
- .destructor = free
- },
- [AIT_TASKMANAGE] = {
- .constructor = __appinfo_add_taskmanage,
- .destructor = free
- },
- [AIT_VISIBILITY] = {
- .constructor = NULL,
- .destructor = free
- },
- [AIT_APPTYPE] = {
- .constructor = __appinfo_add_apptype,
- .destructor = free
- },
- [AIT_ROOT_PATH] = {
- .constructor = __appinfo_add_root_path,
- .destructor = free
- },
- [AIT_SPLASH_SCREEN] = {
- .constructor = __appinfo_add_splash_screens,
- .destructor = __appinfo_remove_splash_screen
- },
- [AIT_SPLASH_SCREEN_DISPLAY] = {
- .constructor = __appinfo_add_splash_screen_display,
- .destructor = NULL
- },
- [AIT_API_VERSION] = {
- .constructor = __appinfo_add_api_version,
- .destructor = free
- },
- [AIT_ENABLEMENT] = {
- .constructor = __appinfo_add_enablement,
- .destructor = NULL
- },
- [AIT_COOLDOWN] = {
- .constructor = __appinfo_add_cooldown_mode,
- .destructor = free
- },
- [AIT_SYSTEM] = {
- .constructor = __appinfo_add_system,
- .destructor = free
- },
- [AIT_IME] = {
- .constructor = __appinfo_add_ime,
- .destructor = free
- },
- [AIT_IGNORE] = {
- .constructor = __appinfo_add_ignore,
- .destructor = free
- },
-};
-
-static void __appinfo_remove_handler(gpointer data)
-{
- struct appinfo *c = data;
- int i;
-
- if (!c)
- return;
-
- for (i = AIT_START; i < AIT_MAX; i++) {
- if (appinfo_table[i].destructor && c->val[i] != NULL)
- appinfo_table[i].destructor(c->val[i]);
- }
-
- free(c);
-}
-
-static int __appinfo_insert_handler (const pkgmgrinfo_appinfo_h handle,
- void *data)
-{
- int i;
- struct appinfo *c;
- struct user_appinfo *info = (struct user_appinfo *)data;
- char *appid;
- int ret;
- char err_buf[1024];
-
- if (!handle || !info) {
- _E("null app handle");
- return -1;
- }
-
- if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK) {
- _E("fail to get appinfo");
- return -1;
- }
-
- g_hash_table_remove(info->tbl, appid);
-
- c = calloc(1, sizeof(struct appinfo));
- if (!c) {
- _E("create appinfo: %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- return -1;
- }
-
- c->val[AIT_NAME] = strdup(appid);
- if (c->val[AIT_NAME] == NULL) {
- _E("Out of memory");
- free(c);
- return -1;
- }
-
- for (i = AIT_START; i < AIT_MAX; i++) {
- if (appinfo_table[i].constructor) {
- ret = appinfo_table[i].constructor(handle, c, info);
- if (ret < 0) {
- _E("failed to load appinfo of %s", appid);
- __appinfo_remove_handler(c);
- return 0;
- }
- }
- }
-
- SECURE_LOGD("%s : %s : %s : %s", c->val[AIT_NAME], c->val[AIT_COMPTYPE],
- c->val[AIT_PKGTYPE], c->val[AIT_APPTYPE]);
-
- g_hash_table_insert(info->tbl, c->val[AIT_NAME], c);
- _app_property_insert(info->uid, c->val[AIT_NAME], handle);
- _noti_send(AMD_NOTI_MSG_APPINFO_INSERT, info->uid, 0, handle, NULL);
-
- return 0;
-}
-
-static int __appinfo_update_handler(const pkgmgrinfo_appinfo_h handle,
- void *data)
-{
- int i;
- struct appinfo *c;
- struct user_appinfo *info = (struct user_appinfo *)data;
- char *appid;
- int ret;
- bool restart;
- int auto_restart;
-
- if (!handle || !info) {
- _E("Invalid parameter");
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get appinfo");
- return -1;
- }
-
- c = (struct appinfo *)g_hash_table_lookup(info->tbl, appid);
- if (!c) {
- c = calloc(1, sizeof(struct appinfo));
- if (!c) {
- _E("Failed to create appinfo(%s)", appid);
- return -1;
- }
-
- c->val[AIT_NAME] = strdup(appid);
- if (c->val[AIT_NAME] == NULL) {
- _E("Out of memory");
- free(c);
- return -1;
- }
-
- g_hash_table_insert(info->tbl, c->val[AIT_NAME], c);
- }
-
- if (c->val[AIT_STATUS] && strcmp(c->val[AIT_STATUS], "restart") == 0)
- restart = true;
- else
- restart = false;
-
- _app_property_delete(info->uid, appid);
- _noti_send(AMD_NOTI_MSG_APPINFO_REMOVE, info->uid, 0, appid, NULL);
- for (i = AIT_START + 1; i < AIT_MAX; i++) {
- if (appinfo_table[i].destructor && c->val[i])
- appinfo_table[i].destructor(c->val[i]);
- c->val[i] = NULL;
-
- if (appinfo_table[i].constructor) {
- ret = appinfo_table[i].constructor(handle, c, info);
- if (ret < 0) {
- g_hash_table_remove(info->tbl, appid);
- return -1;
- }
- }
- }
- SECURE_LOGD("%s : %s : %s : %s",
- c->val[AIT_NAME], c->val[AIT_COMPTYPE],
- c->val[AIT_PKGTYPE], c->val[AIT_APPTYPE]);
- _app_property_insert(info->uid, appid, handle);
- _noti_send(AMD_NOTI_MSG_APPINFO_INSERT, info->uid, 0, handle, NULL);
-
- auto_restart = GPOINTER_TO_INT(c->val[AIT_RESTART]);
- if (auto_restart && restart)
- _launch_start_app_local(info->uid, c->val[AIT_NAME]);
- else
- _launch_start_onboot_app_local(info->uid, c->val[AIT_NAME], c);
-
- return 0;
-}
-
-static int __insert_appinfo(const pkgmgrinfo_appinfo_h handle, void *data)
-{
- int ret;
- struct appinfo *ai;
- struct user_appinfo *info = (struct user_appinfo *)data;
- char *appid = NULL;
-
- ret = __appinfo_insert_handler(handle, data);
- if (ret < 0)
- return -1;
-
- ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
- if (ret != PMINFO_R_OK)
- return -1;
-
- ai = (struct appinfo *)g_hash_table_lookup(info->tbl, appid);
- if (ai == NULL)
- return -1;
-
- _launch_start_onboot_app_local(info->uid, appid, ai);
-
- return 0;
-}
-
-static void __remove_user_appinfo(uid_t uid)
-{
- g_hash_table_remove(user_tbl, GINT_TO_POINTER(uid));
-}
-
-static struct user_appinfo *__add_user_appinfo(uid_t uid)
-{
- int r;
- struct user_appinfo *info;
-
- info = calloc(1, sizeof(struct user_appinfo));
- if (info == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- info->uid = uid;
- info->tbl = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- __appinfo_remove_handler);
- if (info->tbl == NULL) {
- _E("out of memory");
- free(info);
- return NULL;
- }
-
- g_hash_table_insert(user_tbl, GINT_TO_POINTER(uid), info);
-
- r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
- __appinfo_insert_handler, uid,
- PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
- if (r != PMINFO_R_OK) {
- __remove_user_appinfo(uid);
- return NULL;
- }
-
- _D("loaded appinfo table for uid %d", uid);
-
- return info;
-}
-
-static struct user_appinfo *__find_user_appinfo(uid_t uid)
-{
- return g_hash_table_lookup(user_tbl, GINT_TO_POINTER(uid));
-}
-
-static void __appinfo_set_blocking_cb(void *user_data,
- const char *appid, struct appinfo *info)
-{
- struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
-
- if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
- return;
-
- if (pkg_info->target_uid == GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "false"))
- return;
- else if (pkg_info->target_uid != GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "true"))
- return;
-
- free(info->val[AIT_STATUS]);
- info->val[AIT_STATUS] = strdup("blocking");
- _D("%s status changed: blocking", appid);
-}
-
-static void __appinfo_unset_blocking_cb(void *user_data,
- const char *appid, struct appinfo *info)
-{
- struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
-
- if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
- return;
-
- if (pkg_info->target_uid == GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "false"))
- return;
- else if (pkg_info->target_uid != GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "true"))
- return;
-
- free(info->val[AIT_STATUS]);
- info->val[AIT_STATUS] = strdup("installed");
- if (info->val[AIT_STATUS] == NULL)
- _W("Out of memory");
- _D("%s status changed: installed", appid);
-}
-
-static void __appinfo_restart_cb(void *user_data,
- const char *appid, struct appinfo *info)
-{
- bool restart;
- int auto_restart;
- struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
-
- if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
- return;
-
- if (info->val[AIT_STATUS] && !strcmp(info->val[AIT_STATUS], "restart"))
- restart = true;
- else
- restart = false;
-
- __appinfo_unset_blocking_cb(user_data, appid, info);
-
- auto_restart = GPOINTER_TO_INT(info->val[AIT_RESTART]);
- if (auto_restart && restart)
- _launch_start_app_local(pkg_info->uid, info->val[AIT_NAME]);
-}
-
-static gboolean __appinfo_remove_cb(gpointer key, gpointer value, gpointer data)
-{
- struct pkg_event_info *pkg_info = (struct pkg_event_info *)data;
- struct appinfo *info = (struct appinfo *)value;
-
- if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
- return FALSE;
-
- if (pkg_info->target_uid == GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "false"))
- return FALSE;
- else if (pkg_info->target_uid != GLOBAL_USER &&
- !strcmp(info->val[AIT_GLOBAL], "true"))
- return FALSE;
-
- _app_property_delete(GPOINTER_TO_UINT(key), info->val[AIT_NAME]);
- _noti_send("appnifo.remove", GPOINTER_TO_UINT(key), 0,
- info->val[AIT_NAME], NULL);
-
- _D("appinfo removed: %s", info->val[AIT_NAME]);
- return TRUE;
-}
-
-static void __appinfo_delete_on_event(uid_t uid, void *data)
-{
- struct user_appinfo *info;
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("cannot find appinfo for uid %d", uid);
- return;
- }
-
- g_hash_table_foreach_remove(info->tbl, __appinfo_remove_cb,
- (gpointer)data);
-}
-
-static void __appinfo_insert_on_event(uid_t uid, const char *pkgid)
-{
- _appinfo_insert(uid, pkgid);
-}
-
-static void __appinfo_update_on_event(uid_t uid, void *data)
-{
- struct pkg_event_info *pkg_info = (struct pkg_event_info *)data;
- struct user_appinfo *info;
- pkgmgrinfo_pkginfo_h handle;
- int ret;
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("cannot find appinfo for uid %d", uid);
- return;
- }
-
- ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_info->pkgid, uid, &handle);
- if (ret != PMINFO_R_OK) {
- _E("Failed to get pkginfo(%s)", pkg_info->pkgid);
- return;
- }
-
- ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
- __appinfo_update_handler, info, info->uid);
- if (ret != PMINFO_R_OK) {
- _E("Failed to update pkginfo(%s)", pkg_info->pkgid);
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return;
- }
-
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-}
-
-static void __set_blocking(struct pkg_event_info *info)
-{
- uid_t *uids = NULL;
- int r;
- int i;
-
- if (info->target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++) {
- _appinfo_foreach(uids[i],
- __appinfo_set_blocking_cb, info);
- _D("terminate apps by PackageID - %s", info->pkgid);
- _app_status_terminate_apps_by_pkgid(info->pkgid,
- uids[i]);
- }
- free(uids);
-
- return;
- }
-
- _appinfo_foreach(info->target_uid, __appinfo_set_blocking_cb, info);
- _D("terminate apps by PackageID - %s", info->pkgid);
- _app_status_terminate_apps_by_pkgid(info->pkgid, info->target_uid);
-}
-
-static void __unset_blocking(struct pkg_event_info *info, bool restart)
-{
- uid_t *uids = NULL;
- int r;
- int i;
-
- if (info->target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++) {
- if (restart) {
- info->uid = uids[i];
- _appinfo_foreach(uids[i],
- __appinfo_restart_cb, info);
- } else {
- _appinfo_foreach(uids[i],
- __appinfo_unset_blocking_cb,
- info);
- }
- }
- free(uids);
-
- return;
- }
-
- if (restart) {
- info->uid = info->target_uid;
- _appinfo_foreach(info->target_uid,
- __appinfo_restart_cb, info);
- } else {
- _appinfo_foreach(info->target_uid,
- __appinfo_unset_blocking_cb, info);
- }
-}
-
-static void __delete_on_event(struct pkg_event_info *info)
-{
- uid_t *uids = NULL;
- int r;
- int i;
-
- if (info->target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++)
- __appinfo_delete_on_event(uids[i], info);
- free(uids);
-
- return;
- }
-
- __appinfo_delete_on_event(info->target_uid, info);
-}
-
-static void __insert_on_event(struct pkg_event_info *info)
-{
- uid_t *uids = NULL;
- int r;
- int i;
-
- if (info->target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++)
- __appinfo_insert_on_event(uids[i], info->pkgid);
- free(uids);
-
- return;
- }
-
- __appinfo_insert_on_event(info->target_uid, info->pkgid);
-}
-
-static void __update_on_event(struct pkg_event_info *info)
-{
- uid_t *uids = NULL;
- int r;
- int i;
-
- if (info->target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++)
- __appinfo_update_on_event(uids[i], info);
- free(uids);
-
- return;
- }
-
- __appinfo_update_on_event(info->target_uid, info);
-}
-
-static int __appinfo_is_pkg_exist(uid_t uid, const char *pkgid)
-{
- int r;
- struct user_appinfo *info;
- GHashTableIter iter;
- gpointer key;
- gpointer value;
- uid_t *uids = NULL;
- struct appinfo *ai;
-
- if (pkgid == NULL)
- return 0;
-
- if (uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return 0;
-
- uid = uids[0];
-
- free(uids);
- }
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("cannot find appinfo for uid %d", uid);
- return 0;
- }
-
- g_hash_table_iter_init(&iter, info->tbl);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- ai = (struct appinfo *)value;
- if (strcmp(pkgid, ai->val[AIT_PKGID]) == 0)
- return 1;
- }
-
- return 0;
-}
-
-static void __appinfo_enable_pkg_apps(uid_t uid, const char *pkgid, int enable)
-{
- int r;
- int i;
- struct user_appinfo *info;
- GHashTableIter iter;
- gpointer key;
- gpointer value;
- uid_t *uids = NULL;
- struct appinfo *ai;
- int prev_val;
- const char *appid;
-
- if (pkgid == NULL)
- return;
-
- if (uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return;
-
- for (i = 0; i < r; i++)
- __appinfo_enable_pkg_apps(uids[i], pkgid, enable);
-
- free(uids);
-
- return;
- }
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("cannot find appinfo for uid %d", uid);
- return;
- }
-
- g_hash_table_iter_init(&iter, info->tbl);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- ai = (struct appinfo *)value;
- if (strcmp(pkgid, ai->val[AIT_PKGID]) == 0) {
- _appinfo_get_int_value(ai, AIT_ENABLEMENT, &prev_val);
- _appinfo_set_int_value(ai, AIT_ENABLEMENT, enable);
- if (prev_val == 0 && enable == 1) {
- appid = _appinfo_get_value(ai, AIT_NAME);
- _launch_start_onboot_app_local(uid, appid, ai);
- }
- }
- }
-}
-
-static int __package_event_cb(uid_t target_uid, int req_id,
- const char *pkg_type, const char *pkgid,
- const char *key, const char *val, const void *pmsg, void *data)
-{
- int ret;
- char *op;
- struct pkg_event_info info = {
- .target_uid = target_uid,
- .pkgid = pkgid
- };
- pkgmgrinfo_pkginfo_h pkginfo;
-
- if (!strcasecmp(key, "start")) {
- if (!strcasecmp(val, "uninstall") ||
- !strcasecmp(val, "update") ||
- !strcasecmp(val, "move")) {
- _W("[__PKGMGR__] Package(%s) event(%s) - start",
- pkgid, val);
- __set_blocking(&info);
- }
-
- g_hash_table_insert(pkg_pending, strdup(pkgid), strdup(val));
- }
-
- if (!strcasecmp(key, "error")) {
- op = g_hash_table_lookup(pkg_pending, pkgid);
- if (op == NULL)
- return 0;
-
- if (!strcasecmp(op, "uninstall") ||
- !strcasecmp(op, "update") ||
- !strcasecmp(op, "move")) {
- _W("[__PKGMGR__] Package(%s) event(%s) - error",
- pkgid, val);
- __unset_blocking(&info, true);
- _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
- target_uid, 0, (void *)pkgid, NULL);
- }
-
- g_hash_table_remove(pkg_pending, pkgid);
- }
-
- if (!strcasecmp(key, "end")) {
- _W("[__PKGMGR__] Package(%s) event(%s) - end", pkgid, val);
- op = g_hash_table_lookup(pkg_pending, pkgid);
- if (op == NULL)
- return 0;
-
- if (!strcasecmp(op, "uninstall")) {
- ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(
- info.pkgid, info.target_uid,
- &pkginfo);
- if (ret == PMINFO_R_OK) {
- pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
- __unset_blocking(&info, false);
- __appinfo_enable_pkg_apps(info.target_uid,
- info.pkgid, 0);
- } else {
- __delete_on_event(&info);
- }
- _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END,
- target_uid, 0, (void *)pkgid, NULL);
- } else if (!strcasecmp(op, "install")) {
- if (!__appinfo_is_pkg_exist(
- info.target_uid,
- info.pkgid)) {
- __insert_on_event(&info);
- } else {
- __unset_blocking(&info, false);
- __appinfo_enable_pkg_apps(info.target_uid,
- info.pkgid, 1);
- }
- _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END,
- target_uid, 0, (void *)pkgid, NULL);
- } else if (!strcasecmp(op, "update") ||
- !strcasecmp(op, "move")) {
- __update_on_event(&info);
- _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
- target_uid, 0, (void *)pkgid, NULL);
- }
-
- g_hash_table_remove(pkg_pending, pkgid);
- }
-
- return 0;
-}
-
-static void __add_app_event_info(int req_id, int type, uid_t uid)
-{
- struct app_event_info *info;
-
- info = (struct app_event_info *)malloc(sizeof(struct app_event_info));
- if (info == NULL) {
- _E("Out of memory");
- return;
- }
-
- info->req_id = req_id;
- info->type = type;
- info->uid = uid;
-
- app_event_list = g_list_append(app_event_list, (gpointer)info);
-}
-
-static struct app_event_info *__find_app_event_info(int req_id, uid_t uid)
-{
- GList *iter;
- struct app_event_info *info;
-
- iter = g_list_first(app_event_list);
- while (iter) {
- info = (struct app_event_info *)iter->data;
- if (info && info->req_id == req_id && info->uid == uid)
- return info;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static void __remove_app_event_info(struct app_event_info *info)
-{
- if (info == NULL)
- return;
-
- app_event_list = g_list_remove(app_event_list, info);
- free(info);
-}
-
-static void __handle_app_event_start(const char *event_name,
- struct appinfo *ai, const char *appid, int req_id, uid_t uid)
-{
- int old = 0;
-
- if (!strcasecmp(event_name, "enable_global_app_for_uid") ||
- !strcasecmp(event_name, "enable_app")) {
- if (ai) {
- _appinfo_get_int_value(ai, AIT_ENABLEMENT, &old);
- old |= APP_ENABLEMENT_MASK_REQUEST;
- _appinfo_set_int_value(ai, AIT_ENABLEMENT, old);
- }
- __add_app_event_info(req_id, AIT_ENABLEMENT, uid);
- } else if (!strcasecmp(event_name, "disable_global_app_for_uid") ||
- !strcasecmp(event_name, "disable_app")) {
- __add_app_event_info(req_id, AIT_ENABLEMENT, uid);
- } else if (!strcasecmp(event_name, "enable_app_splash_screen")) {
- if (ai) {
- _appinfo_get_int_value(ai, AIT_SPLASH_SCREEN_DISPLAY,
- &old);
- old |= APP_ENABLEMENT_MASK_REQUEST;
- _appinfo_set_int_value(ai, AIT_SPLASH_SCREEN_DISPLAY,
- old);
- }
- __add_app_event_info(req_id, AIT_SPLASH_SCREEN_DISPLAY, uid);
- } else if (!strcasecmp(event_name, "disable_app_splash_screen")) {
- __add_app_event_info(req_id, AIT_SPLASH_SCREEN_DISPLAY, uid);
- }
-}
-
-static void __handle_app_event_end(const char *event_name,
- struct appinfo *ai, const char *appid, int req_id, uid_t uid)
-{
- pkgmgrinfo_appinfo_h handle;
- struct user_appinfo *info;
- struct app_event_info *ei;
- int old = 0;
- int r;
-
- ei = __find_app_event_info(req_id, uid);
- if (ei == NULL)
- return;
-
- if (!strcasecmp(event_name, "ok")) {
- if (ei->type == AIT_ENABLEMENT) {
- if (ai) {
- _appinfo_get_int_value(ai, ei->type, &old);
- old >>= 1;
- _appinfo_set_int_value(ai, ei->type, old);
- } else {
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("Failed to load appinfo(%d)", uid);
- __remove_app_event_info(ei);
- return;
- }
-
- r = pkgmgrinfo_appinfo_get_usr_appinfo(appid,
- uid, &handle);
- if (r != PMINFO_R_OK) {
- _E("Failed to get appinfo(%s)", appid);
- __remove_app_event_info(ei);
- return;
- }
-
- _I("add the new appinfo(%s)", appid);
- __insert_appinfo(handle, info);
- pkgmgrinfo_appinfo_destroy_appinfo(handle);
- __remove_app_event_info(ei);
- _noti_send(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
- uid, 0, (void *)appid, NULL);
- return;
- }
-
- if (!(old & APP_ENABLEMENT_MASK_ACTIVE)) {
- _E("terminate apps: %s(%d)", appid, uid);
- _app_status_terminate_apps(appid, uid);
- _noti_send(AMD_NOTI_MSG_APPINFO_APP_DISABLED_END,
- uid, 0, (void *)appid, NULL);
- } else if (old & APP_ENABLEMENT_MASK_ACTIVE) {
- _launch_start_onboot_app_local(uid, appid, ai);
- _noti_send(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
- uid, 0, (void *)appid, NULL);
- }
- } else if (ei->type == AIT_SPLASH_SCREEN_DISPLAY) {
- if (ai) {
- _appinfo_get_int_value(ai, ei->type, &old);
- old >>= 1;
- _appinfo_set_int_value(ai, ei->type, old);
- }
- }
- } else if (!strcasecmp(event_name, "fail")) {
- if (ei->type == AIT_ENABLEMENT ||
- ei->type == AIT_SPLASH_SCREEN_DISPLAY) {
- if (ai) {
- _appinfo_get_int_value(ai, ei->type, &old);
- old &= APP_ENABLEMENT_MASK_ACTIVE;
- _appinfo_set_int_value(ai, ei->type, old);
- }
- }
- }
- __remove_app_event_info(ei);
-}
-
-static int __package_app_event_cb(uid_t target_uid, int req_id,
- const char *pkg_type, const char *pkgid, const char *appid,
- const char *key, const char *val, const void *pmsg, void *data)
-{
- struct appinfo *ai;
- uid_t *uids = NULL;
- int r;
- int i;
-
- _D("appid:%s, key:%s, val:%s, req_id: %d, target_uid: %d",
- appid, key, val, req_id, target_uid);
- if (target_uid < REGULAR_UID_MIN) {
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return 0;
- } else {
- r = 1;
- }
-
- for (i = 0; i < r; i++) {
- if (uids)
- target_uid = uids[i];
- ai = _appinfo_find(target_uid, appid);
-
- if (!strcasecmp(key, "start")) {
- __handle_app_event_start(val, ai, appid, req_id,
- target_uid);
- } else if (!strcasecmp(key, "end")) {
- __handle_app_event_end(val, ai, appid, req_id,
- target_uid);
- }
- }
-
- free(uids);
- return 0;
-}
-
-static int __init_package_event_handler(void *data)
-{
- int ret;
-
- pc = pkgmgr_client_new(PC_LISTENING);
- if (pc == NULL)
- return -1;
-
- ret = pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_ALL);
- if (ret < 0)
- return -1;
-
- ret = pkgmgr_client_listen_status(pc, __package_event_cb, NULL);
- if (ret < 0)
- return -1;
-
- ret = pkgmgr_client_listen_app_status(pc, __package_app_event_cb, NULL);
- if (ret < 0)
- return -1;
-
- _W("[__PKGMGR__] Package event handler is initialized");
- return 0;
-}
-
-static void __fini_package_event_handler(void)
-{
- pkgmgr_client_free(pc);
-}
-
-static void __reload_appinfo(gpointer key, gpointer value, gpointer user_data)
-{
- int r;
- struct user_appinfo *info = (struct user_appinfo *)value;
-
- g_hash_table_remove_all(info->tbl);
-
- r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
- __appinfo_insert_handler, info->uid,
- PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
- if (r != PMINFO_R_OK) {
- __remove_user_appinfo(info->uid);
- return;
- }
-
- _noti_send(AMD_NOTI_MSG_APPINFO_RELOAD, (int)info->uid, 0, NULL, NULL);
- _D("reloaded appinfo table for uid %d", info->uid);
-}
-
-static int __dispatch_amd_reload_appinfo(request_h req)
-{
- _D("AMD_RELOAD_APPINFO");
- g_hash_table_foreach(user_tbl, __reload_appinfo, NULL);
- _request_send_result(req, 0);
-
- return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = AMD_RELOAD_APPINFO,
- .callback = __dispatch_amd_reload_appinfo
- },
-};
-
-int _appinfo_init(void)
-{
- FILE *fp;
- char buf[LINE_MAX];
- char *tmp;
- int r;
-
- fp = fopen("/proc/cmdline", "r");
- if (fp == NULL) {
- _E("appinfo init failed: %d", errno);
- return -1;
- }
-
- if (fgets(buf, sizeof(buf), fp) != NULL) {
- tmp = strstr(buf, "gles");
- if (tmp != NULL) {
- if (sscanf(tmp, "gles=%d", &gles) != 1)
- _D("Failed to convert format");
- }
- }
- fclose(fp);
-
- user_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
- __free_user_appinfo);
- if (user_tbl == NULL)
- return -1;
-
- pkg_pending = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, free);
- if (pkg_pending == NULL)
- return -1;
-
- _signal_add_ready_cb(__init_package_event_handler, NULL);
-
- r = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- return 0;
-}
-
-void _appinfo_fini(void)
-{
- __fini_package_event_handler();
- g_hash_table_destroy(user_tbl);
- g_hash_table_destroy(pkg_pending);
-}
-
-struct appinfo *_appinfo_find(uid_t caller_uid, const char *appid)
-{
- struct user_appinfo *info;
-
- if (appid == NULL) {
- _W("appid is NULL");
- return NULL;
- }
-
- /* search from user table */
- info = __find_user_appinfo(caller_uid);
- if (info == NULL)
- return NULL;
-
- return g_hash_table_lookup(info->tbl, appid);
-}
-
-int _appinfo_insert(uid_t uid, const char *pkgid)
-{
- int ret;
- struct user_appinfo *info;
- pkgmgrinfo_pkginfo_h handle;
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _E("load appinfo for uid %d failed", uid);
- return -1;
- }
-
- ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
- if (ret != PMINFO_R_OK) {
- _E("get pkginfo failed: %s", pkgid);
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
- __insert_appinfo, info, info->uid);
- if (ret != PMINFO_R_OK) {
- _E("add appinfo of pkg %s failed", pkgid);
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return -1;
- }
-
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-
- return 0;
-}
-
-const char *_appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
-{
- if (!c) {
- _E("Invalid parameter");
- return NULL;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return NULL;
-
- return c->val[type];
-}
-
-const void *_appinfo_get_ptr_value(const struct appinfo *c,
- enum appinfo_type type)
-{
- if (!c) {
- _E("Invalid parameter");
- return NULL;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return NULL;
-
- return c->val[type];
-}
-
-int _appinfo_get_int_value(const struct appinfo *c, enum appinfo_type type,
- int *val)
-{
- if (!c) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return -1;
-
- *val = GPOINTER_TO_INT(c->val[type]);
-
- return 0;
-}
-
-int _appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type,
- bool *val)
-{
- if (!c || type < AIT_START || type >= AIT_MAX || c->val[type] == NULL) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (!strcmp(c->val[type], "true") || !strcmp(c->val[type], "1")) {
- *val = true;
- } else if (!strcmp(c->val[type], "false") ||
- !strcmp(c->val[type], "0")) {
- *val = false;
- } else {
- _E("Unexpected appinfo field value");
- return -1;
- }
-
- return 0;
-}
-
-int _appinfo_set_value(struct appinfo *c, enum appinfo_type type,
- const char *val)
-{
- if (!c || !val) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return -1;
-
- _D("%s : %s : %s", c->val[AIT_NAME], c->val[type], val);
- if (c->val[type])
- free(c->val[type]);
-
- c->val[type] = strdup(val);
- if (c->val[type] == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-int _appinfo_set_ptr_value(struct appinfo *c, enum appinfo_type type, void *val)
-{
- if (!c || !val) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return -1;
-
- _D("%s : %p : %p", c->val[AIT_NAME], c->val[type], val);
- if (appinfo_table[type].destructor && c->val[type] != NULL)
- appinfo_table[type].destructor(c->val[type]);
-
- c->val[type] = (char *)val;
- return 0;
-}
-
-int _appinfo_set_int_value(struct appinfo *c, enum appinfo_type type, int val)
-{
- if (!c) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (type < AIT_START || type >= AIT_MAX)
- return -1;
-
- _D("%s : %p : %d", c->val[AIT_NAME], c->val[type], val);
-
- c->val[type] = (char *)GINT_TO_POINTER(val);
- return 0;
-}
-
-static void __iter_cb(gpointer key, gpointer value, gpointer user_data)
-{
- struct callback_info *cb_info = user_data;
-
- if (cb_info == NULL)
- return;
-
- cb_info->cb(cb_info->user_data, key, value);
-}
-
-void _appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data)
-{
- struct user_appinfo *info;
- struct callback_info cb_info = {
- .cb = cb,
- .user_data = user_data
- };
-
- if (!cb) {
- _E("Invalid parameter");
- return;
- }
-
- info = __find_user_appinfo(uid);
- if (info == NULL)
- return;
-
- g_hash_table_foreach(info->tbl, __iter_cb, &cb_info);
-}
-
-int _appinfo_load(uid_t uid)
-{
- struct user_appinfo *info;
-
- info = __find_user_appinfo(uid);
- if (info) {
- _D("%d appinfo already exists", uid);
- return 0;
- }
-
- info = __add_user_appinfo(uid);
- if (info == NULL) {
- _W("Failed to load appinfo - %d", uid);
- return -1;
- }
-
- _noti_send(AMD_NOTI_MSG_APPINFO_LOAD, (int)uid, 0, NULL, NULL);
- _D("loaded appinfo table for uid(%d)", uid);
- return 0;
-}
-
-void _appinfo_unload(uid_t uid)
-{
- struct user_appinfo *info;
-
- info = __find_user_appinfo(uid);
- if (info == NULL) {
- _D("%d appinfo doesn't exist", uid);
- return;
- }
-
- __remove_user_appinfo(uid);
- _noti_send(AMD_NOTI_MSG_APPINFO_UNLOAD, (int)uid, 0, NULL, NULL);
- _D("unloaded appinfo table for uid(%d)", uid);
-}
-
-struct appinfo_splash_image *_appinfo_find_splash_image(struct appinfo *c,
- const char *name, bool landscape)
-{
- struct appinfo_splash_screen *splash_screen;
-
- if (!c || !name) {
- _E("Invalid parameter");
- return NULL;
- }
-
- splash_screen = (struct appinfo_splash_screen *)_appinfo_get_value(c,
- AIT_SPLASH_SCREEN);
- if (!splash_screen)
- return NULL;
-
- if (landscape)
- return g_hash_table_lookup(splash_screen->landscape, name);
-
- return g_hash_table_lookup(splash_screen->portrait, name);
-}
-
-const char *_appinfo_splash_image_get_source(struct appinfo_splash_image *s)
-{
- if (!s) {
- _E("Invalid parameter");
- return NULL;
- }
-
- return s->src;
-}
-
-const char *_appinfo_splash_image_get_type(struct appinfo_splash_image *s)
-{
- if (!s) {
- _E("Invalid paramter");
- return NULL;
- }
-
- return s->type;
-}
-
-int _appinfo_splash_image_get_indicator_display(struct appinfo_splash_image *s)
-{
- if (!s) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (!strcmp(s->indicatordisplay, "true"))
- return 1;
-
- return 0;
-}
-
-int _appinfo_splash_image_get_color_depth(struct appinfo_splash_image *s)
-{
- int color_depth = 24; /* default */
-
- if (!s) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (isdigit(s->color_depth[0]))
- color_depth = atoi(s->color_depth);
-
- return color_depth;
-}
-
-bool _appinfo_is_pkg_updating(const char *pkgid)
-{
- char *op;
-
- if (pkg_pending == NULL)
- return false;
-
- op = g_hash_table_lookup(pkg_pending, pkgid);
- if (op != NULL && !strcasecmp(op, "update"))
- return true;
-
- return false;
-}
-
-static char *__get_cert_value_from_pkginfo(const char *pkgid, uid_t uid)
-{
- int ret;
- const char *cert_value;
- char *ret_cert;
- pkgmgrinfo_certinfo_h certinfo;
-
- ret = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
- if (ret != PMINFO_R_OK) {
- _E("Failed to create certinfo");
- return NULL;
- }
-
- ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
- if (ret != PMINFO_R_OK) {
- _E("Failed to load certinfo");
- pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
- return NULL;
- }
-
- ret = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
- PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
- if (ret != PMINFO_R_OK || cert_value == NULL) {
- _E("Failed to get cert value");
- pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
- return NULL;
- }
-
- ret_cert = strdup(cert_value);
- pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
-
- return ret_cert;
-}
-
-static int __get_visibility_from_certsvc(const char *cert_value)
-{
- int ret;
- CertSvcInstance instance;
- CertSvcCertificate certificate;
- CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
-
- if (cert_value == NULL)
- return (int)visibility;
-
- ret = certsvc_instance_new(&instance);
- if (ret != CERTSVC_SUCCESS) {
- _E("certsvc_instance_new() is failed.");
- return (int)visibility;
- }
-
- ret = certsvc_certificate_new_from_memory(instance,
- (const unsigned char *)cert_value,
- strlen(cert_value),
- CERTSVC_FORM_DER_BASE64,
- &certificate);
- if (ret != CERTSVC_SUCCESS) {
- _E("certsvc_certificate_new_from_memory() is failed.");
- certsvc_instance_free(instance);
- return (int)visibility;
- }
-
- ret = certsvc_certificate_get_visibility(certificate, &visibility);
- if (ret != CERTSVC_SUCCESS)
- _E("certsvc_certificate_get_visibility() is failed.");
-
- certsvc_certificate_free(certificate);
- certsvc_instance_free(instance);
-
- return (int)visibility;
-}
-
-int _appinfo_get_cert_visibility(const char *pkgid, uid_t uid)
-{
- char *cert_value;
- int r;
-
- cert_value = __get_cert_value_from_pkginfo(pkgid, uid);
- r = __get_visibility_from_certsvc(cert_value);
-
- if (cert_value)
- free(cert_value);
-
- return r;
-}
-
-bool _appinfo_is_platform_app(const char *appid, uid_t uid)
-{
- struct appinfo *ai;
- const char *pkgid;
- const char *v;
- int vi_num;
- int visibility;
- char num[12];
-
- ai = _appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- v = _appinfo_get_value(ai, AIT_VISIBILITY);
- if (!v) {
- pkgid = _appinfo_get_value(ai, AIT_PKGID);
- vi_num = _appinfo_get_cert_visibility(pkgid, uid);
- snprintf(num, sizeof(num), "%d", vi_num);
- _appinfo_set_value(ai, AIT_VISIBILITY, num);
- v = num;
- }
-
- visibility = atoi(v);
- if (visibility & CERTSVC_VISIBILITY_PLATFORM)
- return true;
-
- return false;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#include "amd_app_property.h"
-#include "amd_app_status.h"
-#include "amd_appinfo.h"
-#include "amd_boot_manager.h"
-#include "amd_config.h"
-#include "amd_launch.h"
-#include "amd_signal.h"
-#include "amd_util.h"
-#include "app_signal.h"
-
-#define METADATA_KEY_ONBOOT_PRIORITY \
- "http://tizen.org/metadata/on-boot/priority"
-#define MIN_PRIORITY 1
-#define MAX_PRIORITY 99
-
-struct onboot_appinfo_s {
- char *app_id;
- uid_t uid;
- int priority;
-};
-
-static GList *__onboot_list;
-
-static void __destroy_onboot_appinfo(gpointer data)
-{
- struct onboot_appinfo_s *info = data;
-
- if (!info)
- return;
-
- free(info->app_id);
- free(info);
-}
-
-static struct onboot_appinfo_s *__create_onboot_appinfo(const char *app_id,
- uid_t uid, int priority)
-{
- struct onboot_appinfo_s *info;
-
- info = calloc(1, sizeof(struct onboot_appinfo_s));
- if (!info) {
- _E("Out of memory");
- return NULL;
- }
-
- info->app_id = strdup(app_id);
- if (!info->app_id) {
- _E("Failed to duplicate application ID(%s)", app_id);
- __destroy_onboot_appinfo(info);
- return NULL;
- }
-
- info->uid = uid;
- info->priority = priority;
-
- return info;
-}
-
-static gboolean __unlock_display_state(gpointer data)
-{
- _W("Unlock display state");
- _signal_send_display_unlock_state(SYSTEM_LCD_OFF, SYSTEM_SLEEP_MARGIN);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean __delay_start_onboot_apps(gpointer data)
-{
- struct onboot_appinfo_s *info = data;
- app_status_h app_status;
- int pid = -1;
-
- if (!info) {
- _E("Critical error!");
- return G_SOURCE_REMOVE;
- }
-
- app_status = _app_status_find_by_appid(info->app_id, info->uid);
- if (app_status)
- pid = _app_status_is_running(app_status);
-
- if (pid < 0)
- pid = _launch_start_app_local(info->uid, info->app_id);
-
- _W("app_id(%s), pid(%d), uid(%u), priority(%d)",
- info->app_id, pid, info->uid, info->priority);
- __destroy_onboot_appinfo(info);
-
- return G_SOURCE_REMOVE;
-}
-
-static gint __compare_priority(gconstpointer a, gconstpointer b)
-{
- struct onboot_appinfo_s *info_a = (struct onboot_appinfo_s *)a;
- struct onboot_appinfo_s *info_b = (struct onboot_appinfo_s *)b;
-
- if (info_a->priority < info_b->priority)
- return 1;
-
- if (info_a->priority > info_b->priority)
- return -1;
-
- return 0;
-}
-
-static int __metadata_foreach_cb(const char *value, void *user_data)
-{
- int *priority = (int *)user_data;
-
- if (!value)
- return 0;
-
- *priority = atoi(value);
- return -1;
-}
-
-static int __get_priority(const char *app_id, uid_t uid)
-{
- app_property_h app_property;
- int priority = MIN_PRIORITY;
-
- app_property = _app_property_find(uid);
- if (!app_property)
- return priority;
-
- _app_property_metadata_foreach(app_property, app_id,
- METADATA_KEY_ONBOOT_PRIORITY,
- __metadata_foreach_cb,
- (void *)&priority);
-
- if (priority < MIN_PRIORITY)
- priority = MIN_PRIORITY;
- else if (priority > MAX_PRIORITY)
- priority = MAX_PRIORITY;
-
- return priority;
-}
-
-static bool __appinfo_check_onboot_cond(struct appinfo *ai)
-{
- const char *comp_type;
- const char *onboot;
-
- comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp_type == NULL || strcmp(comp_type, APP_TYPE_SERVICE) != 0)
- return false;
-
- onboot = _appinfo_get_value(ai, AIT_ONBOOT);
- if (onboot == NULL || strcmp(onboot, "true") != 0)
- return false;
-
- return true;
-}
-
-static void __appinfo_foreach_cb(void *data, const char *app_id,
- struct appinfo *ai)
-{
- uid_t uid = GPOINTER_TO_UINT(data);
- app_status_h app_status;
- struct onboot_appinfo_s *info;
- int priority;
-
- if (!__appinfo_check_onboot_cond(ai))
- return;
-
- app_status = _app_status_find_by_appid(app_id, uid);
- if (_app_status_is_running(app_status) > 0)
- return;
-
- priority = __get_priority(app_id, uid);
- info = __create_onboot_appinfo(app_id, uid, priority);
- if (!info)
- return;
-
- __onboot_list = g_list_append(__onboot_list, info);
-}
-
-static gboolean __load_onboot_apps(gpointer data)
-{
-#define MAX_ONBOOT_INTERVAL 18000
- GList *iter;
- guint d = 0;
- guint i = 0;
- guint idle_interval;
- guint interval = 0;
- guint len;
- guint max_len;
- struct onboot_appinfo_s *info;
- uid_t uid = GPOINTER_TO_UINT(data);
-
- _W("Onboot uid(%u)", uid);
- _appinfo_foreach(uid, __appinfo_foreach_cb, data);
-
- if (!__onboot_list) {
- _signal_send_display_unlock_state(SYSTEM_LCD_OFF,
- SYSTEM_SLEEP_MARGIN);
- return G_SOURCE_REMOVE;
- }
-
- __onboot_list = g_list_sort(__onboot_list, __compare_priority);
-
- idle_interval = MAX_ONBOOT_INTERVAL - _config_get_onboot_interval();
-
- max_len = idle_interval / _config_get_onboot_interval();
- len = g_list_length(__onboot_list);
- if (len > max_len)
- d = _config_get_onboot_interval() / (len - max_len);
-
- iter = __onboot_list;
- while (iter) {
- info = (struct onboot_appinfo_s *)iter->data;
- iter = g_list_next(iter);
-
- if (interval >= idle_interval)
- interval += d;
- else
- interval = _config_get_onboot_interval() * i++;
-
- g_timeout_add(interval, __delay_start_onboot_apps, info);
- __onboot_list = g_list_remove(__onboot_list, info);
- if (!__onboot_list) {
- g_timeout_add(interval + 5000, __unlock_display_state,
- NULL);
- }
- }
-
- return G_SOURCE_REMOVE;
-}
-
-int _boot_manager_start_onboot_apps(uid_t uid)
-{
- _I("Lock display state");
- _signal_send_display_lock_state(SYSTEM_LCD_OFF,
- SYSTEM_STAY_CUR_STATE, 0);
- g_idle_add(__load_onboot_apps, GUINT_TO_POINTER(uid));
-
- return 0;
-}
-
-int _boot_manager_init(void)
-{
- int ret;
-
- _W("AMD_BOOT_MANAGER_INIT");
-
- ret = _app_property_metadata_add_filter(METADATA_KEY_ONBOOT_PRIORITY,
- NULL);
- if (ret < 0) {
- _E("Failed to add metadata filter");
- return -1;
- }
-
- return 0;
-}
-
-void _boot_manager_fini(void)
-{
- _W("AMD_BOOT_MANAGER_FINI");
- if (__onboot_list)
- g_list_free_full(__onboot_list, __destroy_onboot_appinfo);
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <uuid/uuid.h>
-
-#include <glib.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-
-#include "amd_api_noti.h"
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_request.h"
-#include "amd_noti.h"
-#include "amd_compinfo.h"
-#include "amd_comp_status.h"
-#include "amd_socket.h"
-#include "amd_app_status.h"
-#include "amd_launch.h"
-#include "amd_cynara.h"
-
-struct comp_status_s {
- char *comp_id;
- char *instance_id;
- char *leader_instance_id;
- pid_t pid;
- int comp_type;
- int window;
- int status;
- bool is_subcomp;
- bool started;
-};
-
-static GList *__comp_list;
-
-const char *_comp_status_generate_instance(const char *comp_id)
-{
- static char buf[MAX_PACKAGE_STR_SIZE];
- char uuid[37];
- uuid_t u;
-
- if (!comp_id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- uuid_generate(u);
- uuid_unparse(u, uuid);
- snprintf(buf, sizeof(buf), "%s:%s", uuid, comp_id);
- return buf;
-}
-
-static void __destroy_comp_status(gpointer data)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)data;
-
- if (!comp_status)
- return;
-
- if (comp_status->instance_id)
- free(comp_status->instance_id);
- if (comp_status->comp_id)
- free(comp_status->comp_id);
- free(comp_status);
-}
-
-static int __convert_comp_type(const char *type)
-{
- if (!type)
- return -1;
-
- if (!strcmp(type, "frame"))
- return CT_FRAME_COMP;
- else if (!strcmp(type, "service"))
- return CT_SERVICE_COMP;
-
- return -1;
-}
-
-static const char *__get_comp_type_string(int comp_type)
-{
- switch (comp_type) {
- case CT_FRAME_COMP:
- return "frame";
- case CT_SERVICE_COMP:
- return "service";
- default:
- return "Unknown";
- }
-}
-
-static struct comp_status_s *__create_comp_status(compinfo_h ci,
- const char *instance_id, pid_t pid, bool is_subcomp)
-{
- struct comp_status_s *comp_status;
- const char *comp_id;
- const char *type;
-
- comp_status = calloc(1, sizeof(struct comp_status_s));
- if (!comp_status) {
- _E("Out of memory");
- return NULL;
- }
-
- comp_id = _compinfo_get_value(ci, CIT_NAME);
- if (!comp_id) {
- _E("Failed to get component ID");
- free(comp_status);
- return NULL;
- }
-
- comp_status->comp_id = strdup(comp_id);
- if (!comp_status->comp_id) {
- _E("Failed to duplicate component ID(%s)", comp_id);
- __destroy_comp_status(comp_status);
- return NULL;
- }
-
- comp_status->instance_id = strdup(instance_id);
- if (!comp_status->instance_id) {
- _E("Failed to duplicate instance ID(%s)", instance_id);
- __destroy_comp_status(comp_status);
- return NULL;
- }
-
- comp_status->pid = pid;
- comp_status->is_subcomp = is_subcomp;
- comp_status->started = false;
-
- type = _compinfo_get_value(ci, CIT_TYPE);
- comp_status->comp_type = __convert_comp_type(type);
- comp_status->status = COMP_STATUS_INITIALIZED;
-
- return comp_status;
-}
-
-static gint __compare_window(gconstpointer a, gconstpointer b)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)a;
- int window = GPOINTER_TO_INT(b);
-
- return (comp_status->window != window);
-}
-
-static gint __compare_instance(gconstpointer a, gconstpointer b)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)a;
- const char *instance_id = (const char *)b;
-
- return strcmp(comp_status->instance_id, instance_id);
-}
-
-int _comp_status_add_comp_info(compinfo_h ci, pid_t pid,
- const char *instance_id, bool is_subcomp)
-{
- struct comp_status_s *comp_status;
- GList *found;
-
- if (!ci || pid < 0 || !instance_id)
- return -1;
-
- found = g_list_find_custom(__comp_list, instance_id,
- __compare_instance);
- if (found) {
- _D("Already exists. %d:%s", pid, instance_id);
- return 0;
- }
-
- comp_status = __create_comp_status(ci, instance_id, pid, is_subcomp);
- if (!comp_status) {
- _E("Failed to create component status. %d:%s",
- pid, instance_id);
- return -1;
- }
-
- __comp_list = g_list_append(__comp_list, comp_status);
-
- _noti_send(AMD_NOTI_MSG_COMP_STATUS_ADD, 0, 0, (void *)comp_status, NULL);
-
- return 0;
-}
-
-comp_status_h _comp_status_find(const char *comp_id)
-{
- struct comp_status_s *comp_status;
- GList *iter;
-
- if (!comp_id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- iter = __comp_list;
- while (iter) {
- comp_status = (struct comp_status_s *)iter->data;
- if (!comp_status->is_subcomp &&
- !strcmp(comp_status->comp_id, comp_id))
- return comp_status;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-comp_status_h _comp_status_find_by_instance_id(const char *instance_id)
-{
- GList *found;
-
- if (!instance_id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- found = g_list_find_custom(__comp_list, instance_id,
- __compare_instance);
- if (!found)
- return NULL;
-
- return found->data;
-}
-
-comp_status_h _comp_status_find_by_window(int window)
-{
- GList *found;
-
- if (window <= 0) {
- _E("Invalid parameter");
- return NULL;
- }
-
- found = g_list_find_custom(__comp_list, GINT_TO_POINTER(window),
- __compare_window);
- if (!found)
- return NULL;
-
- return found->data;
-}
-
-comp_status_h _comp_status_find_v2(pid_t pid, const char *instance_id)
-{
- struct comp_status_s *comp_status;
- pid_t pgid;
-
- comp_status = _comp_status_find_by_instance_id(instance_id);
- if (!comp_status)
- return NULL;
-
- if (comp_status->pid != pid) {
- pgid = getpgid(pid);
- if (comp_status->pid == pgid) {
- _E("Process ID(%d:%d) is not equal to %d",
- pid, pgid, comp_status->pid);
- return NULL;
- }
- }
-
- return comp_status;
-}
-
-pid_t _comp_status_get_pid(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return -1;
-
- return comp_status->pid;
-}
-
-const char *_comp_status_get_comp_id(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return NULL;
-
- return comp_status->comp_id;
-}
-
-const char *_comp_status_get_instance_id(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return NULL;
-
- return comp_status->instance_id;
-}
-
-int _comp_status_set_leader_id(comp_status_h h, const char *instance_id)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status || instance_id == NULL)
- return -1;
-
- if (comp_status->leader_instance_id) {
- free(comp_status->leader_instance_id);
- comp_status->leader_instance_id = NULL;
- }
-
- comp_status->leader_instance_id = strdup(instance_id);
- if (comp_status->leader_instance_id == NULL) {
- _E("Fail to dup id");
- return -1;
- }
-
- return 0;
-}
-
-int _comp_status_set_window(comp_status_h h, int window)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return -1;
-
- if (window <= 0)
- return -1;
-
- comp_status->window = window;
-
- return 0;
-}
-
-const char *_comp_status_get_leader_id(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return NULL;
-
- return comp_status->leader_instance_id;
-}
-
-int _comp_status_get_comp_type(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return -1;
-
- return comp_status->comp_type;
-}
-
-int _comp_status_get_status(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return -1;
-
- return comp_status->status;
-}
-
-bool _comp_status_is_running(comp_status_h h)
-{
- struct comp_status_s *comp_status = (struct comp_status_s *)h;
-
- if (!comp_status)
- return false;
-
- if (comp_status->status == COMP_STATUS_DESTROYED)
- return false;
-
- return true;
-}
-
-static int __on_main_app_dead(const char *msg, int arg1, int arg2, void *arg3,
- bundle *b)
-{
- struct comp_status_s *comp_status;
- pid_t pid = (pid_t)arg1;
- GList *iter;
-
- iter = __comp_list;
- while (iter) {
- comp_status = (struct comp_status_s *)iter->data;
- iter = g_list_next(iter);
- if (comp_status->pid == pid) {
- __comp_list = g_list_remove(__comp_list, comp_status);
- __destroy_comp_status(comp_status);
- }
- }
-
- return NOTI_CONTINUE;
-}
-
-static int __dispatch_comp_notify_start(request_h req)
-{
- struct comp_status_s *comp_status;
- pid_t pid = _request_get_pid(req);
- bundle *b = _request_get_bundle(req);
- const char *instance_id;
-
- if (!b) {
- _E("Failed to get bundle. pid(%d)", pid);
- return -1;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- comp_status = _comp_status_find_v2(pid, instance_id);
- if (!comp_status) {
- _E("Failed to find component status. pid(%d)", pid);
- return -1;
- }
-
- comp_status->started = true;
-
- _W("[COMP_NOTIFY_START] pid(%d), instance_id(%s)", pid, instance_id);
-
- return 0;
-}
-
-static int __dispatch_comp_notify_exit(request_h req)
-{
- struct comp_status_s *comp_status;
- pid_t pid = _request_get_pid(req);
- uid_t uid = _request_get_uid(req);
- bundle *b = _request_get_bundle(req);
- const char *instance_id;
-
- if (!b) {
- _E("Failed to get bundle. pid(%d)", pid);
- return -1;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- comp_status = _comp_status_find_v2(pid, instance_id);
- if (!comp_status) {
- _E("Failed to find component status. pid(%d)", pid);
- return -1;
- }
-
- __comp_list = g_list_remove(__comp_list, comp_status);
- __destroy_comp_status(comp_status);
-
- _noti_send(AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT, (int)pid, (int)uid,
- (void *)instance_id, NULL);
-
- _W("[COMP_NOTIFY_EXIT] pid(%d), instance_id(%s)", pid, instance_id);
-
- return 0;
-}
-
-static int __dispatch_comp_status_update(request_h req)
-{
- struct comp_status_s *comp_status;
- pid_t pid = _request_get_pid(req);
- bundle *b = _request_get_bundle(req);
- const char *instance_id;
- const char *status_str;
- bool update_group_info = false;
- int status;
-
- if (!b) {
- _E("Failed to get bundle. pid(%d)", pid);
- return -1;
- }
-
- status_str = bundle_get_val(b, AUL_K_STATUS);
- if (!status_str) {
- _E("Invalid request. pid(%d)", pid);
- return -1;
- }
-
- status = atoi(status_str);
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- comp_status = _comp_status_find_v2(pid, instance_id);
- if (!comp_status) {
- _E("Failed to find component status. pid(%d)", pid);
- return -1;
- }
-
- comp_status->status = status;
-
- if (comp_status->comp_type == CT_FRAME_COMP)
- update_group_info = true;
-
- _noti_send(AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END,
- pid, update_group_info, comp_status, NULL);
-
- _W("[COMP_STATUS_UPDATE] pid(%d), instance(%s), status(%d)",
- pid, instance_id, comp_status->status);
-
- return 0;
-}
-
-static bundle *__create_compinfo_bundle(struct comp_status_s *comp_status)
-{
- char buf[MAX_PID_STR_BUFSZ];
- const char *comp_type;
- const char *appid = NULL;
- app_status_h app_status;
- bundle *b;
-
- b = bundle_create();
- if (!b)
- return NULL;
-
- app_status = _app_status_find_v2(comp_status->pid);
- if (app_status)
- appid = _app_status_get_appid(app_status);
-
- if (appid)
- bundle_add(b, AUL_K_APPID, appid);
-
- bundle_add(b, AUL_K_COMPONENT_ID, comp_status->comp_id);
- bundle_add(b, AUL_K_INSTANCE_ID, comp_status->instance_id);
-
- snprintf(buf, sizeof(buf), "%d", comp_status->pid);
- bundle_add(b, AUL_K_PID, buf);
-
- comp_type = __get_comp_type_string(comp_status->comp_type);
- bundle_add(b, AUL_K_COMPONENT_TYPE, comp_type);
-
- snprintf(buf, sizeof(buf), "%d", comp_status->status);
- bundle_add(b, AUL_K_STATUS, buf);
-
- snprintf(buf, sizeof(buf), "%d", comp_status->is_subcomp);
- bundle_add(b, AUL_K_IS_SUB_COMP, buf);
-
- return b;
-}
-
-static int __send_running_compinfo(struct comp_status_s *comp_status, int fd)
-{
- bundle *b;
- int ret;
-
- b = __create_compinfo_bundle(comp_status);
- if (!b) {
- _E("Out of memory");
- aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
- NULL, 0, AUL_SOCK_ASYNC);
- return -1;
- }
-
- ret = aul_sock_send_bundle_with_fd(fd, APP_GET_INFO_OK, b,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send bundle data. error(%d)", ret);
- bundle_free(b);
- return -1;
- }
- bundle_free(b);
-
- return 0;
-}
-
-static int __dispatch_comp_context_foreach(request_h req)
-{
- struct comp_status_s *comp_status;
- int fd = _request_remove_fd(req);
- GList *iter;
- int count;
- int ret;
-
- count = g_list_length(__comp_list);
- if (count == 0) {
- _E("Components are not running");
- _send_result_to_client(fd, -ENOENT);
- return -1;
- }
- _send_result_to_client_v2(fd, count);
-
- for (iter = __comp_list; iter; iter = g_list_next(iter)) {
- comp_status = (struct comp_status_s *)iter->data;
- if (!comp_status)
- continue;
-
- ret = __send_running_compinfo(comp_status, fd);
- if (ret < 0) {
- close(fd);
- return -1;
- }
- }
- close(fd);
-
- return 0;
-}
-
-static int __dispatch_comp_context_get(request_h req)
-{
- struct comp_status_s *comp_status;
- bundle *b = _request_get_bundle(req);
- int fd = _request_remove_fd(req);
- const char *comp_id;
- int ret;
-
- if (!b) {
- _E("Invalid parameter");
- aul_sock_send_raw_with_fd(fd, AUL_R_EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -1;
- }
-
- comp_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
- if (!comp_id) {
- _E("Failed to get component ID");
- aul_sock_send_raw_with_fd(fd, AUL_R_EINVAL, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -1;
- }
-
- comp_status = _comp_status_find(comp_id);
- if (!comp_status) {
- _E("Failed to find running component(%s) context",
- comp_id);
- aul_sock_send_raw_with_fd(fd, AUL_R_ENOENT, NULL, 0,
- AUL_SOCK_NOREPLY);
- return -1;
- }
-
- ret = __send_running_compinfo(comp_status, fd);
- if (ret < 0) {
- close(fd);
- return -1;
- }
- close(fd);
-
- return 0;
-}
-
-static int __dispatch_comp_context_is_running(request_h req)
-{
- struct comp_status_s *comp_status;
- bundle *b = _request_get_bundle(req);
- const char *instance_id;
- int is_running;
-
- if (!b) {
- _E("Invalid parameter");
- _request_send_result(req, -EINVAL);
- return -1;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!instance_id) {
- _E("Failed to get instance ID");
- _request_send_result(req, -EINVAL);
- return -1;
- }
-
- comp_status = _comp_status_find_by_instance_id(instance_id);
- is_running = (int)_comp_status_is_running(comp_status);
- _request_send_result(req, is_running);
- _I("[COMP_CONTEXT_IS_RUNNING] is_running(%s)",
- is_running ? "true" : "false");
-
- return 0;
-}
-
-static int __comp_context_process(request_h req)
-{
- struct comp_status_s *comp_status;
- bundle *b = _request_get_bundle(req);
- const char *instance_id;
- int cmd;
- int ret;
-
- if (!b) {
- _E("Invalid parameter");
- _request_send_result(req, -EINVAL);
- return -1;
- }
-
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!instance_id) {
- _E("Failed to get instance ID");
- _request_send_result(req, -EINVAL);
- return -1;
- }
-
- comp_status = _comp_status_find_by_instance_id(instance_id);
- if (!comp_status) {
- _E("Failed to find running context. instance(%s)", instance_id);
- _request_send_result(req, -ENOENT);
- return -1;
- }
-
- cmd = _request_get_cmd(req);
- switch (cmd) {
- case COMP_CONTEXT_RESUME:
- case COMP_CONTEXT_PAUSE:
- aul_send_app_resume_request_signal(comp_status->pid, NULL,
- NULL, NULL);
- break;
- case COMP_CONTEXT_TERMINATE_BG_COMP:
- case COMP_CONTEXT_TERMINATE:
- aul_send_app_terminate_request_signal(comp_status->pid, NULL,
- NULL, NULL);
- break;
- default:
- break;
- }
-
- switch (cmd) {
- case COMP_CONTEXT_RESUME:
- ret = _launch_resume_inst(comp_status->pid, req);
- break;
- case COMP_CONTEXT_PAUSE:
- ret = _launch_pause_inst(comp_status->pid, req);
- break;
- case COMP_CONTEXT_TERMINATE_BG_COMP:
- ret = _launch_terminate_bg_inst(comp_status->pid, req);
- break;
- case COMP_CONTEXT_TERMINATE:
- ret = _launch_terminate_inst(comp_status->pid, req);
- break;
- default:
- _E("Unknown command: %d", cmd);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-static int __dispatch_comp_context_resume(request_h req)
-{
- return __comp_context_process(req);
-}
-
-static int __dispatch_comp_context_pause(request_h req)
-{
- return __comp_context_process(req);
-}
-
-static int __dispatch_comp_context_terminate_bg_comp(request_h req)
-{
- int fd = _request_remove_fd(req);
- int ret;
-
- ret = __comp_context_process(req);
- _send_result_to_client(fd, ret);
-
- return ret;
-}
-
-static int __dispatch_comp_context_terminate(request_h req)
-{
- int fd = _request_remove_fd(req);
- int ret;
-
- ret = __comp_context_process(req);
- _send_result_to_client(fd, ret);
-
- return ret;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = COMP_NOTIFY_START,
- .callback = __dispatch_comp_notify_start
- },
- {
- .cmd = COMP_NOTIFY_EXIT,
- .callback = __dispatch_comp_notify_exit
- },
- {
- .cmd = COMP_STATUS_UPDATE,
- .callback = __dispatch_comp_status_update
- },
- {
- .cmd = COMP_CONTEXT_FOREACH,
- .callback = __dispatch_comp_context_foreach
- },
- {
- .cmd = COMP_CONTEXT_GET,
- .callback = __dispatch_comp_context_get
- },
- {
- .cmd = COMP_CONTEXT_IS_RUNNING,
- .callback = __dispatch_comp_context_is_running
- },
- {
- .cmd = COMP_CONTEXT_RESUME,
- .callback = __dispatch_comp_context_resume
- },
- {
- .cmd = COMP_CONTEXT_PAUSE,
- .callback = __dispatch_comp_context_pause
- },
- {
- .cmd = COMP_CONTEXT_TERMINATE_BG_COMP,
- .callback = __dispatch_comp_context_terminate_bg_comp
- },
- {
- .cmd = COMP_CONTEXT_TERMINATE,
- .callback = __dispatch_comp_context_terminate
- },
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = COMP_CONTEXT_RESUME,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = COMP_CONTEXT_PAUSE,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = COMP_CONTEXT_TERMINATE_BG_COMP,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL_BGAPP
- },
- {
- .cmd = COMP_CONTEXT_TERMINATE,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = COMP_CONTEXT_GET,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_PACKAGEMANAGER_INFO
- },
- {
- .cmd = COMP_CONTEXT_FOREACH,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_PACKAGEMANAGER_INFO
- }
-};
-
-int _comp_status_init(void)
-{
- int ret;
-
- _D("Component status init");
-
- ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register commands");
- return -1;
- }
-
- ret = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register cynara checkers");
- return -1;
- }
-
- _noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD, __on_main_app_dead);
-
- return 0;
-}
-
-void _comp_status_fini(void)
-{
- _D("Component status fini");
- if (__comp_list)
- g_list_free_full(__comp_list, __destroy_comp_status);
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <glib.h>
-#include <dirent.h>
-#include <pkgmgr-info.h>
-#include <aul_comp_info_internal.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-
-#include "amd_api_noti.h"
-#include "amd_util.h"
-#include "amd_appinfo.h"
-#include "amd_compinfo.h"
-#include "amd_noti.h"
-#include "amd_cynara.h"
-#include "amd_request.h"
-#include "amd_socket.h"
-
-struct compinfo_s {
- char *val[CIT_MAX];
-};
-
-struct compinfo_localized_info_s {
- char *locale;
- char *icon;
- char *label;
-};
-
-typedef int (*compinfo_handler_add_cb)(aul_compinfo_h handle,
- struct compinfo_s *info, void *data);
-typedef void (*compinfo_handler_remove_cb)(void *data);
-
-typedef struct _compinfo_vft {
- compinfo_handler_add_cb constructor;
- compinfo_handler_remove_cb destructor;
-} compinfo_vft;
-
-struct user_compinfo_s {
- uid_t uid;
- GHashTable *tbl;
-};
-
-struct cb_info_s {
- compinfo_foreach_cb callback;
- void *user_data;
-};
-
-static GHashTable *__user_table;
-
-static int __compinfo_add_appid(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- const char *appid;
- int ret;
-
- ret = aul_compinfo_get_app_id(handle, &appid);
- if (ret != 0) {
- _E("Failed to get appid");
- return -1;
- }
-
- info->val[CIT_APPID] = strdup(appid);
- if (!info->val[CIT_APPID]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __compinfo_add_taskmanage(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- int ret;
- bool is_taskmanage;
-
- ret = aul_compinfo_is_taskmanage(handle, &is_taskmanage);
- if (ret != 0) {
- _E("Failed to get taskmanage");
- return -1;
- }
-
- info->val[CIT_TASKMANAGE] =
- is_taskmanage ? strdup("true") : strdup("false");
- if (!info->val[CIT_TASKMANAGE]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __compinfo_add_type(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- const char *type;
- int ret;
-
- ret = aul_compinfo_get_type(handle, &type);
- if (ret != 0) {
- _E("Failed to get component type");
- return -1;
- }
-
- info->val[CIT_TYPE] = strdup(type);
- if (!info->val[CIT_TYPE]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __compinfo_add_launch_mode(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- const char *launch_mode;
- int ret;
-
- ret = aul_compinfo_get_launch_mode(handle, &launch_mode);
- if (ret != 0) {
- _E("Failed to get launch mode");
- return -1;
- }
-
- info->val[CIT_LAUNCH_MODE] = strdup(launch_mode);
- if (!info->val[CIT_LAUNCH_MODE]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __compinfo_add_main(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- bool is_main = false;
- int ret;
-
- ret = aul_compinfo_is_main_comp(handle, &is_main);
- if (ret != 0) {
- _E("Failed to check whether the component is main or not");
- return -1;
- }
-
- info->val[CIT_MAIN] = strdup(is_main ? "true" : "false");
- if (!info->val[CIT_MAIN]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static int __compinfo_add_icon_display(aul_compinfo_h handle,
- struct compinfo_s *info, void *data)
-{
- bool icon_display = false;
- int ret;
-
- ret = aul_compinfo_is_icon_display(handle, &icon_display);
- if (ret != 0) {
- _E("Failed to check the icon display");
- return -1;
- }
-
- info->val[CIT_ICON_DISPLAY] = strdup(icon_display ? "true" : "false");
- if (!info->val[CIT_ICON_DISPLAY]) {
- _E("Out of memory");
- return -1;
- }
-
- return 0;
-}
-
-static compinfo_vft compinfo_table[CIT_MAX] = {
- [CIT_NAME] = {
- .constructor = NULL,
- .destructor = NULL
- },
- [CIT_APPID] = {
- .constructor = __compinfo_add_appid,
- .destructor = free
- },
- [CIT_TASKMANAGE] = {
- .constructor = __compinfo_add_taskmanage,
- .destructor = free
- },
- [CIT_TYPE] = {
- .constructor = __compinfo_add_type,
- .destructor = free
- },
- [CIT_LAUNCH_MODE] = {
- .constructor = __compinfo_add_launch_mode,
- .destructor = free
- },
- [CIT_MAIN] = {
- .constructor = __compinfo_add_main,
- .destructor = free
- },
- [CIT_ICON_DISPLAY] = {
- .constructor = __compinfo_add_icon_display,
- .destructor = free
- },
-};
-
-static void __compinfo_remove_handler(gpointer data)
-{
- struct compinfo_s *info = (struct compinfo_s *)data;
- int i;
-
- if (!info)
- return;
-
- for (i = CIT_START; i < CIT_MAX; i++) {
- if (compinfo_table[i].destructor && info->val[i] != NULL)
- compinfo_table[i].destructor(info->val[i]);
- }
-
- free(info);
-}
-
-static bool __compinfo_insert_handler(aul_compinfo_h handle, void *data)
-{
- struct user_compinfo_s *user_info = (struct user_compinfo_s *)data;
- struct compinfo_s *info;
- const char *comp_id;
- int r;
- int i;
-
- if (!handle || !user_info) {
- _E("Invalid parameter");
- return false;
- }
-
- r = aul_compinfo_get_comp_id(handle, &comp_id);
- if (r != 0) {
- _E("Failed to get component ID");
- return false;
- }
-
- g_hash_table_remove(user_info->tbl, comp_id);
-
- info = calloc(1, sizeof(struct compinfo_s));
- if (!info) {
- _E("Out of memory");
- return false;
- }
-
- info->val[CIT_NAME] = strdup(comp_id);
- if (!info->val[CIT_NAME]) {
- _E("Failed to duplicate component ID(%s)", comp_id);
- free(info);
- return false;
- }
-
- for (i = CIT_START; i < CIT_MAX; i++) {
- if (compinfo_table[i].constructor) {
- r = compinfo_table[i].constructor(handle, info,
- user_info);
- if (r < 0) {
- _E("Failed to load component info %s", comp_id);
- __compinfo_remove_handler(info);
- return true;
- }
- }
- }
-
- SECURE_LOGD("%s : %s : %s : %s",
- info->val[CIT_APPID],
- info->val[CIT_NAME],
- info->val[CIT_TYPE],
- info->val[CIT_TASKMANAGE]);
-
- g_hash_table_insert(user_info->tbl, info->val[CIT_NAME], info);
-
- return true;
-}
-
-compinfo_h _compinfo_find(uid_t uid, const char *id)
-{
- struct user_compinfo_s *user_info;
-
- if (!id) {
- _E("Invalid parameter");
- return NULL;
- }
-
- user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (!user_info) {
- _E("Failed to find user(%u) info", uid);
- return NULL;
- }
-
- return (struct compinfo_s *)g_hash_table_lookup(user_info->tbl, id);
-}
-
-const char *_compinfo_get_value(compinfo_h handle, compinfo_type type)
-{
- struct compinfo_s *info = (struct compinfo_s *)handle;
-
- if (!info) {
- _E("Invalid parameter");
- return NULL;
- }
-
- if (type >= CIT_MAX) {
- _E("Invalid parameter");
- return NULL;
- }
-
- return info->val[type];
-}
-
-static void __foreach_cb(gpointer key, gpointer value, gpointer user_data)
-{
- struct compinfo_s *info = (struct compinfo_s *)value;
- struct cb_info_s *cb_info = (struct cb_info_s *)user_data;
-
- cb_info->callback(info, info->val[CIT_APPID],
- info->val[CIT_NAME], cb_info->user_data);
-}
-
-int _compinfo_foreach(uid_t uid, compinfo_foreach_cb callback,
- void *user_data)
-{
- struct user_compinfo_s *user_info;
- struct cb_info_s cb_info = {callback, user_data};
-
- if (!callback) {
- _E("Invalid parameter");
- return -1;
- }
-
- user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (!user_info) {
- _E("Failed to find user(%u) info", uid);
- return -1;
- }
-
- g_hash_table_foreach(user_info->tbl, __foreach_cb, &cb_info);
-
- return 0;
-}
-
-static int __on_appinfo_insert(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- pkgmgrinfo_appinfo_h handle = (pkgmgrinfo_appinfo_h)arg3;
- struct user_compinfo_s *user_info;
- char *comp_type = NULL;
- char *appid = NULL;
- uid_t uid = (uid_t)arg1;
- int r;
-
- r = pkgmgrinfo_appinfo_get_component_type(handle, &comp_type);
- if (r != PMINFO_R_OK) {
- _E("Failed to get component type");
- return NOTI_CONTINUE;
- }
-
- if (comp_type && strcmp(comp_type, APP_TYPE_COMPONENT_BASED) != 0)
- return NOTI_CONTINUE;
-
- user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (!user_info) {
- _E("Failed to find user(%u) table", uid);
- return NOTI_CONTINUE;
- }
-
- r = pkgmgrinfo_appinfo_get_appid(handle, &appid);
- if (r != PMINFO_R_OK) {
- _E("Failed to get appid");
- return NOTI_CONTINUE;
- }
-
- r = aul_compinfo_usr_foreach_compinfo_from_app(appid, uid,
- __compinfo_insert_handler, user_info);
- if (r != 0) {
- _E("Failed to retrieve component info");
- return NOTI_CONTINUE;
- }
-
- return NOTI_CONTINUE;
-}
-
-static gboolean __foreach_remove_cb(gpointer key, gpointer value,
- gpointer user_data)
-{
- const char *appid = (const char *)user_data;
- struct compinfo_s *info = (struct compinfo_s *)value;
-
- if (!strcmp(info->val[CIT_APPID], appid))
- return TRUE;
-
- return FALSE;
-}
-
-static int __on_appinfo_remove(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- struct user_compinfo_s *user_info;
- uid_t uid = (uid_t)arg1;
- char *appid = (char *)arg3;
-
- user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (!user_info) {
- _E("Failed to find user(%u) info", uid);
- return NOTI_CONTINUE;
- }
-
- g_hash_table_foreach_remove(user_info->tbl, __foreach_remove_cb, appid);
-
- return NOTI_CONTINUE;
-}
-
-static struct user_compinfo_s *__create_user_compinfo(uid_t uid)
-{
- struct user_compinfo_s *info;
-
- info = calloc(1, sizeof(struct user_compinfo_s));
- if (!info) {
- _E("Out of memory");
- return NULL;
- }
-
- info->uid = uid;
- info->tbl = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- __compinfo_remove_handler);
- if (!info->tbl) {
- _E("Out of memory");
- free(info);
- return NULL;
- }
-
- return info;
-}
-
-static void __destroy_user_compinfo(gpointer data)
-{
- struct user_compinfo_s *info = (struct user_compinfo_s *)data;
-
- if (!info)
- return;
-
- if (info->tbl)
- g_hash_table_destroy(info->tbl);
- free(info);
-}
-
-static int __on_login_monitor_login_start(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- struct user_compinfo_s *info;
- uid_t uid = (uid_t)arg1;
-
- info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (info)
- return NOTI_CONTINUE;
-
- info = __create_user_compinfo(uid);
- if (!info) {
- _E("Failed to create user(%u) info", uid);
- return NOTI_CONTINUE;
- }
-
- g_hash_table_insert(__user_table, GUINT_TO_POINTER(uid), info);
-
- return NOTI_CONTINUE;
-}
-
-static int __on_login_monitor_logout(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- struct user_compinfo_s *info;
- uid_t uid = (uid_t)arg1;
-
- info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
- GUINT_TO_POINTER(uid));
- if (!info)
- return NOTI_CONTINUE;
-
- g_hash_table_remove(__user_table, GUINT_TO_POINTER(uid));
-
- return NOTI_CONTINUE;
-}
-
-int _compinfo_init(void)
-{
- _D("Component info init");
-
- __user_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __destroy_user_compinfo);
- if (!__user_table) {
- _E("Failed to create user table");
- return -1;
- }
-
- _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START,
- __on_login_monitor_login_start);
- _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
- __on_login_monitor_logout);
- _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT,
- __on_appinfo_insert);
- _noti_listen(AMD_NOTI_MSG_APPINFO_REMOVE,
- __on_appinfo_remove);
-
- return 0;
-}
-
-void _compinfo_fini(void)
-{
- _D("Component info fini");
-
- if (__user_table)
- g_hash_table_destroy(__user_table);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <system_info.h>
-#include <iniparser.h>
-
-#include "amd_config.h"
-#include "amd_util.h"
-
-#define CONFIG_FILE_PATH "/usr/share/amd/conf/amd.conf"
-#define CONFIG_SECTION_NAME "configuration"
-#define CONFIG_SERVICE_APP_ONBOOT_INTERVAL "service_app_onboot_interval"
-#define CONFIG_FG_TIMEOUT "fg_timeout"
-#define CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE "launchpad_max_launch_failure"
-
-typedef struct config_s {
- tizen_profile_t profile;
- unsigned int onboot_interval;
- unsigned int fg_timeout;
- unsigned int max_launch_failure;
-} config;
-
-static config __config;
-
-tizen_profile_t _config_get_tizen_profile(void)
-{
- char *profile_name = NULL;
-
- if (__builtin_expect(__config.profile != TIZEN_PROFILE_UNKNOWN, 1))
- return __config.profile;
-
- system_info_get_platform_string("http://tizen.org/feature/profile",
- &profile_name);
- if (profile_name == NULL)
- return __config.profile;
-
- switch (*profile_name) {
- case 'm':
- case 'M':
- __config.profile = TIZEN_PROFILE_MOBILE;
- break;
- case 'w':
- case 'W':
- __config.profile = TIZEN_PROFILE_WEARABLE;
- break;
- case 't':
- case 'T':
- __config.profile = TIZEN_PROFILE_TV;
- break;
- case 'i':
- case 'I':
- __config.profile = TIZEN_PROFILE_IVI;
- break;
- default: /* common or unknown ==> ALL ARE COMMON. */
- __config.profile = TIZEN_PROFILE_COMMON;
- break;
- }
- free(profile_name);
-
- return __config.profile;
-}
-
-unsigned int _config_get_onboot_interval(void)
-{
- return __config.onboot_interval;
-}
-
-unsigned int _config_get_fg_timeout(void)
-{
- return __config.fg_timeout;
-}
-
-unsigned int _config_get_max_launch_failure(void)
-{
- return __config.max_launch_failure;
-}
-
-static int __get_config_int(dictionary *d, const char *key)
-{
- char buf[512];
- int val;
-
- snprintf(buf, sizeof(buf), "configuration:%s", key);
- val = iniparser_getint(d, buf, -1);
- if (val < 0) {
- _W("Failed to get %s", buf);
- return -1;
- }
-
- return val;
-}
-
-static int __load_config_file(const char *path)
-{
- int r;
- dictionary *d;
-
- r = access(path, F_OK);
- if (r != 0) {
- _W("Failed to access %s, errno(%d)", path, errno);
- return -1;
- }
-
- d = iniparser_load(path);
- if (!d) {
- _E("Failed to load %s", path);
- return -1;
- }
-
- r = __get_config_int(d, CONFIG_SERVICE_APP_ONBOOT_INTERVAL);
- if (r > 0) {
- __config.onboot_interval = r;
- _I("[__CONFIG__] Onboot interval: %u",
- __config.onboot_interval);
- }
-
- r = __get_config_int(d, CONFIG_FG_TIMEOUT);
- if (r > 0) {
- __config.fg_timeout = r;
- _I("[__CONFIG__] FG timeout: %u", __config.fg_timeout);
- }
-
- r = __get_config_int(d, CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE);
- if (r > 0) {
- __config.max_launch_failure = r;
- _I("[__CONFIG__] Max launch failure : %u",
- __config.max_launch_failure);
- }
-
- iniparser_freedict(d);
-
- return 0;
-}
-
-int _config_init(void)
-{
- _D("config init");
-
- __config.profile = TIZEN_PROFILE_UNKNOWN;
- __config.onboot_interval = 3000;
- __config.fg_timeout = 5000;
- __config.max_launch_failure = 5;
-
- if (__load_config_file(CONFIG_FILE_PATH) < 0)
- _W("Failed to load config file");
-
- return 0;
-}
-
-void _config_fini(void)
-{
- _D("config fini");
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <malloc.h>
-#include <stdlib.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <glib.h>
-#include <glib-unix.h>
-#include <aul_sock.h>
-#include <aul_svc.h>
-#include <aul_svc_priv_key.h>
-#include <amd_request.h>
-#include <amd_appinfo.h>
-#include <aul.h>
-
-#include "amd_cynara.h"
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_app_status.h"
-
-static cynara_ops __cynara_ops;
-static cynara_caller_info_ops __cynara_ci_ops;
-static GList *__pending_checkers;
-static GList *__pending_sub_checkers;
-
-struct checker_info {
- const cynara_checker *checkers;
- int cnt;
-};
-
-struct sub_checker_info {
- char *name;
- sub_checker_func func;
-};
-
-int _cynara_simple_checker(caller_info_h info, request_h req, void *data)
-{
- if (__cynara_ops.check)
- return __cynara_ops.check(info, req, data);
-
- return AMD_CYNARA_ALLOWED;
-}
-
-int _cynara_check_privilege(request_h req, cynara_response_cb callback)
-{
- if (__cynara_ops.check_async)
- return __cynara_ops.check_async(req, callback);
-
- return AMD_CYNARA_ALLOWED;
-}
-
-int _cynara_check_privilege_offline(request_h req, const char *appid, const char *privilege)
-{
- if (__cynara_ops.check_offline)
- return __cynara_ops.check_offline(req, appid, privilege);
-
- return AMD_CYNARA_ALLOWED;
-}
-
-int _cynara_register_checkers(const cynara_checker *checkers, int cnt)
-{
- struct checker_info *info;
-
- if (__cynara_ops.register_checkers)
- return __cynara_ops.register_checkers(checkers, cnt);
-
- info = calloc(1, sizeof(struct checker_info));
- if (!info) {
- _E("Out-of-memory");
- return -1;
- }
-
- info->checkers = checkers;
- info->cnt = cnt;
- __pending_checkers = g_list_append(__pending_checkers, info);
-
- return 0;
-}
-
-const char *_cynara_caller_info_get_client(caller_info_h info)
-{
- if (__cynara_ci_ops.get_client)
- return __cynara_ci_ops.get_client(info);
-
- return NULL;
-}
-
-int _cynara_sub_checker_add(const char *name, sub_checker_func func)
-{
- struct sub_checker_info *sub_info;
-
- if (__cynara_ops.sub_checker_add)
- return __cynara_ops.sub_checker_add(name, func);
-
- sub_info = calloc(1, sizeof(struct sub_checker_info));
- if (!sub_info) {
- _E("Out-of-memory");
- return -1;
- }
-
- sub_info->name = strdup(name);
- sub_info->func = func;
-
- if (!sub_info->name) {
- _E("Out-of-memory");
- free(sub_info);
- return -1;
- }
-
- __pending_sub_checkers = g_list_append(__pending_sub_checkers, sub_info);
-
- return 0;
-}
-
-int _cynara_sub_checker_check(const char *name, caller_info_h info, request_h req)
-{
- if (__cynara_ops.sub_checker_check)
- return __cynara_ops.sub_checker_check(name, info, req);
-
- return AMD_CYNARA_CONTINUE;
-}
-
-static void __clear_sub_checker_info(gpointer data)
-{
- struct sub_checker_info *sub_info = data;
-
- if (!data)
- return;
-
- free(sub_info->name);
- free(sub_info);
-}
-
-static void __clear_pending_list(void)
-{
- if (__pending_checkers) {
- g_list_free_full(__pending_checkers, free);
- __pending_checkers = NULL;
- }
-
- if (__pending_sub_checkers) {
- g_list_free_full(__pending_sub_checkers, __clear_sub_checker_info);
- __pending_sub_checkers = NULL;
- }
-}
-
-int _cynara_register_ops(cynara_ops ops, cynara_caller_info_ops ci_ops)
-{
- GList *i = __pending_checkers;
- struct checker_info *info;
- struct sub_checker_info *sub_info;
-
- __cynara_ops = ops;
- __cynara_ci_ops = ci_ops;
- while (i) {
- info = i->data;
- if (__cynara_ops.register_checkers)
- __cynara_ops.register_checkers(info->checkers, info->cnt);
-
- i = g_list_next(i);
- }
-
- i = __pending_sub_checkers;
- while (i) {
- sub_info = i->data;
- if (__cynara_ops.sub_checker_add)
- __cynara_ops.sub_checker_add(sub_info->name, sub_info->func);
-
- i = g_list_next(i);
- }
-
- __clear_pending_list();
-
- return 0;
-}
-
-int _cynara_init(void)
-{
- _D("cynara init");
-
- return 0;
-}
-
-void _cynara_finish(void)
-{
- _D("cynara fini");
- __clear_pending_list();
-}
-
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <aul_key.h>
-#include <aul_svc.h>
-#include <bundle_internal.h>
-
-#include "amd_appinfo.h"
-#include "amd_app_property.h"
-#include "amd_direct_launch.h"
-#include "amd_noti.h"
-#include "amd_util.h"
-
-#define KEY_DIRECT_LAUNCH "http://tizen.org/metadata/direct-launch"
-
-static int __on_check_direct_launch(const char *msg, int arg1, int arg2,
- void *arg3, bundle *b)
-{
- const struct appinfo *ai = (const struct appinfo *)arg3;
- uid_t target_uid = (uid_t)arg2;
- app_property_h app_property;
- const char *appid;
- const char *loader_id;
-
- loader_id = bundle_get_val(b, AUL_K_LOADER_ID);
- if (loader_id)
- return NOTI_CONTINUE;
-
- appid = _appinfo_get_value(ai, AIT_NAME);
- app_property = _app_property_find(target_uid);
- if (_app_property_metadata_match(app_property, appid,
- KEY_DIRECT_LAUNCH, "yes"))
- aul_svc_set_loader_id(b, PAD_LOADER_ID_DIRECT);
-
- return NOTI_CONTINUE;
-}
-
-int _direct_launch_init(void)
-{
- int r;
-
- _D("direct launch init");
- r = _app_property_metadata_add_filter(KEY_DIRECT_LAUNCH, "yes");
- if (r < 0) {
- _E("Failed to add metadata filter");
- return -1;
- }
-
- _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
- __on_check_direct_launch);
- return 0;
-}
-
-void _direct_launch_fini(void)
-{
- _D("direct launch fini");
- _app_property_metadata_remove_filter(KEY_DIRECT_LAUNCH, "yes");
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/inotify.h>
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_inotify.h"
-
-struct inotify_watch_info_s {
- int fd;
- int wd;
- GIOChannel *io;
- guint tag;
- uint32_t mask;
- inotify_watch_cb cb;
- void *data;
-};
-
-static GList *__watch_list;
-
-static gboolean __inotify_cb(GIOChannel *source, GIOCondition condition,
- gpointer data)
-{
-#define ALIGN_INOTIFY_EVENT \
- __attribute__ ((aligned(__alignof__(struct inotify_event))))
- int fd = g_io_channel_unix_get_fd(source);
- char buf[4096] ALIGN_INOTIFY_EVENT;
- const struct inotify_event *event;
- struct inotify_watch_info_s *info = data;
- ssize_t len;
- char *ptr;
- char *nptr;
-
- while ((len = read(fd, buf, sizeof(buf))) > 0) {
- for (ptr = buf; ptr < buf + len;
- ptr += sizeof(struct inotify_event) + event->len) {
- event = (const struct inotify_event *)ptr;
- nptr = ptr + sizeof(struct inotify_event) + event->len;
- if (nptr > buf + len)
- break;
-
- if (event->mask & info->mask) {
- if (!info->cb(event->name, info->data)) {
- _inotify_rm_watch(info);
- return G_SOURCE_CONTINUE;
- }
- }
- }
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-static void __destroy_inotify_watch_info(gpointer data)
-{
- struct inotify_watch_info_s *info = (struct inotify_watch_info_s *)data;
-
- if (info == NULL)
- return;
-
- if (info->tag > 0)
- g_source_remove(info->tag);
-
- if (info->io)
- g_io_channel_unref(info->io);
-
- if (info->wd > 0)
- inotify_rm_watch(info->fd, info->wd);
-
- if (info->fd > 0)
- close(info->fd);
-
- free(info);
-}
-
-static struct inotify_watch_info_s *__create_inotify_watch_info(
- const char *path, uint32_t mask, inotify_watch_cb cb,
- void *data)
-{
- GIOCondition cond = G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP;
- struct inotify_watch_info_s *info;
-
- info = calloc(1, sizeof(struct inotify_watch_info_s));
- if (info == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- info->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
- if (info->fd < 0) {
- _E("inotify_init1() is failed. errno(%d)", errno);
- __destroy_inotify_watch_info(info);
- return NULL;
- }
-
- info->wd = inotify_add_watch(info->fd, path, mask);
- if (info->wd < 0) {
- _E("inotify_add_watch() is failed. path(%s), errno(%d)",
- path, errno);
- __destroy_inotify_watch_info(info);
- return NULL;
- }
-
- info->io = g_io_channel_unix_new(info->fd);
- if (!info->io) {
- _E("g_io_channel_unix_new() is failed");
- __destroy_inotify_watch_info(info);
- return NULL;
- }
-
- info->tag = g_io_add_watch(info->io, cond,
- __inotify_cb, info);
- if (!info->tag) {
- _E("g_io_add_watch() is failed");
- __destroy_inotify_watch_info(info);
- return NULL;
- }
-
- info->mask = mask;
- info->cb = cb;
- info->data = data;
-
- return info;
-}
-
-inotify_watch_info_h _inotify_add_watch(const char *path, uint32_t mask,
- inotify_watch_cb callback, void *data)
-{
- struct inotify_watch_info_s *info;
-
- if (path == NULL || callback == NULL) {
- _E("Invalid parameter");
- return NULL;
- }
-
- info = __create_inotify_watch_info(path, mask, callback, data);
- if (info == NULL)
- return NULL;
-
- __watch_list = g_list_append(__watch_list, info);
-
- return info;
-}
-
-void _inotify_rm_watch(inotify_watch_info_h handle)
-{
- if (handle == NULL)
- return;
-
- __watch_list = g_list_remove(__watch_list, handle);
- __destroy_inotify_watch_info(handle);
-}
-
-int _inotify_init(void)
-{
- _D("inotify init");
-
- return 0;
-}
-
-void _inotify_fini(void)
-{
- _D("inotify fini");
-
- if (__watch_list)
- g_list_free_full(__watch_list, __destroy_inotify_watch_info);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <aul.h>
-#include <aul_rpc_port.h>
-#include <aul_sock.h>
-#include <aul_svc.h>
-#include <aul_svc_priv_key.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-#include <glib.h>
-#include <pkgmgr-info.h>
-#include <ttrace.h>
-#include <tzplatform_config.h>
-#include <vconf.h>
-
-#include "amd_anr_monitor.h"
-#include "amd_api_noti.h"
-#include "amd_app_com.h"
-#include "amd_app_property.h"
-#include "amd_app_status.h"
-#include "amd_appinfo.h"
-#include "amd_boot_manager.h"
-#include "amd_comp_status.h"
-#include "amd_compinfo.h"
-#include "amd_config.h"
-#include "amd_cynara.h"
-#include "amd_launch.h"
-#include "amd_launchpad.h"
-#include "amd_login_monitor.h"
-#include "amd_noti.h"
-#include "amd_proc.h"
-#include "amd_request.h"
-#include "amd_signal.h"
-#include "amd_socket.h"
-#include "amd_suspend.h"
-#include "amd_util.h"
-#include "app_signal.h"
-
-#define DAC_ACTIVATE
-
-#define TERM_WAIT_SEC 3
-#define INIT_PID 1
-
-#define AUL_PR_NAME 16
-#define OSP_K_LAUNCH_TYPE "__OSP_LAUNCH_TYPE__"
-#define OSP_V_LAUNCH_TYPE_DATACONTROL "datacontrol"
-#define PENDING_REQUEST_TIMEOUT 5000 /* msec */
-#define SYSTEM_REQUEST_TIMEOUT 90000 /* msec */
-#define PENDING_MESSAGE_MAX_CNT 100
-
-#define APPID_WIDGET_VIEWER_SDK "org.tizen.widget_viewer_sdk"
-
-struct launch_s {
- const char *appid;
- struct appinfo *ai;
- const char *instance_id;
- int pid;
- bool new_process;
- bool is_subapp;
- int prelaunch_attr;
- int bg_category;
- bool bg_allowed;
- bool bg_launch;
- bool new_instance;
- app_status_h app_status;
- bool debug_mode;
- const char *comp_id;
- compinfo_h ci;
- comp_status_h comp_status;
- bool is_custom_effect;
-};
-
-struct fgmgr {
- guint tid;
- int pid;
-};
-
-struct result_info_s {
- int pid;
- int fd;
- char *seq;
- guint timer;
-};
-
-static GList *_fgmgr_list;
-static int __pid_of_last_launched_ui_app;
-static int __focused_pid;
-static GList *__result_info_list;
-static int __poweroff_state;
-static launch_mode_e __launch_mode = LAUNCH_MODE_NORMAL;
-static unsigned int __failure_count;
-
-static void __set_reply_handler(int fd, int pid, request_h req, int cmd);
-static int __nofork_processing(int cmd, int pid, bundle *kb, request_h req);
-
-static void __poweroff_state_cb(int state, void *user_data)
-{
- _W("[__POWEROFF__] state: %d -> %d", __poweroff_state, state);
- __poweroff_state = state;
- if (__poweroff_state == POWEROFF_DIRECT ||
- __poweroff_state == POWEROFF_RESTART) {
- _W("System shutdown");
- __launch_mode = LAUNCH_MODE_BLOCK;
- }
- _noti_send(AMD_NOTI_MSG_LAUNCH_POWEROFF_STATE_CHANGE, state, 0, NULL, NULL);
-}
-
-static void __add_result_info(struct result_info_s *info)
-{
- __result_info_list = g_list_append(__result_info_list, info);
-}
-
-static void __remove_result_info(struct result_info_s *info)
-{
- __result_info_list = g_list_remove(__result_info_list, info);
-}
-
-static void __destroy_result_info(gpointer data)
-{
- struct result_info_s *info = (struct result_info_s *)data;
-
- if (!info)
- return;
- if (info->timer)
- g_source_remove(info->timer);
- if (info->seq)
- free(info->seq);
- free(info);
-}
-
-static gboolean __result_info_timeout_handler(gpointer data)
-{
- struct result_info_s *info = (struct result_info_s *)data;
-
- if (!info)
- return G_SOURCE_REMOVE;
-
- _W("[__WARNING__] timed out. pid(%d), fd(%d), seq(%s)",
- info->pid, info->fd, info->seq);
- info->timer = 0;
- __remove_result_info(info);
- __destroy_result_info(info);
-
- return G_SOURCE_REMOVE;
-}
-
-static guint __get_timeout_interval(struct timespec *start,
- struct timespec *end)
-{
- guint interval;
-
- interval = (end->tv_sec - start->tv_sec) * 1e3 +
- (end->tv_nsec - start->tv_nsec) / 1e6;
- if (interval >= PENDING_REQUEST_TIMEOUT)
- return 0;
-
- return PENDING_REQUEST_TIMEOUT - interval;
-}
-
-static struct result_info_s *__create_result_info(unsigned int interval,
- int pid, int fd, const char *seq)
-{
- struct result_info_s *info;
-
- info = calloc(1, sizeof(struct result_info_s));
- if (!info) {
- _E("Out of memory");
- return NULL;
- }
-
- info->seq = strdup(seq);
- if (!info->seq) {
- _E("Failed to duplicate sequence");
- free(info);
- return NULL;
- }
-
- info->timer = g_timeout_add(interval, __result_info_timeout_handler,
- info);
- if (info->timer == 0) {
- _E("Failed to add timer");
- __destroy_result_info(info);
- return NULL;
- }
-
- info->pid = pid;
- info->fd = fd;
-
- return info;
-}
-
-static struct result_info_s *__find_result_info(const char *seq)
-{
- struct result_info_s *info;
- GList *iter;
-
- iter = __result_info_list;
- while (iter) {
- info = (struct result_info_s *)iter->data;
- if (!strcmp(info->seq, seq))
- return info;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static void __set_stime(bundle *kb)
-{
- struct timespec start;
- char tmp[MAX_LOCAL_BUFSZ];
-
- clock_gettime(CLOCK_MONOTONIC, &start);
- snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", start.tv_sec, start.tv_nsec);
- bundle_add(kb, AUL_K_STARTTIME, tmp);
-}
-
-int _launch_start_app_local_with_bundle(uid_t uid, const char *appid,
- bundle *kb)
-{
- request_h req;
- int r;
- bool dummy;
- bool dummy_mode;
-
- __set_stime(kb);
- bundle_add(kb, AUL_K_APPID, appid);
- req = _request_create_local(APP_START, uid, getpid(), kb);
- if (req == NULL) {
- _E("out of memory");
- return -1;
- }
-
- r = _launch_start_app(appid, req, &dummy, &dummy_mode, false);
- _request_free_local(req);
-
- return r;
-}
-
-int _launch_start_app_local(uid_t uid, const char *appid)
-{
- int pid;
- bundle *kb;
-
- kb = bundle_create();
- if (kb == NULL) {
- _E("out of memory");
- return -1;
- }
-
- pid = _launch_start_app_local_with_bundle(uid, appid, kb);
- bundle_free(kb);
-
- return pid;
-}
-
-static bool __check_onboot_cond(uid_t uid, const char *appid,
- struct appinfo *ai)
-{
- app_status_h app_status;
- const char *comp_type;
- const char *onboot;
-
- comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp_type == NULL || strcmp(comp_type, APP_TYPE_SERVICE) != 0)
- return false;
-
- onboot = _appinfo_get_value(ai, AIT_ONBOOT);
- if (onboot == NULL || strcmp(onboot, "true") != 0)
- return false;
-
- app_status = _app_status_find_by_appid(appid, uid);
- if (_app_status_is_running(app_status) > 0)
- return false;
-
- return true;
-}
-
-int _launch_start_onboot_app_local(uid_t uid, const char *appid,
- struct appinfo *ai)
-{
- if (appid == NULL || ai == NULL)
- return -1;
-
- if (!__check_onboot_cond(uid, appid, ai))
- return -1;
-
- _D("start app %s from user %d by onboot", appid, uid);
- return _launch_start_app_local(uid, appid);
-}
-
-int _terminate_app_local(uid_t uid, int pid)
-{
- request_h req;
- int ret;
-
- req = _request_create_local(APP_TERM_BY_PID, uid, getpid(), NULL);
- if (req == NULL) {
- _E("Out of memory");
- return -1;
- }
-
- aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
- ret = _term_app(pid, req);
- _request_free_local(req);
-
- return ret;
-}
-
-static int __send_sigkill(int pid, uid_t uid)
-{
- int pgid;
- pid_t launchpad_pid;
-
- if (pid <= 1)
- return -1;
-
- pgid = getpgid(pid);
- if (pgid <= 1)
- return -1;
-
- launchpad_pid = _login_monitor_get_launchpad_pid(uid);
- if (launchpad_pid == pgid) {
- SECURE_LOGE("pgid(%d) of pid(%d) is launchpad", pgid, pid);
- if (kill(pid, SIGKILL) < 0) {
- _E("Failed to send SIGKILL to %d", pid);
- return -1;
- }
- return 0;
- }
-
- _W("Kill Process Group: pid(%d), pgid(%d)", pid, pgid);
- if (killpg(pgid, SIGKILL) < 0)
- return -1;
-
- return 0;
-}
-
-int _resume_app(int pid, request_h req)
-{
- int dummy;
- int ret;
- uid_t target_uid = _request_get_target_uid(req);
-
- ret = aul_sock_send_raw(pid, target_uid,
- APP_RESUME_BY_PID, (unsigned char *)&dummy, 0,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- if (ret == -EAGAIN) {
- _E("resume packet timeout error");
- } else {
- _E("raise failed - %d resume fail\n", pid);
- _E("we will term the app - %d\n", pid);
- __send_sigkill(pid, target_uid);
- ret = -1;
- }
- _request_send_result(req, ret);
- }
- _D("resume done\n");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_RESUME_BY_PID);
-
- return ret;
-}
-
-int _launch_resume_inst(int pid, request_h req)
-{
- uid_t uid = _request_get_target_uid(req);
- bundle *b = _request_get_bundle(req);
- int ret;
-
- if (!b) {
- _E("Invalid parameter");
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_sock_send_bundle(pid, uid, APP_RESUME_INSTANCE,
- b, AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send resume request. pid(%d)", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _D("Resume done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_RESUME_INSTANCE);
-
- return 0;
-}
-
-int _pause_app(int pid, request_h req)
-{
- int dummy;
- int ret;
- uid_t target_uid = _request_get_target_uid(req);
-
- ret = aul_sock_send_raw(pid, target_uid,
- APP_PAUSE_BY_PID, (unsigned char *)&dummy, 0,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- if (ret == -EAGAIN) {
- _E("pause packet timeout error");
- } else {
- _E("iconify failed - %d pause fail", pid);
- _E("we will term the app - %d", pid);
- __send_sigkill(pid, target_uid);
- ret = -1;
- }
- _request_send_result(req, ret);
- }
- _D("pause done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_PAUSE_BY_PID);
-
- return ret;
-}
-
-int _launch_pause_inst(int pid, request_h req)
-{
- uid_t uid = _request_get_target_uid(req);
- bundle *b = _request_get_bundle(req);
- int ret;
-
- if (!b) {
- _E("Invalid parameter");
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_sock_send_bundle(pid, uid, APP_PAUSE_INSTANCE,
- b, AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send pause request. pid(%d)", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _D("Resume done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_PAUSE_INSTANCE);
-
- return 0;
-}
-
-int _term_sub_app(int pid, uid_t uid)
-{
- int dummy;
- int ret;
-
- ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID_ASYNC,
- (unsigned char *)&dummy, 0, AUL_SOCK_NOREPLY);
- if (ret < 0) {
- _E("terminate packet send error - use SIGKILL pid(%d)", pid);
- if (__send_sigkill(pid, uid) < 0) {
- _E("fail to killing - %d\n", pid);
- return -1;
- }
- }
-
- return 0;
-}
-
-int _term_sub_inst(pid_t pid, const char *inst_id, uid_t uid)
-{
- bundle *b;
- int ret;
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return -1;
- }
-
- if (inst_id)
- bundle_add(b, AUL_K_INSTANCE_ID, inst_id);
-
- ret = aul_sock_send_bundle(pid, uid,
- APP_TERM_INSTANCE_ASYNC,
- b, AUL_SOCK_NOREPLY);
- bundle_free(b);
- if (ret < 0) {
- SECURE_LOGE("Failed to send terminate request. "
- "pid(%d), inst_id(%s)", pid, inst_id);
- return -1;
- }
-
- return 0;
-}
-
-int _term_app(int pid, request_h req)
-{
- int dummy;
- int ret;
- uid_t uid = _request_get_target_uid(req);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_APP_START, pid, 0, req, NULL);
- ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID,
- (unsigned char *)&dummy, 0, AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("terminate packet send error - use SIGKILL pid(%d)", pid);
- if (__send_sigkill(pid, uid) < 0) {
- _E("fail to killing - %d\n", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _request_send_result(req, 0);
- }
- _D("term done\n");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_TERM_BY_PID);
-
- return 0;
-}
-
-int _launch_terminate_inst(int pid, request_h req)
-{
- uid_t uid = _request_get_target_uid(req);
- bundle *b = _request_get_bundle(req);
- int ret;
-
- if (!b) {
- _E("Invalid parameter");
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = aul_sock_send_bundle(pid, uid, APP_TERM_INSTANCE_ASYNC,
- b, AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send terminate request. pid(%d)", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _D("Terminate instance done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_TERM_INSTANCE_ASYNC);
-
- return 0;
-}
-
-int _term_req_app(int pid, request_h req)
-{
- int dummy;
- int ret;
-
- ret = aul_sock_send_raw(pid, _request_get_target_uid(req),
- APP_TERM_REQ_BY_PID, (unsigned char *)&dummy, 0,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _D("terminate req send error");
- _request_send_result(req, ret);
- }
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_TERM_REQ_BY_PID);
-
- return 0;
-}
-
-int _term_bgapp(int pid, request_h req)
-{
- int dummy;
- int ret;
- uid_t uid = _request_get_target_uid(req);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START, pid, 0, req, NULL);
- ret = aul_sock_send_raw(pid, uid, APP_TERM_BGAPP_BY_PID,
- (unsigned char *)&dummy, sizeof(int), AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("terminate packet send error - use SIGKILL pid(%d)", pid);
- if (__send_sigkill(pid, uid) < 0) {
- _E("fail to killing - %d", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _request_send_result(req, 0);
- }
- _D("term_bgapp done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_TERM_BGAPP_BY_PID);
-
- return 0;
-}
-
-int _launch_terminate_bg_inst(int pid, request_h req)
-{
- uid_t uid = _request_get_target_uid(req);
- bundle *b = _request_get_bundle(req);
- int ret;
-
- ret = aul_sock_send_bundle(pid, uid, APP_TERM_BG_INSTANCE,
- b, AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("Failed to send terminate bg inst. pid(%d)", pid);
- _request_send_result(req, -1);
- return -1;
- }
- _D("Terminate bg instance done");
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, APP_TERM_BG_INSTANCE);
-
- return 0;
-}
-
-int _term_app_v2(int pid, request_h req, bool *pend)
-{
- int dummy;
- int ret;
- uid_t uid = _request_get_target_uid(req);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_APP_START, pid, 0, req, NULL);
- ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID_SYNC,
- (unsigned char *)&dummy, 0,
- AUL_SOCK_ASYNC | AUL_SOCK_NOREPLY);
- if (ret < 0) {
- _E("Failed to send the terminate packet - use SIGKILL pid(%d)",
- pid);
- if (__send_sigkill(pid, uid) < 0) {
- _E("Failed to kill - %d\n", pid);
- _request_send_result(req, -1);
- return -1;
- }
- }
- _D("term v2 done");
-
- if (pend)
- *pend = true;
-
- return 0;
-}
-
-static int __fake_launch_app(int cmd, int pid, bundle *kb, request_h req)
-{
- int ret;
-
- ret = aul_sock_send_bundle(pid, _request_get_target_uid(req), cmd, kb,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("error request fake launch - error code = %d", ret);
- _request_send_result(req, ret);
- }
-
- if (ret > 0)
- __set_reply_handler(ret, pid, req, cmd);
-
- return ret;
-}
-
-static int __fake_launch_app_async(int cmd, int pid, bundle *kb, request_h req)
-{
- int ret;
-
- ret = aul_sock_send_bundle(pid, _request_get_target_uid(req), cmd, kb,
- AUL_SOCK_ASYNC);
- if (ret < 0) {
- _E("error request fake launch - error code = %d", ret);
- _request_send_result(req, ret);
- }
-
- if (ret > 0) {
- _send_result_to_client(_request_remove_fd(req), pid);
- __set_reply_handler(ret, pid, req, cmd);
- }
-
- return ret;
-}
-
-static gboolean __au_glib_check(GSource *src)
-{
- GSList *fd_list;
- GPollFD *tmp;
-
- fd_list = src->poll_fds;
- do {
- tmp = (GPollFD *) fd_list->data;
- if ((tmp->revents & (POLLIN | POLLPRI)))
- return TRUE;
- fd_list = fd_list->next;
- } while (fd_list);
-
- return FALSE;
-}
-
-static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
- gpointer data)
-{
- callback(data);
- return TRUE;
-}
-
-static gboolean __au_glib_prepare(GSource *src, gint *timeout)
-{
- return FALSE;
-}
-
-static GSourceFuncs funcs = {
- .prepare = __au_glib_prepare,
- .check = __au_glib_check,
- .dispatch = __au_glib_dispatch,
- .finalize = NULL
-};
-
-struct reply_info {
- GSource *src;
- GPollFD *gpollfd;
- guint timer_id;
- int clifd;
- int pid;
- int cmd;
- bundle *kb;
- uid_t uid;
-};
-
-static gboolean __reply_handler(gpointer data)
-{
- struct reply_info *r_info = (struct reply_info *)data;
- int fd = r_info->gpollfd->fd;
- int len;
- int res = 0;
- int clifd = r_info->clifd;
- int pid = r_info->pid;
- char err_buf[1024];
-
- len = recv(fd, &res, sizeof(int), 0);
- if (len == -1) {
- if (errno == EAGAIN) {
- _E("recv timeout : %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- res = -EAGAIN;
- } else {
- _E("recv error : %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- res = -ECOMM;
- }
- } else if (len == 0) {
- _E("A stream socket peer(%d) has performed an orderly shutdown",
- pid);
- res = -ECOMM;
- }
-
- if (res < 0 && r_info->cmd == APP_START_ASYNC) {
- _noti_send(AMD_NOTI_MSG_LAUNCH_RECV_ERROR, r_info->pid, r_info->uid,
- NULL, r_info->kb);
- }
-
- close(fd);
-
- if (res >= 0)
- res = pid;
- _send_result_to_client(clifd, res);
-
- _D("listen fd : %d , send fd : %d, pid : %d", fd, clifd, pid);
-
- g_source_remove(r_info->timer_id);
- g_source_remove_poll(r_info->src, r_info->gpollfd);
- g_source_destroy(r_info->src);
- g_source_unref(r_info->src);
- g_free(r_info->gpollfd);
- if (r_info->kb)
- bundle_free(r_info->kb);
- free(r_info);
-
- _anr_monitor_remove_timer(pid);
-
- return TRUE;
-}
-
-static gboolean __recv_timeout_handler(gpointer data)
-{
- struct reply_info *r_info = (struct reply_info *)data;
- int fd = r_info->gpollfd->fd;
- int clifd = r_info->clifd;
- app_status_h app_status;
- uid_t uid;
- int ret = -EAGAIN;
-
- _E("application is not responding: pid(%d) cmd(%d)",
- r_info->pid, r_info->cmd);
- close(fd);
-
- switch (r_info->cmd) {
- case APP_OPEN:
- case APP_RESUME:
- case APP_RESUME_BY_PID:
- case APP_START:
- case APP_START_RES:
- case APP_START_ASYNC:
- case APP_START_RES_ASYNC:
- case APP_SEND_LAUNCH_REQUEST:
- case APP_SEND_LAUNCH_REQUEST_SYNC:
- case APP_SEND_RESUME_REQUEST:
- app_status = _app_status_find(r_info->pid);
- if (app_status == NULL)
- break;
-
- uid = _app_status_get_uid(app_status);
- _noti_send(AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT,
- r_info->pid, uid, NULL, r_info->kb);
- break;
- case APP_TERM_BY_PID:
- case APP_TERM_BGAPP_BY_PID:
- if (__send_sigkill(r_info->pid, r_info->uid) == 0)
- ret = 0;
- break;
- }
-
- _send_result_to_client(clifd, ret);
- g_source_remove_poll(r_info->src, r_info->gpollfd);
- g_source_destroy(r_info->src);
- g_source_unref(r_info->src);
- g_free(r_info->gpollfd);
- if (r_info->kb)
- bundle_free(r_info->kb);
- free(r_info);
-
- return FALSE;
-}
-
-static void __set_reply_handler(int fd, int pid, request_h req, int cmd)
-{
- GPollFD *gpollfd;
- GSource *src;
- struct reply_info *r_info;
- struct timeval tv;
- bundle *kb = _request_get_bundle(req);
-
- src = g_source_new(&funcs, sizeof(GSource));
- if (src == NULL) {
- _E("Out of memory");
- return;
- }
-
- gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
- if (gpollfd == NULL) {
- _E("Out of memory");
- g_source_unref(src);
- return;
- }
-
- gpollfd->events = POLLIN;
- gpollfd->fd = fd;
-
- r_info = malloc(sizeof(*r_info));
- if (r_info == NULL) {
- _E("out of memory");
- g_free(gpollfd);
- g_source_unref(src);
- return;
- }
-
- if (kb) {
- r_info->kb = bundle_dup(kb);
- if (r_info->kb == NULL) {
- _E("Out of memory");
- free(r_info);
- g_free(gpollfd);
- g_source_unref(src);
- return;
- }
- } else {
- r_info->kb = NULL;
- }
-
- if (cmd == APP_SEND_LAUNCH_REQUEST_SYNC)
- r_info->clifd = -1;
- else
- r_info->clifd = _request_remove_fd(req);
- r_info->pid = pid;
- r_info->src = src;
- r_info->gpollfd = gpollfd;
- r_info->cmd = cmd;
- r_info->uid = _request_get_target_uid(req);
-
- tv = aul_sock_get_rcv_timeval();
- r_info->timer_id = g_timeout_add_seconds(tv.tv_sec,
- __recv_timeout_handler, (gpointer)r_info);
- g_source_add_poll(src, gpollfd);
- g_source_set_callback(src, (GSourceFunc)__reply_handler,
- (gpointer)r_info, NULL);
- g_source_set_priority(src, G_PRIORITY_DEFAULT);
- g_source_attach(src, NULL);
-
- _anr_monitor_add_timer(pid);
-
- _D("listen fd : %d, send fd : %d", fd, r_info->clifd);
-}
-
-static int __nofork_processing(int cmd, int pid, bundle *kb, request_h req)
-{
- int ret;
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START,
- cmd, pid, req, kb);
-
- switch (cmd) {
- case APP_OPEN:
- case APP_RESUME:
- case APP_SEND_RESUME_REQUEST:
- _D("resume app's pid : %d\n", pid);
- ret = _resume_app(pid, req);
- if (ret < 0)
- _E("__resume_app failed. error code = %d", ret);
- _D("resume app done");
- break;
- case APP_START:
- case APP_START_RES:
- case APP_SEND_LAUNCH_REQUEST:
- case APP_SEND_LAUNCH_REQUEST_SYNC:
- _D("fake launch pid : %d\n", pid);
- ret = __fake_launch_app(cmd, pid, kb, req);
- if (ret < 0)
- _E("fake_launch failed. error code = %d", ret);
- _D("fake launch done");
- break;
- case APP_START_ASYNC:
- case APP_START_RES_ASYNC:
- ret = __fake_launch_app_async(cmd, pid, kb, req);
- if (ret < 0)
- _E("fake_launch_async failed. error code = %d", ret);
- _D("fake launch async done");
- break;
- default:
- _E("unknown command: %d", cmd);
- ret = -1;
- }
-
- return ret;
-}
-
-static int __compare_signature(const struct appinfo *ai, int cmd,
- uid_t caller_uid, const char *appid, const char *caller_appid)
-{
- const char *permission;
- const struct appinfo *caller_ai;
- const char *preload;
- const char *api_version;
- pkgmgrinfo_cert_compare_result_type_e compare_result;
-
- permission = _appinfo_get_value(ai, AIT_PERM);
- if (permission && strcmp(permission, "signature") == 0) {
- if (caller_uid != 0 && (cmd == APP_START ||
- cmd == APP_START_RES ||
- cmd == APP_START_ASYNC ||
- cmd == APP_START_RES_ASYNC ||
- cmd == APP_SEND_LAUNCH_REQUEST ||
- cmd == APP_SEND_LAUNCH_REQUEST_SYNC)) {
- caller_ai = _appinfo_find(caller_uid, caller_appid);
- preload = _appinfo_get_value(caller_ai, AIT_PRELOAD);
- if (!preload || strcmp(preload, "true") == 0)
- return 0;
-
- api_version = _appinfo_get_value(caller_ai,
- AIT_API_VERSION);
- if (api_version && strverscmp(api_version, "2.4") < 0)
- return 0;
-
- /* is admin is global */
- if (caller_uid != GLOBAL_USER) {
- pkgmgrinfo_pkginfo_compare_usr_app_cert_info(
- caller_appid, appid,
- caller_uid, &compare_result);
- } else {
- pkgmgrinfo_pkginfo_compare_app_cert_info(
- caller_appid, appid,
- &compare_result);
- }
-
- if (compare_result != PMINFO_CERT_COMPARE_MATCH)
- return -EILLEGALACCESS;
- }
- }
-
- return 0;
-}
-
-static void __prepare_to_suspend(int pid, uid_t uid)
-{
- int dummy = 0;
-
- SECURE_LOGD("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
- aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
- sizeof(int), AUL_SOCK_NOREPLY);
-}
-
-static void __prepare_to_wake_services(int pid, uid_t uid)
-{
- int dummy = 0;
-
- SECURE_LOGD("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
- aul_sock_send_raw(pid, uid, APP_WAKE, (unsigned char *)&dummy,
- sizeof(int), AUL_SOCK_NOREPLY);
-}
-
-static gboolean __check_service_only(gpointer user_data)
-{
- int pid = GPOINTER_TO_INT(user_data);
- app_status_h app_status;
-
- SECURE_LOGD("[__SUSPEND__] pid :%d", pid);
- app_status = _app_status_find(pid);
- _app_status_check_service_only(app_status,
- __prepare_to_suspend);
-
- return FALSE;
-}
-
-static int __check_allowed_appid(const char *callee_appid,
- const char *caller_appid, uid_t uid)
-{
- app_property_h app_property;
- GList *list;
- GList *iter;
- char *allowed_appid;
-
- app_property = _app_property_find(uid);
- if (app_property == NULL)
- return -1;
-
- list = _app_property_get_allowed_app_list(app_property, callee_appid);
- iter = g_list_first(list);
- while (iter) {
- allowed_appid = (char *)iter->data;
- if (allowed_appid && strcmp(allowed_appid, caller_appid) == 0) {
- _D("allowed appid(%s), appid(%s)",
- allowed_appid, callee_appid);
- return 0;
- }
-
- iter = g_list_next(iter);
- }
-
- return -1;
-}
-
-static int __check_execute_permission(const char *callee_pkgid,
- const char *caller_appid, uid_t caller_uid, request_h req)
-{
- bundle *kb = _request_get_bundle(req);
- struct appinfo *ai;
- const char *caller_pkgid;
- const char *launch_type;
- const char *callee_appid = bundle_get_val(kb, AUL_K_APPID);
- const char *req_type;
- int ret;
-
- if (callee_pkgid == NULL)
- return -1;
-
- ai = _appinfo_find(caller_uid, caller_appid);
- if (ai == NULL)
- return 0;
-
- caller_pkgid = _appinfo_get_value(ai, AIT_PKGID);
- if (caller_pkgid == NULL)
- return 0;
-
- if (strcmp(caller_pkgid, callee_pkgid) == 0)
- return 0;
-
- ret = __check_allowed_appid(callee_appid, caller_appid, caller_uid);
- if (ret == 0)
- return 0;
-
- req_type = _request_get_request_type(req);
- if (req_type &&
- (!strcmp(req_type, "rpc-port") ||
- !strcmp(req_type, "complication") ||
- !strcmp(req_type, "bypass")))
- return 0;
-
- launch_type = bundle_get_val(kb, OSP_K_LAUNCH_TYPE);
- if (launch_type == NULL
- || strcmp(launch_type, OSP_V_LAUNCH_TYPE_DATACONTROL) != 0) {
- if (!_appinfo_is_platform_app(caller_appid, caller_uid)) {
- _E("Couldn't launch service app in other packages");
- return -EREJECTED;
- }
- }
-
- return 0;
-}
-
-static gboolean __fg_timeout_handler(gpointer data)
-{
- struct fgmgr *fg = data;
- app_status_h app_status;
-
- if (!fg)
- return FALSE;
-
- app_status = _app_status_find(fg->pid);
- if (app_status) {
- if (_app_status_get_status(app_status) != STATUS_VISIBLE) {
- _W("%d is running in the background", fg->pid);
- _app_status_update_status(app_status, STATUS_BG,
- true, true);
- }
- }
-
- _fgmgr_list = g_list_remove(_fgmgr_list, fg);
- free(fg);
-
- return FALSE;
-}
-
-struct fgmgr *__launch_find_fgmgr(int pid)
-{
- struct fgmgr *fg;
- GList *iter;
-
- iter = _fgmgr_list;
- while (iter) {
- fg = (struct fgmgr *)iter->data;
- if (fg->pid == pid)
- return fg;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static int __launch_add_fgmgr(int pid)
-{
- struct fgmgr *fg;
-
- _W("Add timer. pid(%d)", pid);
- fg = __launch_find_fgmgr(pid);
- if (fg) {
- g_source_remove(fg->tid);
- } else {
- fg = calloc(1, sizeof(struct fgmgr));
- if (!fg) {
- _E("Out of memory");
- return -1;
- }
-
- fg->pid = pid;
- _fgmgr_list = g_list_append(_fgmgr_list, fg);
- }
-
- fg->tid = g_timeout_add(_config_get_fg_timeout(),
- __fg_timeout_handler, fg);
-
- return 0;
-}
-
-static void __launch_remove_fgmgr(int pid)
-{
- struct fgmgr *fg;
-
- if (pid < 0)
- return;
-
- fg = __launch_find_fgmgr(pid);
- if (!fg)
- return;
-
- _W("Remove timer. pid(%d)", pid);
- g_source_remove(fg->tid);
- _fgmgr_list = g_list_remove(_fgmgr_list, fg);
- free(fg);
-}
-
-static int __send_hint_for_visibility(uid_t uid)
-{
- bundle *b;
- int ret;
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return -1;
- }
-
- ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
- PAD_CMD_VISIBILITY, b);
- bundle_free(b);
- __pid_of_last_launched_ui_app = 0;
-
- return ret;
-}
-
-static int __app_status_handler(int pid, int status, void *data)
-{
- const char *appid;
- int old_status;
- const struct appinfo *ai;
- app_status_h app_status;
- uid_t uid;
-
- _W("pid(%d) status(%d)", pid, status);
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return 0;
-
- old_status = _app_status_get_status(app_status);
- if (old_status == STATUS_DYING && old_status != PROC_STATUS_LAUNCH)
- return 0;
-
- uid = _app_status_get_uid(app_status);
- switch (status) {
- case PROC_STATUS_FG:
- __launch_remove_fgmgr(pid);
- _app_status_update_status(app_status, STATUS_VISIBLE, false,
- true);
- _suspend_remove_timer(pid);
- _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
- pid, uid, app_status, NULL);
- break;
- case PROC_STATUS_BG:
- _app_status_update_status(app_status, STATUS_BG, false, true);
- appid = _app_status_get_appid(app_status);
- ai = _appinfo_find(uid, appid);
- if (!_suspend_is_excluded(pid) &&
- !_suspend_is_allowed_background(ai)) {
- __prepare_to_suspend(pid, uid);
- _suspend_add_timer(pid);
- }
- _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_BG,
- pid, uid, app_status, NULL);
- break;
- case PROC_STATUS_FOCUS:
- __focused_pid = pid;
- _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
- pid, uid, app_status, NULL);
- break;
-
- case PROC_STATUS_HIDE:
- _app_status_update_status(app_status, STATUS_BG, false, true);
- _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_HIDE,
- pid, uid, app_status, NULL);
- break;
-
- case PROC_STATUS_LAUNCH:
- appid = _app_status_get_appid(app_status);
- if (appid) {
- LOG(LOG_DEBUG, "LAUNCH",
- "[%s:Application:Launching:done]",
- appid);
- }
- if (pid == __pid_of_last_launched_ui_app)
- __send_hint_for_visibility(uid);
- _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH,
- pid, uid, app_status, NULL);
- break;
-
- }
-
- return 0;
-}
-
-void _launch_set_focused_pid(int pid)
-{
- __focused_pid = pid;
-}
-
-int _launch_get_focused_pid(void)
-{
- return __focused_pid;
-}
-
-static int __listen_app_status_signal(void *data)
-{
- int ret;
-
- ret = aul_listen_app_status_signal(__app_status_handler, data);
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-static int __listen_poweroff_state_signal(void *data)
-{
- int ret;
-
- ret = _signal_subscribe_poweroff_state(__poweroff_state_cb, data);
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-static void __set_effective_appid(uid_t uid, bundle *kb)
-{
- const struct appinfo *ai;
- const struct appinfo *effective_ai;
- const char *appid;
- const char *effective_appid;
- const char *pkgid;
- const char *effective_pkgid;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (appid == NULL)
- return;
-
- ai = _appinfo_find(uid, appid);
- if (ai == NULL)
- return;
-
- bundle_del(kb, AUL_SVC_K_PKG_NAME);
- bundle_add(kb, AUL_SVC_K_PKG_NAME, appid);
-
- effective_appid = _appinfo_get_value(ai, AIT_EFFECTIVE_APPID);
- if (effective_appid == NULL)
- return;
-
- effective_ai = _appinfo_find(uid, effective_appid);
- if (effective_ai == NULL)
- return;
-
- pkgid = _appinfo_get_value(ai, AIT_PKGID);
- effective_pkgid = _appinfo_get_value(effective_ai, AIT_PKGID);
- if (pkgid && effective_pkgid && strcmp(pkgid, effective_pkgid) == 0) {
- _D("use effective appid instead of the real appid");
- bundle_del(kb, AUL_K_APPID);
- bundle_add(kb, AUL_K_APPID, effective_appid);
- }
-}
-
-static void __set_real_appid(uid_t uid, bundle *kb)
-{
- const char *alias_appid;
- const char *appid;
- const char *alias_info;
- app_property_h app_property;
-
- alias_appid = bundle_get_val(kb, AUL_K_APPID);
- if (alias_appid == NULL)
- return;
-
- alias_info = bundle_get_val(kb, AUL_SVC_K_ALIAS_INFO);
- if (alias_info && strcmp(alias_info, "disable") == 0)
- return;
-
- app_property = _app_property_find(uid);
- if (app_property == NULL)
- return;
-
- appid = _app_property_get_real_appid(app_property, alias_appid);
- if (appid == NULL)
- return;
-
- _D("alias_appid(%s), appid(%s)", alias_appid, appid);
- bundle_del(kb, AUL_K_ORG_APPID);
- bundle_add(kb, AUL_K_ORG_APPID, alias_appid);
- bundle_del(kb, AUL_K_APPID);
- bundle_add(kb, AUL_K_APPID, appid);
-}
-
-static void __check_new_instance(bundle *kb, bool *new_instance)
-{
- const char *str;
-
- str = bundle_get_val(kb, AUL_K_NEW_INSTANCE);
- if (str && !strcmp(str, "true"))
- *new_instance = true;
- else
- *new_instance = false;
-}
-
-static void __pend_result_info(request_h req, int pid)
-{
- struct result_info_s *info;
- bundle *kb;
- const char *seq;
- struct timespec end;
- unsigned int interval;
-
- if (pid <= 0)
- return;
-
- kb = _request_get_bundle(req);
- seq = bundle_get_val(kb, AUL_K_SEQ_NUM);
- if (!seq) {
- _E("Failed to get sequence");
- return;
- }
-
- clock_gettime(CLOCK_MONOTONIC, &end);
- interval = __get_timeout_interval(_request_get_start_time(req), &end);
- info = __create_result_info(interval, pid,
- _request_remove_fd(req), seq);
- if (!info) {
- _E("Failed to create result info");
- return;
- }
-
- __add_result_info(info);
-}
-
-static int __dispatch_app_start(request_h req)
-{
- const char *appid;
- int ret;
- bundle *kb;
- bool pending = false;
- bool bg_launch = false;
- bool new_instance = false;
- request_reply_h reply;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- __set_real_appid(_request_get_target_uid(req), kb);
- __set_effective_appid(_request_get_target_uid(req), kb);
-
- bundle_del(kb, AUL_K_NEW_INSTANCE);
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req, kb);
- __check_new_instance(kb, &new_instance);
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- ret = _launch_start_app(appid, req, &pending, &bg_launch, new_instance);
- if (ret <= 0)
- _noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, ret, 0, NULL, NULL);
-
- if (_request_get_cmd(req) == APP_SEND_LAUNCH_REQUEST_SYNC)
- __pend_result_info(req, ret);
-
- /* add pending list to wait app launched successfully */
- if (pending) {
- reply = _request_reply_create(req, ret, ret,
- _request_get_cmd(req));
- if (reply == NULL)
- return -1;
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_PEND,
- ret, bg_launch, req, (bundle *)reply);
-
- if (_request_reply_append(ret, reply) < 0) {
- _request_send_result(req, ret);
- return -1;
- }
-
- return 0;
- }
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END, ret, bg_launch, req, kb);
-
- return 0;
-}
-
-static int __get_caller_uid(bundle *kb, uid_t *uid)
-{
- const char *val;
-
- val = bundle_get_val(kb, AUL_K_ORG_CALLER_UID);
- if (val == NULL)
- val = bundle_get_val(kb, AUL_K_CALLER_UID);
-
- if (val == NULL) {
- _E("Failed to get caller uid");
- return -1;
- }
-
- *uid = atol(val);
- _D("caller uid(%d)", *uid);
-
- return 0;
-}
-
-static void __set_instance_id(bundle *kb)
-{
- app_status_h app_status;
- const char *instance_id;
- const char *callee_pid;
- int pid;
-
- callee_pid = bundle_get_val(kb, AUL_K_FWD_CALLEE_PID);
- if (callee_pid == NULL)
- callee_pid = bundle_get_val(kb, AUL_K_CALLEE_PID);
-
- if (callee_pid == NULL) {
- _E("Failed to get callee pid");
- return;
- }
-
- pid = atoi(callee_pid);
- if (pid <= 0)
- return;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return;
-
- instance_id = _app_status_get_instance_id(app_status);
- if (instance_id == NULL)
- return;
-
- bundle_del(kb, AUL_K_INSTANCE_ID);
- bundle_add(kb, AUL_K_INSTANCE_ID, instance_id);
- _D("instance_id(%s)", instance_id);
-}
-
-static int __get_caller_pid(bundle *kb)
-{
- const char *pid_str;
- int pid;
-
- pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
- if (pid_str)
- goto end;
-
- pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
- if (pid_str == NULL)
- return -1;
-
-end:
- pid = atoi(pid_str);
- if (pid <= 1)
- return -1;
-
- return pid;
-}
-
-static int __dispatch_app_result(request_h req)
-{
- bundle *kb;
- int pid;
- int pgid;
- char tmp_pid[MAX_PID_STR_BUFSZ];
- int res;
- const char *appid;
- uid_t target_uid = _request_get_target_uid(req);
- app_status_h app_status;
- struct result_info_s *info = NULL;
- const char *seq;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- pid = __get_caller_pid(kb);
- if (pid < 0)
- return AUL_R_ERROR;
-
- pgid = getpgid(_request_get_pid(req));
- if (pgid > 0) {
- snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pgid);
- bundle_del(kb, AUL_K_CALLEE_PID);
- bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
- }
-
- if (__get_caller_uid(kb, &target_uid) < 0)
- return AUL_R_ERROR;
-
- __set_instance_id(kb);
- app_status = _app_status_find(getpgid(pid));
- appid = _app_status_get_appid(app_status);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_RESULT_START,
- pgid, target_uid, (void *)appid, kb);
-
- seq = bundle_get_val(kb, AUL_K_SEQ_NUM);
- if (seq)
- info = __find_result_info(seq);
-
- if (info) {
- res = aul_sock_send_bundle_with_fd(info->fd, pid, kb,
- AUL_SOCK_NOREPLY);
- __remove_result_info(info);
- __destroy_result_info(info);
- } else {
- res = aul_sock_send_bundle(pid, target_uid,
- _request_get_cmd(req), kb,
- AUL_SOCK_NOREPLY);
- }
- if (res < 0)
- res = AUL_R_ERROR;
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_RESULT_END,
- pid, target_uid, GINT_TO_POINTER(res), NULL);
-
- return 0;
-}
-
-static int __dispatch_app_pause(request_h req)
-{
- const char *appid;
- bundle *kb;
- int ret;
- app_status_h app_status;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- ret = _app_status_get_pid(app_status);
- if (ret > 0)
- ret = _pause_app(ret, req);
- else
- _E("%s is not running", appid);
-
- return 0;
-}
-
-static int __app_process_by_pid(request_h req, const char *pid_str,
- bool *pending)
-{
- int pid;
- int ret;
- int dummy;
- const char *appid;
- const char *pkgid;
- const char *type;
- const struct appinfo *ai;
- uid_t target_uid = _request_get_target_uid(req);
- app_status_h app_status;
-
- if (pid_str == NULL)
- return -1;
-
- pid = atoi(pid_str);
- if (pid <= 1) {
- _E("invalid pid");
- return -1;
- }
-
- app_status = _app_status_find(pid);
- if (app_status == NULL) {
- _E("pid %d is not an application", pid);
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = _app_status_get_appid(app_status);
- ai = _appinfo_find(target_uid, appid);
- if (ai == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- pkgid = _appinfo_get_value(ai, AIT_PKGID);
- type = _appinfo_get_value(ai, AIT_COMPTYPE);
-
- switch (_request_get_cmd(req)) {
- case APP_RESUME_BY_PID:
- case APP_RESUME_BY_PID_ASYNC:
- case APP_PAUSE_BY_PID:
- aul_send_app_resume_request_signal(pid, appid, pkgid, type);
- break;
- default:
- aul_send_app_terminate_request_signal(pid, appid, pkgid, type);
- break;
- }
-
- switch (_request_get_cmd(req)) {
- case APP_RESUME_BY_PID_ASYNC:
- _request_send_result(req, 0);
- ret = _resume_app(pid, req);
- break;
- case APP_RESUME_BY_PID:
- ret = _resume_app(pid, req);
- break;
- case APP_TERM_BY_PID:
- ret = _term_app(pid, req);
- break;
- case APP_TERM_BY_PID_WITHOUT_RESTART:
- if (_app_status_get_app_type(app_status) == AT_WIDGET_APP)
- _app_status_update_is_exiting(app_status, true);
- ret = _term_app(pid, req);
- break;
- case APP_TERM_BGAPP_BY_PID:
- ret = _term_bgapp(pid, req);
- break;
- case APP_KILL_BY_PID:
- ret = __send_sigkill(pid, target_uid);
- if (ret < 0)
- _E("fail to killing - %d\n", pid);
- _app_status_update_status(app_status, STATUS_DYING, false, true);
- _request_send_result(req, ret);
- break;
- case APP_TERM_REQ_BY_PID:
- ret = _term_req_app(pid, req);
- break;
- case APP_TERM_BY_PID_ASYNC:
- ret = aul_sock_send_raw(pid, target_uid, _request_get_cmd(req),
- (unsigned char *)&dummy, sizeof(int),
- AUL_SOCK_NOREPLY);
- if (ret < 0)
- _D("terminate req packet send error");
-
- _request_send_result(req, ret);
- break;
- case APP_PAUSE_BY_PID:
- ret = _pause_app(pid, req);
- break;
- case APP_TERM_BY_PID_SYNC:
- case APP_TERM_BY_PID_SYNC_WITHOUT_RESTART:
- if (_app_status_get_status(app_status) == STATUS_DYING) {
- _W("%d is dying", pid);
- if (pending)
- *pending = true;
- ret = 0;
- break;
- }
- ret = _term_app_v2(pid, req, pending);
- break;
- case APP_TERM_INSTANCE_ASYNC:
- ret = _launch_terminate_inst(pid, req);
- break;
- default:
- _E("unknown command: %d", _request_get_cmd(req));
- ret = -1;
- }
-
- return ret;
-}
-
-static int __dispatch_app_process_by_pid(request_h req)
-{
- const char *appid;
- bundle *kb;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- __app_process_by_pid(req, appid, NULL);
-
- return 0;
-}
-
-static int __dispatch_app_term_async(request_h req)
-{
- const char *appid;
- bundle *kb;
- const char *term_pid;
- struct appinfo *ai;
- app_status_h app_status;
- const char *ai_status;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- term_pid = bundle_get_val(kb, AUL_K_APPID);
- app_status = _app_status_find(atoi(term_pid));
- appid = _app_status_get_appid(app_status);
- ai = _appinfo_find(_request_get_target_uid(req), appid);
- if (ai) {
- ai_status = _appinfo_get_value(ai, AIT_STATUS);
- if (ai_status && strcmp(ai_status, "blocking") != 0)
- _appinfo_set_value(ai, AIT_STATUS, "norestart");
- __app_process_by_pid(req, term_pid, NULL);
- }
-
- return 0;
-}
-
-static int __dispatch_app_term(request_h req)
-{
- const char *appid;
- bundle *kb;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- __app_process_by_pid(req, appid, NULL);
-
- return 0;
-}
-
-static int __dispatch_app_term_sync(request_h req)
-{
- int ret;
- int pid;
- const char *appid;
- bundle *kb;
- bool pending = false;
- request_reply_h reply;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- ret = __app_process_by_pid(req, appid, &pending);
- if (ret < 0)
- return -1;
-
- /* add pending list to wait app terminated successfully */
- if (pending) {
- pid = atoi(appid);
- reply = _request_reply_create(req, pid, -EAGAIN,
- _request_get_cmd(req));
- if (reply == NULL)
- return -1;
-
- _request_reply_append(pid, reply);
- _request_reply_reset_pending_timer(req, -1, pid);
- }
-
- return 0;
-}
-
-static int __dispatch_app_term_sync_without_restart(request_h req)
-{
- int ret = -1;
- const char *appid;
- const char *term_pid;
- const char *component_type;
- struct appinfo *ai;
- app_status_h app_status;
- const char *ai_status;
-
- term_pid = bundle_get_val(_request_get_bundle(req), AUL_K_APPID);
- if (term_pid == NULL)
- goto exception;
-
- app_status = _app_status_find(atoi(term_pid));
- if (app_status == NULL)
- goto exception;
-
- appid = _app_status_get_appid(app_status);
- if (appid == NULL)
- goto exception;
-
- ai = _appinfo_find(_request_get_target_uid(req), appid);
- if (ai == NULL)
- goto exception;
-
- component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (!component_type)
- goto exception;
-
- ret = __dispatch_app_term_sync(req);
- if (ret < 0)
- return ret;
-
- if (strcmp(component_type, APP_TYPE_SERVICE) == 0) {
- ai_status = _appinfo_get_value(ai, AIT_STATUS);
- if (ai_status && strcmp(ai_status, "blocking") != 0)
- _appinfo_set_value(ai, AIT_STATUS, "norestart");
- }
- return 0;
-
-exception:
- _request_send_result(req, ret);
- return ret;
-}
-
-static int __dispatch_app_startup_signal(request_h req)
-{
- int pid = _request_get_pid(req);
- app_status_h app_status;
-
- _W("[START] pid(%d)", pid);
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return -1;
-
- _app_status_update_is_starting(app_status, true);
- if (_app_status_get_app_type(app_status) == AT_UI_APP &&
- _app_status_get_status(app_status) != STATUS_VISIBLE)
- __launch_add_fgmgr(pid);
-
- _request_reply_reset_pending_timer(req, PENDING_REQUEST_TIMEOUT, pid);
- _noti_send(AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END, pid, 0, req, NULL);
- _W("[END] pid(%d)", pid);
-
- return 0;
-}
-
-static int __dispatch_app_term_instance_async(request_h req)
-{
- const char *appid;
- bundle *kb;
- int clifd;
- int ret;
-
- kb = _request_get_bundle(req);
- if (!kb) {
- _E("Invalid request");
- _request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- clifd = _request_remove_fd(req);
- ret = __app_process_by_pid(req, appid, NULL);
- _send_result_to_client(clifd, ret);
- _I("[APP_TERM_INSTANCE_ASYNC] result: %d", ret);
-
- return 0;
-}
-
-static int __dispatch_app_terminate(request_h req)
-{
- app_status_h app_status;
- const char *instance_id;
- const char *appid;
- uid_t target_uid;
- bundle *kb;
- int pid;
- int ret;
- int fd;
-
- kb = _request_get_bundle(req);
- if (!kb) {
- _E("Invalid request");
- _request_send_result(req, -EINVAL);
- return -EINVAL;
- }
-
- target_uid = _request_get_target_uid(req);
- appid = bundle_get_val(kb, AUL_K_APPID);
- instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- if (instance_id) {
- app_status = _app_status_find_by_instance_id(appid,
- instance_id, target_uid);
- } else {
- app_status = _app_status_find_by_appid(appid, target_uid);
- }
-
- if (!app_status) {
- _E("Failed to find app status");
- _request_send_result(req, -ENOENT);
- return -ENOENT;
- }
-
- fd = _request_remove_fd(req);
- pid = _app_status_get_pid(app_status);
- aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
- ret = _term_req_app(pid, req);
- _send_result_to_client(fd, ret);
- _I("[APP_TERMINATE] result: %d", ret);
-
- return 0;
-}
-
-static const char *__convert_operation_to_privilege(const char *operation)
-{
- if (operation == NULL)
- return NULL;
- else if (!strcmp(operation, AUL_SVC_OPERATION_DOWNLOAD))
- return PRIVILEGE_DOWNLOAD;
- else if (!strcmp(operation, AUL_SVC_OPERATION_CALL))
- return PRIVILEGE_CALL;
-
- return NULL;
-}
-
-struct checker_info {
- caller_info_h caller;
- request_h req;
- int result;
-};
-
-static int __appcontrol_privilege_func(const char *privilege_name,
- void *user_data)
-{
- int ret;
- struct checker_info *info = (struct checker_info *)user_data;
-
- ret = _cynara_simple_checker(info->caller, info->req,
- (void *)privilege_name);
- if (ret >= 0 && info->result == AMD_CYNARA_UNKNOWN)
- return ret;
-
- info->result = ret;
- return ret;
-}
-
-static int __appcontrol_checker(caller_info_h info, request_h req,
- void *data)
-{
- bundle *appcontrol;
- const char *op_priv = NULL;
- const char *appid = NULL;
- char *op = NULL;
- int ret;
- const char *target_appid;
- bool unknown = false;
- const char *syspopup;
- const char *below;
- struct checker_info checker = {
- .caller = info,
- .req = req,
- .result = AMD_CYNARA_ALLOWED
- };
-
- appcontrol = _request_get_bundle(req);
- if (appcontrol == NULL)
- return AMD_CYNARA_ALLOWED;
-
- if (bundle_get_type(appcontrol, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
- target_appid = bundle_get_val(appcontrol, AUL_K_APPID);
-
- if (target_appid && strcmp(target_appid, APPID_WIDGET_VIEWER_SDK) != 0) {
- ret = _cynara_check_privilege_offline(req, target_appid,
- "http://tizen.org/privilege/internal/appdebugging");
- if (ret != AMD_CYNARA_ALLOWED) {
- _E("appdebugging privilege is needed to debug");
- return ret;
- }
- }
- }
-
- ret = _cynara_sub_checker_check("appcontrol", info, req);
- if (ret != AMD_CYNARA_CONTINUE)
- return ret;
-
- ret = bundle_get_str(appcontrol, AUL_SVC_K_OPERATION, &op);
- if (ret == BUNDLE_ERROR_NONE)
- op_priv = __convert_operation_to_privilege(op);
- if (op_priv) {
- ret = _cynara_simple_checker(info, req, (void *)op_priv);
- if (ret < 0)
- return ret;
- if (ret == AMD_CYNARA_UNKNOWN)
- unknown = true;
- }
-
- appid = bundle_get_val(appcontrol, AUL_K_APPID);
- if (appid && op) {
- ret = pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(
- appid, op, __appcontrol_privilege_func,
- &checker, _request_get_target_uid(req));
- if (ret < 0) {
- _E("Failed to get appcontrol privileges");
- return ret;
- }
-
- if (checker.result < 0)
- return checker.result;
- else if (checker.result == AMD_CYNARA_UNKNOWN)
- unknown = true;
- }
-
- syspopup = bundle_get_val(appcontrol, SYSPOPUP_NAME);
- below = bundle_get_val(appcontrol, AUL_SVC_K_RELOCATE_BELOW);
- if (below || syspopup) {
- ret = _cynara_simple_checker(info, req, PRIVILEGE_PLATFORM);
- if (ret < 0)
- return ret;
- if (ret == AMD_CYNARA_UNKNOWN)
- unknown = true;
- }
-
- ret = _cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
- if (unknown && ret >= 0)
- return AMD_CYNARA_UNKNOWN;
-
- return ret;
-}
-
-static int __term_req_checker(caller_info_h info, request_h req,
- void *data)
-{
- app_status_h app_status;
- int caller_pid = _request_get_pid(req);
- int target_pid = -1;
- int first_caller_pid;
- const char *pid_str;
- bundle *b;
-
- b = _request_get_bundle(req);
- if (!b) {
- _E("Failed to get bundle");
- return AMD_CYNARA_DENIED;
- }
-
- pid_str = bundle_get_val(b, AUL_K_APPID);
- if (!pid_str) {
- _E("Failed to get process ID");
- return AMD_CYNARA_DENIED;
- }
-
- target_pid = atoi(pid_str);
- if (target_pid < 1) {
- _E("Process ID: %d", target_pid);
- return AMD_CYNARA_DENIED;
- }
-
- app_status = _app_status_find(target_pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", target_pid);
- return AMD_CYNARA_DENIED;
- }
-
- if (_app_status_get_app_type(app_status) != AT_UI_APP) {
- _E("Target application is not UI application");
- return AMD_CYNARA_DENIED;
- }
-
- first_caller_pid = _app_status_get_org_caller_pid(app_status);
- if (first_caller_pid != caller_pid &&
- first_caller_pid != getpgid(caller_pid)) {
- _E("Request denied. caller(%d)", caller_pid);
- return AMD_CYNARA_DENIED;
- }
-
- return AMD_CYNARA_ALLOWED;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_START,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_START_ASYNC,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_START_RES_ASYNC,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_START_RES,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_OPEN,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_RESUME,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_RESUME_BY_PID,
- .callback = __dispatch_app_process_by_pid
- },
- {
- .cmd = APP_RESUME_BY_PID_ASYNC,
- .callback = __dispatch_app_process_by_pid
- },
- {
- .cmd = APP_TERM_BY_PID,
- .callback = __dispatch_app_term
- },
- {
- .cmd = APP_TERM_BY_PID_WITHOUT_RESTART,
- .callback = __dispatch_app_term_async
- },
- {
- .cmd = APP_TERM_BY_PID_SYNC,
- .callback = __dispatch_app_term_sync
- },
- {
- .cmd = APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
- .callback = __dispatch_app_term_sync_without_restart
- },
- {
- .cmd = APP_TERM_REQ_BY_PID,
- .callback = __dispatch_app_process_by_pid
- },
- {
- .cmd = APP_TERM_BY_PID_ASYNC,
- .callback = __dispatch_app_term_async
- },
- {
- .cmd = APP_TERM_BGAPP_BY_PID,
- .callback = __dispatch_app_term
- },
- {
- .cmd = APP_RESULT,
- .callback = __dispatch_app_result
- },
- {
- .cmd = APP_CANCEL,
- .callback = __dispatch_app_result
- },
- {
- .cmd = APP_PAUSE,
- .callback = __dispatch_app_pause
- },
- {
- .cmd = APP_PAUSE_BY_PID,
- .callback = __dispatch_app_process_by_pid
- },
- {
- .cmd = APP_KILL_BY_PID,
- .callback = __dispatch_app_term
- },
- {
- .cmd = APP_STARTUP_SIGNAL,
- .callback = __dispatch_app_startup_signal
- },
- {
- .cmd = APP_SEND_LAUNCH_REQUEST,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_SEND_LAUNCH_REQUEST_SYNC,
- .callback = __dispatch_app_start
- },
- {
- .cmd = APP_TERM_INSTANCE_ASYNC,
- .callback = __dispatch_app_term_instance_async
- },
- {
- .cmd = APP_TERMINATE,
- .callback = __dispatch_app_terminate
- },
- {
- .cmd = APP_SEND_RESUME_REQUEST,
- .callback = __dispatch_app_start
- },
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_OPEN,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_RESUME,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_START,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_START_RES,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_TERM_BY_PID_WITHOUT_RESTART,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_TERM_BY_PID_ASYNC,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_TERM_BY_PID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_KILL_BY_PID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_TERM_BGAPP_BY_PID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL_BGAPP
- },
- {
- .cmd = APP_START_ASYNC,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_TERM_BY_PID_SYNC,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_START_RES_ASYNC,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_TERM_REQ_BY_PID,
- .checker = __term_req_checker,
- .data = NULL
- },
- {
- .cmd = APP_RESUME_BY_PID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = APP_RESUME_BY_PID_ASYNC,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = APP_PAUSE,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = APP_PAUSE_BY_PID,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
- {
- .cmd = APP_SEND_LAUNCH_REQUEST,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_SEND_LAUNCH_REQUEST_SYNC,
- .checker = __appcontrol_checker,
- .data = NULL
- },
- {
- .cmd = APP_TERMINATE,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_KILL
- },
- {
- .cmd = APP_SEND_RESUME_REQUEST,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_APPMANAGER_LAUNCH
- },
-};
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- app_status_h app_status = arg3;
- int pid;
-
- pid = _app_status_get_pid(app_status);
- __launch_remove_fgmgr(pid);
-
- return 0;
-}
-
-static int __default_launcher(bundle *b, uid_t uid, void *data)
-{
- int r;
-
- if (!b) {
- _E("Invalid parameter");
- return -1;
- }
-
- r = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
- PAD_CMD_LAUNCH, b);
- return r;
-}
-
-int _launch_init(void)
-{
- int ret;
-
- _D("_launch_init");
-
- _launchpad_set_launcher(__default_launcher, NULL);
-
- _signal_add_ready_cb(__listen_app_status_signal, NULL);
- _signal_add_ready_cb(__listen_poweroff_state_signal, NULL);
-
- ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- ret = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (ret < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- _noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP, __on_app_status_cleanup);
-
- return 0;
-}
-
-static int __check_ver(const char *required, const char *actual)
-{
- int ret;
-
- if (required && actual) {
- ret = strverscmp(required, actual);
- if (ret < 1)
- return 1;
- }
-
- return 0;
-}
-
-static int __get_prelaunch_attribute(struct appinfo *ai,
- const char *appid, uid_t uid)
-{
- int attribute_val = RESOURCED_BG_MANAGEMENT_ATTRIBUTE;
- const char *api_version;
- const char *comp;
- const char *pkg_type;
- bool system = false;
- app_property_h prop;
- bool activate;
-
- api_version = _appinfo_get_value(ai, AIT_API_VERSION);
- if (api_version && __check_ver("2.4", api_version))
- attribute_val |= RESOURCED_API_VER_2_4_ATTRIBUTE;
-
- comp = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp && !strcmp(comp, APP_TYPE_SERVICE))
- attribute_val |= RESOURCED_ATTRIBUTE_SERVICE_APP;
-
- pkg_type = _appinfo_get_value(ai, AIT_PKGTYPE);
- if (pkg_type && !strcmp(pkg_type, "wgt")) {
- attribute_val |= RESOURCED_ATTRIBUTE_LARGEMEMORY;
- attribute_val |= RESOURCED_ATTRIBUTE_WEB_APP;
- }
-
- _appinfo_get_boolean(ai, AIT_SYSTEM, &system);
- if (!system)
- attribute_val |= RESOURCED_ATTRIBUTE_DOWNLOAD_APP;
-
- prop = _app_property_find(uid);
- if (prop) {
- activate = _app_property_metadata_query_activation(prop, appid,
- METADATA_LARGEMEMORY);
- if (activate)
- attribute_val |= RESOURCED_ATTRIBUTE_LARGEMEMORY;
- activate = _app_property_metadata_query_activation(prop, appid,
- METADATA_OOMTERMINATION);
- if (activate)
- attribute_val |= RESOURCED_ATTRIBUTE_OOMTERMINATION;
- activate = _app_property_metadata_query_activation(prop, appid,
- METADATA_VIPAPP);
- if (activate && _appinfo_is_platform_app(appid, uid))
- attribute_val |= RESOURCED_ATTRIBUTE_VIP_APP;
-
- }
-
- _D("api-version: %s", api_version);
- _D("prelaunch attribute %d%d%d%d%d%d",
- (attribute_val & 0x20) >> 5,
- (attribute_val & 0x10) >> 4,
- (attribute_val & 0x8) >> 3,
- (attribute_val & 0x4) >> 2,
- (attribute_val & 0x2) >> 1,
- (attribute_val & 0x1));
-
- return attribute_val;
-}
-
-static int __get_background_category(const struct appinfo *ai)
-{
- int category = 0x0;
-
- category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
-
- _D("background category: %#x", category);
-
- return category;
-}
-
-static void __set_caller_appinfo(const char *caller_appid, int caller_pid,
- uid_t caller_uid, bundle *kb)
-{
- char buf[MAX_PID_STR_BUFSZ];
-
- snprintf(buf, sizeof(buf), "%d", caller_pid);
- bundle_del(kb, AUL_K_CALLER_PID);
- bundle_add(kb, AUL_K_CALLER_PID, buf);
-
- snprintf(buf, sizeof(buf), "%d", caller_uid);
- bundle_del(kb, AUL_K_CALLER_UID);
- bundle_add(kb, AUL_K_CALLER_UID, buf);
-
- if (caller_appid) {
- bundle_del(kb, AUL_K_CALLER_APPID);
- bundle_add(kb, AUL_K_CALLER_APPID, caller_appid);
- }
-}
-
-static const char *__get_caller_appid(int caller_pid, uid_t caller_uid)
-{
- app_status_h app_status;
-
- app_status = _app_status_find(caller_pid);
- if (app_status == NULL && caller_uid >= REGULAR_UID_MIN)
- app_status = _app_status_find(getpgid(caller_pid));
-
- return _app_status_get_appid(app_status);
-}
-
-static int __check_caller(pid_t caller_pid)
-{
- char attr[512] = { 0, };
- int r;
-
- r = _proc_get_attr(caller_pid, attr, sizeof(attr));
- if (r < 0) {
- _E("Failed to get attr. pid(%d)", caller_pid);
- return -EILLEGALACCESS;
- }
-
- if (!strncmp(attr, "User::Pkg::", strlen("User::Pkg::"))) {
- _E("Reject request. caller(%d:%s)", caller_pid, attr);
- return -EILLEGALACCESS;
- }
-
- return 0;
-}
-
-static int __check_executable(const struct appinfo *ai)
-{
- const char *status;
- const char *ignore;
- int enable;
- int ret;
-
- status = _appinfo_get_value(ai, AIT_STATUS);
- if (status == NULL) {
- _E("Failed to get status value");
- return -1;
- }
-
- if (!strcmp(status, "blocking") || !strcmp(status, "restart")) {
- ignore = _appinfo_get_value(ai, AIT_IGNORE);
- if (!ignore || strcmp(ignore, "true") != 0) {
- _W("Blocking");
- return -ENOENT;
- }
- _W("Ignore blocking");
- }
-
- ret = _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
- if (ret == 0 && !(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
- _W("Disabled");
- return -ENOENT;
- }
-
- return 0;
-}
-
-static void __set_appinfo_for_launchpad(const struct appinfo *ai, bundle *kb)
-{
- const char *str;
-
- str = _appinfo_get_value(ai, AIT_HWACC);
- if (str) {
- bundle_del(kb, AUL_K_HWACC);
- bundle_add(kb, AUL_K_HWACC, str);
- }
-
- str = _appinfo_get_value(ai, AIT_ROOT_PATH);
- if (str) {
- bundle_del(kb, AUL_K_ROOT_PATH);
- bundle_add(kb, AUL_K_ROOT_PATH, str);
- }
-
- str = _appinfo_get_value(ai, AIT_EXEC);
- if (str) {
- bundle_del(kb, AUL_K_EXEC);
- bundle_add(kb, AUL_K_EXEC, str);
- }
-
- str = _appinfo_get_value(ai, AIT_PKGTYPE);
- if (str) {
- bundle_del(kb, AUL_K_PACKAGETYPE);
- bundle_add(kb, AUL_K_PACKAGETYPE, str);
- }
-
- str = _appinfo_get_value(ai, AIT_PKGID);
- if (str) {
- bundle_del(kb, AUL_K_PKGID);
- bundle_add(kb, AUL_K_PKGID, str);
- }
-
- str = _appinfo_get_value(ai, AIT_POOL);
- if (str) {
- bundle_del(kb, AUL_K_INTERNAL_POOL);
- bundle_add(kb, AUL_K_INTERNAL_POOL, str);
- }
-
- str = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (str) {
- bundle_del(kb, AUL_K_COMP_TYPE);
- bundle_add(kb, AUL_K_COMP_TYPE, str);
- }
-
- str = _appinfo_get_value(ai, AIT_APPTYPE);
- if (str) {
- bundle_del(kb, AUL_K_APP_TYPE);
- bundle_add(kb, AUL_K_APP_TYPE, str);
- }
-
- str = _appinfo_get_value(ai, AIT_API_VERSION);
- if (str) {
- bundle_del(kb, AUL_K_API_VERSION);
- bundle_add(kb, AUL_K_API_VERSION, str);
- }
-
- if (_config_get_tizen_profile() == TIZEN_PROFILE_WEARABLE) {
- bundle_del(kb, AUL_K_PROFILE);
- bundle_add(kb, AUL_K_PROFILE, "wearable");
- }
-
- str = _appinfo_get_value(ai, AIT_GLOBAL);
- if (str) {
- bundle_del(kb, AUL_K_IS_GLOBAL);
- bundle_add(kb, AUL_K_IS_GLOBAL, str);
- }
-
- str = _appinfo_get_value(ai, AIT_STORAGE_TYPE);
- if (str) {
- bundle_del(kb, AUL_K_INSTALLED_STORAGE);
- bundle_add(kb, AUL_K_INSTALLED_STORAGE, str);
- }
-}
-
-static int __get_comp_status(struct launch_s *handle, request_h req)
-{
- int status;
-
- if (handle->instance_id) {
- handle->comp_status = _comp_status_find_by_instance_id(
- handle->instance_id);
- } else {
- handle->comp_status = _comp_status_find(handle->comp_id);
- }
-
- status = _comp_status_get_status(handle->comp_status);
- if (status == COMP_STATUS_DESTROYED) {
- SECURE_LOGW("%s is destroyed", handle->instance_id);
- if (handle->instance_id)
- return -1;
-
- handle->comp_status = NULL;
- }
-
- if (handle->comp_status == NULL)
- handle->new_instance = true;
-
- return 0;
-}
-
-static int __compare_compinfo_appid(struct launch_s *handle)
-{
- const char *appid;
-
- appid = _compinfo_get_value(handle->ci, CIT_APPID);
- if (!appid) {
- _E("Failed to get application ID. component(%s)",
- handle->comp_id);
- return -EREJECTED;
- }
-
- if (strcmp(appid, handle->appid) != 0) {
- _E("Invalid request(%s:%s)", appid, handle->appid);
- return -EREJECTED;
- }
-
- return 0;
-}
-
-void __find_main_compinfo(compinfo_h info, const char *appid,
- const char *id, void *user_data)
-{
- struct launch_s *handle = (struct launch_s *)user_data;
- const char *val;
-
- if (strcmp(appid, handle->appid) != 0)
- return;
-
- val = _compinfo_get_value(info, CIT_MAIN);
- if (val && !strcmp(val, "true")) {
- handle->ci = info;
- handle->comp_id = id;
- }
-}
-
-static int __set_main_comp_id(struct launch_s *handle, bundle *kb, uid_t uid)
-{
- int ret;
-
- ret = _compinfo_foreach(uid, __find_main_compinfo, handle);
- if (ret != 0) {
- _E("Failed to retrieve compinfo");
- return -EREJECTED;
- }
-
- if (handle->ci == NULL || handle->comp_id == NULL) {
- _E("Failed to find compinfo");
- return -EREJECTED;
- }
-
- bundle_add(kb, AUL_K_COMPONENT_ID, handle->comp_id);
- SECURE_LOGW("Set Main Component ID(%s) of App ID(%s)",
- handle->comp_id, handle->appid);
-
- return 0;
-}
-
-static int __get_app_status(struct launch_s *handle, request_h req,
- const char *comp_type, const char *caller_appid)
-{
- const char *widget_viewer;
- const char *multiple;
- int *target_pid = NULL;
- size_t target_pid_sz;
- bundle *kb = _request_get_bundle(req);
- int caller_pid = _request_get_pid(req);
- uid_t target_uid = _request_get_target_uid(req);
- int ret;
-
- if (caller_appid && strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
- handle->is_subapp = true;
- widget_viewer = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
- if (widget_viewer && strcmp(widget_viewer, caller_appid) == 0) {
- _D("widget_viewer(%s)", widget_viewer);
- handle->app_status = _app_status_find_with_org_caller(
- handle->appid, target_uid, caller_pid);
- } else {
- ret = bundle_get_byte(kb, AUL_K_TARGET_PID,
- (void **)&target_pid, &target_pid_sz);
- if (ret != BUNDLE_ERROR_NONE) {
- _E("Cannot launch widget app");
- return -EREJECTED;
- }
-
- handle->app_status = _app_status_find(*target_pid);
- if (handle->app_status == NULL) {
- _E("Cannot find widget app(%d)", *target_pid);
- return -EREJECTED;
- }
-
- if (_app_status_get_status(handle->app_status)
- == STATUS_DYING) {
- _E("Dying widget(%s) reject launching",
- handle->appid);
- return -EREJECTED;
- }
- }
- } else if (strcmp(comp_type, APP_TYPE_WATCH) == 0) {
- handle->is_subapp = true;
- widget_viewer = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
- if (widget_viewer && caller_appid &&
- !strcmp(widget_viewer, caller_appid)) {
- _D("watch_viewer(%s)", widget_viewer);
- handle->app_status = _app_status_find_with_org_caller(
- handle->appid, target_uid, caller_pid);
- } else {
- ret = bundle_get_byte(kb, AUL_K_TARGET_PID,
- (void **)&target_pid, &target_pid_sz);
- if (ret != BUNDLE_ERROR_NONE) {
- handle->app_status =
- _app_status_find_by_appid_v2(
- handle->appid,
- target_uid);
- } else {
- handle->app_status =
- _app_status_find(*target_pid);
- }
-
- if (handle->app_status == NULL) {
- _E("Cannot find watch app(%s)", handle->appid);
- return -EREJECTED;
- }
- }
- } else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0) {
- handle->comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- if (!handle->comp_id) {
- ret = __set_main_comp_id(handle, kb, target_uid);
- if (ret < 0)
- return ret;
- }
-
- handle->instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- SECURE_LOGD("component(%s), instance(%s)",
- handle->comp_id, handle->instance_id);
-
- if (!handle->ci) {
- handle->ci = _compinfo_find(target_uid,
- handle->comp_id);
- }
-
- if (!handle->ci) {
- _E("Failed to find component(%s)", handle->comp_id);
- return -EREJECTED;
- }
-
- ret = __compare_compinfo_appid(handle);
- if (ret < 0)
- return ret;
-
- handle->app_status = _app_status_find_by_appid(handle->appid,
- target_uid);
- if (handle->app_status) {
- ret = __get_comp_status(handle, req);
- if (ret < 0) {
- _E("Failed to get component(%s) status",
- handle->appid);
- return -EREJECTED;
- }
- } else {
- handle->new_instance = true;
- }
- } else {
- handle->instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
- if (handle->instance_id) {
- handle->app_status = _app_status_find_by_instance_id(
- handle->appid, handle->instance_id,
- target_uid);
- if (!handle->app_status && !handle->new_instance) {
- _E("Failed to find app instance(%s)",
- handle->instance_id);
- return -EREJECTED;
- }
- } else {
- multiple = _appinfo_get_value(handle->ai, AIT_MULTI);
- if (multiple == NULL || !strcmp(multiple, "false")) {
- handle->app_status = _app_status_find_by_appid(
- handle->appid, target_uid);
- }
- }
- }
-
- handle->pid = _app_status_get_pid(handle->app_status);
-
- return 0;
-}
-
-static void __set_comp_instance_info(struct launch_s *handle, bundle *kb)
-{
- if (!handle->comp_status) {
- handle->instance_id = _comp_status_generate_instance(
- handle->comp_id);
- } else {
- handle->instance_id = _comp_status_get_instance_id(
- handle->comp_status);
- }
-
- bundle_del(kb, AUL_K_INSTANCE_ID);
- bundle_add(kb, AUL_K_INSTANCE_ID, handle->instance_id);
-}
-
-static int __prepare_starting_app(struct launch_s *handle, request_h req,
- const char *appid, bool new_instance)
-{
- int ret;
- int status;
- const char *pkgid;
- const char *comp_type;
- const char *caller_appid = NULL;
- const char *bg_launch;
- int cmd = _request_get_cmd(req);
- int caller_pid = _request_get_pid(req);
- uid_t caller_uid = _request_get_uid(req);
- uid_t target_uid = _request_get_target_uid(req);
- bundle *kb = _request_get_bundle(req);
- const struct appinfo *caller_ai;
-
- if (__launch_mode != LAUNCH_MODE_NORMAL) {
- _E("Launch mode is not normal: %d", __launch_mode);
- return -EREJECTED;
- }
-
- handle->new_instance = new_instance;
- handle->appid = appid;
- handle->ai = _appinfo_find(target_uid, appid);
- if (handle->ai == NULL) {
- _E("Failed to find appinfo of %s", appid);
- return -ENOENT;
- }
-
- ret = __check_executable(handle->ai);
- if (ret < 0)
- return ret;
-
- if (caller_uid >= REGULAR_UID_MIN) {
- caller_appid = __get_caller_appid(caller_pid, caller_uid);
- if (!caller_appid) {
- ret = __check_caller(caller_pid);
- if (ret != 0)
- return ret;
- }
- }
-
- if (caller_appid) {
- caller_ai = _appinfo_find(caller_uid, caller_appid);
- if (caller_ai) {
- comp_type = _appinfo_get_value(caller_ai, AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI))
- bundle_del(kb, AUL_SVC_K_CAN_BE_LEADER);
- }
- }
- __set_caller_appinfo(caller_appid, caller_pid, caller_uid, kb);
-
- ret = __compare_signature(handle->ai, cmd, target_uid, appid,
- caller_appid);
- if (ret < 0)
- return ret;
-
- ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
- (int)target_uid, 0, (void *)(handle->ai), NULL);
- if (ret < 0) {
- _E("Unable to launch %s (Some listeners don't want to continue)",
- handle->appid);
- return -1;
- }
-
- bg_launch = bundle_get_val(kb, AUL_SVC_K_BG_LAUNCH);
- if (bg_launch && strcmp(bg_launch, "enable") == 0)
- handle->bg_launch = true;
-
- comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
- if (comp_type == NULL)
- return -1;
-
- ret = __get_app_status(handle, req, comp_type, caller_appid);
- if (ret < 0)
- return ret;
-
- if (strcmp(comp_type, APP_TYPE_UI) == 0) {
- status = _app_status_get_status(handle->app_status);
- ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
- status, target_uid, handle, kb);
- if (ret < 0)
- return -EILLEGALACCESS;
-
- if (handle->pid > 0) {
- handle->app_status = _app_status_find(handle->pid);
- status = _app_status_get_status(handle->app_status);
- }
-
- if (handle->pid <= 0 || status == STATUS_DYING)
- handle->new_process = true;
-
- if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END,
- handle->bg_launch, caller_pid,
- (void *)(handle->app_status), NULL) < 0)
- return -1;
- } else if (caller_appid && strcmp(comp_type, APP_TYPE_SERVICE) == 0) {
- pkgid = _appinfo_get_value(handle->ai, AIT_PKGID);
- ret = __check_execute_permission(pkgid, caller_appid,
- target_uid, req);
- if (ret < 0)
- return ret;
- if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_SERVICE,
- 0, 0, req, NULL) < 0)
- return -1;
- } else if (caller_appid && strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
- if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET,
- 0, 0, req, NULL) < 0)
- return -1;
- } else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0) {
- status = _app_status_get_status(handle->app_status);
- ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
- status, target_uid, handle, kb);
- if (ret < 0)
- return -EILLEGALACCESS;
-
- if (handle->pid > 0) {
- handle->app_status = _app_status_find(handle->pid);
- status = _app_status_get_status(handle->app_status);
- }
-
- if (handle->pid <= 0 || status == STATUS_DYING)
- handle->new_process = true;
-
- if (!handle->comp_status)
- handle->new_instance = true;
-
- if (!handle->instance_id)
- __set_comp_instance_info(handle, kb);
- }
-
- if (cmd == APP_START_RES ||
- cmd == APP_START_RES_ASYNC ||
- cmd == APP_SEND_LAUNCH_REQUEST ||
- cmd == APP_SEND_LAUNCH_REQUEST_SYNC) {
- bundle_del(kb, AUL_K_WAIT_RESULT);
- bundle_add(kb, AUL_K_WAIT_RESULT, "1");
- }
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
- caller_pid, target_uid, (void *)(handle->ai), kb);
- handle->prelaunch_attr = __get_prelaunch_attribute(
- handle->ai, appid, target_uid);
- handle->bg_category = __get_background_category(handle->ai);
- handle->bg_allowed = _suspend_is_allowed_background(handle->ai);
- if (handle->bg_allowed) {
- _D("[__SUSPEND__] allowed background, appid: %s, app-type: %s",
- appid, comp_type);
- bundle_del(kb, AUL_K_ALLOWED_BG);
- bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
- }
-
- _request_set_request_type(req, NULL);
-
- return 0;
-}
-
-
-static void __kill_and_cleanup_status(struct launch_s *handle, uid_t uid)
-{
- app_type_e type;
- char buf[12];
-
- type = _app_status_get_app_type(handle->app_status);
- if (type == AT_WIDGET_APP || type == AT_WATCH_APP) {
- _W("Dead %s:%d", handle->appid, handle->pid);
- _noti_send(AMD_NOTI_MSG_LAUNCH_MAIN_APP_DEAD,
- handle->pid, uid, handle->app_status, NULL);
- }
-
- if (!_app_status_is_debug_mode(handle->app_status))
- __send_sigkill(handle->pid, uid);
-
- snprintf(buf, sizeof(buf), "%d", handle->pid);
- _util_save_log("TERMINATED", buf);
-
- _app_status_cleanup(handle->app_status);
- handle->app_status = NULL;
-}
-
-static int __do_starting_app(struct launch_s *handle, request_h req,
- bool *pending, bool *bg_launch)
-{
- int status = -1;
- int cmd = _request_get_cmd(req);
- int caller_pid = _request_get_pid(req);
- uid_t target_uid = _request_get_target_uid(req);
- bundle *kb = _request_get_bundle(req);
- const char *pkgid;
- const char *comp_type;
- int ret;
- bool socket_exists;
- bool is_ime = false;
-
- pkgid = _appinfo_get_value(handle->ai, AIT_PKGID);
- comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
- status = _app_status_get_status(handle->app_status);
- if (handle->pid > 0 && status != STATUS_DYING) {
- if (handle->pid == caller_pid) {
- SECURE_LOGD("caller & callee process are same. %s:%d,",
- handle->appid, handle->pid);
- if (comp_type &&
- strcmp(comp_type, APP_TYPE_COMPONENT_BASED))
- return -ELOCALLAUNCH_ID;
- }
-
- _util_save_log("RESUMING", handle->appid);
-
- aul_send_app_resume_request_signal(handle->pid,
- handle->appid, pkgid, comp_type);
- _suspend_remove_timer(handle->pid);
- if (comp_type && !strcmp(comp_type, APP_TYPE_SERVICE)) {
- if (handle->bg_allowed == false) {
- __prepare_to_wake_services(handle->pid,
- target_uid);
- }
- }
-
- ret = __nofork_processing(cmd, handle->pid, kb, req);
- if (ret < 0) {
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL,
- ret, 0, NULL, NULL);
- socket_exists =
- _app_status_socket_exists(handle->app_status);
- if ((ret == -ECOMM && socket_exists) ||
- getpgid(handle->pid) < 0) {
- _E("ECOMM error, we will term the app - %s:%d",
- handle->appid, handle->pid);
- __kill_and_cleanup_status(handle, target_uid);
- return -1;
- }
- }
-
- _app_status_update_last_caller_pid(
- handle->app_status, caller_pid);
- _app_status_update_bg_launch(
- handle->app_status, handle->bg_launch);
- *bg_launch = _app_status_get_bg_launch(handle->app_status);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END,
- handle->pid, handle->bg_launch, handle,
- (bundle *)req);
-
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI) &&
- status != STATUS_VISIBLE)
- __launch_add_fgmgr(handle->pid);
- return ret;
- }
-
- if (handle->pid > 0 && status == STATUS_DYING)
- __kill_and_cleanup_status(handle, target_uid);
-
- __set_appinfo_for_launchpad(handle->ai, kb);
- if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
- aul_svc_set_loader_id(kb, PAD_LOADER_ID_DIRECT);
- handle->debug_mode = true;
- }
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START, cmd, 0, handle, kb);
- _signal_send_proc_prelaunch(handle->appid, pkgid,
- handle->prelaunch_attr, handle->bg_category);
-
- ret = _launchpad_launch(kb, target_uid);
- if (ret < 0) {
- __failure_count++;
- _E("[%u] Failed to send launch request. appid(%s), error(%d)",
- __failure_count, handle->appid, ret);
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
- ret, 0, NULL, NULL);
- if (__failure_count > _config_get_max_launch_failure()) {
- _launchpad_recover_launcher(target_uid);
- __failure_count = 0;
- }
- return ret;
- }
-
- __failure_count = 0;
- handle->pid = ret;
- *pending = true;
- *bg_launch = handle->bg_launch;
- handle->new_process = true;
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
- handle->pid, handle->bg_launch, handle, (bundle *)req);
- _suspend_add_proc(handle->pid);
- aul_send_app_launch_request_signal(handle->pid, handle->appid,
- pkgid, comp_type);
- _appinfo_get_boolean(handle->ai, AIT_IME, &is_ime);
- if (is_ime)
- _signal_send_system_service(handle->pid);
-
- _util_save_log("LAUNCHING", handle->appid);
- if (handle->debug_mode) {
- _W("Exclude - %s(%d)", handle->appid, handle->pid);
- _suspend_exclude(handle->pid);
- return ret;
- }
-
- if (handle->bg_category == BACKGROUND_CATEGORY_BACKGROUND_NETWORK) {
- if (!handle->bg_allowed)
- _suspend_include(handle->pid);
- }
-
- if (comp_type && !strcmp(comp_type, APP_TYPE_SERVICE)) {
- if (!handle->bg_allowed)
- g_idle_add(__check_service_only, GINT_TO_POINTER(ret));
- }
-
- return ret;
-}
-
-static int __complete_starting_app(struct launch_s *handle, request_h req)
-{
- bundle *kb = _request_get_bundle(req);
- uid_t target_uid = _request_get_target_uid(req);
- int caller_pid = _request_get_pid(req);
- const char *comp_type;
- char log_status[AUL_PR_NAME];
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
- handle->pid, handle->new_process,
- (void *)(handle->ai), kb);
- comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- if (handle->new_process) {
- __pid_of_last_launched_ui_app = handle->pid;
- }
- }
-
- _app_status_add_app_info(handle->ai, handle->pid, handle->is_subapp,
- target_uid, caller_pid, handle->bg_launch,
- handle->instance_id, handle->debug_mode);
- _comp_status_add_comp_info(handle->ci, handle->pid, handle->instance_id,
- handle->is_subapp);
-
- _noti_send(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
- handle->pid, target_uid, handle->ai, kb);
- snprintf(log_status, sizeof(log_status), "SUCCESS: %d", handle->pid);
- _util_save_log(log_status, handle->appid);
- return handle->pid;
-}
-
-int _launch_start_onboot_apps(uid_t uid)
-{
- return _boot_manager_start_onboot_apps(uid);
-}
-
-int _launch_start_app(const char *appid, request_h req, bool *pending,
- bool *bg_launch, bool new_instance)
-{
- int ret;
- struct launch_s launch_data = {0,};
- int caller_pid = _request_get_pid(req);
- uid_t caller_uid = _request_get_uid(req);
- int cmd = _request_get_cmd(req);
-
- traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AMD:START_APP");
- _W("_launch_start_app: appid=%s caller pid=%d uid=%d",
- appid, caller_pid, caller_uid);
-
- ret = __prepare_starting_app(&launch_data, req, appid, new_instance);
- if (ret < 0) {
- _request_send_result(req, ret);
- traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
- _util_save_log("FAILURE", appid);
- return -1;
- }
-
- ret = __do_starting_app(&launch_data, req, pending, bg_launch);
- if (ret < 0) {
- _request_send_result(req, ret);
- traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
- _util_save_log("FAILURE", appid);
- return -1;
- }
-
- if (cmd == APP_START_ASYNC || cmd == APP_START_RES_ASYNC)
- _request_send_result(req, ret);
-
- ret = __complete_starting_app(&launch_data, req);
- traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
- if (ret < 0)
- _util_save_log("FAILURE", appid);
-
- return ret;
-}
-
-int _launch_context_get_pid(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return -1;
-
- return h->pid;
-}
-
-int _launch_context_set_pid(launch_h h, int pid)
-{
- struct launch_s *context = h;
-
- if (!context)
- return -1;
-
- h->pid = pid;
-
- return 0;
-}
-
-const char *_launch_context_get_appid(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return NULL;
-
- return h->appid;
-}
-
-bool _launch_context_is_new_instance(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return false;
-
- return h->new_instance;
-}
-
-int _launch_context_set_subapp(launch_h h, bool is_subapp)
-{
- struct launch_s *context = h;
-
- if (!context)
- return -1;
-
- h->is_subapp = is_subapp;
-
- return 0;
-}
-
-int _launch_context_set_app_status(launch_h h, app_status_h status)
-{
- struct launch_s *context = h;
-
- if (!context)
- return -1;
-
- h->app_status = status;
-
- return 0;
-}
-
-int _launch_context_set_comp_status(launch_h h, comp_status_h status)
-{
- struct launch_s *context = h;
-
- if (!context)
- return -1;
-
- h->comp_status = status;
-
- return 0;
-}
-
-const char *_launch_context_get_instance_id(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return NULL;
-
- return h->instance_id;
-}
-
-bool _launch_context_is_subapp(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return false;
-
- return h->is_subapp;
-}
-
-bool _launch_context_is_bg_launch(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return false;
-
- return h->bg_launch;
-}
-
-const struct appinfo *_launch_context_get_appinfo(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return NULL;
-
- return h->ai;
-}
-
-void _launch_context_set_custom_effect(launch_h h, bool is_custom_effect)
-{
- struct launch_s *context = h;
-
- if (!context)
- return;
-
- h->is_custom_effect = is_custom_effect;
-}
-
-bool _launch_context_is_custom_effect(launch_h h)
-{
- struct launch_s *context = h;
-
- if (!context)
- return false;
-
- return h->is_custom_effect;
-}
-
-void _launch_set_mode(launch_mode_e mode)
-{
- if (mode > LAUNCH_MODE_BLOCK) {
- _E("Invalid mode: %d", mode);
- return;
- }
-
- __launch_mode = mode;
- _W("Mode: %d", __launch_mode);
-}
-
-int _launch_send_sigkill(int pid, uid_t uid)
-{
- return __send_sigkill(pid, uid);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <aul.h>
-#include <system_info.h>
-#include <aul_comp_types.h>
-
-#include <amd.h>
-
-#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
-
-bool _launch_mode_is_group_mode(bundle *kb, uid_t uid)
-{
- const char *str;
- const char *mode = NULL;
- const char *appid;
- const char *comp_type;
- const char *comp_id;
- const char *type;
- amd_appinfo_h ai;
- amd_compinfo_h ci;
-
- if (!kb)
- return false;
-
- appid = bundle_get_val(kb, AUL_K_APPID);
- if (!appid)
- return false;
-
- ai = amd_appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
- if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
- mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
- } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
- comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
- if (!comp_id)
- return false;
-
- ci = amd_compinfo_find(uid, comp_id);
- if (!ci)
- return false;
-
- type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
- if (!type || strcmp(type, "frame") != 0)
- return false;
-
- mode = amd_compinfo_get_value(ci,
- AMD_COMPINFO_TYPE_LAUNCH_MODE);
- }
-
- if (mode && !strcmp(mode, "caller")) {
- str = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
- if (str && !strcmp(str, "group"))
- return true;
- } else if (mode && !strcmp(mode, "group")) {
- return true;
- }
-
- return false;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <bundle_internal.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_sock.h>
-
-#include "amd_api_noti.h"
-#include "amd_app_com.h"
-#include "amd_app_status.h"
-#include "amd_launch.h"
-#include "amd_launcher_service.h"
-#include "amd_noti.h"
-#include "amd_request.h"
-#include "amd_util.h"
-
-struct launcher_service_context_s {
- char *launcher_service;
- char *serial;
-};
-
-static struct launcher_service_context_s __context;
-
-static bundle *__create_bundle(const char *app_id, const char *instance_id,
- int pid)
-{
- char pid_str[MAX_PID_STR_BUFSZ];
- bundle *b;
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return NULL;
- }
-
- bundle_add(b, AUL_K_APPID, app_id);
- bundle_add(b, AUL_K_INSTANCE_ID, instance_id ? instance_id : "");
-
- snprintf(pid_str, sizeof(pid_str), "%d", pid);
- bundle_add(b, AUL_K_PID, pid_str);
-
- return b;
-}
-
-static void __publish_launcher_service(const char *endpoint,
- const char *app_id, const char *instance_id, int pid,
- const char *serial, uid_t uid)
-{
- bundle *b;
-
- b = __create_bundle(app_id, instance_id, pid);
- if (!b)
- return;
-
- bundle_add(b, AUL_K_LAUNCHER_SERVICE_SERIAL, serial);
-
- _app_com_send(endpoint, pid, b, uid);
- bundle_free(b);
-}
-
-static const char *__get_instance_id(int pid)
-{
- app_status_h app_status;
-
- app_status = _app_status_find_v2(pid);
- if (!app_status)
- return NULL;
-
- return _app_status_get_instance_id(app_status);
-}
-
-static int __on_launch_do_starting_app_end(const char *msg,
- int arg1, int arg2, void *arg3, bundle *data)
-{
- int pid = arg1;
- int bg_launch = arg2;
- request_h req = (request_h)data;
- bundle *b = _request_get_bundle(req);
- int caller_pid = _request_get_pid(req);
- uid_t uid = _request_get_uid(req);
- char endpoint[MAX_LOCAL_BUFSZ];
- const char *instance_id;
- const char *app_id;
-
- if (pid < 0 || uid < REGULAR_UID_MIN)
- return NOTI_CONTINUE;
-
- if (bg_launch) {
- _W("Background launch");
- return NOTI_CONTINUE;
- }
-
- if (!__context.launcher_service || !__context.serial)
- return NOTI_CONTINUE;
-
- snprintf(endpoint, sizeof(endpoint), "launcher_service:%s:%d",
- __context.launcher_service, caller_pid);
- if (!_app_com_endpoint_exists(endpoint))
- return NOTI_CONTINUE;
-
- app_id = bundle_get_val(b, AUL_K_APPID);
- instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
- if (!instance_id)
- instance_id = __get_instance_id(pid);
-
- __publish_launcher_service(endpoint, app_id, instance_id, pid,
- __context.serial, uid);
-
- return NOTI_CONTINUE;
-}
-
-static int __on_launch_prepare_start(const char *msg,
- int arg1, int arg2, void *arg3, bundle *data)
-{
- launch_h h = arg3;
- const char *val;
-
- if (__context.launcher_service) {
- free(__context.launcher_service);
- __context.launcher_service = NULL;
- }
-
- if (__context.serial) {
- free(__context.serial);
- __context.serial = NULL;
- }
-
- val = bundle_get_val(data, AUL_K_LAUNCHER_SERVICE);
- if (val) {
- __context.launcher_service = strdup(val);
- bundle_del(data, AUL_K_LAUNCHER_SERVICE);
- }
-
- val = bundle_get_val(data, AUL_K_LAUNCHER_SERVICE_SERIAL);
- if (val) {
- __context.serial = strdup(val);
- bundle_del(data, AUL_K_LAUNCHER_SERVICE_SERIAL);
- }
-
- if (__context.launcher_service && __context.serial) {
- _launch_context_set_custom_effect(h, true);
- _D("launcher_service(%s), serial(%s)",
- __context.launcher_service, __context.serial);
- }
-
- return NOTI_CONTINUE;
-}
-
-static void __publish_launcher_service_event(const char *endpoint,
- const char *app_id, const char *instance_id, int pid,
- int event, uid_t uid)
-{
- char event_str[MAX_PID_STR_BUFSZ];
- bundle *b;
-
- b = __create_bundle(app_id, instance_id, pid);
- if (!b)
- return;
-
- snprintf(event_str, sizeof(event_str), "%d", event);
- bundle_add(b, AUL_K_LAUNCHER_SERVICE_EVENT, event_str);
-
- _app_com_send(endpoint, pid, b, uid);
- bundle_free(b);
-}
-
-static int __dispatch_launcher_service_notify_status(request_h req)
-{
- app_status_h app_status;
- const char *instance_id;
- const char *app_id;
- char endpoint[512];
- int event;
- uid_t uid;
- int cmd;
- int pid;
-
- uid = _request_get_uid(req);
- pid = _request_get_pid(req);
- app_status = _app_status_find_v2(pid);
- if (!app_status) {
- _E("Failed to find app status. pid(%d)", pid);
- return -1;
- }
-
- instance_id = _app_status_get_instance_id(app_status);
- app_id = _app_status_get_appid(app_status);
- snprintf(endpoint, sizeof(endpoint), "launcher_service_event:%s",
- app_id);
- cmd = _request_get_cmd(req);
- event = (cmd == LAUNCHER_SERVICE_NOTIFY_ANIMATION_STARTED) ? 0 : 1;
- __publish_launcher_service_event(endpoint, app_id, instance_id,
- pid, event, uid);
-
- _I("[__LAUNCHER_SERVICE__] pid(%d), cmd(%d)", pid, cmd);
- return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = LAUNCHER_SERVICE_NOTIFY_ANIMATION_STARTED,
- .callback = __dispatch_launcher_service_notify_status,
- },
- {
- .cmd = LAUNCHER_SERVICE_NOTIFY_ANIMATION_FINISHED,
- .callback = __dispatch_launcher_service_notify_status,
- },
-};
-
-int _launcher_service_init(void)
-{
- int ret;
-
- _D("init");
-
- ret = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (ret < 0) {
- _E("Failed to register cmds. error(%d)", ret);
- return ret;
- }
-
- _noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END,
- __on_launch_do_starting_app_end);
- _noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
- __on_launch_do_starting_app_end);
- _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
- __on_launch_prepare_start);
- _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
- __on_launch_prepare_start);
-
-
- return 0;
-}
-
-void _launcher_service_fini(void)
-{
- _D("fini");
-
- if (__context.launcher_service)
- free(__context.launcher_service);
-
- if (__context.serial)
- free(__context.serial);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 - 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include <aul.h>
-#include <glib.h>
-
-#include "amd_app_status.h"
-#include "amd_config.h"
-#include "amd_launch.h"
-#include "amd_launchpad.h"
-#include "amd_login_monitor.h"
-#include "amd_signal.h"
-#include "amd_util.h"
-#include "amd_socket.h"
-
-#define TIMEOUT_INTERVAL 1000
-#define LAUNCHPAD_RECOVERY_SOCK ".launchpad-recovery-sock"
-
-struct launchpad_info {
- int (*launcher)(bundle *, uid_t t, void *);
- void *data;
-};
-
-static struct launchpad_info __launchpad;
-static GHashTable *__timer_tbl;
-
-int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
- void *user_data)
-{
- __launchpad.launcher = callback;
- __launchpad.data = user_data;
-
- return 0;
-}
-
-int _launchpad_launch(bundle *kb, uid_t uid)
-{
- if (!__launchpad.launcher) {
- _E("Launcher is not prepared");
- return -1;
- }
-
- return __launchpad.launcher(kb, uid, __launchpad.data);
-}
-
-static void __remove_recovery_timer(gpointer data)
-{
- guint timer = GPOINTER_TO_UINT(data);
-
- g_source_remove(timer);
-}
-
-static void __unset_recovery_timer(uid_t uid)
-{
- if (!g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid)))
- return;
-
- g_hash_table_remove(__timer_tbl, GUINT_TO_POINTER(uid));
- _W("[__RECOVERY__] timer is removed. uid(%u)", uid);
-}
-
-static gboolean __launchpad_recovery_cb(gpointer data)
-{
- uid_t uid = GPOINTER_TO_UINT(data);
- bundle *b;
- pid_t pgid;
- pid_t pid;
- int ret;
-
- pid = _login_monitor_get_launchpad_pid(uid);
- if (pid > 0) {
- pgid = getpgid(pid);
- if (pgid > 0) {
- _W("[__RECOVERY__] launchpad(%d) is running", pid);
- return G_SOURCE_CONTINUE;
- }
- }
-
- b = bundle_create();
- ret = _send_cmd_to_launchpad_async(LAUNCHPAD_RECOVERY_SOCK, uid,
- 0, b);
- bundle_free(b);
- if (ret < 0) {
- _E("[__RECOVERY__] Failed to send recovery request. error(%d)",
- ret);
- return G_SOURCE_CONTINUE;
- }
-
- _W("[__RECOVERY__] Recovery launchpad");
- __unset_recovery_timer(uid);
- return G_SOURCE_CONTINUE;
-}
-
-static void __set_recovery_timer(uid_t uid)
-{
- guint timer;
-
- timer = g_timeout_add(TIMEOUT_INTERVAL, __launchpad_recovery_cb,
- GUINT_TO_POINTER(uid));
- g_hash_table_insert(__timer_tbl, GUINT_TO_POINTER(uid),
- GUINT_TO_POINTER(timer));
- _W("[__RECOVERY__] timer(%u) is removed. uid(%u)", timer, uid);
-}
-
-static bool __is_recovering(uid_t uid)
-{
- return g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid));
-}
-
-static void __running_appinfo_cb(app_status_h app_status, void *user_data)
-{
- const char *appid;
- uid_t uid;
- pid_t pid;
- int ret;
-
- appid = _app_status_get_appid(app_status);
- pid = _app_status_get_pid(app_status);
- uid = _app_status_get_uid(app_status);
-
- aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
- ret = _launch_send_sigkill(pid, uid);
- _E("[__RECOVERY__] appid(%s), pid(%d), result(%d)", appid, pid, ret);
-
- ret = _signal_send_app_dead(pid);
- if (ret < 0) {
- _W("Failed to send app dead signal. pid(%d)", pid);
- _app_status_cleanup(app_status);
- }
-}
-
-int _launchpad_recover_launcher(uid_t uid)
-{
- pid_t pid;
- int ret;
-
- if (__is_recovering(uid))
- return 0;
-
- _W("[__RECOVERY__] uid(%u)", uid);
- pid = _login_monitor_get_launchpad_pid(uid);
- if (pid < 0) {
- _E("Failed to get launchpad pid. uid(%u)", uid);
- return -1;
- }
-
- _app_status_foreach_running_appinfo(__running_appinfo_cb, NULL);
-
- ret = kill(pid, SIGABRT);
- _E("[__RECOVERY__] launchpad pid(%d), uid(%d), result(%d)",
- pid, uid, ret);
-
- __set_recovery_timer(uid);
- return ret;
-}
-
-int _launchpad_init(void)
-{
- _D("LAUNCHPAD_INIT");
-
- __timer_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __remove_recovery_timer);
- if (!__timer_tbl) {
- _E("g_hash_table_new() is failed");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-void _launchpad_fini(void)
-{
- _D("LAUNCHPAD_FINI");
- if (__timer_tbl)
- g_hash_table_destroy(__timer_tbl);
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "amd_logger.h"
-#include "amd_util.h"
-
-#define LOG_MAX_SIZE 2500
-#define LOG_APPFW_PATH "/var/log/appfw"
-#define LOG_PATH "/var/log/appfw/amd"
-
-struct logger_s {
- int fd;
- int index;
-};
-
-static gid_t __get_gid(const char *group_name)
-{
- char buf[sysconf(_SC_GETGR_R_SIZE_MAX)];
- struct group grp;
- struct group *result;
- int ret;
-
- ret = getgrnam_r(group_name, &grp, buf, sizeof(buf), &result);
- if (ret < 0) {
- _E("Failed to get group(%s) file entry. errno(%d)",
- group_name, errno);
- return -1;
- }
-
- return grp.gr_gid;
-}
-
-static int __set_ownership(const char *path, uid_t uid, gid_t gid)
-{
- int ret;
- int fd;
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- _E("Failed to open directory(%s). errno(%d)", path, errno);
- return -1;
- }
-
- ret = fchown(fd, uid, gid);
- close(fd);
- if (ret < 0) {
- _E("Failed to change ownership. path(%s), errno(%d)",
- path, errno);
- return -1;
- }
-
- return 0;
-}
-
-int _logger_create(const char *path, logger_h *handle)
-{
- struct logger_s *logger;
- off_t offset;
-
- if (!path || !handle) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- logger = calloc(1, sizeof(struct logger_s));
- if (!logger) {
- _E("Out of memory");
- return -ENOMEM;
- }
-
- logger->fd = open(path, O_CREAT | O_WRONLY, 0640);
- if (logger->fd < 0) {
- _E("Failed to open path(%s), errno(%d)", path, errno);
- _logger_destroy(logger);
- return -1;
- }
-
- __set_ownership(path, getuid(), __get_gid("system_share"));
-
- offset = lseek(logger->fd, 0, SEEK_END);
- if (offset != 0) {
- logger->index = (int)(offset / LOG_MAX_STRING_SIZE);
- if (logger->index >= LOG_MAX_SIZE) {
- logger->index = 0;
- lseek(logger->fd, 0, SEEK_SET);
- }
- }
-
- *handle = logger;
-
- return 0;
-}
-
-int _logger_destroy(logger_h handle)
-{
- if (!handle) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- if (handle->fd > 0)
- close(handle->fd);
-
- free(handle);
-
- return 0;
-}
-
-int _logger_print(logger_h handle, const char *tag, const char *format, ...)
-{
- char format_buf[128];
- char buf[LOG_MAX_STRING_SIZE];
- struct tm tm = { 0, };
- time_t t;
- ssize_t ret;
- va_list ap;
- off_t offset;
-
- if (!handle || !tag || !format) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- t = time(NULL);
- localtime_r(&t, &tm);
-
- if (handle->index != 0)
- offset = lseek(handle->fd, 0, SEEK_CUR);
- else
- offset = lseek(handle->fd, 0, SEEK_SET);
-
- if (offset == -1)
- _E("lseek() is failed. errno(%d)", errno);
-
- va_start(ap, format);
- vsnprintf(format_buf, sizeof(format_buf), format, ap);
- va_end(ap);
-
- snprintf(buf, sizeof(buf),
- "[%6d] %04d-%02d-%02d %02d:%02d:%02d %-16s %-100s\n",
- handle->index,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tag, format_buf);
- ret = write(handle->fd, buf, strlen(buf));
- if (ret < 0) {
- _E("Failed to write log message. errno(%d)", errno);
- return -1;
- }
-
- if (++handle->index >= LOG_MAX_SIZE)
- handle->index = 0;
-
- return ret;
-}
-
-int _logger_get_fd(logger_h handle, int *fd)
-{
- if (!handle || !fd) {
- _E("Invalid parameter");
- return -EINVAL;
- }
-
- *fd = handle->fd;
-
- return 0;
-}
-
-static int __create_directory(const char *path)
-{
- gid_t gid;
- int ret;
-
- ret = access(path, F_OK);
- if (ret == 0)
- return 0;
-
- ret = mkdir(path, (S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IWGRP | S_IXGRP));
- if (ret < 0) {
- _E("Failed to create directory(%s). errno(%d)", path, errno);
- return -1;
- }
-
- gid = __get_gid("system_share");
- if (gid == (gid_t)-1) {
- _E("Failed to get gid");
- return -1;
- }
-
- return __set_ownership(path, getuid(), gid);
-}
-
-int _logger_init(void)
-{
- int ret;
-
- ret = __create_directory(LOG_APPFW_PATH);
- if (ret < 0)
- return ret;
-
- ret = __create_directory(LOG_PATH);
- if (ret < 0)
- return ret;
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <mntent.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <systemd/sd-login.h>
-#include <tzplatform_config.h>
-#include <bundle_internal.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <vconf.h>
-
-#include "amd_api_noti.h"
-#include "amd_util.h"
-#include "amd_login_monitor.h"
-#include "amd_appinfo.h"
-#include "amd_app_property.h"
-#include "amd_app_status.h"
-#include "amd_socket.h"
-#include "amd_request.h"
-#include "amd_launch.h"
-#include "amd_signal.h"
-#include "amd_cynara.h"
-#include "amd_noti.h"
-
-#define PATH_AUL_DAEMONS "/run/aul/daemons"
-#define LOGIN_TIMEOUT_SEC 90
-
-typedef int (*login_cb)(uid_t uid);
-typedef void (*logout_cb)(uid_t uid);
-
-typedef struct login_handler_s {
- uid_state state;
- login_cb login;
-} login_handler;
-
-typedef struct logout_handler_s {
- uid_state state;
- logout_cb logout;
-} logout_handler;
-
-struct login_monitor_s {
- sd_login_monitor *m;
- GIOChannel *io;
- guint sid;
- bool booting_status;
-};
-
-struct user_s {
- uid_t uid;
- uid_state state;
- guint timer;
- guint app_counter_timer;
- GList *app_counter_list;
- pid_t launchpad_pid;
-};
-
-struct app_counter_s {
- char *app_type;
- int number[AT_WATCH_APP + 1];
-};
-
-static guint sid;
-static struct login_monitor_s *login_monitor;
-static GList *user_list;
-static login_handler login_table[] = {
- {
- .state = UID_STATE_OPENING | UID_STATE_ONLINE |
- UID_STATE_ACTIVE,
- .login = _appinfo_load
- },
- {
- .state = UID_STATE_OPENING | UID_STATE_ONLINE |
- UID_STATE_ACTIVE,
- .login = _app_property_load
- },
- {
- .state = UID_STATE_OPENING | UID_STATE_ONLINE |
- UID_STATE_ACTIVE,
- .login = _app_status_usr_init
- },
- {
- .state = UID_STATE_ONLINE | UID_STATE_ACTIVE,
- .login = _request_usr_init
- },
- {
- .state = UID_STATE_ACTIVE,
- .login = _launch_start_onboot_apps
- }
-};
-static logout_handler logout_table[] = {
- {
- .state = UID_STATE_OFFLINE,
- .logout = _appinfo_unload
- },
- {
- .state = UID_STATE_OFFLINE,
- .logout = _app_property_unload
- },
- {
- .state = UID_STATE_CLOSING | UID_STATE_OFFLINE,
- .logout = _app_status_usr_fini
- }
-};
-
-static int __connect_to_launchpad(uid_t uid);
-static void __user_login(struct user_s *user);
-static struct user_s *__find_user(uid_t uid);
-
-pid_t _login_monitor_get_launchpad_pid(uid_t uid)
-{
- struct user_s *user;
-
- if (uid < REGULAR_UID_MIN)
- return -1;
-
- user = __find_user(uid);
- if (!user)
- return -1;
-
- return user->launchpad_pid;
-}
-
-static void __set_launchpad_pid(uid_t uid, pid_t pid)
-{
- struct user_s *user;
-
- if (uid < REGULAR_UID_MIN)
- return;
-
- user = __find_user(uid);
- if (!user)
- return;
-
- if (user->launchpad_pid == pid)
- return;
-
- user->launchpad_pid = pid;
- SECURE_LOGD("User(%u), Launchpad pid(%d)", uid, pid);
-}
-
-static void __destroy_app_counter(gpointer data)
-{
- struct app_counter_s *ac = (struct app_counter_s *)data;
-
- if (!ac) {
- _E("Critical error!");
- return;
- }
-
- free(ac->app_type);
- free(ac);
-}
-
-static struct app_counter_s *__create_app_counter(const char *app_type)
-{
- struct app_counter_s *ac;
-
- ac = (struct app_counter_s *)calloc(1, sizeof(struct app_counter_s));
- if (!ac) {
- _E("Out of memory");
- return NULL;
- }
-
- ac->app_type = strdup(app_type);
- if (!ac->app_type) {
- _E("Out of memory");
- free(ac);
- return NULL;
- }
-
- return ac;
-}
-
-static void __reset_app_counter(gpointer data, gpointer user_data)
-{
- struct app_counter_s *ac = (struct app_counter_s *)data;
- int i;
-
- if (!ac)
- return;
-
- for (i = 0; i <= AT_WATCH_APP; ++i)
- ac->number[i] = 0;
-}
-
-static int __update_app_type_info(const char *app_type, int total, uid_t uid)
-{
- bundle *b;
- int r;
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return -1;
- }
-
- r = bundle_add(b, AUL_K_APP_TYPE, app_type);
- if (r != BUNDLE_ERROR_NONE) {
- _E("Failed to add app type(%s)", app_type);
- bundle_free(b);
- return -1;
- }
-
- r = bundle_add(b, AUL_K_IS_INSTALLED, total > 0 ? "true" : "false");
- if (r != BUNDLE_ERROR_NONE) {
- _E("Failed to add install info");
- bundle_free(b);
- return -1;
- }
-
- r = _send_cmd_to_launchpad_async(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
- PAD_CMD_UPDATE_APP_TYPE, b);
- bundle_free(b);
-
- return r;
-}
-
-static void __foreach_app_counter(gpointer data, gpointer user_data)
-{
- struct app_counter_s *ac = (struct app_counter_s *)data;
- struct user_s *user = (struct user_s *)user_data;
- int total;
- int r;
-
- total = ac->number[AT_UI_APP] + ac->number[AT_WIDGET_APP] +
- ac->number[AT_WATCH_APP];
-
- r = __update_app_type_info(ac->app_type, total, user->uid);
- if (r < 0)
- _W("Failed to update app type info");
-
- _D("app type(%s), total(%d)", ac->app_type, total);
-}
-
-static struct app_counter_s *__find_app_counter(GList *list,
- const char *app_type)
-{
- struct app_counter_s *ac;
- GList *iter;
-
- iter = g_list_first(list);
- while (iter) {
- ac = (struct app_counter_s *)iter->data;
- if (ac && ac->app_type && !strcmp(ac->app_type, app_type))
- return ac;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static int __convert_to_component_type(const char *str)
-{
- if (!str)
- return -1;
-
- if (!strcmp(str, APP_TYPE_SERVICE))
- return AT_SERVICE_APP;
- else if (!strcmp(str, APP_TYPE_UI))
- return AT_UI_APP;
- else if (!strcmp(str, APP_TYPE_WIDGET))
- return AT_WIDGET_APP;
- else if (!strcmp(str, APP_TYPE_WATCH))
- return AT_WATCH_APP;
-
- return -1;
-}
-
-static void __foreach_appinfo(void *data, const char *appid, struct appinfo *ai)
-{
- struct user_s *user = (struct user_s *)data;
- struct app_counter_s *ac;
- const char *app_type;
- const char *str;
- int enable = 0;
- int component_type;
-
- _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
- if (!(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
- return;
- }
-
- app_type = _appinfo_get_value(ai, AIT_APPTYPE);
- ac = __find_app_counter(user->app_counter_list, app_type);
- if (!ac) {
- ac = __create_app_counter(app_type);
- if (!ac)
- return;
-
- user->app_counter_list = g_list_append(
- user->app_counter_list, ac);
- }
-
- str = _appinfo_get_value(ai, AIT_COMPTYPE);
- component_type = __convert_to_component_type(str);
- if (component_type < 0) {
- _W("Error! component type(%s)", str);
- return;
- }
-
- ac->number[component_type]++;
-}
-
-static gboolean __app_counter_cb(gpointer data)
-{
- struct user_s *user = (struct user_s *)data;
-
- if (user->app_counter_list) {
- g_list_foreach(user->app_counter_list,
- __reset_app_counter, user);
- }
-
- _appinfo_foreach(user->uid, __foreach_appinfo, user);
-
- if ((user->state & (UID_STATE_ONLINE | UID_STATE_ACTIVE))) {
- g_list_foreach(user->app_counter_list,
- __foreach_app_counter, user);
- }
-
- user->app_counter_timer = 0;
- return G_SOURCE_REMOVE;
-}
-
-static int __on_appinfo_handler(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- struct user_s *user;
- GList *iter;
-
- _D("message(%s), uid(%u)", msg, uid);
- iter = user_list;
- while (iter) {
- user = (struct user_s *)iter->data;
- iter = g_list_next(iter);
- if (uid >= REGULAR_UID_MIN && uid != user->uid)
- continue;
-
- if (user->app_counter_timer)
- g_source_remove(user->app_counter_timer);
-
- user->app_counter_timer = g_timeout_add(500,
- __app_counter_cb, user);
- }
-
- return 0;
-}
-
-static void __destroy_user(gpointer data)
-{
- struct user_s *user = (struct user_s *)data;
-
- if (!user) {
- _E("Critical error!");
- return;
- }
-
- if (user->app_counter_list)
- g_list_free_full(user->app_counter_list, __destroy_app_counter);
-
- if (user->app_counter_timer)
- g_source_remove(user->app_counter_timer);
-
- if (user->timer)
- g_source_remove(user->timer);
-
- free(user);
-}
-
-static struct user_s *__create_user(uid_t uid)
-{
- struct user_s *user;
-
- user = (struct user_s *)calloc(1, sizeof(struct user_s));
- if (!user) {
- _E("Out of memory");
- return NULL;
- }
-
- user->uid = uid;
- user->state = UID_STATE_OPENING;
-
- return user;
-}
-
-static struct user_s *__find_user(uid_t uid)
-{
- struct user_s *user;
- GList *iter;
-
- iter = user_list;
- while (iter) {
- user = (struct user_s *)iter->data;
- if (user && user->uid == uid)
- return user;
-
- iter = g_list_next(iter);
- }
-
- return NULL;
-}
-
-static bool __is_mounted(const char *dir)
-{
- struct mntent *ent;
- FILE *fp;
- bool is_mounted = false;
-
- if (!dir)
- return false;
-
- fp = setmntent("/etc/mtab", "r");
- if (!fp) {
- _E("Failed to open /etc/mtab");
- return false;
- }
-
- ent = getmntent(fp);
- while (ent) {
- if (strstr(ent->mnt_dir, dir)) {
- is_mounted = true;
- break;
- }
-
- ent = getmntent(fp);
- }
-
- endmntent(fp);
-
- return is_mounted;
-}
-
-static gboolean __login_timeout_handler(gpointer data)
-{
- struct user_s *user = (struct user_s *)data;
-
- if (user->state == UID_STATE_ACTIVE) {
- _W("User(%u) is already active state", user->uid);
- user->timer = 0;
- return G_SOURCE_REMOVE;
- }
-
- if (!__is_mounted("/opt/usr")) {
- _W("/opt/usr is not mounted");
- return G_SOURCE_CONTINUE;
- }
-
- user->timer = 0;
- user->state = UID_STATE_ACTIVE;
- __user_login(user);
-
- return G_SOURCE_REMOVE;
-}
-
-static void __remove_login_timer(struct user_s *user)
-{
- if (user->timer == 0)
- return;
-
- g_source_remove(user->timer);
- user->timer = 0;
-}
-
-static void __add_login_timer(struct user_s *user)
-{
- if (user->timer != 0)
- return;
-
- user->timer = g_timeout_add_seconds(LOGIN_TIMEOUT_SEC,
- __login_timeout_handler, user);
-}
-
-static void __user_login(struct user_s *user)
-{
- unsigned int i;
-
- if (user->state == UID_STATE_OPENING) {
- if (__connect_to_launchpad(user->uid) == 0)
- user->state = UID_STATE_ONLINE;
-
- __add_login_timer(user);
- }
-
- if (user->state == UID_STATE_ONLINE) {
- if (user->app_counter_list) {
- g_list_foreach(user->app_counter_list,
- __foreach_app_counter, user);
- }
-
- __add_login_timer(user);
- }
-
- _W("[__LOGIN_MONITOR__] user login - uid(%d), state(%d)",
- user->uid, user->state);
- _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START,
- user->uid, user->state, NULL, NULL);
- for (i = 0; i < ARRAY_SIZE(login_table); i++) {
- if (login_table[i].state & user->state) {
- if (login_table[i].login)
- login_table[i].login(user->uid);
- }
- }
-
- _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN,
- user->uid, user->state, NULL, NULL);
-}
-
-static void __user_logout(struct user_s *user)
-{
- unsigned int i;
-
- _D("user logout - uid(%d), state(%d)", user->uid, user->state);
- for (i = 0; i < ARRAY_SIZE(logout_table); i++) {
- if (logout_table[i].state & user->state) {
- if (logout_table[i].logout)
- logout_table[i].logout(user->uid);
- }
- }
-
- _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
- user->uid, user->state, NULL, NULL);
-}
-
-void _login_monitor_set_uid_state(uid_t uid, uid_state state)
-{
- struct user_s *user;
-
- if (uid < REGULAR_UID_MIN)
- return;
-
- user = __find_user(uid);
- if (!user)
- return;
-
- if (user->state != state) {
- user->state = state;
- if (user->state == UID_STATE_ONLINE)
- __user_login(user);
- else
- __user_logout(user);
- }
-}
-
-uid_state _login_monitor_get_uid_state(uid_t uid)
-{
- uid_state res = UID_STATE_UNKNOWN;
- struct user_s *user;
-
- if (uid < REGULAR_UID_MIN)
- return res;
-
- user = __find_user(uid);
- if (!user)
- return res;
-
- return user->state;
-}
-
-int _login_monitor_get_uids(uid_t **uids)
-{
- int r;
- uid_t *l;
- GList *iter;
- unsigned int i = 0;
- struct user_s *user;
-
- if (uids == NULL) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (user_list == NULL)
- return -1;
-
- r = g_list_length(user_list);
- if (r == 0)
- return 0;
-
- l = calloc(r, sizeof(uid_t));
- if (l == NULL) {
- _E("out of memory");
- return -1;
- }
-
- iter = g_list_first(user_list);
- while (iter) {
- user = (struct user_s *)iter->data;
- l[i++] = user->uid;
- iter = g_list_next(iter);
- }
-
- *uids = l;
-
- return r;
-}
-
-static int __connect_to_launchpad(uid_t uid)
-{
- int r;
- bundle *b;
- char path[PATH_MAX];
-
- snprintf(path, sizeof(path), "%s/%d/%s",
- PATH_AUL_DAEMONS, uid, LAUNCHPAD_PROCESS_POOL_SOCK);
- if (access(path, F_OK) != 0) {
- _D("%s doesn't exist", path);
- return -1;
- }
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return -1;
- }
-
- r = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
- uid, PAD_CMD_PING, b);
- bundle_free(b);
- if (r < 0) {
- _E("Failed to connect launchpad - uid(%d), result(%d)", uid, r);
- return -1;
- }
-
- __set_launchpad_pid(uid, r);
-
- return 0;
-}
-
-static void __check_user_state(void)
-{
- uid_t *uids = NULL;
- int ret;
- int i;
- char *state = NULL;
- struct user_s *user;
-
- ret = sd_get_uids(&uids);
- if (ret <= 0) {
- _W("Failed to get uids - %d", ret);
- return;
- }
-
- for (i = 0; i < ret; i++) {
- if (uids[i] < REGULAR_UID_MIN)
- continue;
-
- if (sd_uid_get_state(uids[i], &state) < 0)
- continue;
-
- user = __find_user(uids[i]);
-
- if (strcmp(state, "opening") == 0 ||
- strcmp(state, "online") == 0) {
- if (!user) {
- user = __create_user(uids[i]);
- if (!user) {
- free(uids);
- return;
- }
- user_list = g_list_append(user_list, user);
- __user_login(user);
- }
- } else if (strcmp(state, "closing") == 0) {
- if (user) {
- user->state = UID_STATE_CLOSING;
- __user_logout(user);
- }
- } else if (strcmp(state, "offline") == 0) {
- if (user) {
- user_list = g_list_remove(user_list,
- user);
- user->state = UID_STATE_OFFLINE;
- __user_logout(user);
- __destroy_user(user);
- }
- }
- _D("uid(%d), state(%s)", uids[i], state);
- free(state);
- state = NULL;
- }
- free(uids);
-}
-
-static gboolean __monitor_login_cb(GIOChannel *io, GIOCondition condition,
- gpointer data)
-{
- _D("login monitor");
- sd_login_monitor_flush(login_monitor->m);
-
- __check_user_state();
-
- return TRUE;
-}
-
-static int __init_login_monitor(void)
-{
- int r;
- int fd;
-
- login_monitor = (struct login_monitor_s *)calloc(1,
- sizeof(struct login_monitor_s));
- if (login_monitor == NULL) {
- _E("out of memory");
- return -1;
- }
-
- r = sd_login_monitor_new("uid", &login_monitor->m);
- if (r < 0) {
- _E("Failed to create sd login monitor");
- return -1;
- }
-
- fd = sd_login_monitor_get_fd(login_monitor->m);
- if (fd < 0) {
- _E("Failed to get file descriptor");
- return -1;
- }
-
- login_monitor->io = g_io_channel_unix_new(fd);
- if (login_monitor->io == NULL) {
- _E("Failed to create GIOChannel");
- return -1;
- }
-
- login_monitor->sid = g_io_add_watch(login_monitor->io,
- G_IO_IN | G_IO_HUP, __monitor_login_cb, NULL);
- if (login_monitor->sid == 0) {
- _E("Failed to add gio watch");
- return -1;
- }
-
- return 0;
-}
-
-static void __fini_login_monitor(void)
-{
- if (login_monitor == NULL)
- return;
-
- if (login_monitor->sid) {
- g_source_remove(login_monitor->sid);
- login_monitor->sid = 0;
- }
-
- if (login_monitor->io) {
- g_io_channel_unref(login_monitor->io);
- login_monitor->io = NULL;
- }
-
- if (login_monitor->m) {
- sd_login_monitor_unref(login_monitor->m);
- login_monitor->m = NULL;
- }
-
- free(login_monitor);
- login_monitor = NULL;
-}
-
-static int __on_startup_finished(const char *msg, int arg1, int arg2,
- void *arg3, bundle *data)
-{
- uid_t uid = (uid_t)arg1;
- struct user_s *user;
-
- _W("uid(%d)", uid);
- if (uid < REGULAR_UID_MIN)
- return -1;
-
- user = __find_user(uid);
- if (!user) {
- user = __create_user(uid);
- if (!user)
- return -1;
-
- user_list = g_list_append(user_list, user);
- } else {
- if (user->state == UID_STATE_ACTIVE) {
- _W("The user(%u) is already active state.", uid);
- return 0;
- }
- }
-
- __remove_login_timer(user);
- user->state = UID_STATE_ACTIVE;
- __user_login(user);
-
- return 0;
-}
-
-static int __startup_finished_cb(uid_t uid, void *user_data)
-{
- _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
- (int)uid, 0, user_data, NULL);
-
- return 0;
-}
-
-static int __subscribe_startup_finished(void *data)
-{
- return _signal_subscribe_startup_finished(__startup_finished_cb, data);
-}
-
-static int __dispatch_app_add_loader(request_h req)
-{
- bundle *kb;
- int ret;
- char tmpbuf[MAX_PID_STR_BUFSZ];
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- snprintf(tmpbuf, sizeof(tmpbuf), "%d", getpgid(_request_get_pid(req)));
- bundle_add(kb, AUL_K_CALLER_PID, tmpbuf);
- ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
- _request_get_target_uid(req), PAD_CMD_ADD_LOADER, kb);
- _request_send_result(req, ret);
-
- return ret;
-}
-
-static int __dispatch_app_remove_loader(request_h req)
-{
- bundle *kb;
- int ret;
-
- kb = _request_get_bundle(req);
- if (kb == NULL)
- return -1;
-
- ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
- _request_get_target_uid(req), PAD_CMD_REMOVE_LOADER,
- kb);
- _request_send_result(req, ret);
-
- return ret;
-}
-
-static int __dispatch_launchpad_dead_signal(request_h req)
-{
- uid_t target_uid = _request_get_target_uid(req);
- pid_t pid = _request_get_pid(req);
-
- _W("uid(%d), pid(%d)", target_uid, pid);
- _login_monitor_set_uid_state(target_uid, UID_STATE_CLOSING);
- __set_launchpad_pid(target_uid, 0);
- close(_request_remove_fd(req));
-
- return 0;
-}
-
-static int __dispatch_app_prepare_candidate_process(request_h req)
-{
- bundle *b = NULL;
- int ret;
-
- b = bundle_create();
- if (b == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
- _request_get_target_uid(req), PAD_CMD_DEMAND, b);
- bundle_free(b);
-
- _request_send_result(req, ret);
- return 0;
-}
-
-static int __dispatch_launchpad_launch_signal(request_h req)
-{
- uid_t target_uid = _request_get_target_uid(req);
- pid_t pid = _request_get_pid(req);
-
- _D("uid(%d), pid(%d)", target_uid, pid);
- _login_monitor_set_uid_state(target_uid, UID_STATE_ONLINE);
- __set_launchpad_pid(target_uid, pid);
- close(_request_remove_fd(req));
-
- return 0;
-}
-
-static int __label_checker(caller_info_h info, request_h req,
- void *data)
-{
- if (strcmp(_cynara_caller_info_get_client(info), "System::Privileged") == 0)
- return 0;
-
- return -1;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_ADD_LOADER,
- .callback = __dispatch_app_add_loader
- },
- {
- .cmd = APP_REMOVE_LOADER,
- .callback = __dispatch_app_remove_loader
- },
- {
- .cmd = LAUNCHPAD_DEAD_SIGNAL,
- .callback = __dispatch_launchpad_dead_signal
- },
- {
- .cmd = APP_PREPARE_CANDIDATE_PROCESS,
- .callback = __dispatch_app_prepare_candidate_process
- },
- {
- .cmd = LAUNCHPAD_LAUNCH_SIGNAL,
- .callback = __dispatch_launchpad_launch_signal
- },
-
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = LAUNCHPAD_LAUNCH_SIGNAL,
- .checker = __label_checker,
- .data = NULL
- },
- {
- .cmd = LAUNCHPAD_DEAD_SIGNAL,
- .checker = __label_checker,
- .data = NULL
- },
- {
- .cmd = APP_ADD_LOADER,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
- {
- .cmd = APP_REMOVE_LOADER,
- .checker = _cynara_simple_checker,
- .data = PRIVILEGE_PLATFORM
- },
-};
-
-static void __booting_status_changed_cb(keynode_t *node, void *user_data)
-{
- int booting_status;
- struct user_s *user;
- GList *iter;
-
- booting_status = vconf_keynode_get_int(node);
- if (booting_status != login_monitor->booting_status) {
- _W("Booting status is changed. %d -> %d",
- login_monitor->booting_status,
- booting_status);
- login_monitor->booting_status = booting_status;
- if (booting_status != VCONFKEY_SYSMAN_BOOTING_SUCCESS)
- return;
-
- iter = user_list;
- while (iter) {
- user = (struct user_s *)iter->data;
- if (user->state != UID_STATE_ACTIVE &&
- user->state != UID_STATE_CLOSING &&
- user->state != UID_STATE_OFFLINE) {
- user->state = UID_STATE_ACTIVE;
- __remove_login_timer(user);
- __user_login(user);
- }
-
- iter = g_list_next(iter);
- }
- }
-}
-
-static bool __check_system_boot_finished(void)
-{
- bool boot_finished = false;
- int booting_status;
- int ret;
-
- if (login_monitor->booting_status == VCONFKEY_SYSMAN_BOOTING_SUCCESS)
- return true;
-
- ret = vconf_get_int(VCONFKEY_SYSMAN_BOOTINGSTATUS, &booting_status);
- if (ret == 0 && booting_status == VCONFKEY_SYSMAN_BOOTING_SUCCESS) {
- _W("Booting success");
- login_monitor->booting_status = booting_status;
- return true;
- }
-
- _signal_check_system_boot_finished(&boot_finished);
- return boot_finished;
-}
-
-static gboolean __login_default_user(gpointer data)
-{
- struct user_s *user;
- uid_t uid;
-
- sid = 0;
- __check_user_state();
-
- uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
- _W("default user(%d)", uid);
-
- user = __find_user(uid);
- if (!user) {
- _E("Failed to find default user info");
- return G_SOURCE_REMOVE;
- }
-
- if (user->state == UID_STATE_ACTIVE) {
- _W("Already active state");
- return G_SOURCE_REMOVE;
- }
-
- if (user->state == UID_STATE_UNKNOWN)
- user->state = UID_STATE_OPENING;
-
- if (__check_system_boot_finished())
- user->state = UID_STATE_ACTIVE;
-
- __user_login(user);
- return G_SOURCE_REMOVE;
-}
-
-int _login_monitor_init(void)
-{
- int r;
- uid_t uid;
- struct user_s *user;
- int booting_status;
-
- _D("login monitor init");
- if (__init_login_monitor()) {
- _E("Failed to initialize login monitor");
- __fini_login_monitor();
- return -1;
- }
-
- r = vconf_get_int(VCONFKEY_SYSMAN_BOOTINGSTATUS, &booting_status);
- if (r == 0) {
- _W("booting status(%d)", booting_status);
- login_monitor->booting_status = booting_status;
- }
-
- r = vconf_notify_key_changed(VCONFKEY_SYSMAN_BOOTINGSTATUS,
- __booting_status_changed_cb, NULL);
- if (r != 0)
- _W("Failed to register callback for checking booting");
-
- _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
- __on_startup_finished);
- _noti_listen(AMD_NOTI_MSG_APPINFO_LOAD,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_UNLOAD,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_RELOAD,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
- __on_appinfo_handler);
- _noti_listen(AMD_NOTI_MSG_APPINFO_APP_DISABLED_END,
- __on_appinfo_handler);
-
- uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
- _D("default user(%d)", uid);
- user = __create_user(uid);
- if (!user)
- return -1;
-
- user_list = g_list_append(user_list, user);
- sid = g_idle_add_full(G_PRIORITY_HIGH, __login_default_user,
- NULL, NULL);
-
- _signal_add_ready_cb(__subscribe_startup_finished, NULL);
-
- r = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-void _login_monitor_fini(void)
-{
- _D("login monitor fini");
-
- if (sid)
- g_source_remove(sid);
-
- _signal_unsubscribe_startup_finished();
-
- if (user_list)
- g_list_free_full(user_list, __destroy_user);
-
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_BOOTINGSTATUS,
- __booting_status_changed_cb);
-
- __fini_login_monitor();
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <aul.h>
-#include <glib.h>
-#include <systemd/sd-daemon.h>
-#include <tzplatform_config.h>
-
-#include "amd_api_noti.h"
-#include "amd_anr_monitor.h"
-#include "amd_api.h"
-#include "amd_app_com.h"
-#include "amd_app_property.h"
-#include "amd_app_status.h"
-#include "amd_appinfo.h"
-#include "amd_boot_manager.h"
-#include "amd_comp_status.h"
-#include "amd_compinfo.h"
-#include "amd_config.h"
-#include "amd_cynara.h"
-#include "amd_direct_launch.h"
-#include "amd_inotify.h"
-#include "amd_launch.h"
-#include "amd_launcher_service.h"
-#include "amd_launchpad.h"
-#include "amd_logger.h"
-#include "amd_login_monitor.h"
-#include "amd_noti.h"
-#include "amd_request.h"
-#include "amd_signal.h"
-#include "amd_socket.h"
-#include "amd_suspend.h"
-#include "amd_unix_signal.h"
-#include "amd_util.h"
-
-#define AMD_MOD_PATH "/usr/share/amd/mod"
-#define NAME_AMD_MOD_INIT "AMD_MOD_INIT"
-#define NAME_AMD_MOD_FINI "AMD_MOD_FINI"
-
-typedef int (*amd_mod_init_cb)(void);
-typedef void (*amd_mod_fini_cb)(void);
-
-struct restart_info {
- char *appid;
- int count;
- guint timer;
-};
-
-static GHashTable *restart_tbl;
-static GList *so_handles;
-static sigset_t old_mask;
-
-static gboolean __restart_timeout_handler(void *data)
-{
- struct restart_info *ri = (struct restart_info *)data;
-
- _D("ri (%p)", ri);
- _D("appid (%s)", ri->appid);
-
- g_hash_table_remove(restart_tbl, ri->appid);
- free(ri->appid);
- free(ri);
-
- return FALSE;
-}
-
-static bool __check_restart(const char *appid)
-{
- struct restart_info *ri = NULL;
- char err_buf[1024];
-
- ri = g_hash_table_lookup(restart_tbl, appid);
- if (!ri) {
- ri = calloc(1, sizeof(struct restart_info));
- if (!ri) {
- _E("create restart info: %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- return false;
- }
- ri->appid = strdup(appid);
- if (ri->appid == NULL) {
- _E("Out of memory");
- free(ri);
- return false;
- }
- ri->count = 1;
- g_hash_table_insert(restart_tbl, ri->appid, ri);
-
- _D("ri (%p)", ri);
- _D("appid (%s)", appid);
-
- ri->timer = g_timeout_add(10 * 1000, __restart_timeout_handler,
- ri);
- } else {
- ri->count++;
- _D("count (%d)", ri->count);
- if (ri->count > 5) {
- g_source_remove(ri->timer);
- g_hash_table_remove(restart_tbl, ri->appid);
- free(ri->appid);
- free(ri);
- return false;
- }
- }
- return true;
-}
-
-static bool __can_restart_app(const char *appid, uid_t uid)
-{
- const char *pkg_status;
- const char *component_type;
- struct appinfo *ai;
- int r;
- int val = 0;
- int enable = 1;
-
- _D("appid: %s", appid);
- ai = _appinfo_find(uid, appid);
- if (!ai)
- return false;
-
- component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (!component_type)
- return false;
-
- if (strcmp(component_type, APP_TYPE_SERVICE) != 0)
- return false;
-
- r = _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
- if (r == 0 && !(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
- _D("Disabled");
- return false;
- }
-
- pkg_status = _appinfo_get_value(ai, AIT_STATUS);
- if (pkg_status && strcmp(pkg_status, "blocking") == 0) {
- _appinfo_set_value(ai, AIT_STATUS, "restart");
- } else if (pkg_status && strcmp(pkg_status, "norestart") == 0) {
- _appinfo_set_value(ai, AIT_STATUS, "installed");
- } else {
- r = _appinfo_get_int_value(ai, AIT_RESTART, &val);
- if (r == 0 && val && __check_restart(appid))
- return true;
- }
-
- return false;
-}
-
-static int __app_dead_handler(int pid, void *data)
-{
- bool restart = false;
- char *appid = NULL;
- const char *tmp_appid;
- app_status_h app_status;
- uid_t uid;
- char buf[MAX_LOCAL_BUFSZ];
-
- if (pid <= 0)
- return 0;
-
- _W("APP_DEAD_SIGNAL : %d", pid);
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return 0;
-
- uid = _app_status_get_uid(app_status);
- _noti_send(AMD_NOTI_MSG_MAIN_APP_DEAD, pid, uid, app_status, NULL);
- tmp_appid = _app_status_get_appid(app_status);
- if (tmp_appid == NULL)
- return 0;
-
- uid = _app_status_get_uid(app_status);
- restart = __can_restart_app(tmp_appid, uid);
- if (restart) {
- appid = strdup(tmp_appid);
- if (appid == NULL)
- _W("Out of memory");
- }
-
- _request_flush_pending_request(pid);
- _app_status_publish_status(pid, STATUS_TERMINATE);
- _app_status_cleanup(app_status);
-
- if (restart)
- _launch_start_app_local(uid, appid);
- if (appid)
- free(appid);
-
- snprintf(buf, sizeof(buf), "%d", pid);
- _util_save_log("TERMINATED", buf);
- return 0;
-}
-
-static int __listen_app_dead_signal(void *data)
-{
- int ret;
-
- ret = aul_listen_app_dead_signal(__app_dead_handler, data);
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-static void __ignore_app_dead_signal(void)
-{
- aul_listen_app_dead_signal(NULL, NULL);
-}
-
-static int __load_modules(const char *path)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- char buf[PATH_MAX];
- char *ext;
- void *handle;
- amd_mod_init_cb init_cb;
-
- if (path == NULL)
- return -1;
-
- dp = opendir(path);
- if (dp == NULL)
- return -1;
-
- while ((dentry = readdir(dp)) != NULL) {
- if (dentry->d_name[0] == '.')
- continue;
-
- ext = strrchr(dentry->d_name, '.');
- if (ext && strcmp(ext, ".so") != 0)
- continue;
- snprintf(buf, sizeof(buf), "%s/%s",
- path, dentry->d_name);
-
- handle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
- if (!handle) {
- _E("Failed to load - %s", dlerror());
- continue;
- }
-
- init_cb = dlsym(handle, NAME_AMD_MOD_INIT);
- if (!init_cb) {
- _E("Failed to find entry point");
- dlclose(handle);
- continue;
- }
-
- if (init_cb() < 0) {
- _E("Failed to init %s", dentry->d_name);
- dlclose(handle);
- closedir(dp);
- return -1;
- }
-
- so_handles = g_list_append(so_handles, handle);
- }
- closedir(dp);
-
- return 0;
-}
-
-static void __unload_modules()
-{
- GList *i = so_handles;
- amd_mod_fini_cb fini_cb;
-
- while (i) {
- fini_cb = dlsym(i->data, NAME_AMD_MOD_FINI);
- if (fini_cb)
- fini_cb();
- else
- _E("Failed to find entry point");
-
- dlclose(i->data);
- i = g_list_next(i);
- }
-
- g_list_free(so_handles);
- so_handles = NULL;
-}
-
-static void __block_sigchld(void)
-{
- sigset_t mask;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
-
- if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
- _E("Failed to chagne blocked signal");
-}
-
-static void __unblock_sigchld(void)
-{
- if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0)
- _E("Failed to change blocked signal");
-}
-
-static int __init(void)
-{
- int r;
-
- __block_sigchld();
- _logger_init();
- _unix_signal_init();
- _request_init();
- _noti_init();
- _compinfo_init();
- _direct_launch_init();
- if (_appinfo_init()) {
- _E("_appinfo_init failed");
- return -1;
- }
-
- _signal_add_ready_cb(__listen_app_dead_signal, NULL);
-
- restart_tbl = g_hash_table_new(g_str_hash, g_str_equal);
-
- r = _cynara_init();
- if (r != 0) {
- _E("cynara initialize failed.");
- return -1;
- }
-
- _app_status_init();
- _comp_status_init();
- _app_com_broker_init();
- _boot_manager_init();
- _launch_init();
- _suspend_init();
- _app_property_init();
- _login_monitor_init();
- _util_init();
- _inotify_init();
- _config_init();
- _anr_monitor_init();
- _launcher_service_init();
- _signal_init();
- _launchpad_init();
-
- if (access(AMD_MOD_PATH, F_OK) == 0) {
- if (__load_modules(AMD_MOD_PATH) < 0)
- return -1;
- }
-
- return 0;
-}
-
-static void __ready(void)
-{
- int fd;
-
- _D("AMD is ready");
-
- fd = creat("/run/.amd_ready",
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (fd != -1)
- close(fd);
-
- sd_notify(0, "READY=1");
-}
-
-static void __finish(void)
-{
- __unload_modules();
-
- _launchpad_fini();
- _launcher_service_fini();
- _anr_monitor_fini();
- _config_fini();
- _inotify_fini();
- _util_fini();
- _login_monitor_fini();
- _app_property_fini();
- _suspend_fini();
- _boot_manager_fini();
- _app_com_broker_fini();
- _comp_status_fini();
- _app_status_finish();
- _request_fini();
- _cynara_finish();
-
- if (restart_tbl) {
- g_hash_table_destroy(restart_tbl);
- restart_tbl = NULL;
- }
-
- __ignore_app_dead_signal();
-
- _appinfo_fini();
- _direct_launch_fini();
- _compinfo_fini();
- _noti_fini();
- _unix_signal_fini();
- __unblock_sigchld();
-}
-
-EXPORT int main(int argc, char *argv[])
-{
- GMainLoop *mainloop = NULL;
-
- if (__init() != 0) {
- _E("AMD Initialization failed!\n");
- return -1;
- }
-
- __ready();
-
- mainloop = g_main_loop_new(NULL, FALSE);
- if (!mainloop) {
- _E("failed to create glib main loop");
- return -1;
- }
- g_main_loop_run(mainloop);
-
- __finish();
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 - 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 <bundle.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <list>
-#include <string>
-#include <unordered_map>
-
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_noti.h"
-
-namespace {
- std::unordered_map<std::string, std::list<noti_cb>> __listeners;
-}
-
-int _noti_send(const char* msg, int arg1, int arg2, void* arg3, bundle* data) {
- int ret;
-
- if (!msg) {
- _E("Invalid parameter");
- return -1;
- }
-
- auto iter = __listeners.find(msg);
- if (iter == __listeners.end())
- return 0;
-
- auto& li = iter->second;
- for (noti_cb noti_callback : li) {
- if (noti_callback) {
- ret = noti_callback(msg, arg1, arg2, arg3, data);
- if (ret != NOTI_CONTINUE)
- return -1;
- }
- }
-
- return 0;
-}
-
-int _noti_listen(const char* msg, noti_cb callback) {
- if (!msg) {
- _E("Invalid parameter");
- return -1;
- }
- auto& li = __listeners[msg];
- li.push_back(callback);
- return 0;
-}
-
-int _noti_init(void) {
- return 0;
-}
-
-void _noti_fini(void) {
- __listeners.clear();
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_proc.h"
-
-int _proc_get_attr(pid_t pid, char *buf, int buf_size)
-{
- char path[PATH_MAX];
- int fd;
- ssize_t s;
-
- if (pid < 1 || !buf) {
- _E("Invalid parameter");
- return -1;
- }
-
- snprintf(path, sizeof(path), "/proc/%d/attr/current", pid);
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- _E("Failed to open %s. errno(%d)", path, errno);
- return -1;
- }
-
- s = read(fd, buf, buf_size -1);
- if (s <= 0) {
- _E("Failed to read %s. errno(%d)", path, errno);
- close(fd);
- return -1;
- }
-
- buf[s] = 0;
- close(fd);
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <poll.h>
-#include <ctype.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <tzplatform_config.h>
-#include <systemd/sd-login.h>
-#include <aul_sock.h>
-#include <aul_svc.h>
-#include <aul_app_com.h>
-
-#include "amd_api_noti.h"
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_request.h"
-#include "amd_app_status.h"
-#include "amd_cynara.h"
-#include "amd_socket.h"
-#include "aul_svc_priv_key.h"
-#include "amd_signal.h"
-#include "amd_login_monitor.h"
-#include "amd_noti.h"
-
-#define PENDING_REQUEST_TIMEOUT 5000 /* msec */
-#define SYSTEM_REQUEST_TIMEOUT 90000 /* msec */
-#define PENDING_MESSAGE_MAX_CNT 100
-
-static int amd_fd;
-static GIOChannel *amd_io;
-static guint amd_wid;
-static GHashTable *pending_table;
-static GHashTable *__dispatch_table;
-
-struct pending_item {
- int pid;
- guint timer;
- GList *pending_list;
- GList *reply_list;
-};
-
-struct request_s {
- struct timespec start;
- guint timer;
- int cmd;
- int clifd;
- pid_t pid;
- pid_t t_pid;
- uid_t uid;
- uid_t t_uid;
- bundle *kb;
- int len;
- int opt;
- bool critical;
- unsigned char data[1];
-};
-
-struct extra_info {
- char *key;
- void *extra;
- void (*free_cb)(void *data);
-};
-
-struct reply_info {
- guint timer;
- pid_t pid;
- int result;
- int cmd;
- int clifd;
- GList *extra_list;
-};
-
-static gboolean __timeout_pending_item(gpointer user_data);
-static gboolean __dispatch_request(gpointer data);
-static gboolean __timeout_request(gpointer data);
-static int __add_request_on_pending_list(request_h req);
-
-static void __free_extra_info(gpointer data)
-{
- struct extra_info *info = data;
-
- if (info->free_cb)
- info->free_cb(info->extra);
- free(info->key);
- free(info);
-}
-
-static void __free_reply_info(gpointer data)
-{
- struct reply_info *reply = (struct reply_info *)data;
-
- if (reply == NULL)
- return;
-
- if (reply->extra_list)
- g_list_free_full(reply->extra_list, __free_extra_info);
- if (reply->clifd)
- close(reply->clifd);
- if (reply->timer)
- g_source_remove(reply->timer);
- free(reply);
-}
-
-static gboolean __timeout_reply(gpointer data)
-{
- struct reply_info *reply = (struct reply_info *)data;
-
- if (reply == NULL)
- return FALSE;
-
- _request_reply_remove(reply->pid, reply);
- _send_result_to_client(reply->clifd, reply->result);
- reply->clifd = 0;
- reply->timer = 0;
- __free_reply_info(reply);
-
- return FALSE;
-}
-
-static struct reply_info *__create_reply_info(guint interval, pid_t pid,
- int result, int cmd, int clifd)
-{
- struct reply_info *reply;
-
- reply = malloc(sizeof(struct reply_info));
- if (reply == NULL) {
- _E("Out of memory");
- return NULL;
- }
-
- reply->pid = pid;
- reply->result = result;
- reply->cmd = cmd;
- reply->clifd = clifd;
- reply->timer = g_timeout_add(interval, __timeout_reply, reply);
- reply->extra_list = NULL;
-
- return reply;
-}
-
-static void __free_request(gpointer data)
-{
- request_h req = (request_h)data;
-
- if (req == NULL)
- return;
-
- if (req->clifd)
- close(req->clifd);
- if (req->timer)
- g_source_remove(req->timer);
- if (req->kb)
- bundle_free(req->kb);
-
- free(req);
-}
-
-static void __free_pending_item(gpointer user_data)
-{
- struct pending_item *item = (struct pending_item *)user_data;
-
- if (item == NULL)
- return;
-
- if (item->reply_list)
- g_list_free_full(item->reply_list, __free_reply_info);
- if (item->pending_list)
- g_list_free_full(item->pending_list, __free_request);
- if (g_main_context_find_source_by_user_data(NULL, item))
- g_source_remove(item->timer);
- free(item);
-}
-
-static void __timeout_pending_reply(gpointer data, gpointer user_data)
-{
- struct reply_info *reply = (struct reply_info *)data;
-
- if (reply == NULL)
- return;
-
- _send_result_to_client(reply->clifd, reply->result);
- reply->clifd = 0;
-}
-
-static void __timeout_pending_request(gpointer data, gpointer user_data)
-{
- request_h req = (request_h)data;
-
- if (req == NULL)
- return;
-
- _request_send_result(req, -EAGAIN);
-}
-
-static gboolean __timeout_pending_item(gpointer user_data)
-{
- struct pending_item *item = (struct pending_item *)user_data;
-
- if (item == NULL)
- return FALSE;
-
- g_list_foreach(item->reply_list, __timeout_pending_reply, NULL);
- g_list_foreach(item->pending_list, __timeout_pending_request, NULL);
- g_hash_table_remove(pending_table, GINT_TO_POINTER(item->pid));
-
- return FALSE;
-}
-
-static void __flush_pending_reply_list(GList **reply_list, bool is_dead)
-{
- GList *iter;
- struct reply_info *reply;
-
- if (reply_list == NULL)
- return;
-
- iter = g_list_first(*reply_list);
- while (iter) {
- reply = (struct reply_info *)iter->data;
- iter = g_list_next(iter);
- if (reply == NULL)
- continue;
-
- if (reply->cmd == APP_TERM_BY_PID_SYNC_WITHOUT_RESTART ||
- reply->cmd == APP_TERM_BY_PID_SYNC) {
- if (!is_dead)
- continue;
-
- reply->result = 0;
- }
-
- *reply_list = g_list_remove(*reply_list, reply);
- _send_result_to_client(reply->clifd, reply->result);
- reply->clifd = 0;
- __free_reply_info(reply);
- }
-}
-
-static void __flush_pending_request_list(GList **pending_list)
-{
- GList *iter;
- request_h req;
-
- if (pending_list == NULL)
- return;
-
- iter = g_list_first(*pending_list);
- while (iter) {
- req = (request_h)iter->data;
- iter = g_list_next(iter);
- if (req == NULL)
- continue;
-
- *pending_list = g_list_remove(*pending_list, req);
- if (req->timer) {
- g_source_remove(req->timer);
- req->timer = 0;
- }
- g_idle_add(__dispatch_request, req);
- }
-}
-
-int _request_flush_pending_request(int pid)
-{
- struct pending_item *item;
-
- item = (struct pending_item *)g_hash_table_lookup(pending_table,
- GINT_TO_POINTER(pid));
- if (item == NULL)
- return -1;
-
- __flush_pending_reply_list(&item->reply_list, true);
- __timeout_pending_item((gpointer)item);
-
- return 0;
-}
-
-int _request_reply_for_pending_request(int pid)
-{
- struct pending_item *item;
-
- _app_status_publish_status(pid, STATUS_LAUNCHING);
-
- item = (struct pending_item *)g_hash_table_lookup(pending_table,
- GINT_TO_POINTER(pid));
- if (item == NULL)
- return -1;
-
- __flush_pending_reply_list(&item->reply_list, false);
- __flush_pending_request_list(&item->pending_list);
-
- return 0;
-}
-
-static struct timespec __get_start_time(request_h req)
-{
- int r;
- struct timespec start;
- const char *start_time = NULL;
-
- if (req->kb)
- start_time = bundle_get_val(req->kb, AUL_K_STARTTIME);
-
- if (start_time) {
- r = sscanf(start_time, "%ld/%ld",
- &start.tv_sec, &start.tv_nsec);
- if (r != 2)
- clock_gettime(CLOCK_MONOTONIC, &start);
- } else {
- clock_gettime(CLOCK_MONOTONIC, &start);
- }
-
- return start;
-}
-
-static request_h __get_request(int clifd, app_pkt_t *pkt,
- struct ucred cr)
-{
- request_h req;
- const char *target_uid;
-
- req = (request_h)malloc(sizeof(struct request_s) + pkt->len);
- if (req == NULL)
- return NULL;
-
- req->timer = 0;
- req->clifd = clifd;
- req->pid = cr.pid;
- req->t_pid = 0;
- req->uid = cr.uid;
- req->cmd = pkt->cmd;
- req->len = pkt->len;
- req->opt = pkt->opt;
- req->critical = false;
- memcpy(req->data, pkt->data, pkt->len + 1);
-
- if (pkt->opt & AUL_SOCK_BUNDLE) {
- req->kb = bundle_decode(pkt->data, pkt->len);
- if (req->kb == NULL) {
- free(req);
- return NULL;
- }
-
- target_uid = bundle_get_val(req->kb, AUL_K_TARGET_UID);
- if (target_uid && isdigit(target_uid[0]))
- req->t_uid = atoi(target_uid);
- else
- req->t_uid = cr.uid;
- } else {
- req->kb = NULL;
- req->t_uid = cr.uid;
- }
-
- req->start = __get_start_time(req);
-
- return req;
-}
-
-static gboolean __timeout_request(gpointer data)
-{
- request_h req = (request_h)data;
- struct pending_item *item;
- app_status_h app_status;
-
- if (req == NULL)
- return FALSE;
-
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(req->t_pid));
- if (item)
- item->pending_list = g_list_remove(item->pending_list, req);
-
- if (req->clifd)
- _request_send_result(req, -EAGAIN);
- req->timer = 0;
-
- if (req->critical) {
- _E("App is not responding");
- app_status = _app_status_find(req->t_pid);
- if (app_status)
- _app_status_update_status(app_status, STATUS_DYING, false, true);
- }
-
- __free_request(req);
-
- return FALSE;
-}
-
-static app_status_h __get_app_status(request_h req, const char *appid)
-{
- int pid;
- app_status_h app_status;
- int status;
- struct appinfo *ai;
- const char *comp_type;
-
- switch (req->cmd) {
- case APP_RESUME_BY_PID:
- case APP_TERM_BY_PID:
- case APP_TERM_BY_PID_WITHOUT_RESTART:
- case APP_KILL_BY_PID:
- case APP_TERM_REQ_BY_PID:
- case APP_TERM_BY_PID_ASYNC:
- case APP_TERM_BGAPP_BY_PID:
- case APP_PAUSE_BY_PID:
- case APP_TERM_BY_PID_SYNC:
- case APP_TERM_BY_PID_SYNC_WITHOUT_RESTART:
- /* get pid */
- pid = atoi(appid);
- app_status = _app_status_find(pid);
- break;
- case APP_START_ASYNC:
- case APP_START_RES_ASYNC:
- ai = _appinfo_find(_request_get_target_uid(req), appid);
- comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp_type && (strcmp(comp_type, APP_TYPE_WIDGET) == 0 ||
- strcmp(comp_type, APP_TYPE_WATCH) == 0)) {
- app_status = _app_status_find_with_org_caller(appid,
- _request_get_target_uid(req),
- _request_get_pid(req));
- } else {
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- }
- break;
- default:
- app_status = _app_status_find_by_appid(appid,
- _request_get_target_uid(req));
- break;
- }
-
- if (app_status == NULL)
- return NULL;
-
- status = _app_status_get_status(app_status);
- if (status == STATUS_DYING)
- return NULL;
-
- return app_status;
-}
-
-static int __check_request(request_h req)
-{
- int pid;
- struct pending_item *item;
- app_status_h app_status;
- const char *appid;
-
- if (req->opt & AUL_SOCK_NOREPLY)
- close(_request_remove_fd(req));
-
- if ((req->opt & AUL_SOCK_QUEUE) == 0)
- return 0;
-
- if (req->kb == NULL)
- return -1;
-
- appid = bundle_get_val(req->kb, AUL_K_APPID);
- if (appid == NULL)
- return -1;
-
- app_status = __get_app_status(req, appid);
- if (app_status == NULL)
- return 0;
-
- if (_app_status_socket_exists(app_status))
- return 0;
-
- pid = _app_status_get_pid(app_status);
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
- if (item == NULL)
- return 0;
-
- if (!_app_status_is_starting(app_status)) {
- req->t_pid = pid;
- _W("%s(%d) is waiting to be started.", appid, pid);
- req->critical = true;
- req->timer = g_timeout_add(PENDING_REQUEST_TIMEOUT,
- __timeout_request, req);
- }
-
- item->pending_list = g_list_append(item->pending_list, req);
-
- return 1;
-}
-
-static int __check_target_user(request_h req)
-{
- int r;
- uid_t *uids;
- int i;
- uid_state state;
-
- if (req->t_uid >= REGULAR_UID_MIN) {
- state = _login_monitor_get_uid_state(req->t_uid);
- if (state == UID_STATE_ONLINE || state == UID_STATE_ACTIVE)
- return 0;
-
- if (state == UID_STATE_OPENING)
- return 1;
-
- return -1;
- }
-
- r = _login_monitor_get_uids(&uids);
- if (r <= 0)
- return -1;
-
- for (i = 0; i < r; i++) {
- state = _login_monitor_get_uid_state(uids[i]);
- if (state == UID_STATE_ONLINE || state == UID_STATE_ACTIVE) {
- req->t_uid = uids[i];
- break;
- }
- }
- free(uids);
-
- if (req->t_uid < REGULAR_UID_MIN)
- return -1;
-
- return 0;
-}
-
-static gboolean __dispatch_request(gpointer data)
-{
- request_h req = (request_h)data;
- request_cmd_dispatch *dispatcher;
-
- if (req == NULL)
- return FALSE;
-
- _I("cmd(%s:%d), caller_pid(%d), caller_uid(%u), clifd(%d)",
- aul_cmd_convert_to_string(req->cmd),
- req->cmd, req->pid, req->uid, req->clifd);
- dispatcher = g_hash_table_lookup(__dispatch_table,
- GINT_TO_POINTER(req->cmd));
- if (dispatcher) {
- if (dispatcher->callback(req) != 0) {
- _E("callback returns FALSE : cmd(%s:%d)",
- aul_cmd_convert_to_string(req->cmd),
- req->cmd);
- }
- } else {
- _E("Invalid request or not supported command(%d). caller(%d)",
- req->cmd, req->pid);
- }
-
- __free_request(req);
-
- return FALSE;
-}
-
-static guint __get_pending_interval(struct timespec *start,
- struct timespec *end)
-{
- unsigned int elapsed_time;
-
- elapsed_time = (end->tv_sec - start->tv_sec) * 1e3 +
- (end->tv_nsec - start->tv_nsec) / 1e6;
- if (elapsed_time >= PENDING_REQUEST_TIMEOUT)
- return 0;
-
- return PENDING_REQUEST_TIMEOUT - elapsed_time;
-}
-
-int _request_reply_reset_pending_timer(request_h req, unsigned int interval,
- int pid)
-{
- struct pending_item *item;
- struct timespec end;
-
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
- if (item == NULL) {
- _W("pending item doesn't exist - pid(%d)", pid);
- return -1;
- }
-
- if (item->timer)
- g_source_remove(item->timer);
-
- if (interval <= 0) {
- clock_gettime(CLOCK_MONOTONIC, &end);
- interval = __get_pending_interval(_request_get_start_time(req),
- &end);
- }
-
- item->timer = g_timeout_add(interval, __timeout_pending_item, item);
-
- return 0;
-}
-
-int _request_reply_append(int pid, void *reply)
-{
- struct pending_item *item;
-
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
- if (item == NULL) {
- item = calloc(1, sizeof(struct pending_item));
- if (item == NULL) {
- _E("Out of memory");
- return -1;
- }
- item->pid = pid;
- g_hash_table_insert(pending_table, GINT_TO_POINTER(pid),
- item);
- } else {
- if (item->timer) {
- g_source_remove(item->timer);
- item->timer = 0;
- }
- }
-
- item->reply_list = g_list_append(item->reply_list, reply);
-
- return 0;
-}
-
-int _request_reply_remove(int pid, void *reply)
-{
- struct pending_item *item;
-
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
- if (item)
- item->reply_list = g_list_remove(item->reply_list, reply);
-
- return 0;
-}
-
-request_reply_h _request_reply_create(request_h req, pid_t pid, int result, int cmd)
-{
- request_reply_h reply;
- unsigned int interval;
- struct timespec end;
- int clifd = _request_remove_fd(req);
-
- clock_gettime(CLOCK_MONOTONIC, &end);
- interval = __get_pending_interval(_request_get_start_time(req), &end);
- reply = __create_reply_info(interval, pid, result, cmd, clifd);
-
- if (reply == NULL) {
- _send_result_to_client(clifd, -1);
- return NULL;
- }
-
- return reply;
-}
-
-int _request_reply_add_extra(request_reply_h handle, const char *key,
- void *extra, void (*extra_free_cb)(void *data))
-{
- struct reply_info *reply = handle;
- struct extra_info *info = malloc(sizeof(struct extra_info));
-
- if (!info) {
- _E("Out of memory");
- return -1;
- }
-
- info->extra = extra;
- info->free_cb = extra_free_cb;
- info->key = strdup(key);
- if (!info->key) {
- _E("Out of memory");
- free(info);
- return -1;
- }
-
- reply->extra_list = g_list_append(reply->extra_list, info);
-
- return 0;
-}
-
-int _request_reply_foreach_extra(int pid, int (*callback)(const char *key, void *data))
-{
- struct pending_item *item;
- GList *iter;
- struct reply_info *info;
- struct extra_info *extra_info;
- GList *extra_iter;
-
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
- if (!item)
- return -1;
-
- iter = item->reply_list;
- while (iter) {
- info = iter->data;
- extra_iter = info->extra_list;
- while (extra_iter) {
- extra_info = extra_iter->data;
- if (!callback(extra_info->key, extra_info->extra))
- extra_info->extra = NULL;
- extra_iter = g_list_next(extra_iter);
- }
-
- iter = g_list_next(iter);
- }
-
- return 0;
-}
-
-int _request_usr_init(uid_t uid)
-{
- GList *iter;
- request_h req;
- int r;
- struct pending_item *item;
-
- _noti_send(AMD_NOTI_MSG_REQUEST_USER_INIT, uid, 0, NULL, NULL);
- item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(getpid()));
- if (item == NULL || item->pending_list == NULL)
- return 0;
-
- iter = g_list_first(item->pending_list);
- while (iter) {
- req = (request_h)iter->data;
- iter = g_list_next(iter);
- if (req == NULL)
- continue;
-
- req->t_pid = 0;
- if (req->t_uid < REGULAR_UID_MIN)
- req->t_uid = uid;
-
- if (req->t_uid == uid) {
- g_source_remove(req->timer);
- req->timer = 0;
- item->pending_list = g_list_remove(item->pending_list,
- req);
-
- _request_set_request_type(req, NULL);
- r = __check_request(req);
- if (r == 0)
- g_idle_add(__dispatch_request, (gpointer)req);
- else if (r < 0)
- __free_request(req);
- }
- }
-
- return 0;
-}
-
-static void __cynara_response_callback(enum amd_cynara_res res, request_h req)
-{
- int ret;
-
- if (res == AMD_CYNARA_ALLOWED) {
- ret = __check_target_user(req);
- if (ret > 0) {
- ret = __add_request_on_pending_list(req);
- if (ret < 0) {
- _E("Failed to add request on pending list");
- _request_send_result(req, -EAGAIN);
- __free_request(req);
- }
-
- return;
- }
-
- _request_set_request_type(req, NULL);
- ret = __check_request(req);
- if (ret < 0) {
- _request_send_result(req, ret);
- __free_request(req);
- return;
- } else if (ret > 0) {
- return;
- }
- __dispatch_request((gpointer)req);
- } else {
- _E("request has been denied by cynara");
- ret = -EILLEGALACCESS;
- _request_send_result(req, ret);
- __free_request(req);
- }
-
- return;
-}
-
-static bool __is_indirect_request(request_h req)
-{
- const char *req_type;
-
- req_type = _request_get_request_type(req);
- if (!req_type)
- return false;
-
- if (!strcmp(req_type, "indirect-request"))
- return true;
-
- return false;
-}
-
-static int __add_request_on_pending_list(request_h req)
-{
- struct pending_item *item;
- unsigned int interval;
- struct timespec end;
- int len;
-
- item = g_hash_table_lookup(pending_table,
- GINT_TO_POINTER(getpid()));
- if (item == NULL) {
- item = calloc(1, sizeof(struct pending_item));
- if (item == NULL) {
- _E("Out of memory");
- return -1;
- }
- item->pid = getpid();
- g_hash_table_insert(pending_table,
- GINT_TO_POINTER(getpid()),
- item);
- }
-
- len = g_list_length(item->pending_list);
- if (len <= PENDING_MESSAGE_MAX_CNT) {
- /*
- * To find the request from pending table, the target request
- * is set to the process ID of amd.
- */
- req->t_pid = getpid();
-
- if (req->uid >= REGULAR_UID_MIN || __is_indirect_request(req)) {
- clock_gettime(CLOCK_MONOTONIC, &end);
- interval = __get_pending_interval(
- _request_get_start_time(req), &end);
- req->timer = g_timeout_add(interval,
- __timeout_request, req);
- } else {
- _request_send_result(req, 0);
- req->timer = g_timeout_add(SYSTEM_REQUEST_TIMEOUT,
- __timeout_request, req);
- }
-
- item->pending_list = g_list_append(item->pending_list,
- req);
- _W("request(%s[%d]:%d:%u) is added on pending list",
- aul_cmd_convert_to_string(req->cmd),
- req->cmd, req->pid, req->t_uid);
- } else {
- _W("user(%u) not logged", req->t_uid);
- return -1;
- }
-
- return 0;
-}
-
-static int __check_request_time(request_h req)
-{
- struct timespec current;
- struct timespec *start;
- unsigned int elapsed_time;
-
- start = _request_get_start_time(req);
- clock_gettime(CLOCK_MONOTONIC, ¤t);
-
- elapsed_time = (current.tv_sec - start->tv_sec) * 1e3 +
- (current.tv_nsec - start->tv_nsec) / 1e6;
- if (elapsed_time > PENDING_REQUEST_TIMEOUT) {
- _E("Timeout. elapsed_time(%u)", elapsed_time);
- return -1;
- }
-
- return 0;
-}
-
-static bool __is_async(request_h req)
-{
- return req->opt & AUL_SOCK_NOREPLY;
-}
-
-static gboolean __request_handler(GIOChannel *io, GIOCondition cond,
- gpointer data)
-{
- int fd = g_io_channel_unix_get_fd(io);
- app_pkt_t *pkt;
- int ret;
- int clifd;
- struct ucred cr;
- request_h req;
-
- pkt = aul_sock_recv_pkt(fd, &clifd, &cr);
- if (pkt == NULL) {
- _E("recv error");
- return G_SOURCE_CONTINUE;
- }
-
- req = __get_request(clifd, pkt, cr);
- if (req == NULL) {
- close(clifd);
- free(pkt);
- return G_SOURCE_CONTINUE;
- }
- free(pkt);
-
- ret = __check_request_time(req);
- if (ret < 0 && !__is_indirect_request(req) && !__is_async(req)) {
- _E("Reject request. cmd(%d), caller(%d)", req->cmd, req->pid);
- _request_send_result(req, -EAGAIN);
- __free_request(req);
- return G_SOURCE_CONTINUE;
- }
-
- if (req->uid >= REGULAR_UID_MIN || __is_indirect_request(req)) {
- if (req->uid >= REGULAR_UID_MIN && req->uid != req->t_uid) {
- _E("request has been deined - uid(%d), target_uid(%d)",
- req->uid, req->t_uid);
- ret = -EILLEGALACCESS;
- _request_send_result(req, ret);
- __free_request(req);
- return G_SOURCE_CONTINUE;
- }
-
- ret = _cynara_check_privilege(req, __cynara_response_callback);
- if (ret < 0) {
- _E("request has been denied by cynara");
- ret = -EILLEGALACCESS;
- _request_send_result(req, ret);
- __free_request(req);
- return G_SOURCE_CONTINUE;
- } else if (ret == AMD_CYNARA_UNKNOWN) {
- return G_SOURCE_CONTINUE;
- } else {
- ret = __check_target_user(req);
- if (ret > 0 && req->cmd != LAUNCHPAD_LAUNCH_SIGNAL) {
- ret = __add_request_on_pending_list(req);
- if (ret < 0) {
- _E("Failed to add request on pending list");
- _request_send_result(req, -EAGAIN);
- __free_request(req);
- }
-
- return G_SOURCE_CONTINUE;
- }
- }
- } else {
- ret = __check_target_user(req);
- if (ret != 0 && (req->cmd == APP_START_ASYNC ||
- req->cmd == APP_START_RES_ASYNC)) {
- ret = __add_request_on_pending_list(req);
- if (ret < 0) {
- _E("Failed to add request on pending list");
- _request_send_result(req, -EAGAIN);
- __free_request(req);
- }
-
- return G_SOURCE_CONTINUE;
- }
- }
-
- _request_set_request_type(req, NULL);
- ret = __check_request(req);
- if (ret < 0) {
- _request_send_result(req, ret);
- __free_request(req);
- return G_SOURCE_CONTINUE;
- } else if (ret > 0) {
- return G_SOURCE_CONTINUE;
- }
-
- __dispatch_request((gpointer)req);
-
- return G_SOURCE_CONTINUE;
-}
-
-int _request_get_fd(request_h req)
-{
- return req->clifd;
-}
-
-int _request_get_pid(request_h req)
-{
- return req->pid;
-}
-
-pid_t _request_get_target_pid(request_h req)
-{
- return req->t_pid;
-}
-
-bundle *_request_get_bundle(request_h req)
-{
- return req->kb;
-}
-
-int _request_get_len(request_h req)
-{
- return req->len;
-}
-
-unsigned char *_request_get_raw(request_h req)
-{
- return req->data;
-}
-
-struct timespec *_request_get_start_time(request_h req)
-{
- return &req->start;
-}
-
-int _request_set_request_type(request_h req, const char *req_type)
-{
- if (!req || !req->kb)
- return -1;
-
- bundle_del(req->kb, AUL_K_REQUEST_TYPE);
-
- if (req_type)
- bundle_add(req->kb, AUL_K_REQUEST_TYPE, req_type);
-
- return 0;
-}
-
-const char *_request_get_request_type(request_h req)
-{
- if (!req || !req->kb)
- return NULL;
-
- return bundle_get_val(req->kb, AUL_K_REQUEST_TYPE);
-}
-
-request_h _request_create_local(int cmd, uid_t uid, int pid, bundle *kb)
-{
- request_h req;
-
- req = (request_h)malloc(sizeof(struct request_s));
- if (req == NULL) {
- _E("out of memory");
- return NULL;
- }
-
- clock_gettime(CLOCK_MONOTONIC, &req->start);
- req->timer = 0;
- req->clifd = -1;
- req->pid = pid;
- req->t_pid = 0;
- req->uid = getuid();
- req->t_uid = uid;
- req->cmd = cmd;
- req->len = 0;
- req->opt = AUL_SOCK_NONE;
- req->kb = bundle_dup(kb);
-
- return req;
-}
-
-void _request_free_local(request_h req)
-{
- if (req == NULL)
- return;
-
- if (req->kb)
- bundle_free(req->kb);
-
- free(req);
-}
-
-int _request_get_cmd(request_h req)
-{
- return req->cmd;
-}
-
-int _request_set_cmd(request_h req, int cmd)
-{
- req->cmd = cmd;
-
- return 0;
-}
-
-int _request_remove_fd(request_h req)
-{
- int r = req->clifd;
-
- req->clifd = 0;
-
- return r;
-}
-
-uid_t _request_get_target_uid(request_h req)
-{
- return req->t_uid;
-}
-
-uid_t _request_get_uid(request_h req)
-{
- return req->uid;
-}
-
-int _request_send_raw(request_h req, int cmd, unsigned char *data, int len)
-{
- return aul_sock_send_raw_with_fd(_request_remove_fd(req), cmd, data,
- len, AUL_SOCK_NOREPLY);
-}
-
-int _request_send_result(request_h req, int res)
-{
- if (req->clifd && (req->opt & AUL_SOCK_NOREPLY))
- close(_request_remove_fd(req));
- else if (req->clifd)
- _send_result_to_client(_request_remove_fd(req), res);
-
- return 0;
-}
-
-int _request_register_cmds(const request_cmd_dispatch *cmds, int cnt)
-{
- int i;
-
- if (cnt <= 0 || !__dispatch_table || !cmds)
- return -1;
-
- for (i = 0; i < cnt; i++) {
- g_hash_table_insert(__dispatch_table,
- GINT_TO_POINTER(cmds[i].cmd),
- (gpointer)(&cmds[i]));
- }
-
- return 0;
-}
-
-int _request_init(void)
-{
- _D("request init");
- pending_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, __free_pending_item);
- if (pending_table == NULL) {
- _E("Failed to create pending table");
- _request_fini();
- return -1;
- }
-
- amd_fd = _create_sock_activation();
- if (amd_fd == -1) {
- _D("Create server socket without socket activation");
- amd_fd = _create_server_sock();
- if (amd_fd == -1) {
- _E("Create server socket failed.");
- _request_fini();
- return -1;
- }
- }
-
- amd_io = g_io_channel_unix_new(amd_fd);
- if (amd_io == NULL) {
- _E("Failed to create gio channel");
- _request_fini();
- return -1;
- }
-
- amd_wid = g_io_add_watch(amd_io, G_IO_IN, __request_handler, NULL);
- if (amd_wid == 0) {
- _E("Failed to add gio watch");
- _request_fini();
- return -1;
- }
-
- __dispatch_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, NULL);
-
- return 0;
-}
-
-void _request_fini(void)
-{
- _D("request fini");
- if (amd_wid) {
- g_source_remove(amd_wid);
- amd_wid = 0;
- }
-
- if (amd_io) {
- g_io_channel_unref(amd_io);
- amd_io = NULL;
- }
-
- if (amd_fd > 0) {
- close(amd_fd);
- amd_fd = 0;
- }
-
- if (pending_table) {
- g_hash_table_destroy(pending_table);
- pending_table = NULL;
- }
-
- if (__dispatch_table) {
- g_hash_table_destroy(__dispatch_table);
- __dispatch_table = NULL;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <gio/gio.h>
-#include <glib.h>
-
-#include "amd_api_noti.h"
-#include "amd_noti.h"
-#include "amd_signal.h"
-#include "amd_util.h"
-#include "app_signal.h"
-
-#define MAX_LABEL_BUFSZ 1024
-#define RETRY_INTERVAL 3
-
-typedef struct {
- int pid;
- void (*callback)(int, int, int, void *);
- void *data;
-} proc_status_t;
-
-typedef struct {
- signal_ready_cb callback;
- void *user_data;
-} ready_cb_info_t;
-
-static GDBusConnection *system_conn;
-static guint startup_finished_sid;
-static guint user_session_startup_finished_sid;
-static int (*startup_finished_callback)(uid_t, void *);
-static void *startup_finished_data;
-static uid_t startup_finished_uid;
-static bool system_boot_completed;
-static bool user_boot_completed;
-static guint poweroff_state_sid;
-static void (*poweroff_state_callback)(int, void *);
-static void *poweroff_state_data;
-
-static GList *__ready_cbs;
-
-static gboolean __dispatch_ready_cb(gpointer data);
-
-static GDBusConnection *__get_system_conn(void)
-{
- GError *err = NULL;
-
- if (system_conn)
- return system_conn;
-
- system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (system_conn == NULL) {
- _E("g_bus_get_sync() is failed: %s", err->message);
- g_error_free(err);
- return NULL;
- }
-
- if (__dispatch_ready_cb(NULL)) {
- g_timeout_add_seconds(RETRY_INTERVAL, __dispatch_ready_cb,
- NULL);
- }
-
- return system_conn;
-}
-
-static int __send_signal(const char *object_path, const char *interface_name,
- const char *signal_name, GVariant *parameters)
-{
- GError *err = NULL;
- GDBusConnection *conn;
-
- conn = __get_system_conn();
- if (conn == NULL) {
- if (parameters)
- g_variant_unref(parameters);
- return -1;
- }
-
- if (g_dbus_connection_emit_signal(conn,
- NULL,
- object_path,
- interface_name,
- signal_name,
- parameters,
- &err) == FALSE) {
- _E("g_dbus_connection_emit_signal() is failed: %s",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
- _E("g_dbus_connection_flush_sync() is failed: %s",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- return 0;
-}
-
-int _signal_send_watchdog(int pid, int signal_num)
-{
- int r;
- GVariant *param;
-
- r = _noti_send(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START, pid, signal_num,
- NULL, NULL);
- if (r< 0) {
- _E("Some listeners don't want to continue (pid:%d)", pid);
- return -1;
- }
-
- param = g_variant_new("(ii)", pid, signal_num);
- if (!param) {
- _E("Out of memory");
- return -1;
- }
-
- r = __send_signal(RESOURCED_PROC_OBJECT,
- RESOURCED_PROC_INTERFACE,
- RESOURCED_PROC_WATCHDOG_SIGNAL,
- param);
- if (r < 0) {
- _E("Failed to send a watchdog signal - pid(%d)", pid);
- return -1;
- }
-
- _W("Send a watchdog signal done - pid(%d)", pid);
-
- return 0;
-}
-
-int _signal_send_proc_prelaunch(const char *appid, const char *pkgid,
- int attribute, int category)
-{
- int r;
- GVariant *param;
-
- param = g_variant_new("(ssii)", appid, pkgid, attribute, category);
- if (!param) {
- _E("Out of memory");
- return -1;
- }
-
- r = __send_signal(RESOURCED_PROC_OBJECT,
- RESOURCED_PROC_INTERFACE,
- RESOURCED_PROC_PRELAUNCH_SIGNAL,
- param);
- if (r < 0) {
- _E("Failed to send a prelaunch signal - appid(%s)", appid);
- return -1;
- }
-
- _W("send a prelaunch signal done: " \
- "appid(%s) pkgid(%s) attribute(%x) category(%x)",
- appid, pkgid, attribute, category);
-
- return 0;
-}
-
-int _signal_send_tep_mount(char *mnt_path[], const char *pkgid)
-{
- GError *err = NULL;
- GDBusMessage *msg;
- GDBusConnection *conn;
- int ret = 0;
- int rv = 0;
- struct stat link_buf = {0,};
- GVariant *param;
- char buf[MAX_LABEL_BUFSZ];
-
- if (pkgid == NULL) {
- _E("Invalid parameter");
- return -1;
- }
-
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- rv = lstat(mnt_path[0], &link_buf);
- if (rv == 0) {
- rv = unlink(mnt_path[0]);
- if (rv)
- _E("Unable tp remove link file %s", mnt_path[0]);
- }
-
- msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
- TEP_OBJECT_PATH,
- TEP_INTERFACE_NAME,
- TEP_MOUNT_METHOD);
- if (msg == NULL) {
- _E("g_dbus_message_new_method_call() is failed.");
- return -1;
- }
-
- snprintf(buf, sizeof(buf), "User::Pkg::%s::RO", pkgid);
- param = g_variant_new("(sss)", mnt_path[0], mnt_path[1], buf);
- g_dbus_message_set_body(msg, param);
-
- if (g_dbus_connection_send_message(conn,
- msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE,
- NULL,
- &err) == FALSE) {
- _E("g_dbus_connection_send_message() is failed: %s",
- err->message);
- ret = -1;
- }
-
- if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
- _E("g_dbus_connection_flush_sync() is failed: %s",
- err->message);
- ret = -1;
- }
-
- g_object_unref(msg);
- g_clear_error(&err);
-
- return ret;
-}
-
-int _signal_send_tep_unmount(const char *mnt_path)
-{
- GError *err = NULL;
- GDBusMessage *msg;
- GDBusConnection *conn;
-
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
- TEP_OBJECT_PATH,
- TEP_INTERFACE_NAME,
- TEP_UNMOUNT_METHOD);
- if (msg == NULL) {
- _E("g_dbus_message_new_method_call() is failed.");
- return -1;
- }
-
- g_dbus_message_set_body(msg, g_variant_new("(s)", mnt_path));
- if (g_dbus_connection_send_message(conn,
- msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE,
- NULL,
- &err) == FALSE) {
- _E("g_dbus_connection_send_message() is failed: %s",
- err->message);
- g_object_unref(msg);
- g_clear_error(&err);
- return -1;
- }
-
- g_dbus_connection_flush(conn, NULL, NULL, NULL);
- g_object_unref(msg);
- g_clear_error(&err);
-
- return 0;
-}
-
-int _signal_send_proc_suspend(int pid)
-{
- GError *err = NULL;
- GDBusConnection *conn;
-
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- if (g_dbus_connection_emit_signal(conn,
- NULL,
- APPFW_SUSPEND_HINT_PATH,
- APPFW_SUSPEND_HINT_INTERFACE,
- APPFW_SUSPEND_HINT_SIGNAL,
- g_variant_new("(i)", pid),
- &err) == FALSE) {
- _E("g_dbus_connection_emit_signal() is failed: %s",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
- _E("g_dbus_connection_flush_sync() is failed: %s",
- err->message);
- g_error_free(err);
- return -1;
- }
-
- _D("[__SUSPEND__] Send suspend hint, pid: %d", pid);
-
- return 0;
-}
-
-static void __system_bus_signal_handler(GDBusConnection *connection,
- const gchar *sender_name, const gchar *object_path,
- const gchar *interface_name, const char *signal_name,
- GVariant *parameters, gpointer user_data)
-{
- guint64 uid = 0;
- int state = -1;
-
- _W("[SIGNAL_HANDLER] signal(%s)", signal_name);
- if (g_strcmp0(signal_name, SD_STARTUP_FINISHED_SIGNAL) == 0) {
- system_boot_completed = true;
- _D("[SIGNAL_HANDLER] system boot completed");
- } else if (g_strcmp0(signal_name,
- SD_USER_SESSION_STARTUP_FINISHED_SIGNAL) == 0) {
- user_boot_completed = true;
- g_variant_get(parameters, "(t)", &uid);
- startup_finished_uid = (uid_t)uid;
- _D("[SIGNAL_HANDLER] user boot completed");
- } else if (g_strcmp0(signal_name, SYSTEM_POWEROFF_STATE_SIGNAL) == 0) {
- g_variant_get(parameters, "(i)", &state);
- if (poweroff_state_callback)
- poweroff_state_callback(state, poweroff_state_data);
- _D("[SIGNAL_HANDLER] poweroff state(%d)", state);
- }
-
- if (system_boot_completed && user_boot_completed) {
- if (startup_finished_callback) {
- startup_finished_callback(startup_finished_uid,
- startup_finished_data);
- }
-
- user_boot_completed = false;
- }
-}
-
-static guint __subscribe_system_bus(const char *object_path,
- const char *interface_name, const char *signal_name)
-{
- guint sid;
- GError *err = NULL;
- GDBusConnection *conn;
-
- conn = __get_system_conn();
- if (conn == NULL)
- return 0;
-
- sid = g_dbus_connection_signal_subscribe(conn,
- NULL,
- interface_name,
- signal_name,
- object_path,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- __system_bus_signal_handler,
- NULL,
- NULL);
- if (sid == 0)
- _E("g_bus_connection_signal_subscribe() is failed");
-
- g_clear_error(&err);
-
- return sid;
-}
-
-int _signal_subscribe_startup_finished(int (*callback)(uid_t uid, void *data),
- void *user_data)
-{
- if (callback == NULL)
- return -1;
-
- startup_finished_sid = __subscribe_system_bus(SD_OBJECT_PATH,
- SD_MANAGER_INTERFACE,
- SD_STARTUP_FINISHED_SIGNAL);
- if (startup_finished_sid == 0) {
- _E("Failed to subscribe systemd signal");
- return -1;
- }
-
- user_session_startup_finished_sid = __subscribe_system_bus(
- SD_OBJECT_PATH,
- SD_MANAGER_INTERFACE,
- SD_USER_SESSION_STARTUP_FINISHED_SIGNAL);
- if (user_session_startup_finished_sid == 0) {
- _E("Failed to subscribe systemd signal");
- _signal_unsubscribe_startup_finished();
- return -1;
- }
-
- startup_finished_callback = callback;
- startup_finished_data = user_data;
- _W("[SIGNAL] subscribe startup finished");
-
- return 0;
-}
-
-int _signal_unsubscribe_startup_finished(void)
-{
- GDBusConnection *conn;
-
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- if (!startup_finished_sid && !user_session_startup_finished_sid)
- return 0;
-
- if (startup_finished_sid) {
- g_dbus_connection_signal_unsubscribe(conn,
- startup_finished_sid);
- startup_finished_sid = 0;
- }
-
- if (user_session_startup_finished_sid) {
- g_dbus_connection_signal_unsubscribe(conn,
- user_session_startup_finished_sid);
- user_session_startup_finished_sid = 0;
- }
-
- startup_finished_callback = NULL;
- startup_finished_data = NULL;
- _W("[SIGNAL] unsubscribe startup finished");
-
- return 0;
-}
-
-int _signal_send_display_lock_state(const char *state, const char *flag,
- unsigned int timeout)
-{
- GError *err = NULL;
- GDBusConnection *conn;
- GDBusMessage *msg;
- const char *holdkeyblock_string = "holdkeyblock";
- int ret = 0;
-
- _D("Acquring display lock");
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- msg = g_dbus_message_new_method_call(SYSTEM_BUS_NAME,
- SYSTEM_PATH_DISPLAY,
- SYSTEM_INTERFACE_DISPLAY,
- SYSTEM_LOCK_STATE);
- if (msg == NULL) {
- _E("g_dbus_message_new_method_call() is failed");
- return -1;
- }
-
- g_dbus_message_set_body(msg, g_variant_new("(sssi)", state,
- flag, holdkeyblock_string, timeout));
- if (!g_dbus_connection_send_message(conn, msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
- _E("Unable to send dbus message for acquring lock as %s",
- err->message);
- ret = -1;
- }
-
- _D("Display lock acquired");
- g_object_unref(msg);
- g_dbus_connection_flush_sync(conn, NULL, NULL);
- g_clear_error(&err);
- return ret;
-}
-
-int _signal_send_display_unlock_state(const char *state, const char *flag)
-{
- GError *err = NULL;
- GDBusConnection *conn;
- GDBusMessage *msg;
- int ret = 0;
-
- _D("releasing display lock");
- conn = __get_system_conn();
- if (conn == NULL)
- return -1;
-
- msg = g_dbus_message_new_method_call(SYSTEM_BUS_NAME,
- SYSTEM_PATH_DISPLAY,
- SYSTEM_INTERFACE_DISPLAY,
- SYSTEM_UNLOCK_STATE);
- if (msg == NULL) {
- _E("g_dbus_message_new_method_call() is failed");
- return -1;
- }
-
- g_dbus_message_set_body(msg, g_variant_new("(ss)", state, flag));
- if (!g_dbus_connection_send_message(conn, msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
- _E("Unable to send dbus message for releasing lock as %s",
- err->message);
- ret = -1;
- }
-
- _D("Display lock released");
- g_object_unref(msg);
- g_dbus_connection_flush_sync(conn, NULL, NULL);
- g_clear_error(&err);
- return ret;
-}
-
-int _signal_send_system_service(int pid)
-{
- int r;
- GVariant *param;
-
- param = g_variant_new("(i)", pid);
- if (!param) {
- _E("Out of memory");
- return -1;
- }
-
- r = __send_signal(RESOURCED_PROC_OBJECT,
- RESOURCED_PROC_INTERFACE,
- RESOURCED_SYSTEM_SERVICE_SIGNAL,
- param);
- if (r < 0) {
- _E("Failed to send system service signal - pid(%d)", pid);
- return -1;
- }
-
- _D("Send system service signal: pid(%d)", pid);
-
- return 0;
-}
-
-int _signal_subscribe_poweroff_state(void (*callback)(int state, void *data),
- void *user_data)
-{
- if (callback == NULL)
- return -1;
-
- poweroff_state_sid = __subscribe_system_bus(SYSTEM_PATH_POWEROFF,
- SYSTEM_INTERFACE_POWEROFF,
- SYSTEM_POWEROFF_STATE_SIGNAL);
- if (poweroff_state_sid == 0) {
- _E("Failed to subscribe poweroff state signal");
- return -1;
- }
-
- poweroff_state_callback = callback;
- poweroff_state_data = user_data;
- _D("[SIGNAL] subscribe poweroff state");
-
- return 0;
-}
-
-int _signal_check_system_boot_finished(bool *finished)
-{
- GError *err = NULL;
- GDBusMessage *msg;
- GDBusMessage *reply = NULL;
- GDBusConnection *conn;
- GVariant *body;
- GVariant *param;
- GVariant *v = NULL;
- gsize length = 0;
- const gchar *state;
- int ret = 0;
-
- if (!finished) {
- _E("Invalid parameter");
- return -1;
- }
-
- conn = __get_system_conn();
- if (!conn)
- return -1;
-
- msg = g_dbus_message_new_method_call(SD_BUS_NAME,
- SD_OBJECT_PATH,
- SD_PROPERTIES_INTERFACE,
- SD_GET_METHOD);
- if (!msg) {
- _E("g_dbus_message_new_method_call() is failed");
- return -1;
- }
-
- param = g_variant_new("(ss)",
- SD_MANAGER_INTERFACE,
- SD_SYSTEM_STATE_METHOD);
- g_dbus_message_set_body(msg, param);
-
- reply = g_dbus_connection_send_message_with_reply_sync(conn,
- msg,
- G_DBUS_SIGNAL_FLAGS_NONE,
- -1,
- NULL,
- NULL,
- &err);
- if (!reply) {
- _E("Failed to get reply. error(%s)", err->message);
- ret = -1;
- goto end;
- }
-
- body = g_dbus_message_get_body(reply);
- g_variant_get(body, "(v)", &v);
- if (!v) {
- _E("Failed to get variant");
- ret = -1;
- goto end;
- }
-
- state = g_variant_get_string(v, &length);
- if (g_strcmp0(state, "running") == 0 ||
- g_strcmp0(state, "degraded") == 0)
- *finished = true;
- else
- *finished = false;
-
- _W("state: %s, length: %d", state, (int)length);
-
-end:
- if (v)
- g_variant_unref(v);
- if (reply)
- g_object_unref(reply);
- g_object_unref(msg);
- g_clear_error(&err);
-
- return ret;
-}
-
-static void __wm_proc_reply_cb(GObject *source_object,
- GAsyncResult *res, gpointer user_data)
-{
- GDBusConnection *conn = (GDBusConnection *)source_object;
- proc_status_t *ps = (proc_status_t *)user_data;
- GDBusMessage *reply;
- GError *err = NULL;
- GVariant *var;
- int status = -1;
- int focus = -1;
-
- reply = g_dbus_connection_send_message_with_reply_finish(conn,
- res, &err);
- if (!reply) {
- _E("No reply. err(%s)", err ? err->message : "Unknown");
- goto end;
- }
-
- var = g_dbus_message_get_body(reply);
- if (!var) {
- _E("g_dbus_message_get_body() is failed");
- goto end;
- }
-
- g_variant_get(var, "(ii)", &status, &focus);
- if (status == -1 || focus == -1) {
- _E("Failed to get proc status info");
- goto end;
- }
-
- if (ps->callback)
- ps->callback(ps->pid, status, focus, ps->data);
-
- _D("pid(%d), status(%d), focused(%d)", ps->pid, status, focus);
-end:
- if (err)
- g_error_free(err);
- if (reply)
- g_object_unref(reply);
- if (ps)
- free(ps);
-}
-
-int _signal_get_proc_status_async(int pid,
- void (*callback)(int, int, int, void *),
- void *data)
-{
- GDBusConnection *conn;
- GDBusMessage *msg;
- proc_status_t *ps;
-
- conn = __get_system_conn();
- if (!conn)
- return -1;
-
- msg = g_dbus_message_new_method_call(WM_PROC_NAME,
- WM_PROC_PATH,
- WM_PROC_INTERFACE,
- WM_PROC_METHOD);
- if (!msg) {
- _E("g_dbus_message_new_method_call() is failed");
- return -1;
- }
-
- ps = calloc(1, sizeof(proc_status_t));
- if (!ps) {
- _E("Out of memory");
- g_object_unref(msg);
- return -1;
- }
- ps->pid = pid;
- ps->callback = callback;
- ps->data = data;
-
- g_dbus_message_set_body(msg, g_variant_new("(i)", pid));
- g_dbus_connection_send_message_with_reply(conn, msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE,
- -1, NULL, NULL, __wm_proc_reply_cb,
- (gpointer)ps);
- g_object_unref(msg);
-
- return 0;
-}
-
-static gboolean __dispatch_ready_cb(gpointer user_data)
-{
- ready_cb_info_t *info;
- GList *iter;
-
- iter = __ready_cbs;
- while (iter) {
- info = (ready_cb_info_t *)iter->data;
- iter = g_list_next(iter);
- if (info->callback(info->user_data) < 0)
- continue;
-
- __ready_cbs = g_list_remove(__ready_cbs, info);
- free(info);
- }
-
- if (!__ready_cbs) {
- _D("ready cb info is nullptr");
- return G_SOURCE_REMOVE;
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-int _signal_add_ready_cb(signal_ready_cb callback, void *user_data)
-{
- ready_cb_info_t *info;
-
- if (!callback) {
- _E("Invalid parameter");
- return -1;
- }
-
- info = malloc(sizeof(ready_cb_info_t));
- if (!info) {
- _E("Out of memory");
- return -1;
- }
-
- info->callback = callback;
- info->user_data = user_data;
-
- __ready_cbs = g_list_append(__ready_cbs, info);
-
- return 0;
-}
-
-int _signal_send_app_dead(int pid)
-{
- int ret;
-
- ret = __send_signal(AUL_DBUS_PATH,
- AUL_DBUS_SIGNAL_INTERFACE,
- AUL_DBUS_APPDEAD_SIGNAL,
- g_variant_new("(u)", pid));
- if (ret < 0)
- return ret;
-
- _D("App dead. pid(%d)", pid);
-
- return 0;
-}
-
-static void __get_connection_cb(GObject *source_object,
- GAsyncResult *res, gpointer user_data)
-{
- GError *error = NULL;
-
- if (system_conn) {
- _D("Already exists");
- return;
- }
-
- system_conn = g_bus_get_finish(res, &error);
- if (!system_conn) {
- _E("g_bus_get_finish() is failed. error(%s)", error->message);
- g_error_free(error);
- }
-
- if (__dispatch_ready_cb(NULL)) {
- g_timeout_add_seconds(RETRY_INTERVAL, __dispatch_ready_cb,
- NULL);
- }
-}
-
-int _signal_init(void)
-{
- g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __get_connection_cb, NULL);
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/xattr.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/limits.h>
-#include <systemd/sd-daemon.h>
-#include <bundle.h>
-#include <aul_sock.h>
-
-#include "amd_util.h"
-#include "amd_socket.h"
-
-#define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
-
-int _create_sock_activation(void)
-{
- int fds;
-
- fds = sd_listen_fds(0);
- if (fds == 1)
- return SD_LISTEN_FDS_START;
-
- if (fds > 1)
- _E("Too many file descriptors received.\n");
- else
- _D("There is no socket stream");
-
- return -1;
-}
-
-int _create_server_sock(void)
-{
- int fd;
- struct sockaddr_un addr;
-
- fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (fd < 0) {
- _E("create socket error: %d", errno);
- return -1;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
- unlink(addr.sun_path);
-
- if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
- _E("bind error: %d", errno);
- close(fd);
- return -1;
- }
-
- if (aul_sock_set_sock_option(fd, 0) < 0) {
- _E("Failed to set sock option");
- close(fd);
- return -1;
- }
-
- if (listen(fd, 128) == -1) {
- _E("listen error: %d", errno);
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-static int __connect_client_sock(int fd, const struct sockaddr *saptr,
- socklen_t salen, int nsec)
-{
- int flags;
- int ret;
- int error = 0;
- socklen_t len;
- fd_set readfds;
- fd_set writefds;
- struct timeval timeout;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
- _E("Failed to set the status flags. errno(%d)", errno);
- return -1;
- }
-
- ret = connect(fd, (struct sockaddr *)saptr, salen);
- if (ret < 0) {
- if (errno != EAGAIN && errno != EINPROGRESS) {
- fcntl(fd, F_SETFL, flags);
- return -2;
- }
- }
-
- /* Do whatever we want while the connect is taking place. */
- if (ret == 0)
- goto done; /* connect completed immediately */
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
- writefds = readfds;
- timeout.tv_sec = 0;
- timeout.tv_usec = nsec;
-
- ret = select(fd + 1, &readfds, &writefds, NULL,
- nsec ? &timeout : NULL);
- if (ret == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds)) {
- len = sizeof(error);
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
- return -1; /* Solaris pending error */
- } else {
- return -1; /* select error: sockfd not set*/
- }
-
-done:
- ret = fcntl(fd, F_SETFL, flags);
- if (ret < 0) {
- _E("Failed to set the status flags. errno(%d)", errno);
- return -1;
- }
-
- if (error) {
- errno = error;
- return -1;
- }
-
- return 0;
-}
-
-static int __create_launchpad_client_sock(const char *pad_type, uid_t uid)
-{
- int fd = -1;
- struct sockaddr_un saddr = { 0, };
- int retry = 1;
- int ret = -1;
-
- fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
- /* support above version 2.6.27*/
- if (fd < 0) {
- if (errno == EINVAL) {
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- _E("second chance - socket create error");
- return -1;
- }
- } else {
- _E("socket error");
- return -1;
- }
- }
-
- saddr.sun_family = AF_UNIX;
- snprintf(saddr.sun_path, sizeof(saddr.sun_path),
- "/run/aul/daemons/%d/%s", uid, pad_type);
- retry_con:
- ret = __connect_client_sock(fd, (struct sockaddr *)&saddr,
- sizeof(saddr), 100 * 1000);
- if (ret < -1) {
- _E("maybe peer not launched or peer daed\n");
- if (retry > 0) {
- usleep(100 * 1000);
- retry--;
- goto retry_con;
- }
- }
- if (ret < 0) {
- close(fd);
- return -1;
- }
-
- if (aul_sock_set_sock_option(fd, 1) < 0) {
- _E("Failed to set sock option");
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-int _send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
-{
- int fd;
- int len;
- int res;
- char err_buf[1024];
-
- fd = __create_launchpad_client_sock(pad_type, uid);
- if (fd < 0)
- return -1;
-
- res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
- if (res < 0) {
- close(fd);
- return res;
- }
-
-retry_recv:
- len = recv(fd, &res, sizeof(int), 0);
- if (len == -1) {
- if (errno == EAGAIN) {
- _E("recv timeout : %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- res = -EAGAIN;
- } else if (errno == EINTR) {
- _D("recv : %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- goto retry_recv;
- } else {
- _E("recv error : %s",
- strerror_r(errno, err_buf, sizeof(err_buf)));
- res = -ECOMM;
- }
- }
-
- close(fd);
-
- return res;
-}
-
-int _send_cmd_to_launchpad_async(const char *pad_type, uid_t uid, int cmd,
- bundle *kb)
-{
- int fd;
- int res;
-
- fd = __create_launchpad_client_sock(pad_type, uid);
- if (fd < 0)
- return -1;
-
- res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
- close(fd);
- return res;
-}
-
-void _send_result_to_client(int fd, int res)
-{
- if (fd < 3)
- return;
-
- if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
- if (errno == EPIPE)
- _E("send failed due to EPIPE.");
- _E("send fail to client fd(%d)", fd);
- }
-
- close(fd);
-}
-
-void _send_result_to_client_v2(int fd, int res)
-{
- if (fd < 3)
- return;
-
- if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
- if (errno == EPIPE)
- _E("send failed due to EPIPE.");
- _E("send fail to client fd(%d)", fd);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <gio/gio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <bundle_internal.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <vconf.h>
-
-#include "amd_config.h"
-#include "amd_signal.h"
-#include "amd_util.h"
-#include "amd_suspend.h"
-#include "amd_app_status.h"
-
-typedef struct proc_info {
- pid_t pid;
- guint timer_id;
- int ex_ref;
-} proc_info_t;
-
-typedef struct network_info {
- bool vconf_initialized;
- bool disconnected;
- guint timer_id;
-} network_info_t;
-
-static GHashTable *proc_info_tbl;
-static network_info_t __net_info;
-static guint __init_timer;
-
-static proc_info_t *__create_proc_info(int pid);
-static proc_info_t *__find_proc_info(int pid);
-static int __add_proc_info(proc_info_t *proc);
-
-int _suspend_exclude(int pid)
-{
- proc_info_t *info;
- int ret;
-
- info = __find_proc_info(pid);
- if (!info) {
- info = __create_proc_info(pid);
- if (!info)
- return -ENOMEM;
-
- __add_proc_info(info);
- }
-
- info->ex_ref++;
- if (info->ex_ref == 1) {
- ret = aul_update_freezer_status(pid, "exclude");
- _W("[__SUSPEND__] Exclude pid(%d), result(%d)", pid, ret);
- }
-
- return 0;
-}
-
-int _suspend_include(int pid)
-{
- proc_info_t *info;
- int ret;
-
- info = __find_proc_info(pid);
- if (!info) {
- info = __create_proc_info(pid);
- if (!info)
- return -ENOMEM;
-
- __add_proc_info(info);
- }
-
- if (info->ex_ref > 0)
- info->ex_ref--;
-
- if (info->ex_ref == 0) {
- ret = aul_update_freezer_status(pid, "include");
- _W("[__SUSPEND__] Include pid(%d), result(%d)", pid, ret);
- }
-
- return 0;
-}
-
-bool _suspend_is_excluded(int pid)
-{
- proc_info_t *info;
-
- info = __find_proc_info(pid);
- if (info)
- return (info->ex_ref > 0) ? true : false;
-
- return false;
-}
-
-static void __destroy_proc_info_value(gpointer data)
-{
- proc_info_t *proc = (proc_info_t *)data;
-
- if (proc)
- free(proc);
-}
-
-static bool __network_is_disconnected(int status)
-{
- switch (status) {
- case VCONFKEY_NETWORK_CELLULAR:
- _D("Cellular type");
- return false;
- case VCONFKEY_NETWORK_WIFI:
- _D("Wi-Fi type");
- return false;
- case VCONFKEY_NETWORK_ETHERNET:
- _D("Ethernet type");
- return false;
- case VCONFKEY_NETWORK_BLUETOOTH:
- _D("Bluetooth type");
- return false;
- case VCONFKEY_NETWORK_DEFAULT_PROXY:
- _D("Proxy type for internet connection");
- return false;
- default:
- _D("Disconnected");
- return true;
- }
-}
-
-static void __prepare_to_suspend(int pid, uid_t uid)
-{
- int ret;
- int dummy = 0;
-
- _D("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
- ret = aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
- sizeof(int), AUL_SOCK_NOREPLY);
- if (ret < 0)
- _E("Failed to send APP_SUSPEND %d", pid);
-}
-
-static void __prepare_to_wake(int pid, uid_t uid)
-{
- int ret;
- bundle *kb;
-
- kb = bundle_create();
- if (kb == NULL) {
- _E("out of memory");
- return;
- }
-
- bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
-
- _D("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
- ret = aul_sock_send_bundle(pid, uid, APP_WAKE, kb, AUL_SOCK_NOREPLY);
- if (ret != AUL_R_OK)
- _E("Failed to send APP_WAKE %d", pid);
-
- bundle_free(kb);
-}
-
-static void __wake_bg_apps(app_status_h app_status, void *data)
-{
- const char *appid;
- int status;
- uid_t uid;
- const struct appinfo *ai;
- int target_category;
- int bg_category;
- bool bg_allowed;
- int pid;
-
- if (app_status == NULL)
- return;
-
- status = _app_status_get_status(app_status);
- if (status != STATUS_BG && status != STATUS_SERVICE)
- return;
-
- appid = _app_status_get_appid(app_status);
- uid = _app_status_get_uid(app_status);
- pid = _app_status_get_pid(app_status);
-
- ai = _appinfo_find(uid, appid);
- if (ai == NULL)
- return;
-
- if (data) {
- target_category = GPOINTER_TO_INT(data);
- bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
- if (bg_category != target_category)
- return;
- } else {
- bg_allowed = _suspend_is_allowed_background(ai);
- if (bg_allowed == true)
- return;
- }
-
- _D("[__SUSPEND__] Wake %s %d", appid, pid);
- _suspend_remove_timer(pid);
- __prepare_to_wake(pid, uid);
- _app_status_find_service_apps(app_status, status,
- __prepare_to_wake, false);
- _suspend_exclude(pid);
-}
-
-static void __suspend_bg_apps(app_status_h app_status, void *data)
-{
- const char *appid;
- int status;
- uid_t uid;
- const struct appinfo *ai;
- int target_category;
- int bg_category;
- bool bg_allowed;
- int pid;
-
- if (app_status == NULL)
- return;
-
- status = _app_status_get_status(app_status);
- if (status != STATUS_BG && status != STATUS_SERVICE)
- return;
-
- appid = _app_status_get_appid(app_status);
- uid = _app_status_get_uid(app_status);
- pid = _app_status_get_pid(app_status);
-
- ai = _appinfo_find(uid, appid);
- if (ai == NULL)
- return;
-
- if (data) {
- target_category = GPOINTER_TO_INT(data);
- bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
- if (bg_category != target_category)
- return;
- } else {
- bg_allowed = _suspend_is_allowed_background(ai);
- if (bg_allowed == true)
- return;
- }
-
- _D("[__SUSPEND__] Suspend %s %d", appid, pid);
- _app_status_find_service_apps(app_status, status,
- __prepare_to_suspend, true);
- __prepare_to_suspend(pid, uid);
- _suspend_add_timer(pid);
- _suspend_include(pid);
-}
-
-static gboolean __handle_bg_network_apps(gpointer data)
-{
- int bg_category = BACKGROUND_CATEGORY_BACKGROUND_NETWORK;
-
- if (__net_info.disconnected) {
- _D("[__SUSPEND__] Network is disconnected");
- _app_status_foreach_running_appinfo(__suspend_bg_apps,
- GINT_TO_POINTER(bg_category));
- } else {
- _D("[__SUSPEND__] Network is connected");
- _app_status_foreach_running_appinfo(__wake_bg_apps,
- GINT_TO_POINTER(bg_category));
- }
-
- __net_info.timer_id = 0;
- return G_SOURCE_REMOVE;
-}
-
-static void __network_info_add_timer(void)
-{
- if (__net_info.timer_id)
- g_source_remove(__net_info.timer_id);
-
- __net_info.timer_id = g_timeout_add(500, __handle_bg_network_apps, NULL);
-}
-
-static void __network_info_remove_timer(void)
-{
- if (__net_info.timer_id) {
- g_source_remove(__net_info.timer_id);
- __net_info.timer_id = 0;
- }
-}
-
-static void __network_status_changed_cb(keynode_t *key, void *data)
-{
- int status;
- bool disconnected;
-
- status = vconf_keynode_get_int(key);
- disconnected = __network_is_disconnected(status);
- if (__net_info.disconnected != disconnected) {
- _W("[__SUSPEND__] Network status(%d -> %d) is changed",
- __net_info.disconnected, disconnected);
- __net_info.disconnected = disconnected;
- __network_info_add_timer();
- }
-}
-
-static gboolean __init_network_info(gpointer data)
-{
- int r;
- int status = 0;
-
- r = vconf_get_int(VCONFKEY_NETWORK_STATUS, &status);
- if (r != VCONF_OK)
- _E("Failed to get network status");
- else
- __net_info.disconnected = __network_is_disconnected(status);
-
- r = vconf_notify_key_changed(VCONFKEY_NETWORK_STATUS,
- __network_status_changed_cb, NULL);
- if (r != VCONF_OK) {
- _E("Failed to add vconf notify cb");
- return G_SOURCE_CONTINUE;
- }
-
- __network_info_add_timer();
- __net_info.vconf_initialized = true;
-
- _D("[__SUSPEND__] Network info is initialized");
-
- __init_timer = 0;
- return G_SOURCE_REMOVE;
-}
-
-static void __fini_network_info()
-{
- __network_info_remove_timer();
-
- if (__net_info.vconf_initialized) {
- vconf_ignore_key_changed(VCONFKEY_NETWORK_STATUS,
- __network_status_changed_cb);
- __net_info.vconf_initialized = false;
- }
- _D("[__SUSPEND__] Network info is finished");
-}
-
-void _suspend_init(void)
-{
- if (!proc_info_tbl) {
- proc_info_tbl = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL,
- __destroy_proc_info_value);
- }
-
- __init_timer = g_timeout_add(500, __init_network_info, NULL);
-
- _D("_amd_proc_init done");
-}
-
-void _suspend_fini(void)
-{
- if (__init_timer)
- g_source_remove(__init_timer);
-
- __fini_network_info();
-
- g_hash_table_destroy(proc_info_tbl);
- _D("_amd_proc_fini done");
-}
-
-static proc_info_t *__create_proc_info(int pid)
-{
- proc_info_t *proc;
-
- if (pid < 1) {
- _E("invalid pid");
- return NULL;
- }
-
- proc = (proc_info_t *)calloc(1, sizeof(proc_info_t));
- if (proc == NULL) {
- _E("insufficient memory");
- return NULL;
- }
-
- proc->pid = pid;
- proc->timer_id = 0;
-
- return proc;
-}
-
-static proc_info_t *__find_proc_info(int pid)
-{
- proc_info_t *proc;
-
- if (pid < 1) {
- _E("invalid pid");
- return NULL;
- }
-
- proc = (proc_info_t *)g_hash_table_lookup(proc_info_tbl,
- GINT_TO_POINTER(pid));
- if (proc == NULL) {
- _E("proc info not found");
- return NULL;
- }
-
- return proc;
-}
-
-static int __add_proc_info(proc_info_t *proc)
-{
- if (proc == NULL) {
- _E("invalid proc info");
- return -1;
- }
-
- if (proc->pid < 1) {
- _E("invalid pid");
- return -1;
- }
-
- g_hash_table_insert(proc_info_tbl, GINT_TO_POINTER(proc->pid), proc);
-
- return 0;
-}
-
-int _suspend_add_proc(int pid)
-{
- proc_info_t *proc;
-
- proc = __create_proc_info(pid);
- if (proc)
- return __add_proc_info(proc);
-
- return -1;
-}
-
-int _suspend_remove_proc(int pid)
-{
- proc_info_t *proc;
-
- if (pid < 1) {
- _E("invalid pid");
- return -1;
- }
-
- proc = (proc_info_t *)g_hash_table_lookup(proc_info_tbl,
- GINT_TO_POINTER(pid));
- if (proc == NULL) {
- _E("proc info not found");
- return -1;
- }
-
- g_hash_table_remove(proc_info_tbl, GINT_TO_POINTER(pid));
-
- return 0;
-}
-
-static gboolean __send_suspend_hint(gpointer data)
-{
- proc_info_t *proc;
- int pid = GPOINTER_TO_INT(data);
-
- proc = __find_proc_info(pid);
- if (proc && proc->timer_id > 0) {
- _signal_send_proc_suspend(pid);
- proc->timer_id = 0;
- }
-
- return FALSE;
-}
-
-bool _suspend_is_allowed_background(const struct appinfo *ai)
-{
- int bg_category;
- const char *comp_type;
-
- comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
- if (comp_type == NULL)
- return false;
-
- if (strcmp(comp_type, APP_TYPE_UI) &&
- strcmp(comp_type, APP_TYPE_SERVICE) &&
- strcmp(comp_type, APP_TYPE_COMPONENT_BASED))
- return true;
-
- /*
- * 2.4 bg-categorized (uiapp || svcapp) || watch || widget -> bg allowed
- * 2.3 uiapp -> not allowed, 2.3 svcapp -> bg allowed
- */
- bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
- if (bg_category) {
- if (__net_info.disconnected) {
- if (bg_category &
- (~(int)BACKGROUND_CATEGORY_BACKGROUND_NETWORK))
- return true;
- } else {
- return true;
- }
- }
-
- return false;
-}
-
-void _suspend_add_timer(int pid)
-{
- proc_info_t *proc;
-
- proc = __find_proc_info(pid);
- if (proc == NULL) {
- proc = __create_proc_info(pid);
- if (proc)
- __add_proc_info(proc);
- }
-
- if (proc) {
- proc->timer_id = g_timeout_add_seconds(10, __send_suspend_hint,
- GINT_TO_POINTER(pid));
- }
-}
-
-void _suspend_remove_timer(int pid)
-{
- proc_info_t *proc;
-
- proc = __find_proc_info(pid);
- if (proc && proc->timer_id > 0) {
- g_source_remove(proc->timer_id);
- proc->timer_id = 0;
- }
-}
-
-int _suspend_update_status(int pid, int status)
-{
- app_status_h app_status;
-
- if (pid < 0)
- return -1;
-
- app_status = _app_status_find(pid);
- if (app_status == NULL)
- return -1;
-
- if (status == SUSPEND_STATUS_EXCLUDE) {
- __wake_bg_apps(app_status, NULL);
- } else if (status == SUSPEND_STATUS_INCLUDE) {
- __suspend_bg_apps(app_status, NULL);
- } else {
- _E("Unknown status(%d)", status);
- return -1;
- }
- _D("[__SUSPEND__] pid(%d), status(%d)", pid, status);
-
- return 0;
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <execinfo.h>
-#include <signal.h>
-#include <stdio.h>
-
-#include "amd_logger.h"
-#include "amd_unix_signal.h"
-#include "amd_util.h"
-
-#define BT_BUF_SIZE 128
-#define PATH_AMD_BACKTRACE "/var/log/appfw/amd/amd_backtrace.log"
-
-enum signo_e {
- SIGNO_HUP,
- SIGNO_INT,
- SIGNO_QUIT,
- SIGNO_ILL,
- SIGNO_ABRT,
- SIGNO_FPE,
- SIGNO_BUS,
- SIGNO_SEGV,
- SIGNO_ALRM,
- SIGNO_TERM,
- SIGNO_XCPU,
- SIGNO_XFSZ,
- SIGNO_SYS,
- SIGNO_MAX,
-};
-
-struct signo_map_s {
- const char *key;
- int value;
-};
-
-static struct signo_map_s signo_map[] = {
- [SIGNO_HUP] = { "SIGHUP", SIGHUP },
- [SIGNO_INT] = { "SIGINT", SIGINT },
- [SIGNO_QUIT] = { "SIGQUIT", SIGQUIT },
- [SIGNO_ILL] = { "SIGILL", SIGILL },
- [SIGNO_ABRT] = { "SIGABRT", SIGABRT },
- [SIGNO_FPE] = { "SIGFPE" , SIGFPE },
- [SIGNO_BUS] = { "SIGBUS", SIGBUS },
- [SIGNO_SEGV] = { "SIGSEGV", SIGSEGV },
- [SIGNO_ALRM] = { "SIGALRM", SIGALRM },
- [SIGNO_TERM] = { "SIGTERM", SIGTERM },
- [SIGNO_XCPU] = { "SIGXCPU", SIGXCPU },
- [SIGNO_XFSZ] = { "SIGXFSZ", SIGXFSZ },
- [SIGNO_SYS] = { "SIGSYS", SIGSYS },
-};
-
-static struct sigaction old_action[SIGNO_MAX];
-static logger_h logger;
-static int logger_fd = -1;
-
-static const char *__unix_signal_get_signo_string(int signal)
-{
- int i;
-
- for (i = 0; i < SIGNO_MAX; ++i) {
- if (signo_map[i].value == signal)
- return signo_map[i].key;
- }
-
- return "Unknown";
-}
-
-static enum signo_e __unix_signal_get_signo(int signal)
-{
- int i;
-
- for (i = 0; i < SIGNO_MAX; ++i) {
- if (signo_map[i].value == signal)
- return i;
- }
-
- return -1;
-}
-
-static void __unix_signal_handler(int signal, siginfo_t *info, void *arg)
-{
- enum signo_e signo;
- int nptrs;
- void *buffer[BT_BUF_SIZE];
- sigset_t old_mask;
- sigset_t mask;
-
- sigfillset(&mask);
- sigprocmask(SIG_BLOCK, &mask, &old_mask);
-
- _W("[__UNIX_SIGNAL__] signal: %d(%s)",
- signal, __unix_signal_get_signo_string(signal));
-
- nptrs = backtrace(buffer, BT_BUF_SIZE);
- backtrace_symbols_fd(buffer, nptrs,
- (logger_fd > 0) ? logger_fd : STDERR_FILENO);
-
- sigprocmask(SIG_SETMASK, &old_mask, NULL);
-
- signo = __unix_signal_get_signo(signal);
- if (signo != -1)
- sigaction(signal, &old_action[signo], NULL);
-
- raise(signal);
-}
-
-int _unix_signal_init(void)
-{
- struct sigaction action = { 0, };
- int ret;
- int i;
-
- _W("UNIX_SIGNAL_INIT");
-
- sigemptyset(&action.sa_mask);
- action.sa_sigaction = __unix_signal_handler;
- action.sa_flags = SA_RESTART | SA_SIGINFO;
-
- for (i = 0; i < SIGNO_MAX; ++i) {
- ret = sigaction(signo_map[i].value, &action, &old_action[i]);
- if (ret != 0) {
- _W("Failed to change signal(%s) action. errno(%d)",
- signo_map[i].key, errno);
- }
- }
-
- ret = _logger_create(PATH_AMD_BACKTRACE, &logger);
- if (ret != 0)
- return ret;
-
- _logger_print(logger, "BACKTRACE", "pid: %d", getpid());
- _logger_get_fd(logger, &logger_fd);
-
- return 0;
-}
-
-void _unix_signal_fini(void)
-{
- int i;
-
- _W("UNIX_SIGNAL_FINI");
-
- _logger_destroy(logger);
-
- for (i = 0; i < SIGNO_MAX; ++i)
- sigaction(signo_map[i].value, &old_action[i], NULL);
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <time.h>
-#include <fcntl.h>
-#include <aul.h>
-#include <aul_sock.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-#include <vconf.h>
-
-#include "amd_api_noti.h"
-#include "amd_config.h"
-#include "amd_util.h"
-#include "amd_request.h"
-#include "amd_appinfo.h"
-#include "amd_app_status.h"
-#include "amd_socket.h"
-#include "amd_cynara.h"
-#include "amd_noti.h"
-#include "amd_logger.h"
-
-#define OSP_K_DATACONTROL_PROVIDER "__OSP_DATACONTROL_PROVIDER__"
-#define MAX_NR_OF_DESCRIPTORS 2
-#define AMD_LOG_FILE "/var/log/appfw/amd/amd.log"
-
-static logger_h __logger;
-static GHashTable *__dc_socket_pair_hash;
-static int datacontrol_result;
-static int __memory_status;
-static bool __vconf_initialized;
-static guint __vconf_init_timer;
-
-int _util_save_log(const char *tag, const char *message)
-{
- return _logger_print(__logger, tag, message);
-}
-
-static int __send_message(int sock, const struct iovec *vec, int vec_size,
- const int *desc, int nr_desc)
-{
- struct msghdr msg = {0,};
- int sndret;
- int desclen = 0;
- struct cmsghdr *cmsg = NULL;
- char buff[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)] = {0,};
-
- if (vec == NULL || vec_size < 1)
- return -EINVAL;
- if (nr_desc < 0 || nr_desc > MAX_NR_OF_DESCRIPTORS)
- return -EINVAL;
- if (desc == NULL)
- nr_desc = 0;
-
- msg.msg_iov = (struct iovec *)vec;
- msg.msg_iovlen = vec_size;
-
- /* sending ancillary data */
- if (nr_desc > 0) {
- msg.msg_control = buff;
- msg.msg_controllen = sizeof(buff);
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg == NULL)
- return -EINVAL;
-
- /* packing files descriptors */
- if (nr_desc > 0) {
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- desclen = cmsg->cmsg_len =
- CMSG_LEN(sizeof(int) * nr_desc);
- memcpy((int *)CMSG_DATA(cmsg), desc,
- sizeof(int) * nr_desc);
- cmsg = CMSG_NXTHDR(&msg, cmsg);
- _D("packing file descriptors done");
- }
-
- /* finished packing updating the corect length */
- msg.msg_controllen = desclen;
- } else {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- }
-
- sndret = sendmsg(sock, &msg, 0);
- _D("sendmsg ret : %d", sndret);
- if (sndret < 0)
- return -errno;
-
- return sndret;
-}
-
-static int __dispatch_get_mp_socket_pair(request_h req)
-{
- int handles[2] = {0, 0};
- struct iovec vec[3];
- int msglen = 0;
- char buffer[1024];
- int ret = 0;
-
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, handles) != 0) {
- _E("error create socket pair");
- _request_send_result(req, -1);
- return -1;
- }
-
- if (handles[0] == -1) {
- _E("error socket open");
- _request_send_result(req, -1);
- return -1;
- }
-
- _D("amd send mp fd : [%d, %d]", handles[0], handles[1]);
- vec[0].iov_base = buffer;
- vec[0].iov_len = strlen(buffer) + 1;
-
- msglen = __send_message(_request_get_fd(req), vec, 1, handles, 2);
- if (msglen < 0) {
- _E("Error[%d]: while sending message\n", -msglen);
- _request_send_result(req, -1);
- ret = -1;
- }
-
- close(handles[0]);
- close(handles[1]);
-
- return ret;
-}
-
-static int *__check_dc_socket_pair_handle(char *socket_pair_key,
- const char *datacontrol_type)
-{
- int *handles;
-
- handles = g_hash_table_lookup(__dc_socket_pair_hash, socket_pair_key);
- if (handles == NULL)
- return NULL;
-
- if (strcmp(datacontrol_type, "consumer") == 0) {
- if (handles[0] == -1) {
- g_hash_table_remove(__dc_socket_pair_hash,
- socket_pair_key);
- return NULL;
- }
- } else {
- if (handles[1] == -1) {
- g_hash_table_remove(__dc_socket_pair_hash,
- socket_pair_key);
- return NULL;
- }
- }
-
- return handles;
-}
-
-static int __dispatch_get_dc_socket_pair(request_h req)
-{
- const char *caller;
- const char *callee;
- const char *datacontrol_type;
- char *socket_pair_key = NULL;
- int socket_pair_key_len;
- int *handles = NULL;
- struct iovec vec[3];
- int msglen = 0;
- char buffer[1024];
- bundle *kb = _request_get_bundle(req);
-
- caller = bundle_get_val(kb, AUL_K_CALLER_APPID);
- if (caller == NULL)
- goto err_out;
- callee = bundle_get_val(kb, AUL_K_CALLEE_APPID);
- if (callee == NULL)
- goto err_out;
- datacontrol_type = bundle_get_val(kb, "DATA_CONTROL_TYPE");
- if (datacontrol_type == NULL)
- goto err_out;
-
- socket_pair_key_len = strlen(caller) + strlen(callee) + 2;
-
- socket_pair_key = (char *)calloc(socket_pair_key_len, sizeof(char));
- if (socket_pair_key == NULL) {
- _E("calloc fail");
- goto err_out;
- }
-
- snprintf(socket_pair_key, socket_pair_key_len, "%s_%s", caller, callee);
- _D("socket pair key : %s", socket_pair_key);
-
- handles = __check_dc_socket_pair_handle(socket_pair_key,
- datacontrol_type);
- if (handles == NULL) {
- if (strcmp(datacontrol_type, "consumer") != 0) {
- _E("Only consumer can create socketpair");
- goto err_out;
- }
-
- handles = (int *)calloc(2, sizeof(int));
- if (handles == NULL) {
- _E("calloc fail");
- goto err_out;
- }
-
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, handles) != 0) {
- _E("error create socket pair");
- free(handles);
- handles = NULL;
- goto err_out;
- }
-
- if (handles[0] == -1 || handles[1] == -1) {
- _E("error socket open");
- free(handles);
- handles = NULL;
- goto err_out;
- }
-
- g_hash_table_insert(__dc_socket_pair_hash,
- strdup(socket_pair_key), handles);
- _D("New socket pair insert done.");
- }
-
- SECURE_LOGD("amd send fd : [%d, %d]", handles[0], handles[1]);
- vec[0].iov_base = buffer;
- vec[0].iov_len = 1;
-
- _send_result_to_client_v2(_request_get_fd(req), 0);
-
- if (datacontrol_type != NULL) {
- _D("datacontrol_type : %s", datacontrol_type);
- if (strcmp(datacontrol_type, "consumer") == 0) {
- msglen = __send_message(_request_get_fd(req), vec, 1,
- &handles[0], 1);
- if (msglen < 0) {
- _E("Error[%d]: while sending message", -msglen);
- goto err_out;
- }
- close(handles[0]);
- handles[0] = -1;
- if (handles[1] == -1) {
- _D("remove from hash : %s", socket_pair_key);
- g_hash_table_remove(__dc_socket_pair_hash,
- socket_pair_key);
- }
-
- } else {
- msglen = __send_message(_request_get_fd(req), vec, 1,
- &handles[1], 1);
- if (msglen < 0) {
- _E("Error[%d]: while sending message", -msglen);
- goto err_out;
- }
- close(handles[1]);
- handles[1] = -1;
- if (handles[0] == -1) {
- _D("remove from hash : %s", socket_pair_key);
- g_hash_table_remove(__dc_socket_pair_hash,
- socket_pair_key);
- }
- }
- }
- SECURE_LOGD("send_message msglen : [%d]\n", msglen);
- if (socket_pair_key)
- free(socket_pair_key);
-
- return 0;
-
-err_out:
- _request_send_result(req, -1);
- if (socket_pair_key) {
- g_hash_table_remove(__dc_socket_pair_hash, socket_pair_key);
- free(socket_pair_key);
- }
-
- return -1;
-}
-
-static int __dispatch_app_set_process_group(request_h req)
-{
- int owner_pid;
- int child_pid;
- bundle *kb = NULL;
- const char *child_appid;
- const char *child_pkgid = NULL;
- const struct appinfo *ai;
- const char *str_pid;
- app_status_h app_status;
- int ret;
-
- kb = _request_get_bundle(req);
- if (kb == NULL) {
- _request_send_result(req, -1);
- return -1;
- }
-
- str_pid = bundle_get_val(kb, AUL_K_OWNER_PID);
- if (str_pid == NULL) {
- _E("No owner pid");
- _request_send_result(req, -1);
- return -1;
- }
-
- owner_pid = atoi(str_pid);
- str_pid = bundle_get_val(kb, AUL_K_CHILD_PID);
- if (str_pid == NULL) {
- _E("No child pid");
- _request_send_result(req, -1);
- return -1;
- }
-
- child_pid = atoi(str_pid);
- app_status = _app_status_find(child_pid);
- if (app_status) {
- child_appid = _app_status_get_appid(app_status);
- ai = _appinfo_find(_request_get_target_uid(req), child_appid);
- child_pkgid = _appinfo_get_value(ai, AIT_PKGID);
- }
-
- ret = aul_send_app_group_signal(owner_pid, child_pid, child_pkgid);
-
- _request_send_result(req, ret);
- return 0;
-}
-
-struct checker_info {
- caller_info_h caller;
- request_h req;
-};
-
-int __datacontrol_privilege_func(const char *privilege_name, void *user_data)
-{
- int ret;
- struct checker_info *info = (struct checker_info*)user_data;
-
- ret = _cynara_simple_checker(info->caller, info->req,
- (void *)privilege_name);
- if (ret >= 0 && datacontrol_result == AMD_CYNARA_UNKNOWN)
- return ret;
-
- datacontrol_result = ret;
- return ret;
-}
-
-static int __datacontrol_provider_checker(caller_info_h info, request_h req,
- void *data)
-{
- bundle *b;
- char *provider_id;
- char *type;
- char *data_type;
- int ret;
- struct checker_info checker = {
- .caller = info,
- .req = req
- };
-
- b = _request_get_bundle(req);
- if (b == NULL)
- return -1;
-
- ret = bundle_get_str(b, "DATA_CONTROL_TYPE", &type);
- if (ret < 0)
- return -1;
-
- if (strcmp(type, "provider") == 0)
- return 0;
-
- ret = bundle_get_str(b, OSP_K_DATACONTROL_PROVIDER, &provider_id);
- if (ret < 0)
- return -1;
-
- ret = bundle_get_str(b, "DATA_CONTROL_DATA_TYPE", &data_type);
- if (ret < 0)
- return -1;
-
- datacontrol_result = 0;
-
- ret = pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges(provider_id,
- data_type, __datacontrol_privilege_func,
- &checker, _request_get_target_uid(req));
- if (ret < 0) {
- _E("pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges failed");
- return -1;
- }
-
- return datacontrol_result;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
- {
- .cmd = APP_GET_DC_SOCKET_PAIR,
- .callback = __dispatch_get_dc_socket_pair
- },
- {
- .cmd = APP_GET_MP_SOCKET_PAIR,
- .callback = __dispatch_get_mp_socket_pair
- },
- {
- .cmd = APP_SET_PROCESS_GROUP,
- .callback = __dispatch_app_set_process_group
- },
-};
-
-static cynara_checker __cynara_checkers[] = {
- {
- .cmd = APP_GET_DC_SOCKET_PAIR,
- .checker = __datacontrol_provider_checker,
- .data = NULL,
- },
-};
-
-static void __free_socket_pair(gpointer data)
-{
- int *handles = (int *)data;
-
- if (handles == NULL)
- return;
-
- if (handles[0] > 0)
- close(handles[0]);
- if (handles[1] > 0)
- close(handles[1]);
- free(handles);
-}
-
-static void __memory_status_changed_cb(keynode_t *node, void *data)
-{
- __memory_status = vconf_keynode_get_int(node);
- switch (__memory_status) {
- case VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL:
- _W("Normal");
- _noti_send(AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL, 0, 0, NULL, NULL);
- break;
- case VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING:
- _W("Soft warning");
- break;
- case VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING:
- _W("Hard warning");
- break;
- default:
- break;
- }
-}
-
-bool _util_check_oom(void)
-{
- if (__memory_status >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
- _W("low memory");
- return true;
- }
-
- return false;
-}
-
-static int __init_vconf(void)
-{
- int r;
-
- vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &__memory_status);
- r = vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
- __memory_status_changed_cb, NULL);
- if (r < 0) {
- _E("Failed to initialize vconf");
- return -1;
- }
-
- __vconf_initialized = true;
-
- return 0;
-}
-
-static void __finish_vconf(void)
-{
- if (!__vconf_initialized)
- return;
-
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
- __memory_status_changed_cb);
- __vconf_initialized = false;
-}
-
-static gboolean __retrying_handler(gpointer data)
-{
- static int retry_count;
-
- retry_count++;
- if (__init_vconf() < 0 && retry_count <= 10) {
- _W("Retry count(%d)", retry_count);
- return G_SOURCE_CONTINUE;
- }
-
- __vconf_init_timer = 0;
- return G_SOURCE_REMOVE;
-}
-
-int _util_init(void)
-{
- int r;
-
- r = _logger_create(AMD_LOG_FILE, &__logger);
- if (r < 0)
- return -1;
-
- __vconf_init_timer = g_timeout_add(500, __retrying_handler, NULL);
-
- __dc_socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, __free_socket_pair);
- if (__dc_socket_pair_hash == NULL) {
- _E("Failed to create socket pair table");
- return -1;
- }
-
- r = _request_register_cmds(__dispatch_table,
- ARRAY_SIZE(__dispatch_table));
- if (r < 0) {
- _E("Failed to register cmds");
- return -1;
- }
-
- r = _cynara_register_checkers(__cynara_checkers,
- ARRAY_SIZE(__cynara_checkers));
- if (r < 0) {
- _E("Failed to register checkers");
- return -1;
- }
-
- return 0;
-}
-
-void _util_fini(void)
-{
- if (__vconf_init_timer)
- g_source_remove(__vconf_init_timer);
-
- __finish_vconf();
-
- if (__dc_socket_pair_hash) {
- g_hash_table_destroy(__dc_socket_pair_hash);
- __dc_socket_pair_hash = NULL;
- }
-
- _logger_destroy(__logger);
-}
-
-static int __delete_dir(const char *path)
-{
- DIR *dp;
- struct dirent *dentry = NULL;
- char buf[PATH_MAX];
- struct stat statbuf;
- int ret;
-
- dp = opendir(path);
- if (dp == NULL)
- return -1;
-
- while ((dentry = readdir(dp)) != NULL) {
- if (!strcmp(dentry->d_name, ".") ||
- !strcmp(dentry->d_name, ".."))
- continue;
-
- snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
- ret = stat(buf, &statbuf);
- if (ret == 0) {
- if (S_ISDIR(statbuf.st_mode))
- __delete_dir(buf);
- else
- unlink(buf);
- }
- }
-
- rmdir(path);
- closedir(dp);
-
- return 0;
-}
-
-int _util_unlink(const char *path)
-{
- struct stat statbuf;
- int ret;
-
- if (!path) {
- _E("Invalid parameter");
- return -1;
- }
-
- ret = stat(path, &statbuf);
- if (ret < 0) {
- _E("Failed to get file(%s) status. errno(%d)", path, errno);
- return -1;
- }
-
- if (S_ISDIR(statbuf.st_mode))
- return __delete_dir(path);
-
- unlink(path);
-
- return 0;
-}
+++ /dev/null
-/*
- * 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_app_com.h>
-#include <aul_sock.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "core/app_com/app_com_broker.hh"
-#include "core/common/log_private.hh"
-#include "core/common/key_private.hh"
-
-namespace amd {
-
-AppComBroker::~AppComBroker() {
- if (!disposed_)
- Dispose();
-}
-
-AppComBroker& AppComBroker::GetInst() {
- static AppComBroker inst;
- std::lock_guard<std::recursive_mutex> lock(inst.GetMutex());
- if (inst.disposed_)
- inst.Init();
- return inst;
-}
-
-void AppComBroker::Dispose() {
- queue_.Push(AppComMessage(true));
- if (thread_.joinable()) {
- _W("Join thread");
- thread_.join();
- }
- disposed_ = true;
-}
-
-int AppComBroker::Create(const std::string& endpoint, unsigned int propagate,
- const std::string& privilege) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- if (Exist(endpoint)) {
- _W("Already exists");
- return AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS;
- }
-
- auto* new_endpoint = new (std::nothrow) AppComEndpoint(endpoint,
- propagate, privilege);
- if (new_endpoint == nullptr) {
- _E("Out of memory");
- return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
- }
-
- endpoints_[endpoint] = std::unique_ptr<AppComEndpoint>(new_endpoint);
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-int AppComBroker::Destroy(const std::string& endpoint) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- if (!Exist(endpoint))
- return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
-
- endpoints_.erase(endpoint);
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-int AppComBroker::Join(const std::string& endpoint, const std::string& filter,
- int pid, uid_t uid) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- if (!Exist(endpoint)) {
- _W("Endpoint(%s) does not exist", endpoint.c_str());
- return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
- }
-
- auto* client = new (std::nothrow) AppComClient(filter, pid, uid);
- if (client == nullptr) {
- _E("Out of memory");
- return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
- }
-
- endpoints_[endpoint]->AddClient(pid, std::shared_ptr<AppComClient>(client));
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-int AppComBroker::Send(const std::string& endpoint,
- std::shared_ptr<tizen_base::Bundle> envelope,
- int sender_pid, uid_t sender_uid) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- if (!Exist(endpoint)) {
- _W("Endpoint(%s) does not exist", endpoint.c_str());
- return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
- }
-
- for (auto iter : endpoints_[endpoint]->GetClients()) {
- auto& client = iter.second;
- int pid = client->GetPid();
- if (pid == sender_pid)
- continue;
-
- uid_t uid = client->GetUid();
- if (uid >= REGULAR_UID_MIN && uid != sender_uid)
- continue;
-
- queue_.Push(AppComMessage(pid, uid, envelope));
- }
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-int AppComBroker::Leave(const std::string& endpoint, int pid) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- if (!Exist(endpoint)) {
- _W("Endpoint(%s) does not exist", endpoint.c_str());
- return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
- }
-
- endpoints_[endpoint]->RemoveClient(pid);
- if (endpoints_[endpoint]->GetClientCount() == 0) {
- _W("Remove endpoint(%s)", endpoint.c_str());
- endpoints_.erase(endpoint);
- }
- return AUL_APP_COM_R_ERROR_OK;
-}
-
-int AppComBroker::Remove(int pid) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- auto iter = endpoints_.begin();
- while (iter != endpoints_.end()) {
- auto& key = iter->first;
- auto& endpoint = iter->second;
- endpoint->RemoveClient(pid);
- if (endpoint->GetClientCount() == 0) {
- _W("Remove endpoint(%s)", key.c_str());
- iter = endpoints_.erase(iter);
- } else {
- iter++;
- }
- }
- return 0;
-}
-
-bool AppComBroker::Exist(const std::string& endpoint) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- auto iter = endpoints_.find(endpoint);
- if (iter != endpoints_.end())
- return true;
- return false;
-}
-
-const std::string& AppComBroker::GetPrivilege(const std::string& endpoint) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- return endpoints_[endpoint]->GetPrivilege();
-}
-
-void AppComBroker::Init() {
- thread_ = std::thread([&]() {
- _W("START");
- SetComm();
- do {
- auto msg = queue_.WaitAndPop();
- if (msg.Done()) {
- _W("Done");
- break;
- }
-
- int pid = msg.GetPid();
- uid_t uid = msg.GetUid();
- int ret = aul_sock_send_bundle(pid, uid, APP_COM_MESSAGE,
- msg.GetEnvelope()->GetHandle(), AUL_SOCK_NOREPLY);
- if (ret < 0) {
- if (ret == -ECOMM) {
- _E("Remove client. pid(%d), uid(%u)", pid, uid);
- Remove(pid);
- } else {
- _E("Failed to send message. pid(%d), uid(%u), error(%d)",
- pid, uid, ret);
- }
- }
- } while (true);
- _W("END");
- });
- disposed_ = false;
-}
-
-void AppComBroker::SetComm() {
- pid_t tid = syscall(__NR_gettid);
- std::string path = "/proc/" + std::to_string(tid) + "/comm";
- int fd = open(path.c_str(), O_WRONLY);
- if (fd < 0) {
- _E("open(%s) is failed. errno(%d)", path.c_str(), errno);
- return;
- }
-
- std::string name = "AppComBroker";
- ssize_t bytes_written = write(fd, name.c_str(), name.length() + 1);
- if (bytes_written < 0)
- _E("write(%d) is failed. errno(%d)", fd, errno);
-
- close(fd);
-}
-
-std::recursive_mutex& AppComBroker::GetMutex() const {
- return mutex_;
-}
-
-} // namespace amd
+++ /dev/null
-/*
- * 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 CORE_APP_COM_APP_COM_BROKER_HH_
-#define CORE_APP_COM_APP_COM_BROKER_HH_
-
-#include <bundle_cpp.h>
-
-#include <list>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <thread>
-
-#include "core/app_com/app_com_client.hh"
-#include "core/app_com/app_com_endpoint.hh"
-#include "core/app_com/app_com_message.hh"
-#include "core/common/shared_queue.hh"
-
-namespace amd {
-
-class AppComBroker {
- private:
- AppComBroker() = default;
- ~AppComBroker();
-
- public:
- static AppComBroker& GetInst();
- void Dispose();
-
- int Create(const std::string& endpoint, unsigned int propagate,
- const std::string& privilege);
- int Destroy(const std::string& endpoint);
- int Join(const std::string& endpoint, const std::string& filter,
- int pid, uid_t uid);
- int Send(const std::string& endpoint,
- std::shared_ptr<tizen_base::Bundle> envelope,
- int sender_pid, uid_t sender_uid);
- int Leave(const std::string& endpoint, int pid);
- int Remove(int pid);
- bool Exist(const std::string& endpoint);
- const std::string& GetPrivilege(const std::string& endpoint);
-
- private:
- void Init();
- void SetComm();
- std::recursive_mutex& GetMutex() const;
-
- private:
- bool disposed_ = true;
- std::thread thread_;
- SharedQueue<AppComMessage> queue_;
- std::map<std::string, std::unique_ptr<AppComEndpoint>> endpoints_;
- mutable std::recursive_mutex mutex_;
-};
-
-} // namespace amd
-
-#endif // CORE_APP_COM_APP_COM_BROKER_HH_
+++ /dev/null
-/*
- * 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 "core/app_com/app_com_client.hh"
-
-namespace amd {
-
-AppComClient::AppComClient(std::string filter, int pid, uid_t uid)
- : filter_(std::move(filter)), pid_(pid), uid_(uid) {
-}
-
-AppComClient::~AppComClient() = default;
-
-const std::string& AppComClient::GetFilter() {
- return filter_;
-}
-
-int AppComClient::GetPid() const {
- return pid_;
-}
-
-uid_t AppComClient::GetUid() const {
- return uid_;
-}
-
-} // namespace amd
+++ /dev/null
-/*
- * 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 CORE_APP_COM_APP_COM_CLIENT_HH_
-#define CORE_APP_COM_APP_COM_CLIENT_HH_
-
-#include <map>
-#include <memory>
-#include <string>
-
-namespace amd {
-
-class AppComClient {
- public:
- AppComClient(std::string filter, int pid, uid_t uid);
- virtual ~AppComClient();
-
- const std::string& GetFilter();
- int GetPid() const;
- uid_t GetUid() const;
-
- private:
- std::string filter_;
- int pid_;
- uid_t uid_;
-};
-
-} // namespace amd
-
-#endif // CORE_APP_COM_APP_COM_CLIENT_HH_
+++ /dev/null
-/*
- * 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 "core/app_com/app_com_endpoint.hh"
-
-namespace amd {
-
-AppComEndpoint::AppComEndpoint(std::string endpoint, unsigned int propagate,
- std::string privilege)
- : endpoint_(std::move(endpoint)),
- propagate_(propagate),
- privilege_(std::move(privilege)) {
-}
-
-AppComEndpoint::~AppComEndpoint() = default;
-
-void AppComEndpoint::AddClient(int pid, std::shared_ptr<AppComClient> client) {
- auto iter = clients_.find(pid);
- if (iter != clients_.end())
- return;
-
- clients_[pid] = client;
-}
-
-void AppComEndpoint::RemoveClient(int pid) {
- auto iter = clients_.find(pid);
- if (iter == clients_.end())
- return;
-
- clients_.erase(iter);
-}
-
-const std::string& AppComEndpoint::GetEndpoint() {
- return endpoint_;
-}
-
-unsigned int AppComEndpoint::GetPropagate() const {
- return propagate_;
-}
-
-const std::string& AppComEndpoint::GetPrivilege() {
- return privilege_;
-}
-
-const std::map<int, std::shared_ptr<AppComClient>>&
-AppComEndpoint::GetClients() {
- return clients_;
-}
-
-int AppComEndpoint::GetClientCount() {
- return clients_.size();
-}
-
-} // namespace amd
+++ /dev/null
-/*
- * 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 CORE_APP_COM_APP_COM_ENDPOINT_HH_
-#define CORE_APP_COM_APP_COM_ENDPOINT_HH_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "core/app_com/app_com_client.hh"
-
-namespace amd {
-
-class AppComEndpoint {
- public:
- AppComEndpoint(std::string endpoint, unsigned int propagate,
- std::string privilege);
- virtual ~AppComEndpoint();
-
- void AddClient(int pid, std::shared_ptr<AppComClient> client);
- void RemoveClient(int pid);
-
- const std::string& GetEndpoint();
- unsigned int GetPropagate() const;
- const std::string& GetPrivilege();
- const std::map<int, std::shared_ptr<AppComClient>>& GetClients();
- int GetClientCount();
-
- private:
- std::string endpoint_;
- unsigned int propagate_;
- std::string privilege_;
- std::map<int, std::shared_ptr<AppComClient>> clients_;
-};
-
-} // namespace amd
-
-#endif // CORE_APP_COM_APP_COM_ENDPOINT_HH_
+++ /dev/null
-/*
- * 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 CORE_APP_COM_APP_COM_MESSAGE_H_
-#define CORE_APP_COM_APP_COM_MESSAGE_H_
-
-#include <bundle_cpp.h>
-
-#include <memory>
-#include <string>
-
-namespace amd {
-
-class AppComMessage {
- public:
- AppComMessage(int pid, uid_t uid,
- std::shared_ptr<tizen_base::Bundle> envelope)
- : pid_(pid), uid_(uid), envelope_(std::move(envelope)) {
- }
-
- AppComMessage(bool done = false) : done_(done) {
- }
-
- virtual ~AppComMessage() = default;
-
- int GetPid() const {
- return pid_;
- }
-
- uid_t GetUid() const {
- return uid_;
- }
-
- const std::shared_ptr<tizen_base::Bundle>& GetEnvelope() {
- return envelope_;
- }
-
- bool Done() {
- return done_;
- }
-
- private:
- bool done_ = false;
- int pid_;
- uid_t uid_;
- std::shared_ptr<tizen_base::Bundle> envelope_;
-};
-
-} // namespace amd
-
-#endif // CORE_APP_COM_APP_COM_MESSAGE_HH_
+++ /dev/null
-/*
- * 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 CORE_COMMON_KEY_PRIVATE_HH_
-#define CORE_COMMON_KEY_PRIVATE_HH_
-
-#undef REGULAR_UID_MIN
-#define REGULAR_UID_MIN 5000
-
-#undef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-#endif // CORE_COMMON_KEY_PRIVATE_HH_
+++ /dev/null
-/*
- * 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 CORE_COMMON_LOG_PRIVATE_HH_
-#define CORE_COMMON_LOG_PRIVATE_HH_
-
-#include <dlog.h>
-
-#undef LOG_TAG
-#define LOG_TAG "AMD"
-
-#undef _E
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-
-#undef _D
-#define _D(fmt, arg...) LOGD(fmt, ##arg)
-
-#undef _W
-#define _W(fmt, arg...) LOGW(fmt, ##arg)
-
-#undef _I
-#define _I(fmt, arg...) LOGI(fmt, ##arg)
-
-#endif // CORE_COMMON_LOG_PRIVATE_HH_
+++ /dev/null
-/*
- * 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 CORE_COMMON_SHARED_QUEUE_HH_
-#define CORE_COMMON_SHARED_QUEUE_HH_
-
-#include <condition_variable>
-#include <thread>
-#include <mutex>
-#include <memory>
-#include <queue>
-
-namespace amd {
-
-template <class T>
-class SharedQueue {
- public:
- SharedQueue() = default;
- virtual ~SharedQueue() = default;
-
- void Push(T item) {
- std::lock_guard<std::mutex> lock(mutex_);
- queue_.push(item);
- cond_var_.notify_one();
- }
-
- T WaitAndPop() {
- std::unique_lock<std::mutex> lock(mutex_);
- while (queue_.empty())
- cond_var_.wait(lock);
-
- auto item = std::move(queue_.front());
- queue_.pop();
- return item;
- }
-
- bool IsEmpty() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.empty();
- }
-
- unsigned int Size() const {
- std::lock_guard<std::mutex> lock(mutex_);
- return queue_.size();
- }
-
- private:
- std::queue<T> queue_;
- mutable std::mutex mutex_;
- std::condition_variable cond_var_;
-};
-
-} // namespace amd
-
-#endif // CORE_COMMON_SHARED_QUEUE_HH_
--- /dev/null
+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)
+
+ADD_LIBRARY(${TARGET_LIB_AMD} SHARED
+ ${LIB_SRCS}
+ ${LIB_API_SRCS}
+ ${LIB_APP_COM_SRCS}
+ ${LIB_COMMON_SRCS}
+)
+SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES OUTPUT_NAME amd)
+
+SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES COMPILE_FLAGS
+ ${CFLAGS} "-fpic")
+SET_TARGET_PROPERTIES(${TARGET_LIB_AMD} PROPERTIES LINK_FLAGS "-ldl -lpthread")
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_LIB_AMD} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/api)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_LIB_AMD} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+APPLY_PKG_CONFIG(${TARGET_LIB_AMD} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ CERT_SVC_VCORE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ INIPARSER_DEPS
+ LIBSYSTEMD_DEPS
+ LIBTZPLATFORM_CONFIG_DEPS
+ PKGMGR_DEPS
+ PKGMGR_INFO_DEPS
+ TTRACE_DEPS
+ UUID_DEPS
+ VCONF_DEPS
+)
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/${TARGET_LIB_AMD}.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/amd.pc @ONLY)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/amd.pc DESTINATION
+ ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(TARGETS ${TARGET_LIB_AMD} DESTINATION ${LIB_INSTALL_DIR} COMPONENT
+ RuntimeLibraries)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/api/ DESTINATION include/amd
+ FILES_MATCHING
+ PATTERN "*.h")
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glib.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <bundle_internal.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+
+#include "amd_api_noti.h"
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_signal.h"
+#include "amd_anr_monitor.h"
+#include "amd_app_status.h"
+#include "amd_app_property.h"
+#include "amd_appinfo.h"
+#include "amd_noti.h"
+#include "amd_request.h"
+#include "amd_launch.h"
+
+#define MAX_TIMEOUT 5000
+#define METADATA_ANR_CHECK_BYPASS \
+ "http://tizen.org/metadata/appmanager/anr_check_bypass"
+
+typedef struct proc_info_s {
+ pid_t pid;
+ int ref;
+ guint timer;
+} proc_info_t;
+
+static GHashTable *__proc_tbl;
+
+static proc_info_t *__find_proc_info(pid_t pid);
+static void __remove_proc_info(pid_t pid);
+
+static bool __is_managed_by_taskmgr(app_status_h app_status)
+{
+ struct appinfo *ai;
+ const char *taskmanage;
+ const char *appid;
+ uid_t uid;
+
+ appid = _app_status_get_appid(app_status);
+ uid = _app_status_get_uid(app_status);
+ ai = _appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ taskmanage = _appinfo_get_value(ai, AIT_TASKMANAGE);
+ if (!strcmp(taskmanage, "true"))
+ return true;
+
+ return false;
+}
+
+static bool __can_ignore_anr_policy(app_status_h app_status)
+{
+ app_property_h app_property;
+ const char *appid;
+ bool ignore;
+ uid_t uid;
+
+ appid = _app_status_get_appid(app_status);
+ uid = _app_status_get_uid(app_status);
+ if (!_appinfo_is_platform_app(appid, uid))
+ return false;
+
+ app_property = _app_property_find(uid);
+ ignore = _app_property_metadata_match(app_property,
+ appid, METADATA_ANR_CHECK_BYPASS, "yes");
+ if (ignore)
+ return true;
+
+ return false;
+}
+
+static gboolean __timeout_handler(gpointer data)
+{
+ pid_t pid = GPOINTER_TO_INT(data);
+ app_status_h app_status;
+ proc_info_t *ctx;
+
+ ctx = __find_proc_info(pid);
+ if (!ctx)
+ return G_SOURCE_REMOVE;
+
+ ctx->timer = 0;
+
+ app_status = _app_status_find_v2(pid);
+ if (!app_status) {
+ _W("Failed to find app status. pid(%d)", pid);
+ __remove_proc_info(pid);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (_app_status_get_status(app_status) == STATUS_DYING) {
+ _W("%d is dying", pid);
+ __remove_proc_info(pid);
+ return G_SOURCE_REMOVE;
+ }
+
+ _W("Application(%d) Not Responding", pid);
+ if (__can_ignore_anr_policy(app_status)) {
+ _W("Ignore ANR policy. pid(%d)", pid);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (!__is_managed_by_taskmgr(app_status)) {
+ _W("The process(%d) is not managed by task-manager", pid);
+ return G_SOURCE_REMOVE;
+ }
+
+ __remove_proc_info(pid);
+ _signal_send_watchdog(pid, SIGKILL);
+
+ return G_SOURCE_REMOVE;
+}
+
+static proc_info_t *__create_proc_info(pid_t pid)
+{
+ proc_info_t *ctx;
+
+ ctx = calloc(1, sizeof(proc_info_t));
+ if (!ctx) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ ctx->pid = pid;
+ ctx->ref = 1;
+
+ ctx->timer = g_timeout_add(MAX_TIMEOUT, __timeout_handler,
+ GINT_TO_POINTER(pid));
+ if (ctx->timer == 0)
+ _E("Failed to add timer");
+
+ return ctx;
+}
+
+static void __destroy_proc_info(gpointer data)
+{
+ proc_info_t *ctx = (proc_info_t *)data;
+
+ if (!ctx) {
+ _E("Critical error");
+ return;
+ }
+
+ if (ctx->timer > 0)
+ g_source_remove(ctx->timer);
+
+ free(ctx);
+}
+
+static proc_info_t *__find_proc_info(pid_t pid)
+{
+ if (!g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(pid)))
+ return NULL;
+
+ return g_hash_table_lookup(__proc_tbl, GINT_TO_POINTER(pid));
+}
+
+static void __add_proc_info(proc_info_t *ctx)
+{
+ if (g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(ctx->pid)))
+ return;
+
+ g_hash_table_insert(__proc_tbl, GINT_TO_POINTER(ctx->pid), ctx);
+}
+
+static void __remove_proc_info(pid_t pid)
+{
+ if (!g_hash_table_contains(__proc_tbl, GINT_TO_POINTER(pid)))
+ return;
+
+ g_hash_table_remove(__proc_tbl, GINT_TO_POINTER(pid));
+}
+
+static void __reset_timer(proc_info_t *ctx)
+{
+ if (ctx->timer > 0)
+ g_source_remove(ctx->timer);
+
+ ctx->timer = g_timeout_add(MAX_TIMEOUT, __timeout_handler,
+ GINT_TO_POINTER(ctx->pid));
+ if (ctx->timer == 0)
+ _E("Failed to add timer. pid(%d)", ctx->pid);
+
+ _W("Reset timer. pid(%d)", ctx->pid);
+}
+
+int _anr_monitor_add_timer(pid_t pid)
+{
+ proc_info_t *ctx;
+
+ _W("Add timer. pid(%d)", pid);
+ ctx = __find_proc_info(pid);
+ if (ctx) {
+ __reset_timer(ctx);
+ ctx->ref++;
+ return 0;
+ }
+
+ ctx = __create_proc_info(pid);
+ if (!ctx) {
+ _E("Failed to create process(%d) info", pid);
+ return -1;
+ }
+
+ __add_proc_info(ctx);
+
+ return 0;
+}
+
+int _anr_monitor_remove_timer(pid_t pid)
+{
+ proc_info_t *ctx;
+
+ _W("Remove timer. pid(%d)", pid);
+ ctx = __find_proc_info(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) info", pid);
+ return -1;
+ }
+
+ ctx->ref--;
+ if (ctx->ref > 0)
+ return 0;
+
+ __remove_proc_info(pid);
+
+ return 0;
+}
+
+static int __dispatch_anr_notify(request_h req)
+{
+ bundle *b = _request_get_bundle(req);
+ uid_t uid = _request_get_uid(req);
+ int pid = _request_get_pid(req);
+ app_status_h app_status;
+ const char *cmd_str;
+ int cmd;
+
+ cmd_str = bundle_get_val(b, AUL_K_COMMAND);
+ if (cmd_str)
+ cmd = atoi(cmd_str);
+ else
+ cmd = -1;
+
+ _E("Application(%d) Not Responding. cmd(%d)", pid, cmd);
+
+ app_status = _app_status_find_v2(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return -1;
+ }
+
+ switch (cmd) {
+ case APP_OPEN:
+ case APP_RESUME:
+ case APP_START:
+ case APP_START_RES:
+ case APP_START_ASYNC:
+ case APP_START_RES_ASYNC:
+ case APP_SEND_LAUNCH_REQUEST:
+ case APP_SEND_LAUNCH_REQUEST_SYNC:
+ case APP_SEND_RESUME_REQUEST:
+ if (!_app_status_is_debug_mode(app_status) &&
+ !__can_ignore_anr_policy(app_status) &&
+ __is_managed_by_taskmgr(app_status))
+ _signal_send_watchdog(pid, SIGKILL);
+ break;
+ case APP_TERM_BY_PID:
+ case APP_TERM_REQ_BY_PID:
+ case APP_TERM_BY_PID_ASYNC:
+ case APP_TERM_BGAPP_BY_PID:
+ case APP_TERM_INSTANCE_ASYNC:
+ case APP_TERM_BG_INSTANCE:
+ _launch_send_sigkill(pid, uid);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = ANR_NOTIFY,
+ .callback = __dispatch_anr_notify
+ },
+};
+
+static int __on_signal_send_watchdog_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+
+ _W("Watchdog pid(%d)", pid);
+ _anr_monitor_remove_timer(pid);
+
+ return 0;
+}
+
+int _anr_monitor_init(void)
+{
+ int ret;
+
+ _D("[__ANR_MONITOR__] init");
+
+ __proc_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __destroy_proc_info);
+ if (!__proc_tbl) {
+ _E("Failed to create proc table");
+ return -1;
+ }
+
+ ret = _app_property_metadata_add_filter(METADATA_ANR_CHECK_BYPASS,
+ NULL);
+ if (ret < 0)
+ return -1;
+
+ ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0)
+ return -1;
+
+ _noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
+ __on_signal_send_watchdog_start);
+
+ return 0;
+}
+
+void _anr_monitor_fini(void)
+{
+ _D("[__ANR_MONITOR__] fini");
+
+ _app_property_metadata_remove_filter(METADATA_ANR_CHECK_BYPASS, NULL);
+
+ if (__proc_tbl) {
+ g_hash_table_destroy(__proc_tbl);
+ __proc_tbl = NULL;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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_ANR_MONITOR_H__
+#define __AMD_ANR_MONITOR_H__
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _anr_monitor_add_timer(pid_t pid);
+
+int _anr_monitor_remove_timer(pid_t pid);
+
+int _anr_monitor_init(void);
+
+void _anr_monitor_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_ANR_MONITOR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_H__
+#define __AMD_API_H__
+
+#undef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+
+#undef EXPORT_API
+#define EXPORT_API EXPORT
+
+#endif /* __AMD_API_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_app_com.h"
-#include "amd_app_com.h"
-
-EXPORT_API int amd_app_com_send(const char *endpoint, int cpid,
- bundle *envelope, uid_t uid)
-{
- return _app_com_send(endpoint, cpid, envelope, uid);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_api_app_property.h"
-#include "amd_app_property.h"
-
-EXPORT_API amd_app_property_h amd_app_property_find(uid_t uid)
-{
- return _app_property_find(uid);
-}
-
-EXPORT_API int amd_app_property_metadata_add_filter(const char *key,
- const char *value)
-{
- return _app_property_metadata_add_filter(key, value);
-}
-
-EXPORT_API int amd_app_property_metadata_remove_filter(const char *key,
- const char *value)
-{
- return _app_property_metadata_remove_filter(key, value);
-}
-
-EXPORT_API int amd_app_property_metadata_foreach(
- amd_app_property_h app_property,
- const char *appid, const char *key,
- int (*callback)(const char *value, void *user_data),
- void *user_data)
-{
- return _app_property_metadata_foreach(app_property, appid, key,
- callback, user_data);
-}
-
-EXPORT_API const char *amd_app_property_get_real_appid(
- amd_app_property_h app_property, const char *alias_appid)
-{
- return _app_property_get_real_appid(app_property, alias_appid);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_app_status.h"
-#include "amd_api.h"
-#include "amd_api_app_status.h"
-
-EXPORT_API amd_app_status_h amd_app_status_find_by_effective_pid(int pid)
-{
- return _app_status_find_v2(pid);
-}
-
-EXPORT_API amd_app_status_h amd_app_status_find_by_pid(int pid)
-{
- return _app_status_find(pid);
-}
-
-EXPORT_API amd_app_status_h amd_app_status_find_by_appid(const char *appid,
- uid_t uid)
-{
- return _app_status_find_by_appid(appid, uid);
-}
-
-EXPORT_API int amd_app_status_get_pid(amd_app_status_h h)
-{
- return _app_status_get_pid(h);
-}
-
-EXPORT_API int amd_app_status_is_running(amd_app_status_h h)
-{
- return _app_status_is_running(h);
-}
-
-EXPORT_API uid_t amd_app_status_get_uid(amd_app_status_h h)
-{
- return _app_status_get_uid(h);
-}
-
-EXPORT_API int amd_app_status_get_status(amd_app_status_h h)
-{
- return _app_status_get_status(h);
-}
-
-EXPORT_API bool amd_app_status_is_home_app(amd_app_status_h h)
-{
- return _app_status_is_home_app(h);
-}
-
-EXPORT_API int amd_app_status_get_first_caller_pid(amd_app_status_h h)
-{
- return _app_status_get_org_caller_pid(h);
-}
-
-EXPORT_API const char *amd_app_status_get_appid(amd_app_status_h h)
-{
- return _app_status_get_appid(h);
-}
-
-EXPORT_API const char *amd_app_status_get_pkgid(amd_app_status_h h)
-{
- return _app_status_get_pkgid(h);
-}
-
-EXPORT_API const char *amd_app_status_get_instance_id(amd_app_status_h h)
-{
- return _app_status_get_instance_id(h);
-}
-
-EXPORT_API int amd_app_status_foreach_running_info(amd_app_status_cb callback,
- void *user_data)
-{
- return _app_status_foreach_running_appinfo(callback, user_data);
-}
-
-EXPORT_API int amd_app_status_terminate_apps(const char *appid, uid_t uid)
-{
- return _app_status_terminate_apps(appid, uid);
-}
-
-EXPORT_API bool amd_app_status_is_starting(amd_app_status_h h)
-{
- return _app_status_is_starting(h);
-}
-
-EXPORT_API int amd_app_status_get_app_type(amd_app_status_h app_status)
-{
- return _app_status_get_app_type(app_status);
-}
-
-EXPORT_API int amd_app_status_set_extra(amd_app_status_h app_status,
- const char *key, void *data)
-{
- return _app_status_set_extra(app_status, key, data);
-}
-
-EXPORT_API int amd_app_status_remove_extra(amd_app_status_h app_status,
- const char *key)
-{
- return _app_status_remove_extra(app_status, key);
-}
-
-EXPORT_API void *amd_app_status_get_extra(amd_app_status_h app_status,
- const char *key)
-{
- return _app_status_get_extra(app_status, key);
-}
-
-EXPORT_API const char *amd_app_status_get_leader_id(amd_app_status_h app_status)
-{
- return _app_status_get_leader_id(app_status);
-}
-
-EXPORT_API int amd_app_status_set_leader_id(amd_app_status_h app_status,
- const char *id)
-{
- return _app_status_set_leader_id(app_status, id);
-}
-
-EXPORT_API int amd_app_status_get_fg_cnt(amd_app_status_h app_status)
-{
- return _app_status_get_fg_cnt(app_status);
-}
-
-EXPORT_API int amd_app_status_get_timestamp(amd_app_status_h app_status)
-{
- return _app_status_get_timestamp(app_status);
-}
-
-EXPORT_API int amd_app_status_term_bg_apps(GCompareFunc func)
-{
- return _app_status_term_bg_apps(func);
-}
-
-EXPORT_API bool amd_app_status_get_bg_launch(amd_app_status_h app_status)
-{
- return _app_status_get_bg_launch(app_status);
-}
-
-EXPORT_API amd_app_status_h amd_app_status_find_by_instance_id(const char *appid,
- const char *instance_id, uid_t uid)
-{
- return _app_status_find_by_instance_id(appid, instance_id, uid);
-}
-
-EXPORT_API void amd_app_status_find_service_apps(amd_app_status_h app_status,
- int status, void (*send_event_to_svc_core)(int, uid_t),
- bool suspend)
-{
- _app_status_find_service_apps(app_status, status,
- send_event_to_svc_core, suspend);
-}
-
-EXPORT_API int amd_app_status_get_process_cnt(const char *appid)
-{
- return _app_status_get_process_cnt(appid);
-}
-
-EXPORT_API const char *amd_app_status_get_app_path(amd_app_status_h app_status)
-{
- return _app_status_get_app_path(app_status);
-}
-
-EXPORT_API bool amd_app_status_is_exiting(amd_app_status_h app_status)
-{
- return _app_status_is_exiting(app_status);
-}
-
-EXPORT_API int amd_app_status_register_pid(int pid, const char *appid,
- uid_t uid)
-{
- return _app_status_register_pid(pid, appid, uid);
-}
-
-EXPORT_API bool amd_app_status_is_debug_mode(amd_app_status_h app_status)
-{
- return _app_status_is_debug_mode(app_status);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_appinfo.h"
-#include "amd_api_appinfo.h"
-
-EXPORT_API int amd_appinfo_insert(uid_t uid, const char *pkgid)
-{
- return _appinfo_insert(uid, pkgid);
-}
-
-EXPORT_API amd_appinfo_h amd_appinfo_find(uid_t caller_uid, const char *appid)
-{
- return _appinfo_find(caller_uid, appid);
-}
-
-EXPORT_API const char *amd_appinfo_get_value(amd_appinfo_h h,
- amd_appinfo_type type)
-{
- return _appinfo_get_value(h, (enum appinfo_type)type);
-}
-
-EXPORT_API const void *amd_appinfo_get_ptr_value(amd_appinfo_h h,
- amd_appinfo_type type)
-{
- return _appinfo_get_ptr_value(h, (enum appinfo_type)type);
-}
-
-EXPORT_API int amd_appinfo_get_int_value(amd_appinfo_h h, amd_appinfo_type type,
- int *val)
-{
- return _appinfo_get_int_value(h, (enum appinfo_type)type, val);
-}
-
-EXPORT_API int amd_appinfo_get_boolean(amd_appinfo_h h, amd_appinfo_type type,
- bool *val)
-{
- return _appinfo_get_boolean(h, (enum appinfo_type)type, val);
-}
-
-EXPORT_API int amd_appinfo_set_value(amd_appinfo_h h, amd_appinfo_type type,
- const char *val)
-{
- return _appinfo_set_value(h, (enum appinfo_type)type, val);
-}
-
-EXPORT_API int amd_appinfo_set_ptr_value(amd_appinfo_h h, amd_appinfo_type type,
- void *val)
-{
- return _appinfo_set_ptr_value(h, (enum appinfo_type)type, val);
-}
-
-EXPORT_API int amd_appinfo_set_int_value(amd_appinfo_h h, amd_appinfo_type type,
- int val)
-{
- return _appinfo_set_int_value(h, (enum appinfo_type)type, val);
-}
-
-EXPORT_API void amd_appinfo_foreach(uid_t uid, amd_appinfo_iter_callback cb,
- void *user_data)
-{
- return _appinfo_foreach(uid, cb, user_data);
-}
-
-EXPORT_API int amd_appinfo_load(uid_t uid)
-{
- return _appinfo_load(uid);
-}
-
-EXPORT_API void amd_appinfo_unload(uid_t uid)
-{
- return _appinfo_unload(uid);
-}
-
-EXPORT_API amd_appinfo_splash_image_h amd_appinfo_find_splash_image(
- amd_appinfo_h h, const char *name, bool landscape)
-{
- return _appinfo_find_splash_image(h, name, landscape);
-}
-
-EXPORT_API const char *amd_appinfo_splash_image_get_source(
- amd_appinfo_splash_image_h h)
-{
- return _appinfo_splash_image_get_source(h);
-}
-
-EXPORT_API const char *amd_appinfo_splash_image_get_type(
- amd_appinfo_splash_image_h h)
-{
- return _appinfo_splash_image_get_type(h);
-}
-
-EXPORT_API int amd_appinfo_splash_image_get_indicator_display(
- amd_appinfo_splash_image_h h)
-{
- return _appinfo_splash_image_get_indicator_display(h);
-}
-
-EXPORT_API int amd_appinfo_splash_image_get_color_depth(
- amd_appinfo_splash_image_h h)
-{
- return _appinfo_splash_image_get_color_depth(h);
-}
-
-EXPORT_API bool amd_appinfo_is_pkg_updating(const char *pkgid)
-{
- return _appinfo_is_pkg_updating(pkgid);
-}
-
-EXPORT_API int amd_appinfo_get_cert_visibility(const char *pkgid, uid_t uid)
-{
- return _appinfo_get_cert_visibility(pkgid, uid);
-}
-
-EXPORT_API bool amd_appinfo_is_platform_app(const char *appid, uid_t uid)
-{
- return _appinfo_is_platform_app(appid, uid);
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_comp_status.h"
-#include "amd_api_comp_status.h"
-
-EXPORT_API amd_comp_status_h amd_comp_status_find(const char *comp_id)
-{
- return _comp_status_find(comp_id);
-}
-
-EXPORT_API int amd_comp_status_set_leader_id(amd_comp_status_h h,
- const char *instance_id)
-{
- return _comp_status_set_leader_id(h, instance_id);
-}
-
-
-EXPORT_API const char *amd_comp_status_get_leader_id(amd_comp_status_h h)
-{
- return _comp_status_get_leader_id(h);
-}
-
-EXPORT_API int amd_comp_status_set_window(amd_comp_status_h h, int window)
-{
- return _comp_status_set_window(h, window);
-}
-
-EXPORT_API amd_comp_status_h amd_comp_status_find_by_instance_id(
- const char *instance_id)
-{
- return _comp_status_find_by_instance_id(instance_id);
-}
-
-EXPORT_API amd_comp_status_h amd_comp_status_find_by_window(int window)
-{
- return _comp_status_find_by_window(window);
-}
-
-EXPORT_API pid_t amd_comp_status_get_pid(amd_comp_status_h h)
-{
- return _comp_status_get_pid(h);
-}
-
-EXPORT_API const char *amd_comp_status_get_comp_id(amd_comp_status_h h)
-{
- return _comp_status_get_comp_id(h);
-}
-
-EXPORT_API const char *amd_comp_status_get_instance_id(amd_comp_status_h h)
-{
- return _comp_status_get_instance_id(h);
-}
-
-EXPORT_API int amd_comp_status_get_comp_type(amd_comp_status_h h)
-{
- return _comp_status_get_comp_type(h);
-}
-
-EXPORT_API int amd_comp_status_get_status(amd_comp_status_h h)
-{
- return _comp_status_get_status(h);
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_compinfo.h"
-#include "amd_api_compinfo.h"
-
-EXPORT_API amd_compinfo_h amd_compinfo_find(uid_t uid, const char *id)
-{
- return _compinfo_find(uid, id);
-}
-
-EXPORT_API const char *amd_compinfo_get_value(amd_compinfo_h info,
- amd_compinfo_type type)
-{
- return _compinfo_get_value(info, type);
-}
-
-EXPORT_API int amd_compinfo_foreach(uid_t uid, amd_compinfo_foreach_cb callback,
- void *user_data)
-{
- return _compinfo_foreach(uid, callback, user_data);
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_config.h"
-#include "amd_api.h"
-#include "amd_api_config.h"
-
-EXPORT_API amd_tizen_profile_t amd_config_get_tizen_profile(void)
-{
- return _config_get_tizen_profile();
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_cynara.h"
-#include "amd_cynara.h"
-
-static cynara_ops __ops;
-static cynara_caller_info_ops __ci_ops;
-static amd_cynara_ops __amd_ops;
-static amd_cynara_caller_info_ops __amd_ci_ops;
-
-EXPORT_API int amd_cynara_check_privilege(amd_request_h req,
- amd_cynara_response_cb callback)
-{
- return _cynara_check_privilege(req, (cynara_response_cb)callback);
-}
-
-EXPORT_API int amd_cynara_check_privilege_offline(amd_request_h req,
- const char *appid, const char *privilege)
-{
- return _cynara_check_privilege_offline(req, appid, privilege);
-}
-
-EXPORT_API int amd_cynara_register_checkers(const amd_cynara_checker *checkers,
- int cnt)
-{
- return _cynara_register_checkers((cynara_checker *)checkers, cnt);
-}
-
-EXPORT_API int amd_cynara_simple_checker(amd_cynara_caller_info_h info,
- amd_request_h req, void *data)
-{
- return _cynara_simple_checker(info, req, data);
-}
-
-EXPORT_API const char *amd_cynara_caller_info_get_client(
- amd_cynara_caller_info_h info)
-{
- return _cynara_caller_info_get_client(info);
-}
-
-EXPORT_API int amd_cynara_sub_checker_add(const char *name,
- amd_cynara_sub_checker_func func)
-{
- return _cynara_sub_checker_add(name, func);
-}
-
-EXPORT_API int amd_cynara_sub_checker_check(const char *name,
- amd_cynara_caller_info_h info, amd_request_h req)
-{
- return _cynara_sub_checker_check(name, info, req);
-}
-
-static int __register_checkers(const cynara_checker *checkers, int cnt)
-{
- return __amd_ops.register_checkers((amd_cynara_checker *)checkers, cnt);
-}
-
-static int __sub_checker_add(const char *name, sub_checker_func func)
-{
- return __amd_ops.sub_checker_add(name, func);
-}
-
-static int __sub_checker_check(const char *name, caller_info_h info, request_h req)
-{
- return __amd_ops.sub_checker_check(name, info, req);
-}
-
-static int __check_async(request_h req, cynara_response_cb callback)
-{
- return __amd_ops.check_async(req, (amd_cynara_response_cb)callback);
-}
-
-static int __check(caller_info_h info, request_h req, void *data)
-{
- return __amd_ops.check(info, req, data);
-}
-
-static int __check_offline(request_h req, const char *appid, const char *privilege)
-{
- return __amd_ops.check_offline(req, appid, privilege);
-}
-
-static const char *__get_client(caller_info_h info)
-{
- return __amd_ci_ops.get_client(info);
-}
-
-EXPORT_API int amd_cynara_register_ops(amd_cynara_ops ops,
- amd_cynara_caller_info_ops ci_ops)
-{
- __amd_ops = ops;
- __amd_ci_ops = ci_ops;
-
- __ops.register_checkers = __register_checkers;
- __ops.sub_checker_add = __sub_checker_add;
- __ops.sub_checker_check = __sub_checker_check;
- __ops.check_async = __check_async;
- __ops.check = __check;
- __ops.check_offline = __check_offline;
- __ci_ops.get_client = __get_client;
-
- return _cynara_register_ops(__ops, __ci_ops);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_inotify.h"
-#include "amd_inotify.h"
-
-EXPORT_API amd_inotify_watch_info_h amd_inotify_add_watch(const char *path,
- uint32_t mask, amd_inotify_watch_cb callback, void *data)
-{
- return _inotify_add_watch(path, mask, callback, data);
-}
-
-EXPORT_API void amd_inotify_rm_watch(amd_inotify_watch_info_h handle)
-{
- _inotify_rm_watch(handle);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_launch.h"
-#include "amd_launch.h"
-
-EXPORT_API int amd_launch_start_app(const char *appid, amd_request_h req,
- bool *pending, bool *bg_launch, bool new_instance)
-{
- return _launch_start_app(appid, req, pending, bg_launch, new_instance);
-}
-
-EXPORT_API int amd_launch_term_sub_app(int pid, uid_t uid)
-{
- return _term_sub_app(pid, uid);
-}
-
-EXPORT_API int amd_launch_start_onboot_apps(uid_t uid)
-{
- return _launch_start_onboot_apps(uid);
-}
-
-EXPORT_API void amd_launch_set_mode(amd_launch_mode_e mode)
-{
- _launch_set_mode(mode);
-}
-
-EXPORT_API int amd_launch_term_sub_inst(pid_t pid, const char *inst_id,
- uid_t uid)
-{
- return _term_sub_inst(pid, inst_id, uid);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_launch.h"
-#include "amd_api.h"
-#include "amd_api_launch_context.h"
-
-EXPORT_API amd_appinfo_h amd_launch_context_get_appinfo(
- amd_launch_context_h h)
-{
- return (amd_appinfo_h)_launch_context_get_appinfo(h);
-}
-
-EXPORT_API const char *amd_launch_context_get_appid(amd_launch_context_h h)
-{
- return _launch_context_get_appid(h);
-}
-
-EXPORT_API const char *amd_launch_context_get_instance_id(
- amd_launch_context_h h)
-{
- return _launch_context_get_instance_id(h);
-}
-
-EXPORT_API int amd_launch_context_get_pid(amd_launch_context_h h)
-{
- return _launch_context_get_pid(h);
-}
-
-EXPORT_API bool amd_launch_context_is_subapp(amd_launch_context_h h)
-{
- return _launch_context_is_subapp(h);
-}
-
-EXPORT_API bool amd_launch_context_is_bg_launch(amd_launch_context_h h)
-{
- return _launch_context_is_bg_launch(h);
-}
-
-EXPORT_API int amd_launch_context_set_pid(amd_launch_context_h h,
- int pid)
-{
- return _launch_context_set_pid(h, pid);
-}
-
-EXPORT_API bool amd_launch_context_is_new_instance(amd_launch_context_h h)
-{
- return _launch_context_is_new_instance(h);
-}
-
-EXPORT_API int amd_launch_context_set_subapp(amd_launch_context_h h,
- bool is_subapp)
-{
- return _launch_context_set_subapp(h, is_subapp);
-}
-
-EXPORT_API int amd_launch_context_set_app_status(amd_launch_context_h h,
- amd_app_status_h status)
-{
- return _launch_context_set_app_status(h, status);
-}
-
-EXPORT_API int amd_launch_context_set_comp_status(amd_launch_context_h h,
- amd_comp_status_h status)
-{
- return _launch_context_set_comp_status(h, status);
-}
-
-EXPORT_API void amd_launch_context_set_custom_effect(amd_launch_context_h h,
- bool is_custom_effect)
-{
- _launch_context_set_custom_effect(h, is_custom_effect);
-}
-
-EXPORT_API bool amd_launch_context_is_custom_effect(amd_launch_context_h h)
-{
- return _launch_context_is_custom_effect(h);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_launch_mode.h"
-#include "amd_launch_mode.h"
-
-EXPORT_API bool amd_launch_mode_is_group_mode(bundle *kb, uid_t uid)
-{
- return _launch_mode_is_group_mode(kb, uid);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_launchpad.h"
-#include "amd_api.h"
-#include "amd_api_launchpad.h"
-
-EXPORT_API int amd_launchpad_set_launcher(amd_launcher_cb launcher,
- void *user_data)
-{
- return _launchpad_set_launcher(launcher, user_data);
-}
+++ /dev/null
-/*
- * Copyright (c) 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "amd_logger.h"
-#include "amd_api_logger.h"
-#include "amd_api.h"
-
-EXPORT_API int amd_logger_create(const char *path, amd_logger_h *handle)
-{
- return _logger_create(path, (logger_h *)handle);
-}
-
-EXPORT_API int amd_logger_destroy(amd_logger_h handle)
-{
- return _logger_destroy(handle);
-}
-
-EXPORT_API int amd_logger_print(amd_logger_h handle, const char *tag,
- const char *format, ...)
-{
- char format_buf[LOG_MAX_STRING_SIZE];
- va_list ap;
-
- va_start(ap, format);
- vsnprintf(format_buf, sizeof(format_buf), format, ap);
- va_end(ap);
-
- return _logger_print(handle, tag, format_buf);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_login_monitor.h"
-#include "amd_login_monitor.h"
-
-EXPORT_API int amd_login_monitor_get_uids(uid_t **uids)
-{
- return _login_monitor_get_uids(uids);
-}
-
-EXPORT_API amd_uid_state amd_login_monitor_get_uid_state(uid_t uid)
-{
- return _login_monitor_get_uid_state(uid);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_noti.h"
-#include "amd_api.h"
-#include "amd_api_noti.h"
-
-EXPORT_API int amd_noti_send(const char *msg, int arg1, int arg2, void *arg3,
- bundle *data)
-{
- return _noti_send(msg, arg1, arg2, arg3, data);
-}
-
-EXPORT_API int amd_noti_listen(const char *msg, amd_noti_cb callback)
-{
- return _noti_listen(msg, (noti_cb)callback);
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_api_proc.h"
-#include "amd_proc.h"
-
-EXPORT_API int amd_proc_get_attr(pid_t pid, char *buf, int buf_size)
-{
- return _proc_get_attr(pid, buf, buf_size);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_api_request.h"
-#include "amd_request.h"
-
-EXPORT_API int amd_request_send_result(amd_request_h req, int res)
-{
- return _request_send_result(req, res);
-}
-
-EXPORT_API int amd_request_send_raw(amd_request_h req, int cmd, unsigned char *data, int len)
-{
- return _request_send_raw(req, cmd, data, len);
-}
-
-EXPORT_API int amd_request_get_fd(amd_request_h req)
-{
- return _request_get_fd(req);
-}
-
-EXPORT_API int amd_request_get_pid(amd_request_h req)
-{
- return _request_get_pid(req);
-}
-
-EXPORT_API int amd_request_get_cmd(amd_request_h req)
-{
- return _request_get_cmd(req);
-}
-
-EXPORT_API int amd_request_set_cmd(amd_request_h req, int cmd)
-{
- return _request_set_cmd(req, cmd);
-}
-
-EXPORT_API bundle *amd_request_get_bundle(amd_request_h req)
-{
- return _request_get_bundle(req);
-}
-
-EXPORT_API amd_request_h amd_request_create_local(int cmd, uid_t uid, int pid, bundle *kb)
-{
- return _request_create_local(cmd, uid, pid, kb);
-}
-
-EXPORT_API void amd_request_free_local(amd_request_h req)
-{
- return _request_free_local(req);
-}
-
-EXPORT_API int amd_request_remove_fd(amd_request_h req)
-{
- return _request_remove_fd(req);
-}
-
-EXPORT_API int amd_request_reply_for_pending_request(int pid)
-{
- return _request_reply_for_pending_request(pid);
-}
-
-EXPORT_API int amd_request_flush_pending_request(int pid)
-{
- return _request_flush_pending_request(pid);
-}
-
-EXPORT_API uid_t amd_request_get_target_uid(amd_request_h req)
-{
- return _request_get_target_uid(req);
-}
-
-EXPORT_API uid_t amd_request_get_uid(amd_request_h req)
-{
- return _request_get_uid(req);
-}
-
-EXPORT_API pid_t amd_request_get_target_pid(amd_request_h req)
-{
- return _request_get_target_pid(req);
-}
-
-EXPORT_API int amd_request_usr_init(uid_t uid)
-{
- return _request_usr_init(uid);
-}
-
-EXPORT_API int amd_request_register_cmds(const amd_request_cmd_dispatch *cmds, int cnt)
-{
- return _request_register_cmds((request_cmd_dispatch *)cmds, cnt);
-}
-
-EXPORT_API int amd_request_reply_append(int pid, void *reply)
-{
- return _request_reply_append(pid, reply);
-}
-
-EXPORT_API int amd_request_reply_remove(int pid, void *reply)
-{
- return _request_reply_remove(pid, reply);
-}
-
-EXPORT_API amd_request_reply_h amd_request_reply_create(amd_request_h req,
- pid_t pid, int result, int cmd)
-{
- return _request_reply_create(req, pid, result, cmd);
-}
-
-EXPORT_API int amd_request_reply_add_extra(amd_request_reply_h handle, const char *key,
- void *extra, void (*extra_free_cb)(void *data))
-{
- return _request_reply_add_extra(handle, key, extra, extra_free_cb);
-}
-
-EXPORT_API int amd_request_reply_foreach_extra(int pid, int (*callback)(const char *key, void *data))
-{
- return _request_reply_foreach_extra(pid, callback);
-}
-
-EXPORT_API int amd_request_get_len(amd_request_h req)
-{
- return _request_get_len(req);
-}
-
-EXPORT_API unsigned char *amd_request_get_raw(amd_request_h req)
-{
- return _request_get_raw(req);
-}
-
-EXPORT_API struct timespec *amd_request_get_start_time(amd_request_h req)
-{
- return _request_get_start_time(req);
-}
-
-EXPORT_API int amd_request_set_request_type(amd_request_h req,
- const char *req_type)
-{
- return _request_set_request_type(req, req_type);
-}
-
-EXPORT_API const char *amd_request_get_request_type(amd_request_h req)
-{
- return _request_get_request_type(req);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_api_signal.h"
-#include "amd_signal.h"
-
-EXPORT_API int amd_signal_send_tep_mount(char *mnt_path[], const char *pkgid)
-{
- return _signal_send_tep_mount(mnt_path, pkgid);
-}
-
-EXPORT_API int amd_signal_send_tep_unmount(const char *mnt_path)
-{
- return _signal_send_tep_unmount(mnt_path);
-}
-
-EXPORT_API int amd_signal_send_watchdog(int pid, int signal_num)
-{
- return _signal_send_watchdog(pid, signal_num);
-}
-
-EXPORT_API int amd_signal_add_ready_cb(amd_signal_ready_cb callback,
- void *user_data)
-{
- return _signal_add_ready_cb(callback, user_data);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_socket.h"
-#include "amd_api.h"
-#include "amd_api_socket.h"
-
-EXPORT_API void amd_socket_send_result(int fd, int res, bool close)
-{
- if (close)
- _send_result_to_client(fd, res);
- else
- _send_result_to_client_v2(fd, res);
-}
-
-EXPORT_API int amd_socket_send_cmd_to_launchpad(uid_t uid, pad_cmd_e cmd,
- bundle *b)
-{
- return _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid, cmd, b);
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 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.
- */
-
-#define _GNU_SOURCE
-
-#include "amd_api.h"
-#include "amd_suspend.h"
-#include "amd_api_suspend.h"
-
-EXPORT_API int amd_suspend_add_proc(int pid)
-{
- return _suspend_add_proc(pid);
-}
-
-EXPORT_API int amd_suspend_remove_proc(int pid)
-{
- return _suspend_remove_proc(pid);
-}
-
-EXPORT_API bool amd_suspend_is_excluded(int pid)
-{
- return _suspend_is_excluded(pid);
-}
-
-EXPORT_API bool amd_suspend_is_allowed_background(amd_appinfo_h ai)
-{
- return _suspend_is_allowed_background(ai);
-}
-
-EXPORT_API void amd_suspend_add_timer(int pid)
-{
- _suspend_add_timer(pid);
-}
-
-EXPORT_API void amd_suspend_remove_timer(int pid)
-{
- _suspend_remove_timer(pid);
-}
-
-EXPORT_API int amd_suspend_update_status(int pid, int status)
-{
- return _suspend_update_status(pid, status);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_util.h"
-#include "amd_api.h"
-#include "amd_api_util.h"
-
-EXPORT_API bool amd_util_check_oom(void)
-{
- return _util_check_oom();
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.
- */
-
-#define _GNU_SOURCE
-#include "amd_api.h"
-#include "amd_api_wayland.h"
-
-static void *__display;
-static void *__tizen_policy;
-
-EXPORT_API void *amd_wayland_get_display(void)
-{
- return __display;
-}
-
-EXPORT_API void amd_wayland_set_display(void *display)
-{
- __display = display;
-}
-
-EXPORT_API void *amd_wayland_get_tizen_policy(void)
-{
- return __tizen_policy;
-}
-
-EXPORT_API void amd_wayland_set_tizen_policy(void *tizen_policy)
-{
- __tizen_policy = tizen_policy;
-}
--- /dev/null
+/*
+ * 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_app_com.h>
+#include <aul_cmd.h>
+#include <bundle.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+
+#include "amd_app_com.h"
+#include "amd_cynara.h"
+#include "amd_request.h"
+
+#include "lib/app_com/app_com_broker.hh"
+#include "lib/common/key_private.hh"
+#include "lib/common/log_private.hh"
+
+using namespace amd;
+
+const char* _app_com_get_privilege(const char* endpoint) {
+ auto& inst = AppComBroker::GetInst();
+ if (!inst.Exist(endpoint))
+ return nullptr;
+
+ return inst.GetPrivilege(endpoint).c_str();
+}
+
+int _app_com_send(const char* endpoint, int cpid, bundle* envelope, uid_t uid) {
+ auto& inst = AppComBroker::GetInst();
+ if (!inst.Exist(endpoint)) {
+ _E("Endpoint(%s) does not exist", endpoint);
+ return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+ }
+
+ _D("endpoint=%s cpid=%d", endpoint, cpid);
+ std::string endpoint_str(endpoint);
+ bundle_del(envelope, AUL_K_COM_ENDPOINT);
+ bundle_add_str(envelope, AUL_K_COM_ENDPOINT, endpoint_str.c_str());
+ int result = AUL_APP_COM_R_OK;
+ bundle_add_byte(envelope, AUL_K_COM_RESULT, &result, sizeof(result));
+
+ std::shared_ptr<tizen_base::Bundle> envelope_ptr(
+ new (std::nothrow) tizen_base::Bundle(envelope));
+ if (envelope_ptr.get() == nullptr) {
+ _E("Out of memory");
+ return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+ }
+
+ return inst.Send(endpoint_str, envelope_ptr, cpid, uid);
+}
+
+int _app_com_client_remove(int cpid) {
+ AppComBroker::GetInst().Remove(cpid);
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+bool _app_com_endpoint_exists(const char* endpoint) {
+ return AppComBroker::GetInst().Exist(endpoint);
+}
+
+static int __dispatch_app_com_create(request_h req) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+ if (endpoint == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ const char* privilege = bundle_get_val(kb, AUL_K_COM_PRIVILEGE);
+ if (privilege == nullptr) {
+ _D("Non-privileged endpoint: %s", endpoint);
+ privilege = "";
+ }
+
+ unsigned int propagate;
+ unsigned int* prop;
+ size_t propagate_size;
+ int ret = bundle_get_byte(kb, AUL_K_COM_PROPAGATE, (void **)&prop,
+ &propagate_size);
+ if (ret == BUNDLE_ERROR_NONE)
+ propagate = *prop;
+ else
+ propagate = 0;
+
+ _D("endpoint=%s propagate=%x privilege=%s",
+ endpoint, propagate, privilege);
+
+ ret = AppComBroker::GetInst().Create(endpoint, propagate, privilege);
+ if (ret == AUL_APP_COM_R_ERROR_OK ||
+ ret == AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS) {
+ int pid = _request_get_pid(req);
+ uid_t uid = _request_get_uid(req);
+ ret = AppComBroker::GetInst().Join(endpoint, "", getpgid(pid), uid);
+ if (ret == AUL_APP_COM_R_ERROR_ILLEGAL_ACCESS) {
+ _E("Illegal access: remove endpoint");
+ AppComBroker::GetInst().Destroy(endpoint);
+ }
+ }
+ _request_send_result(req, ret);
+ return ret;
+}
+
+static int __dispatch_app_com_join(request_h req) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+ if (endpoint == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ const char* filter = bundle_get_val(kb, AUL_K_COM_FILTER);
+ int pid = _request_get_pid(req);
+ uid_t uid = _request_get_uid(req);
+ int ret = AppComBroker::GetInst().Join(endpoint, filter ? filter : "",
+ getpgid(pid), uid);
+ _request_send_result(req, ret);
+ return ret;
+}
+
+static int __dispatch_app_com_send(request_h req) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ int sender_pid = _request_get_pid(req);
+ bundle_del(kb, AUL_K_COM_SENDER_PID);
+ bundle_add(kb, AUL_K_COM_SENDER_PID, std::to_string(sender_pid).c_str());
+
+ const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+ if (endpoint == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ uid_t sender_uid = _request_get_uid(req);
+ int ret = _app_com_send(endpoint, getpgid(sender_pid), kb, sender_uid);
+ _request_send_result(req, ret);
+ return ret;
+}
+
+static int __dispatch_app_com_leave(request_h req) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+ if (endpoint == nullptr) {
+ _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+ return -EINVAL;
+ }
+
+ int pid = _request_get_pid(req);
+ int ret = AppComBroker::GetInst().Leave(endpoint, getpgid(pid));
+ _request_send_result(req, ret);
+ return ret;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_COM_CREATE,
+ .callback = __dispatch_app_com_create
+ },
+ {
+ .cmd = APP_COM_JOIN,
+ .callback = __dispatch_app_com_join
+ },
+ {
+ .cmd = APP_COM_SEND,
+ .callback = __dispatch_app_com_send
+ },
+ {
+ .cmd = APP_COM_LEAVE,
+ .callback = __dispatch_app_com_leave
+ },
+};
+
+static int __com_create_checker(caller_info_h info, request_h req, void* data) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ char* privilege = nullptr;
+ bundle_get_str(kb, AUL_K_COM_PRIVILEGE, &privilege);
+ if (privilege == nullptr)
+ return 0;
+
+ return _cynara_simple_checker(info, req, reinterpret_cast<void*>(privilege));
+}
+
+static int __com_join_checker(caller_info_h info, request_h req, void* data) {
+ bundle* kb = _request_get_bundle(req);
+ if (kb == nullptr) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ char* endpoint = nullptr;
+ bundle_get_str(kb, AUL_K_COM_ENDPOINT, &endpoint);
+ if (endpoint == nullptr)
+ return -EINVAL;
+
+ const char* privilege = _app_com_get_privilege(endpoint);
+ if (privilege == nullptr)
+ return 0;
+
+ return _cynara_simple_checker(info, req,
+ static_cast<void*>(const_cast<char*>(privilege)));
+}
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_COM_JOIN,
+ .checker = __com_join_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_COM_CREATE,
+ .checker = __com_create_checker,
+ .data = NULL
+ },
+};
+
+int _app_com_broker_init(void) {
+ _W("APP_COM_BROKER_INIT");
+ AppComBroker::GetInst();
+ int ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ ret = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+int _app_com_broker_fini(void) {
+ _W("APP_COM_BROKER_FINI");
+ AppComBroker::GetInst().Dispose();
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_COM_H__
+#define __AMD_APP_COM_H__
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _app_com_broker_init(void);
+
+int _app_com_broker_fini(void);
+
+int _app_com_client_remove(int cpid);
+
+int _app_com_send(const char *endpoint, int cpid, bundle *envelope, uid_t uid);
+
+const char *_app_com_get_privilege(const char *endpoint);
+
+bool _app_com_endpoint_exists(const char *endpoint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_APP_COM_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+#include <ctype.h>
+#include <gio/gio.h>
+#include <aul_svc.h>
+#include <pkgmgr-info.h>
+#include <aul_sock.h>
+#include <aul.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+
+#include "amd_util.h"
+#include "amd_app_property.h"
+#include "amd_request.h"
+#include "amd_appinfo.h"
+#include "amd_cynara.h"
+
+struct metadata_filter {
+ char *key;
+ char *value; /* Could be NULL */
+};
+
+struct metadata_entity {
+ char *appid;
+ char *key;
+ char *value;
+};
+
+struct app_property_s {
+ uid_t uid;
+ GHashTable *alias_info_table;
+ GHashTable *allowed_info_table;
+ GHashTable *appid_cache_table;
+ GList *metadata_list;
+};
+
+static GHashTable *user_prop_table;
+static GList *metadata_filters;
+
+static int __foreach_allowed_info(const char *appid, const char *allowed_appid,
+ void *data);
+static int __foreach_metadata_info(const pkgmgrinfo_appinfo_h handle,
+ void *data);
+static void __free_metadata_entity(gpointer data);
+
+static int __add_alias_info(const char *alias_appid,
+ const char *appid, void *user_data)
+{
+ GHashTable *alias_info_table = (GHashTable *)user_data;
+ char *key;
+ char *value;
+ char *id;
+
+ if (alias_appid == NULL || appid == NULL || alias_info_table == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ key = strdup(alias_appid);
+ if (key == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ value = strdup(appid);
+ if (value == NULL) {
+ _E("out of memory");
+ free(key);
+ return -1;
+ }
+
+ id = g_hash_table_lookup(alias_info_table, key);
+ if (id) {
+ _D("Replace alias info - alias_appid(%s), appid(%s)",
+ key, value);
+ g_hash_table_replace(alias_info_table, key, value);
+ } else {
+ g_hash_table_insert(alias_info_table, key, value);
+ }
+
+ return 0;
+}
+
+int _app_property_add_alias_info(app_property_h app_property,
+ const char *alias_appid, const char *appid)
+{
+ int ret;
+
+ if (app_property == NULL || appid == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ if (alias_appid && appid) {
+ ret = __add_alias_info(alias_appid, appid,
+ app_property->alias_info_table);
+ if (ret < 0) {
+ _W("Failed to add alias info");
+ return -1;
+ }
+ } else if (appid) {
+ ret = aul_svc_foreach_alias_info_by_appid_for_uid(
+ __add_alias_info, appid,
+ app_property->uid,
+ app_property->alias_info_table);
+ if (ret < 0) {
+ _W("Failed to retrive alias info - appid(%s)", appid);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static gboolean __remove_alias_info(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ if (value == NULL || user_data == NULL) {
+ _W("Invalid parameter");
+ return FALSE;
+ }
+
+ if (strcmp(value, user_data) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+int _app_property_remove_alias_info(app_property_h app_property,
+ const char *alias_appid, const char *appid)
+{
+ const char *id;
+
+ if (app_property == NULL || (alias_appid == NULL && appid == NULL)) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ if (alias_appid) {
+ id = g_hash_table_lookup(app_property->alias_info_table,
+ alias_appid);
+ if (id) {
+ g_hash_table_remove(app_property->alias_info_table,
+ alias_appid);
+ }
+ } else {
+ g_hash_table_foreach_remove(app_property->alias_info_table,
+ __remove_alias_info, (gpointer)appid);
+ }
+
+ return 0;
+}
+
+const char *_app_property_get_real_appid(app_property_h app_property,
+ const char *alias_appid)
+{
+ if (app_property == NULL || alias_appid == NULL) {
+ _W("Invalid parameter");
+ return NULL;
+ }
+
+ return g_hash_table_lookup(app_property->alias_info_table, alias_appid);
+}
+
+GList *_app_property_get_allowed_app_list(app_property_h app_property,
+ const char *appid)
+{
+ if (app_property == NULL || appid == NULL) {
+ _W("Invalid parameter");
+ return NULL;
+ }
+
+ return g_hash_table_lookup(app_property->allowed_info_table, appid);
+}
+
+app_property_h _app_property_find(uid_t uid)
+{
+ if (user_prop_table == NULL)
+ return NULL;
+
+ return g_hash_table_lookup(user_prop_table, GUINT_TO_POINTER(uid));
+}
+
+int _app_property_insert(uid_t uid, const char *appid,
+ const pkgmgrinfo_appinfo_h handle)
+{
+ int ret;
+ app_property_h app_property;
+
+ if (appid == NULL || handle == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL)
+ return -1;
+
+ g_hash_table_remove_all(app_property->appid_cache_table);
+
+ ret = aul_svc_foreach_alias_info_by_appid_for_uid(__add_alias_info,
+ appid, app_property->uid,
+ app_property->alias_info_table);
+ if (ret < 0) {
+ _E("Failed to retrieve alias info - %s:%u:%d",
+ appid, uid, ret);
+ return -1;
+ }
+
+ ret = aul_svc_foreach_allowed_info_by_appid_for_uid(
+ __foreach_allowed_info, appid,
+ app_property->uid, app_property->allowed_info_table);
+ if (ret < 0) {
+ _E("Failed to retrieve allowed info - %s:%u:%d",
+ appid, uid, ret);
+ return -1;
+ }
+
+ ret = __foreach_metadata_info(handle, app_property);
+ if (ret < 0) {
+ _E("Failed to retrieve metadata info - %s:%u:%d",
+ appid, uid, ret);
+ return -1;
+ }
+
+ _D("uid(%d), appid(%s)", uid, appid);
+
+ return 0;
+}
+
+int _app_property_delete(uid_t uid, const char *appid)
+{
+ app_property_h app_property;
+ struct metadata_entity *entity;
+ GList *iter;
+
+ if (appid == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL)
+ return -1;
+
+ iter = app_property->metadata_list;
+ while (iter) {
+ entity = (struct metadata_entity *)iter->data;
+ iter = g_list_next(iter);
+ if (strcmp(entity->appid, appid) == 0) {
+ app_property->metadata_list = g_list_remove(
+ app_property->metadata_list,
+ entity);
+ __free_metadata_entity(entity);
+ }
+ }
+
+ g_hash_table_remove_all(app_property->appid_cache_table);
+
+ g_hash_table_foreach_remove(app_property->alias_info_table,
+ __remove_alias_info, (gpointer)appid);
+
+ g_hash_table_remove(app_property->allowed_info_table, appid);
+ _D("uid(%d), appid(%s)", uid, appid);
+
+ return 0;
+}
+
+static void __foreach_alias_info(const char *alias_appid, const char *appid,
+ void *data)
+{
+ GHashTable *alias_info_table = (GHashTable *)data;
+ char *key;
+ char *value;
+
+ if (alias_appid == NULL || appid == NULL || alias_info_table == NULL) {
+ _W("Invalid parameter");
+ return;
+ }
+
+ key = strdup(alias_appid);
+ if (key == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ value = strdup(appid);
+ if (value == NULL) {
+ _E("out of memory");
+ free(key);
+ return;
+ }
+
+ g_hash_table_insert(alias_info_table, key, value);
+}
+
+static int __foreach_allowed_info(const char *appid, const char *allowed_appid,
+ void *data)
+{
+ GHashTable *allowed_info_table = (GHashTable *)data;
+ char *key;
+ char *value;
+ GList *list;
+
+ if (appid == NULL || allowed_appid == NULL ||
+ allowed_info_table == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ value = strdup(allowed_appid);
+ if (value == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ list = g_hash_table_lookup(allowed_info_table, appid);
+ if (list) {
+ list = g_list_append(list, value);
+ } else {
+ key = strdup(appid);
+ if (key == NULL) {
+ _E("out of memory");
+ free(value);
+ return -1;
+ }
+
+ list = g_list_append(list, value);
+ g_hash_table_insert(allowed_info_table, key, list);
+ }
+
+ return 0;
+}
+
+static void __destroy_allowed_info_list(gpointer data)
+{
+ GList *list = (GList *)data;
+
+ if (list == NULL)
+ return;
+
+ g_list_free_full(list, free);
+}
+
+static struct app_property_s *__create_app_property(uid_t uid)
+{
+ struct app_property_s *prop;
+
+ prop = calloc(1, sizeof(struct app_property_s));
+ if (prop == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ prop->uid = uid;
+ prop->alias_info_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+ if (prop->alias_info_table == NULL) {
+ _E("Failed to create alias info table");
+ free(prop);
+ return NULL;
+ }
+
+ prop->allowed_info_table = g_hash_table_new_full(g_str_hash,
+ g_str_equal, free, __destroy_allowed_info_list);
+ if (prop->allowed_info_table == NULL) {
+ _E("Failed to create allowed info table");
+ g_hash_table_destroy(prop->alias_info_table);
+ free(prop);
+ return NULL;
+ }
+
+ prop->appid_cache_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+ if (prop->appid_cache_table == NULL) {
+ _E("Failed to create appid cache table");
+ g_hash_table_destroy(prop->allowed_info_table);
+ g_hash_table_destroy(prop->alias_info_table);
+ free(prop);
+ return NULL;
+ }
+
+ prop->metadata_list = NULL;
+
+ return prop;
+}
+
+static void __free_metadata_entity(gpointer data)
+{
+ struct metadata_entity *entity = data;
+
+ if (!entity)
+ return;
+
+ if (entity->appid)
+ free(entity->appid);
+ if (entity->key)
+ free(entity->key);
+ if (entity->value)
+ free(entity->value);
+ free(entity);
+}
+
+static void __destroy_app_property(gpointer data)
+{
+ struct app_property_s *prop = (struct app_property_s *)data;
+
+ if (prop == NULL)
+ return;
+
+ if (prop->allowed_info_table)
+ g_hash_table_destroy(prop->allowed_info_table);
+ if (prop->alias_info_table)
+ g_hash_table_destroy(prop->alias_info_table);
+ if (prop->appid_cache_table)
+ g_hash_table_destroy(prop->appid_cache_table);
+ if (prop->metadata_list)
+ g_list_free_full(prop->metadata_list, __free_metadata_entity);
+
+ free(prop);
+}
+
+static gint __comp_metadata_list(gconstpointer a, gconstpointer b)
+{
+ const struct metadata_entity *entity1 = a;
+ const struct metadata_entity *entity2 = b;
+
+ if (!a || !b)
+ return -1;
+
+ if (!strcmp(entity1->appid, entity2->appid) &&
+ !strcmp(entity1->key, entity2->key) &&
+ !strcmp(entity1->value, entity2->value))
+ return 0;
+
+ return -1;
+}
+
+static void __add_metadata_info(const char *appid, const char *key,
+ const char *val, struct app_property_s *prop)
+{
+ struct metadata_entity *entity;
+ GList *found;
+
+ if (appid == NULL || key == NULL || val == NULL) {
+ _W("Invalid parameter");
+ return;
+ }
+
+ entity = calloc(1, sizeof(struct metadata_entity));
+ if (entity == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ entity->appid = strdup(appid);
+ if (!entity->appid) {
+ _E("out of memory");
+ __free_metadata_entity(entity);
+ return;
+ }
+
+ entity->key = strdup(key);
+ if (!entity->key) {
+ _E("out of memory");
+ __free_metadata_entity(entity);
+ return;
+ }
+
+ entity->value = strdup(val);
+ if (!entity->value) {
+ _E("out of memory");
+ __free_metadata_entity(entity);
+ return;
+ }
+
+ found = g_list_find_custom(prop->metadata_list, entity,
+ __comp_metadata_list);
+ if (found) {
+ __free_metadata_entity(entity);
+ return;
+ }
+
+ prop->metadata_list = g_list_append(prop->metadata_list, entity);
+}
+
+static int __foreach_metadata_info(const pkgmgrinfo_appinfo_h handle,
+ void *user_data)
+{
+ struct app_property_s *prop = user_data;
+ char *appid = NULL;
+ char *val;
+ int ret;
+ GList *iter;
+ struct metadata_filter *filter;
+
+ ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (ret < 0 || !appid)
+ return -1;
+
+ for (iter = metadata_filters; iter; iter = g_list_next(iter)) {
+ filter = (struct metadata_filter *)iter->data;
+ val = NULL;
+ ret = pkgmgrinfo_appinfo_get_metadata_value(handle,
+ filter->key, &val);
+ if (ret == PMINFO_R_OK)
+ __add_metadata_info(appid, filter->key, val, prop);
+ }
+
+ return 0;
+}
+
+static int __load_metadata(struct app_property_s *prop)
+{
+ pkgmgrinfo_appinfo_metadata_filter_h handle;
+ int ret;
+ GList *iter;
+ struct metadata_filter *filter;
+
+ ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+
+ for (iter = metadata_filters; iter; iter = g_list_next(iter)) {
+ filter = (struct metadata_filter *)iter->data;
+ ret = pkgmgrinfo_appinfo_metadata_filter_add(handle,
+ filter->key, filter->value);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ }
+
+ ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle,
+ __foreach_metadata_info, prop, prop->uid);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+
+ ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle,
+ __foreach_metadata_info, prop, GLOBAL_USER);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+
+ pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+
+ return 0;
+}
+
+static int __load_app_property(struct app_property_s *prop)
+{
+ int ret;
+
+ if (prop == NULL) {
+ _W("Invalid parameter");
+ return -1;
+ }
+
+ ret = aul_svc_foreach_alias_info_for_uid(__foreach_alias_info,
+ prop->uid, prop->alias_info_table);
+ if (ret < 0) {
+ _E("Failed to retrieve alias info uid(%d) - ret(%d)",
+ prop->uid, ret);
+ return -1;
+ }
+
+ ret = aul_svc_foreach_allowed_info_for_uid(__foreach_allowed_info,
+ prop->uid, prop->allowed_info_table);
+ if (ret < 0) {
+ _E("Failed to retrieve allowed info uid(%d) - ret(%d)",
+ prop->uid, ret);
+ return -1;
+ }
+
+ ret = __load_metadata(prop);
+ if (ret < 0) {
+ _E("Failed to retrieve metadata info uid(%d) - ret(%d)",
+ prop->uid, ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+int _app_property_load(uid_t uid)
+{
+ int ret;
+ struct app_property_s *prop;
+
+ prop = __create_app_property(uid);
+ if (prop == NULL)
+ return -1;
+
+ ret = __load_app_property(prop);
+ if (ret < 0) {
+ _E("Failed to load properties - ret(%d)", ret);
+ __destroy_app_property(prop);
+ return -1;
+ }
+
+ g_hash_table_insert(user_prop_table, GUINT_TO_POINTER(uid), prop);
+
+ return 0;
+}
+
+void _app_property_unload(uid_t uid)
+{
+ g_hash_table_remove(user_prop_table, GUINT_TO_POINTER(uid));
+}
+
+static void __app_property_cache_put(app_property_h app_property,
+ const char *checksum, const char *appid)
+{
+ if (!app_property || !checksum || !appid)
+ return;
+
+ g_hash_table_replace(app_property->appid_cache_table, strdup(checksum),
+ strdup(appid));
+}
+
+static const char *__app_property_cache_get(app_property_h app_property,
+ const char *checksum)
+{
+ if (!app_property || !checksum)
+ return NULL;
+
+ return g_hash_table_lookup(app_property->appid_cache_table, checksum);
+}
+
+void _app_property_cache_invalidate(app_property_h app_property)
+{
+ if (!app_property)
+ return;
+
+ g_hash_table_remove_all(app_property->appid_cache_table);
+}
+
+bool _app_property_metadata_query_bool(app_property_h app_property,
+ const char *appid, const char *key)
+{
+ return _app_property_metadata_match(app_property, appid, key, "true");
+}
+
+int _app_property_metadata_foreach(app_property_h app_property,
+ const char *appid, const char *key,
+ int (*callback)(const char *value, void *data),
+ void *user_data)
+{
+ struct metadata_entity *ret;
+ GList *i;
+
+ if (!app_property || !appid || !key)
+ return -1;
+
+ i = app_property->metadata_list;
+ while (i) {
+ ret = i->data;
+
+ if (!strcmp(ret->appid, appid) &&
+ !strcmp(ret->key, key)) {
+ if (callback(ret->value, user_data) < 0)
+ break;
+ }
+
+ i = g_list_next(i);
+ }
+
+ return 0;
+}
+
+bool _app_property_metadata_match(app_property_h app_property,
+ const char *appid, const char *key, const char *value)
+{
+ struct metadata_entity entity;
+ GList *i;
+
+ if (!app_property || !appid || !key || !value)
+ return false;
+
+ entity.appid = (char *)appid;
+ entity.key = (char *)key;
+ entity.value = (char *)value;
+ i = g_list_find_custom(app_property->metadata_list,
+ &entity, __comp_metadata_list);
+ if (!i)
+ return false;
+
+ return true;
+}
+
+static gint __comp_key(gconstpointer a, gconstpointer b)
+{
+ const struct metadata_entity *entity1 = a;
+ const struct metadata_entity *entity2 = b;
+
+ if (!a || !b)
+ return -1;
+
+ if (!strcmp(entity1->appid, entity2->appid) &&
+ !strcmp(entity1->key, entity2->key)) {
+ if (entity1->value && !strcmp(entity1->value, "false"))
+ return -1;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+bool _app_property_metadata_query_activation(app_property_h app_property,
+ const char *appid, const char *key)
+{
+ struct metadata_entity entity;
+ GList *i;
+
+ if (!app_property || !appid || !key)
+ return false;
+
+ entity.appid = (char *)appid;
+ entity.key = (char *)key;
+ entity.value = NULL;
+
+ i = g_list_find_custom(app_property->metadata_list,
+ &entity, __comp_key);
+ if (!i)
+ return false;
+
+ return true;
+}
+
+static struct metadata_filter *__create_metadata_filter(const char *key,
+ const char *value)
+{
+ struct metadata_filter *filter;
+
+ filter = calloc(1, sizeof(struct metadata_filter));
+ if (!filter) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ filter->key = strdup(key);
+ if (!filter->key) {
+ _E("Failed to duplicate key");
+ free(filter);
+ return NULL;
+ }
+
+ if (value) {
+ filter->value = strdup(value);
+ if (!filter->value) {
+ _E("Failed to duplicate value");
+ free(filter->key);
+ free(filter);
+ return NULL;
+ }
+ }
+
+ return filter;
+}
+
+static void __destroy_metadata_filter(gpointer data)
+{
+ struct metadata_filter *filter = (struct metadata_filter *)data;
+
+ if (!filter)
+ return;
+
+ if (filter->value)
+ free(filter->value);
+ if (filter->key)
+ free(filter->key);
+ free(filter);
+}
+
+static struct metadata_filter *__find_metadata_filter(const char *key,
+ const char *value)
+{
+ struct metadata_filter *filter;
+ GList *iter;
+
+ iter = metadata_filters;
+ while (iter) {
+ filter = (struct metadata_filter *)iter->data;
+ if (!strcmp(filter->key, key)) {
+ if (value && filter->value &&
+ !strcmp(filter->value, value))
+ return filter;
+ else if (!value && !filter->value)
+ return filter;
+ }
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+int _app_property_metadata_add_filter(const char *key, const char *value)
+{
+ struct metadata_filter *filter;
+
+ if (!key) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ filter = __find_metadata_filter(key, value);
+ if (filter) {
+ _W("Already exists");
+ return -1;
+ }
+
+ filter = __create_metadata_filter(key, value);
+ if (!filter)
+ return -1;
+
+ metadata_filters = g_list_append(metadata_filters, filter);
+
+ return 0;
+}
+
+int _app_property_metadata_remove_filter(const char *key, const char *value)
+{
+ struct metadata_filter *filter;
+
+ if (!key) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ filter = __find_metadata_filter(key, value);
+ if (!filter) {
+ _E("Failed to find metadata filter(%s:%s)", key, value);
+ return -1;
+ }
+
+ metadata_filters = g_list_remove(metadata_filters, filter);
+ __destroy_metadata_filter(filter);
+
+ return 0;
+}
+
+static int __dispatch_app_set_alias_appid(request_h req)
+{
+ int ret;
+ const char *appid;
+ const char *alias_appid;
+ const struct appinfo *ai;
+ bundle *kb;
+ uid_t uid = _request_get_target_uid(req);
+ app_property_h app_property;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ alias_appid = bundle_get_val(kb, AUL_K_ALIAS_APPID);
+ if (alias_appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ai = _appinfo_find(uid, appid);
+ if (ai == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_svc_set_alias_appid_for_uid(alias_appid, appid, uid);
+ if (ret < 0) {
+ _E("Failed to set alias appid - alias_appid(%s), appid(%s)",
+ alias_appid, appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL) {
+ _E("Failed to find app property - uid(%d)", uid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _app_property_add_alias_info(app_property, alias_appid, appid);
+ if (ret < 0) {
+ _E("Failed to add alias info - %s:%s", alias_appid, appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ _request_send_result(req, 0);
+
+ return 0;
+}
+
+static int __dispatch_app_unset_alias_appid(request_h req)
+{
+ int ret;
+ const char *alias_appid;
+ bundle *kb;
+ uid_t uid = _request_get_target_uid(req);
+ app_property_h app_property;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ alias_appid = bundle_get_val(kb, AUL_K_ALIAS_APPID);
+ if (alias_appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_svc_unset_alias_appid_for_uid(alias_appid, uid);
+ if (ret < 0) {
+ _E("Failed to unset alias appid - alias_appid(%s)",
+ alias_appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL) {
+ _E("Failed to find app property - uid(%d)", uid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _app_property_remove_alias_info(app_property, alias_appid, NULL);
+ if (ret < 0) {
+ _E("Failed to remove alias info - %s", alias_appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ _request_send_result(req, 0);
+
+ return 0;
+}
+
+static int __dispatch_app_enable_alias_info(request_h req)
+{
+ int ret;
+ const char *appid;
+ bundle *kb;
+ uid_t uid = _request_get_target_uid(req);
+ app_property_h app_property;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_svc_enable_alias_info_for_uid(appid, uid);
+ if (ret < 0) {
+ _E("Failed to activate alias info - appid(%s)", appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL) {
+ _E("Failed to find app property - uid(%d)", uid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _app_property_add_alias_info(app_property, NULL, appid);
+ if (ret < 0) {
+ _E("Failed to add alias info - %s", appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ _request_send_result(req, 0);
+
+ return 0;
+}
+
+static int __dispatch_app_disable_alias_info(request_h req)
+{
+ int ret;
+ const char *appid;
+ bundle *kb;
+ uid_t uid = _request_get_target_uid(req);
+ app_property_h app_property;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_svc_disable_alias_info_for_uid(appid, uid);
+ if (ret < 0) {
+ _E("Failed to deactivate alias info - appid(%s)", appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL) {
+ _E("Failed to find app property - uid(%d)", uid);
+ _request_send_result(req, -1);
+ }
+
+ ret = _app_property_remove_alias_info(app_property, NULL, appid);
+ if (ret < 0) {
+ _E("Failed to remove alias info - appid(%s)", appid);
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ _request_send_result(req, 0);
+
+ return 0;
+}
+
+static int __dispatch_app_set_app_control_default_app(request_h req)
+{
+ bundle *kb = NULL;
+ const char *op;
+ const char *mime_type;
+ const char *uri;
+ const char *appid;
+ int ret;
+ app_property_h prop;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ op = aul_svc_get_operation(kb);
+ appid = aul_svc_get_appid(kb);
+ if (op == NULL || appid == NULL) {
+ _E("Invalid operation, appid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ mime_type = aul_svc_get_mime(kb);
+ uri = aul_svc_get_uri(kb);
+
+ ret = aul_svc_set_defapp_for_uid(op, mime_type, uri,
+ appid, _request_get_target_uid(req));
+ if (ret < 0) {
+ _E("Error[%d], aul_svc_set_defapp", ret);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ prop = _app_property_find(_request_get_target_uid(req));
+ _app_property_cache_invalidate(prop);
+ _request_send_result(req, 0);
+ return 0;
+}
+
+static int __dispatch_app_unset_app_control_default_app(request_h req)
+{
+ char appid[MAX_PACKAGE_STR_SIZE];
+ int ret;
+ app_property_h prop;
+
+ snprintf(appid, MAX_PACKAGE_STR_SIZE - 1, "%s",
+ (const char *)_request_get_raw(req));
+
+ ret = aul_svc_unset_defapp_for_uid(appid, _request_get_target_uid(req));
+ if (ret < 0) {
+ _E("Error[%d], aul_svc_unset_defapp", ret);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ prop = _app_property_find(_request_get_target_uid(req));
+ _app_property_cache_invalidate(prop);
+ _request_send_result(req, 0);
+ return 0;
+}
+
+static int __dispatch_app_get_appid_from_cache(request_h req)
+{
+ const char *checksum;
+ const char *appid;
+ bundle *b = _request_get_bundle(req);
+ app_property_h prop = _app_property_find(_request_get_target_uid(req));
+
+ checksum = bundle_get_val(b, AUL_K_CHECKSUM);
+ appid = __app_property_cache_get(prop, checksum);
+
+ if (!appid) {
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_APPID_FROM_CACHE, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return 0;
+ }
+
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_APPID_FROM_CACHE, (unsigned char *)appid,
+ strlen(appid), AUL_SOCK_NOREPLY);
+
+ return 0;
+}
+
+static int __dispatch_app_set_cache(request_h req)
+{
+ const char *appid;
+ const char *checksum;
+ bundle *b = _request_get_bundle(req);
+ app_property_h prop = _app_property_find(_request_get_target_uid(req));
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ checksum = bundle_get_val(b, AUL_K_CHECKSUM);
+
+ if (!appid || !checksum) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ __app_property_cache_put(prop, checksum, appid);
+ _request_send_result(req, 0);
+ return 0;
+}
+
+static int __dispatch_app_invalidate_cache(request_h req)
+{
+ app_property_h prop = _app_property_find(_request_get_target_uid(req));
+
+ _app_property_cache_invalidate(prop);
+ _request_send_result(req, 0);
+ return 0;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_SET_ALIAS_APPID,
+ .callback = __dispatch_app_set_alias_appid
+ },
+ {
+ .cmd = APP_UNSET_ALIAS_APPID,
+ .callback = __dispatch_app_unset_alias_appid
+ },
+ {
+ .cmd = APP_ENABLE_ALIAS_INFO,
+ .callback = __dispatch_app_enable_alias_info
+ },
+ {
+ .cmd = APP_DISABLE_ALIAS_INFO,
+ .callback = __dispatch_app_disable_alias_info
+ },
+ {
+ .cmd = APP_SET_APP_CONTROL_DEFAULT_APP,
+ .callback = __dispatch_app_set_app_control_default_app
+ },
+ {
+ .cmd = APP_UNSET_APP_CONTROL_DEFAULT_APP,
+ .callback = __dispatch_app_unset_app_control_default_app
+ },
+ {
+ .cmd = APP_GET_APPID_FROM_CACHE,
+ .callback = __dispatch_app_get_appid_from_cache
+ },
+ {
+ .cmd = APP_SET_CACHE,
+ .callback = __dispatch_app_set_cache
+ },
+ {
+ .cmd = APP_INVALIDATE_CACHE,
+ .callback = __dispatch_app_invalidate_cache
+ },
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_SET_APP_CONTROL_DEFAULT_APP,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+ {
+ .cmd = APP_UNSET_APP_CONTROL_DEFAULT_APP,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+ {
+ .cmd = APP_SET_ALIAS_APPID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+ {
+ .cmd = APP_UNSET_ALIAS_APPID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+ {
+ .cmd = APP_ENABLE_ALIAS_INFO,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+ {
+ .cmd = APP_DISABLE_ALIAS_INFO,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_SYSTEM_SETTING
+ },
+};
+
+int _app_property_init(void)
+{
+ struct metadata_filter metadata_table[] = {
+ { METADATA_LARGEMEMORY, NULL },
+ { METADATA_OOMTERMINATION, NULL },
+ { METADATA_VIPAPP, NULL },
+ };
+ int r;
+ int i;
+
+ _D("app property init");
+
+ user_prop_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __destroy_app_property);
+ if (user_prop_table == NULL) {
+ _E("Failed to create user prop table");
+ return -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(metadata_table); i++) {
+ r = _app_property_metadata_add_filter(metadata_table[i].key,
+ metadata_table[i].value);
+ if (r != 0)
+ return -1;
+ }
+
+ r = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _app_property_fini(void)
+{
+ _D("app property fini");
+
+ if (metadata_filters)
+ g_list_free_full(metadata_filters, __destroy_metadata_filter);
+
+ if (user_prop_table)
+ g_hash_table_destroy(user_prop_table);
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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_PROPERTY_H__
+#define __AMD_APP_PROPERTY_H__
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <glib.h>
+#include <pkgmgr-info.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define METADATA_LARGEMEMORY "http://tizen.org/metadata/largememory"
+
+#define METADATA_OOMTERMINATION "http://tizen.org/metadata/oomtermination"
+
+#define METADATA_VIPAPP "http://tizen.org/metadata/vipapp"
+
+typedef struct app_property_s *app_property_h;
+
+int _app_property_add_alias_info(app_property_h app_property,
+ const char *alias_appid, const char *appid);
+
+int _app_property_remove_alias_info(app_property_h app_property,
+ const char *alias_appid, const char *appid);
+
+const char *_app_property_get_real_appid(app_property_h app_property,
+ const char *alias_appid);
+
+GList *_app_property_get_allowed_app_list(app_property_h app_property,
+ const char *appid);
+
+app_property_h _app_property_find(uid_t uid);
+
+int _app_property_insert(uid_t uid, const char *appid,
+ const pkgmgrinfo_appinfo_h handle);
+
+int _app_property_delete(uid_t uid, const char *appid);
+
+int _app_property_load(uid_t uid);
+
+void _app_property_unload(uid_t uid);
+
+int _app_property_init(void);
+
+void _app_property_fini(void);
+
+void _app_property_cache_invalidate(app_property_h app_property);
+
+bool _app_property_metadata_query_bool(app_property_h app_property,
+ const char *appid, const char *key);
+
+int _app_property_metadata_foreach(app_property_h app_property,
+ const char *appid, const char *key,
+ int (*callback)(const char *value, void *data),
+ void *user_data);
+
+bool _app_property_metadata_match(app_property_h app_property,
+ const char *appid, const char *key, const char *value);
+
+bool _app_property_metadata_query_activation(app_property_h app_property,
+ const char *appid, const char *key);
+
+int _app_property_metadata_add_filter(const char *key, const char *value);
+
+int _app_property_metadata_remove_filter(const char *key, const char *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_APP_PROPERTY_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <uuid/uuid.h>
+#include <glib.h>
+#include <aul.h>
+#include <string.h>
+#include <linux/limits.h>
+#include <vconf.h>
+#include <time.h>
+#include <aul_sock.h>
+#include <aul_proc.h>
+#include <ctype.h>
+#include <gio/gio.h>
+#include <bundle_internal.h>
+
+#include "amd_api_noti.h"
+#include "amd_app_status.h"
+#include "amd_appinfo.h"
+#include "amd_request.h"
+#include "amd_launch.h"
+#include "amd_util.h"
+#include "amd_suspend.h"
+#include "amd_socket.h"
+#include "amd_app_com.h"
+#include "amd_signal.h"
+#include "amd_noti.h"
+#include "amd_inotify.h"
+#include "amd_proc.h"
+#include "amd_cynara.h"
+
+#define PATH_AUL_APPS "/run/aul/apps"
+
+struct pkg_status_s {
+ char *pkgid;
+ int status;
+ GSList *ui_list;
+ GSList *svc_list;
+};
+
+struct app_status_s {
+ char *appid;
+ char *app_path;
+ char *pkgid;
+ char *instance_id;
+ int app_type;
+ int pid;
+ uid_t uid;
+ int status;
+ bool is_subapp;
+ char *leader_id;
+ int timestamp;
+ int fg_count;
+ bool managed;
+ int org_caller_pid;
+ int last_caller_pid;
+ struct pkg_status_s *pkg_status;
+ bool bg_launch;
+ bool socket_exists;
+ bool starting;
+ GHashTable *extras;
+ bool exiting;
+ bool debug_mode;
+ guint timer;
+};
+
+struct fault_app_s {
+ int pid;
+ int uid;
+ char *appid;
+ char *pkgid;
+ int type;
+};
+
+struct vconf_context_s {
+ bool initialized;
+ guint timer;
+};
+
+static GSList *app_status_list;
+static GHashTable *pkg_status_table;
+static int limit_bg_uiapps;
+static char *home_appid;
+static GHashTable *__wd_table;
+static inotify_watch_info_h __wh;
+static struct vconf_context_s __vconf;
+
+static int __get_managed_uiapp_cnt(void)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+ int cnt = 0;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->managed &&
+ app_status->app_type == AT_UI_APP)
+ cnt++;
+ }
+
+ return cnt;
+}
+
+static void __cleanup_bg_uiapps(int n)
+{
+ GSList *iter;
+ GSList *iter_next;
+ struct app_status_s *app_status;
+ int i = 0;
+ int ret;
+
+ GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
+ if (i == n)
+ break;
+
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->status != STATUS_VISIBLE) {
+ ret = _terminate_app_local(app_status->uid,
+ app_status->pid);
+ if (ret < 0) {
+ _E("Failed to terminate app(%d)",
+ app_status->pid);
+ continue;
+ }
+ i++;
+ }
+ }
+}
+
+static void __check_running_uiapp_list(void)
+{
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS, 0, 0, NULL, NULL);
+}
+
+int _app_status_term_bg_apps(GCompareFunc func)
+{
+ int len;
+ int n;
+
+ len = __get_managed_uiapp_cnt();
+ if (len <= 0)
+ return -1;
+
+ n = len - limit_bg_uiapps;
+ if (n <= 0)
+ return -1;
+
+ app_status_list = g_slist_sort(app_status_list, func);
+ __cleanup_bg_uiapps(n);
+
+ return 0;
+}
+
+static void __vconf_cb(keynode_t *key, void *data)
+{
+ const char *name;
+
+ name = vconf_keynode_get_name(key);
+ if (name && strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) == 0) {
+ limit_bg_uiapps = vconf_keynode_get_int(key);
+ if (limit_bg_uiapps > 0)
+ __check_running_uiapp_list();
+ }
+}
+
+static void __update_leader_app_status(const char *leader_id)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ if (!leader_id)
+ return;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && !strcmp(app_status->instance_id, leader_id)) {
+ app_status->timestamp = time(NULL) / 10;
+ app_status->fg_count++;
+ break;
+ }
+ }
+}
+
+static void __add_pkg_status(struct app_status_s *app_status)
+{
+ struct pkg_status_s *pkg_status;
+
+ if (app_status == NULL) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ if (app_status->app_type != AT_SERVICE_APP &&
+ app_status->app_type != AT_UI_APP)
+ return;
+
+ if (pkg_status_table == NULL) {
+ pkg_status_table = g_hash_table_new(g_str_hash, g_str_equal);
+ if (pkg_status_table == NULL) {
+ _E("out of memory");
+ return;
+ }
+ }
+
+ pkg_status = g_hash_table_lookup(pkg_status_table, app_status->pkgid);
+ if (pkg_status == NULL) {
+ pkg_status = (struct pkg_status_s *)calloc(1,
+ sizeof(struct pkg_status_s));
+ if (pkg_status == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ pkg_status->pkgid = strdup(app_status->pkgid);
+ if (pkg_status->pkgid == NULL) {
+ _E("out of memory");
+ free(pkg_status);
+ return;
+ }
+
+ g_hash_table_insert(pkg_status_table, pkg_status->pkgid,
+ pkg_status);
+ }
+
+ pkg_status->status = app_status->status;
+ app_status->pkg_status = pkg_status;
+
+ if (app_status->app_type == AT_SERVICE_APP) {
+ pkg_status->svc_list = g_slist_append(pkg_status->svc_list,
+ app_status);
+ } else {
+ pkg_status->ui_list = g_slist_append(pkg_status->ui_list,
+ app_status);
+ }
+}
+
+static int __get_ui_app_status_pkg_status(struct pkg_status_s *pkg_status)
+{
+ struct app_status_s *app_status;
+ GSList *iter;
+
+ for (iter = pkg_status->ui_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status->status != STATUS_BG)
+ return app_status->status;
+ }
+
+ return STATUS_BG;
+}
+
+static int __update_pkg_status(struct app_status_s *app_status)
+{
+ struct pkg_status_s *pkg_status;
+ int ret;
+
+ if (app_status == NULL)
+ return -1;
+
+ if (pkg_status_table == NULL)
+ return -1;
+
+ pkg_status = (struct pkg_status_s *)g_hash_table_lookup(
+ pkg_status_table, app_status->pkgid);
+ if (pkg_status == NULL) {
+ _E("pkgid(%s) is not on list", app_status->pkgid);
+ return -1;
+ }
+
+ if (pkg_status->ui_list) {
+ ret = __get_ui_app_status_pkg_status(pkg_status);
+ if (ret > -1)
+ pkg_status->status = ret;
+ } else {
+ pkg_status->status = STATUS_SERVICE;
+ }
+
+ return 0;
+}
+
+static void __remove_pkg_status(struct app_status_s *app_status)
+{
+ struct pkg_status_s *pkg_status;
+
+ if (app_status == NULL) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ pkg_status = g_hash_table_lookup(pkg_status_table, app_status->pkgid);
+ if (pkg_status == NULL)
+ return;
+
+ if (app_status->app_type == AT_SERVICE_APP) {
+ pkg_status->svc_list = g_slist_remove(pkg_status->svc_list,
+ app_status);
+ _D("STATUS_SERVICE: appid(%s)", app_status->appid);
+ } else {
+ pkg_status->ui_list = g_slist_remove(pkg_status->ui_list,
+ app_status);
+ _D("~STATUS_SERVICE: appid(%s)", app_status->appid);
+ }
+
+ if (!pkg_status->svc_list && !pkg_status->ui_list) {
+ g_hash_table_remove(pkg_status_table, pkg_status->pkgid);
+ if (pkg_status->pkgid)
+ free(pkg_status->pkgid);
+ free(pkg_status);
+ }
+}
+
+static void __destroy_app_status(struct app_status_s *app_status)
+{
+ if (app_status == NULL)
+ return;
+
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_DESTROY, 0, 0, app_status, NULL);
+
+ if (app_status->leader_id)
+ free(app_status->leader_id);
+ if (app_status->instance_id)
+ free(app_status->instance_id);
+ if (app_status->pkgid)
+ free(app_status->pkgid);
+ if (app_status->app_path)
+ free(app_status->app_path);
+ if (app_status->appid)
+ free(app_status->appid);
+ if (app_status->extras)
+ g_hash_table_destroy(app_status->extras);
+ if (app_status->timer)
+ g_source_remove(app_status->timer);
+
+ free(app_status);
+}
+
+static int __get_app_type(const char *comp_type)
+{
+ if (comp_type == NULL)
+ return -1;
+
+ if (strcmp(comp_type, APP_TYPE_SERVICE) == 0)
+ return AT_SERVICE_APP;
+ else if (strcmp(comp_type, APP_TYPE_UI) == 0)
+ return AT_UI_APP;
+ else if (strcmp(comp_type, APP_TYPE_WIDGET) == 0)
+ return AT_WIDGET_APP;
+ else if (strcmp(comp_type, APP_TYPE_WATCH) == 0)
+ return AT_WATCH_APP;
+ else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0)
+ return AT_COMPONENT_BASED_APP;
+
+ return -1;
+}
+
+static int __app_status_set_app_info(struct app_status_s *app_status,
+ const struct appinfo *ai, int pid,
+ bool is_subapp, uid_t uid, int caller_pid,
+ bool bg_launch, const char *instance_id,
+ bool debug_mode)
+{
+ const char *appid;
+ const char *app_path;
+ const char *pkgid;
+ const char *comp_type;
+ const char *taskmanage;
+ char buf[MAX_PACKAGE_STR_SIZE];
+ char uuid[37];
+ uuid_t u;
+
+ appid = _appinfo_get_value(ai, AIT_NAME);
+ if (appid == NULL)
+ return -1;
+
+ app_status->appid = strdup(appid);
+ if (app_status->appid == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ app_path = _appinfo_get_value(ai, AIT_EXEC);
+ if (app_path == NULL)
+ return -1;
+
+ app_status->app_path = strdup(app_path);
+ if (app_status->app_path == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ if (pkgid == NULL)
+ return -1;
+
+ app_status->pkgid = strdup(pkgid);
+ if (app_status->pkgid == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type == NULL)
+ return -1;
+
+ app_status->app_type = __get_app_type(comp_type);
+ if (app_status->app_type == -1) {
+ _E("Unknown component type: %s", comp_type);
+ return -1;
+ }
+
+ if (app_status->app_type == AT_SERVICE_APP)
+ app_status->status = STATUS_SERVICE;
+ else
+ app_status->status = STATUS_LAUNCHING;
+
+ if (instance_id) {
+ app_status->instance_id = strdup(instance_id);
+ if (app_status->instance_id == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+ } else {
+ uuid_generate(u);
+ uuid_unparse(u, uuid);
+
+ snprintf(buf, sizeof(buf), "%s:%s", uuid, appid);
+ app_status->instance_id = strdup(buf);
+ if (app_status->instance_id == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+ }
+
+ app_status->pid = pid;
+ app_status->uid = uid;
+
+ if (app_status->app_type == AT_COMPONENT_BASED_APP)
+ app_status->is_subapp = false;
+ else
+ app_status->is_subapp = is_subapp;
+
+ app_status->timestamp = time(NULL) / 10;
+ app_status->org_caller_pid = caller_pid;
+ app_status->last_caller_pid = caller_pid;
+
+ taskmanage = _appinfo_get_value(ai, AIT_TASKMANAGE);
+ if (taskmanage && !strcmp(taskmanage, "true") && !app_status->is_subapp)
+ app_status->managed = true;
+
+ app_status->bg_launch = bg_launch;
+ app_status->socket_exists = false;
+ app_status->starting = false;
+
+ app_status->extras = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, NULL);
+
+ app_status->debug_mode = debug_mode;
+ app_status->exiting = false;
+
+ return 0;
+}
+
+int _app_status_set_extra(app_status_h app_status, const char *key, void *data)
+{
+ char *name;
+
+ if (!app_status || !app_status->extras)
+ return -1;
+
+ name = strdup(key);
+ if (!name)
+ return -1;
+
+ _app_status_remove_extra(app_status, key);
+ if (g_hash_table_insert(app_status->extras, name, data) == TRUE)
+ return 0;
+
+ return -1;
+}
+
+int _app_status_remove_extra(app_status_h app_status, const char *key)
+{
+ if (!app_status || !app_status->extras)
+ return -1;
+
+ if (g_hash_table_remove(app_status->extras, key) == TRUE)
+ return 0;
+
+ return -1;
+}
+
+void *_app_status_get_extra(app_status_h app_status, const char *key)
+{
+ if (!app_status || !app_status->extras)
+ return NULL;
+
+ return g_hash_table_lookup(app_status->extras, key);
+}
+
+int _app_status_add_app_info(const struct appinfo *ai, int pid,
+ bool is_subapp, uid_t uid, int caller_pid,
+ bool bg_launch, const char *instance_id,
+ bool debug_mode)
+{
+ GSList *iter;
+ GSList *iter_next;
+ struct app_status_s *app_status;
+ int r;
+
+ if (ai == NULL)
+ return -1;
+
+ GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->pid == pid) {
+ if (app_status->uid == uid)
+ return 0;
+
+ app_status_list = g_slist_remove(app_status_list,
+ app_status);
+ __remove_pkg_status(app_status);
+ __destroy_app_status(app_status);
+ break;
+ }
+ }
+
+ app_status = (struct app_status_s *)calloc(1,
+ sizeof(struct app_status_s));
+ if (app_status == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ r = __app_status_set_app_info(app_status, ai, pid, is_subapp, uid,
+ caller_pid, bg_launch, instance_id, debug_mode);
+ if (r < 0) {
+ __destroy_app_status(app_status);
+ return -1;
+ }
+
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_ADD, 0, 0, app_status, NULL);
+ app_status_list = g_slist_append(app_status_list, app_status);
+ __add_pkg_status(app_status);
+
+ return 0;
+}
+
+int _app_status_remove_all_app_info_with_uid(uid_t uid)
+{
+ GSList *iter;
+ GSList *iter_next;
+ struct app_status_s *app_status;
+
+ GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->uid == uid) {
+ app_status_list = g_slist_remove(app_status_list,
+ app_status);
+ __destroy_app_status(app_status);
+ }
+ }
+
+ return 0;
+}
+
+int _app_status_remove(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ app_status_list = g_slist_remove(app_status_list, app_status);
+ __remove_pkg_status(app_status);
+ __destroy_app_status(app_status);
+
+ return 0;
+}
+
+static gboolean __terminate_timer_cb(gpointer data)
+{
+ int pid = GPOINTER_TO_INT(data);
+ app_status_h app_status;
+ int r;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return G_SOURCE_REMOVE;
+
+ _E("pid(%d)", pid);
+ r = kill(pid, SIGKILL);
+ if (r < 0)
+ _W("Failed to send SIGKILL, pid(%d), errno(%d)", pid, errno);
+
+ app_status->timer = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+int _app_status_update_status(app_status_h app_status, int status, bool force,
+ bool update_group_info)
+{
+ if (app_status == NULL || status < 0)
+ return -1;
+
+ _D("pid: %d, status: %d", app_status->pid, status);
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START,
+ status, 0, app_status, NULL);
+ if (app_status->status == STATUS_DYING) {
+ _E("%s is STATUS_DYING", app_status->appid);
+ return -1;
+ }
+
+ app_status->status = status;
+ if (app_status->status == STATUS_VISIBLE) {
+ app_status->timestamp = time(NULL) / 10;
+ app_status->fg_count++;
+ if (!app_status->managed)
+ __update_leader_app_status(app_status->leader_id);
+ if (app_status->fg_count == 1 && limit_bg_uiapps > 0)
+ __check_running_uiapp_list();
+ } else if (app_status->status == STATUS_DYING) {
+ _suspend_remove_timer(app_status->pid);
+ if (!app_status->debug_mode) {
+ app_status->timer = g_timeout_add_seconds(5,
+ __terminate_timer_cb,
+ GINT_TO_POINTER(app_status->pid));
+ }
+ aul_send_app_terminate_request_signal(app_status->pid,
+ NULL, NULL, NULL);
+ }
+
+ __update_pkg_status(app_status);
+ _W("pid: %d, appid: %s, pkgid: %s, status: %s(%d)",
+ app_status->pid, app_status->appid, app_status->pkgid,
+ aul_app_status_convert_to_string(app_status->status),
+ app_status->status);
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
+ force, update_group_info, app_status, NULL);
+
+ return 0;
+}
+
+int _app_status_update_last_caller_pid(app_status_h app_status, int caller_pid)
+{
+ if (app_status == NULL)
+ return -1;
+
+ app_status->last_caller_pid = caller_pid;
+
+ return 0;
+}
+
+int _app_status_update_bg_launch(app_status_h app_status, bool bg_launch)
+{
+ if (app_status == NULL)
+ return -1;
+
+ if (!app_status->bg_launch)
+ return 0;
+
+ app_status->bg_launch = bg_launch;
+
+ return 0;
+}
+
+int _app_status_get_process_cnt(const char *appid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+ int cnt = 0;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->appid &&
+ strcmp(app_status->appid, appid) == 0)
+ cnt++;
+ }
+
+ return cnt;
+}
+
+bool _app_status_is_home_app(app_status_h app_status)
+{
+ const char *appid = _app_status_get_appid(app_status);
+
+ if (!appid)
+ return false;
+ if (!home_appid)
+ return false;
+
+ if (strcmp(home_appid, appid) == 0)
+ return true;
+
+ return false;
+}
+
+int _app_status_get_pid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ return app_status->pid;
+}
+
+int _app_status_get_org_caller_pid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ return app_status->org_caller_pid;
+}
+
+int _app_status_get_last_caller_pid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ return app_status->last_caller_pid;
+}
+
+int _app_status_is_running(app_status_h app_status)
+{
+ if (app_status == NULL ||
+ (app_status->app_type == AT_UI_APP && app_status->is_subapp) ||
+ app_status->status == STATUS_DYING)
+ return -1;
+
+ return app_status->pid;
+}
+
+int _app_status_get_status(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ return app_status->status;
+}
+
+uid_t _app_status_get_uid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return (uid_t)-1;
+
+ return app_status->uid;
+}
+
+const char *_app_status_get_appid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return NULL;
+
+ return app_status->appid;
+}
+
+const char *_app_status_get_pkgid(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return NULL;
+
+ return app_status->pkgid;
+}
+
+bool _app_status_get_bg_launch(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return false;
+
+ return app_status->bg_launch;
+}
+
+const char *_app_status_get_instance_id(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return NULL;
+
+ return app_status->instance_id;
+}
+
+int _app_status_get_app_type(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+ return app_status->app_type;
+}
+
+bool _app_status_socket_exists(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return false;
+
+ return app_status->socket_exists;
+}
+
+bool _app_status_is_starting(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return false;
+
+ return app_status->starting;
+}
+
+int _app_status_update_is_starting(app_status_h app_status, bool is_starting)
+{
+ if (app_status == NULL)
+ return -1;
+
+ app_status->starting = is_starting;
+
+ return 0;
+}
+
+bool _app_status_is_exiting(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return false;
+
+ return app_status->exiting;
+}
+
+int _app_status_update_is_exiting(app_status_h app_status, bool is_exiting)
+{
+ if (app_status == NULL)
+ return -1;
+
+ app_status->exiting = is_exiting;
+
+ return 0;
+}
+
+const char *_app_status_get_app_path(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return NULL;
+
+ return app_status->app_path;
+}
+
+app_status_h _app_status_find(int pid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->pid == pid)
+ return app_status;
+ }
+
+ return NULL;
+}
+
+static int __read_ppid_from_proc(const char *path, int *ppid)
+{
+ FILE *fp;
+ int ret;
+ int result = -1;
+ char *buf = NULL;
+ int val;
+
+ if (path == NULL)
+ return -1;
+
+ fp = fopen(path, "r");
+ if (fp == NULL)
+ return -1;
+
+ ret = fscanf(fp, "%ms %d\n", &buf, &val);
+ while (ret != EOF) {
+ if (ret == 2) {
+ if (buf && strcmp(buf, "PPid:") == 0) {
+ *ppid = val;
+ result = 0;
+ _D("ppid : %d", *ppid);
+ break;
+ }
+ }
+
+ free(buf);
+ buf = NULL;
+ ret = fscanf(fp, "%ms %d\n", &buf, &val);
+ }
+
+ fclose(fp);
+ free(buf);
+
+ return result;
+}
+
+int __proc_get_ppid_by_pid(int pid)
+{
+ char path[PATH_MAX] = { 0, };
+ int ret = 0;
+ int ppid;
+
+ snprintf(path, sizeof(path), "/proc/%d/status", pid);
+ ret = __read_ppid_from_proc(path, &ppid);
+ if (ret < 0)
+ return -1;
+
+ return ppid;
+}
+
+app_status_h _app_status_find_v2(int pid)
+{
+ int ppid;
+ int pgid;
+ struct app_status_s *app_status;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ pgid = getpgid(pid);
+ if (pgid > 0)
+ app_status = _app_status_find(pgid);
+ }
+
+ if (app_status == NULL) {
+ ppid = __proc_get_ppid_by_pid(pid);
+ app_status = _app_status_find(ppid);
+ }
+
+ return app_status;
+}
+
+app_status_h _app_status_find_by_appid(const char *appid, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->appid &&
+ strcmp(app_status->appid, appid) == 0 &&
+ app_status->uid == uid &&
+ (app_status->is_subapp == false ||
+ app_status->app_type == AT_WATCH_APP ||
+ app_status->app_type == AT_WIDGET_APP))
+ return app_status;
+ }
+
+ return NULL;
+}
+
+app_status_h _app_status_find_by_appid_v2(const char *appid, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->appid &&
+ strcmp(app_status->appid, appid) == 0 &&
+ app_status->uid == uid)
+ return app_status;
+ }
+
+ return NULL;
+}
+
+app_status_h _app_status_find_with_org_caller(const char *appid, uid_t uid,
+ int caller_pid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->appid &&
+ strcmp(app_status->appid, appid) == 0 &&
+ app_status->uid == uid &&
+ app_status->org_caller_pid == caller_pid)
+ return app_status;
+ }
+
+ return NULL;
+}
+
+app_status_h _app_status_find_by_instance_id(const char *appid,
+ const char *instance_id, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->instance_id &&
+ app_status->uid == uid &&
+ !strcmp(app_status->instance_id, instance_id) &&
+ !strcmp(app_status->appid, appid))
+ return app_status;
+ }
+
+ return NULL;
+}
+
+void _app_status_find_service_apps(app_status_h app_status, int status,
+ void (*send_event_to_svc_core)(int, uid_t), bool suspend)
+{
+ GSList *iter;
+ GSList *svc_list = NULL;
+ const struct appinfo *ai;
+ struct app_status_s *svc_status;
+ bool bg_allowed;
+ bool excluded;
+ uid_t uid;
+
+ if (app_status == NULL) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ uid = _app_status_get_uid(app_status);
+ if (app_status->pkg_status && app_status->pkg_status->status == status)
+ svc_list = app_status->pkg_status->svc_list;
+
+ for (iter = svc_list; iter; iter = g_slist_next(iter)) {
+ svc_status = (struct app_status_s *)iter->data;
+ if (svc_status && svc_status->uid == uid) {
+ ai = _appinfo_find(uid, svc_status->appid);
+ bg_allowed = _suspend_is_allowed_background(ai);
+ excluded = _suspend_is_excluded(svc_status->pid);
+ if (!excluded && !bg_allowed) {
+ send_event_to_svc_core(svc_status->pid, uid);
+ if (svc_status->status != STATUS_DYING &&
+ suspend)
+ _suspend_add_timer(svc_status->pid);
+ else
+ _suspend_remove_timer(svc_status->pid);
+ }
+ }
+ }
+}
+
+void _app_status_check_service_only(app_status_h app_status,
+ void (*send_event_to_svc_core)(int, uid_t))
+{
+ GSList *iter;
+ GSList *ui_list = NULL;
+ struct app_status_s *ui_status;
+ int ui_cnt = 0;
+ bool bg_allowed;
+ bool excluded;
+ const char *appid;
+ const struct appinfo *ai;
+ uid_t uid;
+ int status;
+
+ if (app_status == NULL) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ uid = _app_status_get_uid(app_status);
+ if (app_status->pkg_status && app_status->pkg_status->ui_list)
+ ui_list = app_status->pkg_status->ui_list;
+
+ for (iter = ui_list; iter; iter = g_slist_next(iter)) {
+ ui_status = (struct app_status_s *)iter->data;
+ if (_app_status_get_status(ui_status) != STATUS_DYING)
+ ui_cnt++;
+ }
+
+ if (ui_cnt == 0) {
+ appid = _app_status_get_appid(app_status);
+ status = _app_status_get_status(app_status);
+ ai = _appinfo_find(uid, appid);
+ bg_allowed = _suspend_is_allowed_background(ai);
+ excluded = _suspend_is_excluded(app_status->pid);
+ if (!excluded && !bg_allowed && status != STATUS_DYING) {
+ send_event_to_svc_core(app_status->pid, uid);
+ _suspend_add_timer(app_status->pid);
+ }
+ }
+}
+
+static bundle *__create_appinfo_bundle(app_status_h app_status)
+{
+ bundle *b;
+ char tmp_str[MAX_PID_STR_BUFSZ];
+
+ b = bundle_create();
+ if (b == NULL)
+ return NULL;
+
+ snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->pid);
+ bundle_add(b, AUL_K_PID, tmp_str);
+ bundle_add(b, AUL_K_APPID, app_status->appid);
+ bundle_add(b, AUL_K_EXEC, app_status->app_path);
+ bundle_add(b, AUL_K_PKGID, app_status->pkgid);
+ snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->status);
+ bundle_add(b, AUL_K_STATUS, tmp_str);
+ snprintf(tmp_str, sizeof(tmp_str), "%d", app_status->is_subapp);
+ bundle_add(b, AUL_K_IS_SUBAPP, tmp_str);
+ if (app_status->instance_id)
+ bundle_add(b, AUL_K_INSTANCE_ID, app_status->instance_id);
+
+ return b;
+}
+
+static int __send_running_appinfo(app_status_h app_status, int fd)
+{
+ int ret;
+ bundle *b;
+ bundle_raw *raw = NULL;
+ int len = 0;
+
+ b = __create_appinfo_bundle(app_status);
+ if (b == NULL) {
+ _E("out of memory");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ ret = bundle_encode(b, &raw, &len);
+ bundle_free(b);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Failed to encode bundle");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR, NULL,
+ 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ ret = aul_sock_send_raw_with_fd(fd, APP_GET_INFO_OK,
+ (unsigned char *)raw, len,
+ AUL_SOCK_ASYNC | AUL_SOCK_BUNDLE);
+ if (ret < 0) {
+ _E("Failed to send raw data: %s", raw);
+ free(raw);
+ return ret;
+ }
+ free(raw);
+
+ return 0;
+}
+
+int _app_status_send_running_appinfo(int fd, int cmd, uid_t uid)
+{
+ GSList *list = NULL;
+ GSList *iter;
+ struct app_status_s *app_status;
+ int ret;
+ int count;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status->uid != uid ||
+ app_status->status == STATUS_DYING)
+ continue;
+ if (cmd != APP_ALL_RUNNING_INFO &&
+ cmd != APP_RUNNING_INSTANCE_INFO &&
+ (app_status->app_type == AT_UI_APP &&
+ app_status->is_subapp))
+ continue;
+ if (cmd == APP_RUNNING_INSTANCE_INFO &&
+ app_status->instance_id == NULL)
+ continue;
+
+ list = g_slist_append(list, app_status);
+ }
+
+ count = g_slist_length(list);
+ if (count == 0) {
+ _E("Applications are not running");
+ _send_result_to_client(fd, -1);
+ return -1;
+ }
+ _send_result_to_client_v2(fd, count);
+
+ for (iter = list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status == NULL)
+ continue;
+
+ ret = __send_running_appinfo(app_status, fd);
+ if (ret < 0) {
+ g_slist_free(list);
+ return -1;
+ }
+ }
+ close(fd);
+ g_slist_free(list);
+
+ return 0;
+}
+
+int _app_status_foreach_running_appinfo(void (*callback)(app_status_h, void *),
+ void *data)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+
+ if (callback == NULL)
+ return -1;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status->status == STATUS_DYING ||
+ app_status->is_subapp)
+ continue;
+ callback(app_status, data);
+ }
+
+ return 0;
+}
+
+int _app_status_terminate_apps(const char *appid, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+ int ret;
+
+ if (appid == NULL)
+ return -1;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status->uid == uid &&
+ strcmp(app_status->appid, appid) == 0 &&
+ app_status->status != STATUS_DYING) {
+ ret = _terminate_app_local(app_status->uid,
+ app_status->pid);
+ if (ret < 0) {
+ _E("Failed to terminate app(%d)",
+ app_status->pid);
+ }
+
+ _app_status_update_status(app_status, STATUS_DYING,
+ false, true);
+ }
+ }
+
+ return 0;
+}
+
+static void __delete_socket_path(pid_t pid, uid_t uid)
+{
+ char buf[PATH_MAX];
+ int ret;
+
+ snprintf(buf, sizeof(buf), "/run/aul/apps/%u/%d", uid, pid);
+ ret = _util_unlink(buf);
+ if (ret != 0)
+ _W("Failed to delete socket path(%s)", buf);
+}
+
+int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+ int ret;
+
+ if (pkgid == NULL)
+ return -1;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status->uid == uid &&
+ strcmp(app_status->pkgid, pkgid) == 0 &&
+ app_status->status != STATUS_DYING) {
+ ret = _terminate_app_local(app_status->uid,
+ app_status->pid);
+ if (ret < 0) {
+ _E("Failed to terminate app(%d)",
+ app_status->pid);
+ }
+
+ _app_status_update_status(app_status, STATUS_DYING,
+ false, true);
+ __delete_socket_path(app_status->pid, app_status->uid);
+ }
+ }
+
+ return 0;
+}
+
+int _app_status_get_appid_bypid(int fd, int pid)
+{
+ int cmd = APP_GET_INFO_ERROR;
+ int len = 0;
+ int pgid;
+ int ppid;
+ int ret;
+ char appid[MAX_PACKAGE_STR_SIZE] = {0,};
+ app_status_h app_status;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ pgid = getpgid(pid);
+ if (pgid > 0) {
+ app_status = _app_status_find(pgid);
+ if (app_status == NULL) {
+ ppid = __proc_get_ppid_by_pid(pid);
+ app_status = _app_status_find(ppid);
+ }
+ }
+ }
+
+ if (app_status) {
+ snprintf(appid, sizeof(appid), "%s",
+ _app_status_get_appid(app_status));
+ SECURE_LOGD("appid for %d is %s", pid, appid);
+ len = strlen(appid);
+ cmd = APP_GET_INFO_OK;
+ }
+
+ ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)appid,
+ len, AUL_SOCK_NOREPLY);
+
+ return ret;
+}
+
+int _app_status_get_pkgid_bypid(int fd, int pid)
+{
+ int cmd = APP_GET_INFO_ERROR;
+ int len = 0;
+ int pgid;
+ int ppid;
+ int ret;
+ char pkgid[MAX_PACKAGE_STR_SIZE] = {0,};
+ app_status_h app_status;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ pgid = getpgid(pid);
+ if (pgid > 0) {
+ app_status = _app_status_find(pgid);
+ if (app_status == NULL) {
+ ppid = __proc_get_ppid_by_pid(pid);
+ app_status = _app_status_find(ppid);
+ }
+ }
+ }
+
+ if (app_status) {
+ snprintf(pkgid, sizeof(pkgid), "%s",
+ _app_status_get_pkgid(app_status));
+ SECURE_LOGD("pkgid for %d is %s", pid, pkgid);
+ len = strlen(pkgid);
+ cmd = APP_GET_INFO_OK;
+ }
+
+ ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)pkgid,
+ len, AUL_SOCK_NOREPLY);
+
+ return ret;
+}
+
+int _app_status_get_instance_id_bypid(int fd, int pid)
+{
+ int cmd = APP_GET_INFO_ERROR;
+ int len = 0;
+ int ret;
+ const char *instance_id;
+ char buf[MAX_PACKAGE_STR_SIZE] = {0,};
+ app_status_h app_status;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ app_status = _app_status_find(getpgid(pid));
+ if (app_status == NULL) {
+ app_status = _app_status_find(
+ __proc_get_ppid_by_pid(pid));
+ }
+ }
+
+ instance_id = _app_status_get_instance_id(app_status);
+ if (instance_id) {
+ snprintf(buf, sizeof(buf), "%s", instance_id);
+ SECURE_LOGD("pid(%d), instance-id(%s)", pid, instance_id);
+ len = strlen(buf);
+ cmd = APP_GET_INFO_OK;
+ }
+
+ ret = aul_sock_send_raw_with_fd(fd, cmd, (unsigned char *)buf, len,
+ AUL_SOCK_NOREPLY);
+
+ return ret;
+}
+
+int _app_status_set_leader_id(app_status_h app_status, const char *id)
+{
+ if (app_status == NULL || id == NULL)
+ return -1;
+
+ if (app_status->leader_id)
+ free(app_status->leader_id);
+
+ app_status->leader_id = strdup(id);
+ if (!app_status->leader_id) {
+ _E("Failed to duplicate leader ID(%s)", id);
+ return -1;
+ }
+
+ return 0;
+}
+
+const char *_app_status_get_leader_id(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return NULL;
+
+
+ return app_status->leader_id;
+}
+
+int _app_status_get_fg_cnt(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+
+ return app_status->fg_count;
+}
+
+int _app_status_get_timestamp(app_status_h app_status)
+{
+ if (app_status == NULL)
+ return -1;
+
+
+ return app_status->timestamp;
+}
+
+static void __home_appid_vconf_cb(keynode_t *key, void *data)
+{
+ char *tmpstr;
+
+ tmpstr = vconf_keynode_get_str(key);
+ if (tmpstr == NULL)
+ return;
+
+ if (home_appid)
+ free(home_appid);
+ home_appid = strdup(tmpstr);
+}
+
+int _app_status_publish_status(int pid, int context_status)
+{
+#define APP_STATUS_EVENT "app_status_event"
+ bundle *b;
+ char endpoint_system[MAX_LOCAL_BUFSZ];
+ char endpoint_user[MAX_LOCAL_BUFSZ];
+ char endpoint_system2[MAX_LOCAL_BUFSZ];
+ char endpoint_user2[MAX_LOCAL_BUFSZ];
+ bool endpoint_system_exists;
+ bool endpoint_user_exists;
+ bool endpoint_system2_exists;
+ bool endpoint_user2_exists;
+ char buf[MAX_PID_STR_BUFSZ];
+ app_status_h app_status;
+ const char *appid;
+ uid_t uid;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return -1;
+
+ appid = _app_status_get_appid(app_status);
+ uid = _app_status_get_uid(app_status);
+ snprintf(endpoint_user, sizeof(endpoint_user), "%s:%s:%u",
+ APP_STATUS_EVENT, appid, uid);
+ snprintf(endpoint_system, sizeof(endpoint_system), "%s:%s",
+ APP_STATUS_EVENT, appid);
+ snprintf(endpoint_user2, sizeof(endpoint_user2), "%s:%u",
+ APP_STATUS_EVENT, uid);
+ snprintf(endpoint_system2, sizeof(endpoint_system2), "%s",
+ APP_STATUS_EVENT);
+ endpoint_system_exists = _app_com_endpoint_exists(endpoint_system);
+ endpoint_user_exists = _app_com_endpoint_exists(endpoint_user);
+ endpoint_system2_exists = _app_com_endpoint_exists(endpoint_system2);
+ endpoint_user2_exists = _app_com_endpoint_exists(endpoint_user2);
+ if (!endpoint_system_exists && !endpoint_user_exists &&
+ !endpoint_system2_exists && !endpoint_user2_exists)
+ return -1;
+
+ b = __create_appinfo_bundle(app_status);
+ if (b == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", context_status);
+ bundle_add(b, "__CONTEXT_STATUS__", buf);
+ if (endpoint_system_exists)
+ _app_com_send(endpoint_system, pid, b, uid);
+ if (endpoint_user_exists)
+ _app_com_send(endpoint_user, pid, b, uid);
+ if (endpoint_system2_exists)
+ _app_com_send(endpoint_system2, pid, b, uid);
+ if (endpoint_user2_exists)
+ _app_com_send(endpoint_user2, pid, b, uid);
+ bundle_free(b);
+
+ return 0;
+}
+
+static void __terminate_widget_apps_by_org_caller(int caller_pid, uid_t uid)
+{
+ GSList *iter;
+ struct app_status_s *app_status;
+ int ret;
+
+ for (iter = app_status_list; iter; iter = g_slist_next(iter)) {
+ app_status = (struct app_status_s *)iter->data;
+ if ((app_status->app_type == AT_WIDGET_APP ||
+ app_status->app_type == AT_WATCH_APP) &&
+ app_status->uid == uid &&
+ app_status->org_caller_pid == caller_pid &&
+ app_status->status != STATUS_DYING) {
+ ret = _terminate_app_local(app_status->uid,
+ app_status->pid);
+ if (ret < 0) {
+ _E("Failed to terminate app(%d)",
+ app_status->pid);
+ }
+ }
+ }
+}
+
+void _app_status_cleanup(app_status_h app_status)
+{
+ int pid;
+ const char *instance_id;
+ uid_t uid;
+
+ if (app_status == NULL)
+ return;
+
+ pid = _app_status_get_pid(app_status);
+ uid = _app_status_get_uid(app_status);
+ _D("pid: %d, uid: %d", pid, uid);
+
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_CLEANUP, pid, uid, app_status, NULL);
+
+ instance_id = _app_status_get_instance_id(app_status);
+ if (instance_id == NULL)
+ instance_id = _app_status_get_appid(app_status);
+
+ __terminate_widget_apps_by_org_caller(pid, uid);
+ _app_com_client_remove(pid);
+ _suspend_remove_proc(pid);
+ _app_status_remove(app_status);
+ aul_send_app_terminated_signal(pid);
+}
+
+static bool __socket_monitor_cb(const char *event_name, void *data)
+{
+ int pid = -1;
+
+ if (event_name == NULL)
+ return true;
+
+ if (isdigit(*event_name))
+ pid = atoi(event_name);
+
+ if (pid > 1)
+ _I("Socket(%d) is created.", pid);
+
+ return true;
+}
+
+static bool __dir_monitor_cb(const char *event_name, void *data)
+{
+ uid_t uid;
+ inotify_watch_info_h handle;
+ char path[PATH_MAX];
+
+ if (event_name == NULL)
+ return true;
+
+ uid = strtol(event_name, NULL, 10);
+ handle = g_hash_table_lookup(__wd_table, GUINT_TO_POINTER(uid));
+ if (!handle) {
+ snprintf(path, sizeof(path), "%s/%u", PATH_AUL_APPS, uid);
+ handle = _inotify_add_watch(path, IN_CREATE,
+ __socket_monitor_cb, NULL);
+ if (handle == NULL) {
+ _E("Failed to add a watch - uid(%d)", uid);
+ return true;;
+ }
+
+ g_hash_table_insert(__wd_table, GUINT_TO_POINTER(uid), handle);
+ }
+
+ return true;
+}
+
+int _app_status_usr_init(uid_t uid)
+{
+ inotify_watch_info_h handle;
+ char buf[PATH_MAX];
+
+ handle = g_hash_table_lookup(__wd_table, GUINT_TO_POINTER(uid));
+ if (handle) {
+ _D("Already exists. uid(%u)", uid);
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf), "/run/aul/apps/%d", uid);
+ if (access(buf, F_OK) == 0) {
+ handle = _inotify_add_watch(buf, IN_CREATE, __socket_monitor_cb,
+ NULL);
+ if (handle == NULL) {
+ _E("Failed to add a watch - uid(%d)", uid);
+ return -1;
+ }
+
+ g_hash_table_insert(__wd_table, GUINT_TO_POINTER(uid), handle);
+ }
+
+ return 0;
+}
+
+void _app_status_usr_fini(uid_t uid)
+{
+ GSList *iter;
+ GSList *iter_next;
+ app_status_h app_status;
+
+ if (g_hash_table_contains(__wd_table, GUINT_TO_POINTER(uid)))
+ g_hash_table_remove(__wd_table, GUINT_TO_POINTER(uid));
+ else
+ _D("Watch fd doesn't exist - uid(%d)", uid);
+
+ GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
+ app_status = (struct app_status_s *)iter->data;
+ if (app_status && app_status->uid == uid)
+ _app_status_cleanup(app_status);
+ }
+}
+
+static void __remove_inotify_watch(gpointer data)
+{
+ inotify_watch_info_h handle = data;
+
+ if (handle == NULL)
+ return;
+
+ _inotify_rm_watch(handle);
+}
+
+static int __dispatch_app_running_info(request_h req)
+{
+ int ret;
+
+ ret = _app_status_send_running_appinfo(_request_remove_fd(req),
+ _request_get_cmd(req), _request_get_target_uid(req));
+ return ret;
+}
+
+static int __dispatch_app_all_running_info(request_h req)
+{
+ int ret;
+
+ ret = _app_status_send_running_appinfo(_request_remove_fd(req),
+ _request_get_cmd(req), _request_get_target_uid(req));
+ return ret;
+}
+
+static int __dispatch_app_is_running(request_h req)
+{
+ const char *appid;
+ int ret;
+ app_status_h app_status;
+ bundle *b = _request_get_bundle(req);
+
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (appid == NULL) {
+ _E("Failed to get appid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ ret = _app_status_is_running(app_status);
+ SECURE_LOGD("APP_IS_RUNNING : %s : %d", appid, ret);
+ _request_send_result(req, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_get_pid(request_h req)
+{
+ const char *appid;
+ int ret;
+ app_status_h app_status;
+ bundle *b;
+
+ b = _request_get_bundle(req);
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (appid == NULL) {
+ _E("Failed to get appid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ ret = _app_status_get_pid(app_status);
+ SECURE_LOGD("APP_GET_PID : %s : %d", appid, ret);
+ _request_send_result(req, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_get_appid_by_pid(request_h req)
+{
+ int pid;
+ int ret;
+ const char *pid_str;
+ bundle *b = _request_get_bundle(req);
+
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str == NULL || !isdigit(pid_str[0])) {
+ _E("Failed to get pid");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid = atoi(pid_str);
+ ret = _app_status_get_appid_bypid(_request_remove_fd(req), pid);
+ _D("app_status_get_appid_bypid : %d : %d", pid, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_get_pkgid_by_pid(request_h req)
+{
+ int pid;
+ int ret;
+ const char *pid_str;
+ bundle *b = _request_get_bundle(req);
+
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str == NULL || !isdigit(pid_str[0])) {
+ _E("Failed to get pid");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req),
+ APP_GET_INFO_ERROR, NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid = atoi(pid_str);
+ ret = _app_status_get_pkgid_bypid(_request_remove_fd(req), pid);
+ _D("APP_GET_PKGID_BYPID : %d : %d", pid, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_status_update(request_h req)
+{
+ int *status;
+ const char *appid;
+ struct appinfo *ai;
+ app_status_h app_status;
+
+ app_status = _app_status_find(_request_get_pid(req));
+ if (app_status == NULL)
+ return -1;
+
+ status = (int *)_request_get_raw(req);
+ switch (*status) {
+ case STATUS_NORESTART:
+ appid = _app_status_get_appid(app_status);
+ ai = _appinfo_find(_request_get_target_uid(req), appid);
+ _appinfo_set_value((struct appinfo *)ai, AIT_STATUS,
+ "norestart");
+ break;
+ case STATUS_VISIBLE:
+ case STATUS_BG:
+ break;
+ default:
+ _app_status_update_status(app_status, *status, false, true);
+ break;
+ }
+
+ return 0;
+}
+
+static int __dispatch_app_get_status(request_h req)
+{
+ int pid;
+ int status;
+ app_status_h app_status;
+ const char *pid_str;
+ bundle *b;
+
+ b = _request_get_bundle(req);
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str == NULL || !isdigit(pid_str[0])) {
+ _E("Falied to get pid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ pid = atoi(pid_str);
+ app_status = _app_status_find(pid);
+ status = _app_status_get_status(app_status);
+ _request_send_result(req, status);
+
+ return 0;
+}
+
+static int __dispatch_app_get_status_by_appid(request_h req)
+{
+ int status;
+ int pid;
+ uid_t uid;
+ const char *appid;
+ bundle *kb;
+ app_status_h app_status;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ uid = _request_get_target_uid(req);
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ app_status = _app_status_find_by_appid(appid, uid);
+ pid = _app_status_is_running(app_status);
+ status = _app_status_get_status(app_status);
+ if (status == STATUS_VISIBLE) {
+ if (_launch_get_focused_pid() == pid)
+ status = STATUS_FOCUS;
+ }
+
+ _request_send_result(req, status);
+ _D("appid: %s, pid: %d, status: %d", appid, pid, status);
+
+ return 0;
+}
+
+static int __dispatch_app_get_last_caller_pid(request_h req)
+{
+ int pid;
+ int ret;
+ app_status_h app_status;
+ const char *pid_str;
+ bundle *b = _request_get_bundle(req);
+
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str == NULL || !isdigit(pid_str[0])) {
+ _E("Failed to get pid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ pid = atoi(pid_str);
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ _E("Failed to get app status info(%d)", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _app_status_get_last_caller_pid(app_status);
+ _D("app_get_last_caller_pid: %d : %d", pid, ret);
+ _request_send_result(req, ret);
+
+ return 0;
+}
+
+static int __verify_app_process(pid_t pid, const char *pkgid)
+{
+ char attr[PATH_MAX] = { 0, };
+ char buf[PATH_MAX];
+ int r;
+
+ r = _proc_get_attr(pid, attr, sizeof(attr));
+ if (r < 0)
+ return -1;
+
+ snprintf(buf, sizeof(buf), "User::Pkg::%s", pkgid);
+ if (!strcmp(buf, attr))
+ return 0;
+
+ SECURE_LOGD("attr:%s, package:%s", attr, pkgid);
+ return -1;
+}
+
+static void __update_proc_status(int pid, int status, int focused, void *data)
+{
+ app_status_h app_status;
+
+ if (focused == 1)
+ _launch_set_focused_pid(pid);
+
+ if (status == PROC_STATUS_FG)
+ status = STATUS_VISIBLE;
+ else if (status == PROC_STATUS_BG)
+ status = STATUS_BG;
+ else
+ return;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return;
+
+ _app_status_update_status(app_status, status, false, true);
+}
+
+int _app_status_register_pid(int pid, const char *appid, uid_t uid)
+{
+ struct appinfo *ai;
+ const char *component_type;
+ const char *pkgid;
+ int ret;
+ app_status_h app_status;
+
+ ai = _appinfo_find(uid, appid);
+ if (!ai)
+ return -1;
+
+ pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ if (__verify_app_process(pid, pkgid) < 0)
+ return -1;
+
+ app_status = _app_status_find_by_appid(appid, uid);
+ ret = _app_status_is_running(app_status);
+ if (ret > 0) {
+ _W("status info is already exist: %s", appid);
+ if (ret == pid)
+ return 0;
+ _W("Running process: %d, request process:%d", ret, pid);
+ return -1;
+ }
+ _D("appid: %s, pid: %d", appid, pid);
+
+ component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ _app_status_add_app_info(ai, pid, false, uid, getpid(),
+ false, NULL, false);
+ _noti_send(AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID, pid, 0, ai, NULL);
+ if (component_type && strcmp(component_type, APP_TYPE_SERVICE) != 0) {
+ ret = _signal_get_proc_status_async(pid,
+ __update_proc_status, NULL);
+ if (ret < 0)
+ return 0;
+ }
+
+ return 0;
+}
+
+static int __dispatch_app_register_pid(request_h req)
+{
+ uid_t target_uid = _request_get_target_uid(req);
+ const char *appid;
+ const char *pid_str;
+ bundle *kb;
+ int pid;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL)
+ return -1;
+
+ pid_str = bundle_get_val(kb, AUL_K_PID);
+ if (pid_str == NULL)
+ return -1;
+
+ pid = atoi(pid_str);
+ if (pid <= 1)
+ return -1;
+
+ return _app_status_register_pid(pid, appid, target_uid);
+}
+
+static int __dispatch_app_running_instance_info(request_h req)
+{
+ int fd = _request_remove_fd(req);
+ int cmd = _request_get_cmd(req);
+ uid_t target_uid = _request_get_target_uid(req);
+
+ return _app_status_send_running_appinfo(fd, cmd, target_uid);
+}
+
+static int __dispatch_app_get_instance_id_by_pid(request_h req)
+{
+ int pid;
+ int ret;
+ const char *pid_str;
+ int fd = _request_remove_fd(req);
+ bundle *b = _request_get_bundle(req);
+
+ if (b == NULL) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str == NULL || !isdigit(pid_str[0])) {
+ _E("Failed to get pid");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ pid = atoi(pid_str);
+ ret = _app_status_get_instance_id_bypid(fd, pid);
+ _D("app get instance-id by pid - pid(%d), ret(%d)", pid, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_notify_exit(request_h req)
+{
+ int pid = _request_get_pid(req);
+ int ret;
+ app_status_h app_status;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ _E("pid(%d) is not an application", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _app_status_update_is_exiting(app_status, true);
+ _D("[APP_NOTIFY_EXIT] result(%d)", ret);
+
+ return 0;
+}
+
+static int __dispatch_app_notify_start(request_h req)
+{
+ int pid = _request_get_pid(req);
+ app_status_h app_status;
+
+ _request_reply_for_pending_request(pid);
+ app_status = _app_status_find(pid);
+ if (app_status) {
+ app_status->socket_exists = true;
+ app_status->starting = true;
+ }
+
+ _W("[APP_NOTIFY_START] pid(%d)", pid);
+
+ return 0;
+}
+
+static int __dispatch_app_is_running_v2(request_h req)
+{
+ app_status_h app_status;
+ const char *instance_id;
+ const char *appid;
+ bundle *b;
+ int ret;
+
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ _request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get application ID");
+ _request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!instance_id) {
+ _E("Failed to get instance ID");
+ _request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ app_status = _app_status_find_by_instance_id(appid,
+ instance_id, _request_get_target_uid(req));
+ ret = _app_status_is_running(app_status);
+ _request_send_result(req, ret > 0 ? ret : 0);
+ SECURE_LOGD("APP_IS_RUNNING_V2 : %s : %s : %d",
+ appid, instance_id, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_get_running_context(request_h req)
+{
+ comp_status_h comp_status = NULL;
+ app_status_h app_status = NULL;
+ const char *component_id;
+ const char *instance_id;
+ const char *appid;
+ char buf[12];
+ int pid;
+ bundle *b;
+ int ret;
+
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req), -EINVAL,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get application ID");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req), -EINVAL,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ component_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
+ if (component_id && instance_id) {
+ comp_status = _comp_status_find_by_instance_id(instance_id);
+ } else if (component_id) {
+ comp_status = _comp_status_find(component_id);
+ } else if (appid && instance_id) {
+ app_status = _app_status_find_by_instance_id(appid,
+ instance_id, _request_get_target_uid(req));
+ } else {
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ }
+
+ if (_comp_status_is_running(comp_status)) {
+ instance_id = _comp_status_get_instance_id(comp_status);
+ pid = _comp_status_get_pid(comp_status);
+ } else if (_app_status_is_running(app_status) > 0) {
+ instance_id = _app_status_get_instance_id(app_status);
+ pid = _app_status_get_pid(app_status);
+ } else {
+ _E("Failed to find information");
+ aul_sock_send_raw_with_fd(_request_remove_fd(req), -ENOENT,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -ENOENT;
+ }
+
+ bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
+ snprintf(buf, sizeof(buf), "%d", pid);
+ bundle_add(b, AUL_K_PID, buf);
+
+ ret = aul_sock_send_bundle_with_fd(_request_remove_fd(req),
+ APP_GET_INFO_OK, b, AUL_SOCK_NOREPLY);
+ _I("[APP_GET_RUNNING_CONTEXT] result: %d", ret);
+
+ return 0;
+}
+
+static int __dispatch_app_context_get(request_h req)
+{
+ app_status_h app_status;
+ const char *appid;
+ int s_pid;
+ int c_pid;
+ bundle *b;
+ int ret;
+ int fd;
+
+ fd = _request_remove_fd(req);
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get application ID");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ if (_app_status_is_running(app_status) < 0) {
+ s_pid = _app_status_get_pid(app_status);
+ c_pid = _request_get_pid(req);
+ if (s_pid != c_pid)
+ app_status = NULL;
+ }
+
+ if (!app_status) {
+ _E("Failed to find app status. appid(%s)", appid);
+ aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -ENOENT;
+ }
+
+ ret = __send_running_appinfo(app_status, fd);
+ if (ret < 0)
+ return ret;
+
+ close(fd);
+ _I("[APP_CONTEXT_GET] result: %d", ret);
+ return 0;
+}
+
+static int __dispatch_app_context_get_by_instance_id(request_h req)
+{
+ app_status_h app_status;
+ const char *instance_id;
+ const char *appid;
+ int status;
+ int s_pid;
+ bundle *b;
+ int pid;
+ int ret;
+ int fd;
+
+ fd = _request_remove_fd(req);
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get application ID");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!instance_id) {
+ _E("Failed to get instance ID");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ pid = _request_get_pid(req);
+ app_status = _app_status_find_by_instance_id(appid, instance_id,
+ _request_get_target_uid(req));
+ if (app_status) {
+ status = _app_status_get_status(app_status);
+ if (status == STATUS_DYING) {
+ s_pid = _app_status_get_pid(app_status);
+ _W("%d is dying", s_pid);
+ if (s_pid != pid)
+ app_status = NULL;
+ }
+ }
+
+ if (!app_status) {
+ _E("Failed to find app status. appid(%s), inst_id(%s)",
+ appid, instance_id);
+ aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -ENOENT;
+ }
+
+ ret = __send_running_appinfo(app_status, fd);
+ if (ret < 0)
+ return ret;
+
+ close(fd);
+ _I("[APP_CONTEXT_GET_BY_INSTANCE_ID] result: %d", ret);
+ return 0;
+}
+
+static int __dispatch_app_context_get_by_pid(request_h req)
+{
+ app_status_h app_status;
+ const char *pid_str;
+ int status;
+ int c_pid;
+ bundle *b;
+ int pid;
+ int ret;
+ int fd;
+
+ fd = _request_remove_fd(req);
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (!pid_str) {
+ _E("Failed to get process ID");
+ aul_sock_send_raw_with_fd(fd, -EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -EINVAL;
+ }
+ pid = atoi(pid_str);
+
+ app_status = _app_status_find_v2(pid);
+ if (app_status) {
+ status = _app_status_get_status(app_status);
+ if (status == STATUS_DYING) {
+ _W("%d is dying", pid);
+ c_pid = _request_get_pid(req);
+ if (c_pid != pid)
+ app_status = NULL;
+ }
+ }
+
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ aul_sock_send_raw_with_fd(fd, -ENOENT, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -ENOENT;
+ }
+
+ ret = __send_running_appinfo(app_status, fd);
+ if (ret < 0)
+ return ret;
+
+ close(fd);
+ _I("[APP_CONTEXT_GET_BY_PID] result: %d", ret);
+ return 0;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_RUNNING_INFO,
+ .callback = __dispatch_app_running_info
+ },
+ {
+ .cmd = APP_ALL_RUNNING_INFO,
+ .callback = __dispatch_app_all_running_info
+ },
+ {
+ .cmd = APP_IS_RUNNING,
+ .callback = __dispatch_app_is_running
+ },
+ {
+ .cmd = APP_GET_PID,
+ .callback = __dispatch_app_get_pid
+ },
+ {
+ .cmd = APP_GET_APPID_BYPID,
+ .callback = __dispatch_app_get_appid_by_pid
+ },
+ {
+ .cmd = APP_GET_PKGID_BYPID,
+ .callback = __dispatch_app_get_pkgid_by_pid
+ },
+ {
+ .cmd = APP_STATUS_UPDATE,
+ .callback = __dispatch_app_status_update
+ },
+ {
+ .cmd = APP_GET_STATUS,
+ .callback = __dispatch_app_get_status
+ },
+ {
+ .cmd = APP_GET_STATUS_BY_APPID,
+ .callback = __dispatch_app_get_status_by_appid
+ },
+ {
+ .cmd = APP_GET_LAST_CALLER_PID,
+ .callback = __dispatch_app_get_last_caller_pid
+ },
+ {
+ .cmd = APP_REGISTER_PID,
+ .callback = __dispatch_app_register_pid
+ },
+ {
+ .cmd = APP_RUNNING_INSTANCE_INFO,
+ .callback = __dispatch_app_running_instance_info
+ },
+ {
+ .cmd = APP_GET_INSTANCE_ID_BYPID,
+ .callback = __dispatch_app_get_instance_id_by_pid
+ },
+ {
+ .cmd = APP_NOTIFY_EXIT,
+ .callback = __dispatch_app_notify_exit
+ },
+ {
+ .cmd = APP_NOTIFY_START,
+ .callback = __dispatch_app_notify_start
+ },
+ {
+ .cmd = APP_IS_RUNNING_V2,
+ .callback = __dispatch_app_is_running_v2
+ },
+ {
+ .cmd = APP_GET_RUNNING_CONTEXT,
+ .callback = __dispatch_app_get_running_context
+ },
+ {
+ .cmd = APP_CONTEXT_GET,
+ .callback = __dispatch_app_context_get
+ },
+ {
+ .cmd = APP_CONTEXT_GET_BY_INSTANCE_ID,
+ .callback = __dispatch_app_context_get_by_instance_id
+ },
+ {
+ .cmd = APP_CONTEXT_GET_BY_PID,
+ .callback = __dispatch_app_context_get_by_pid
+ },
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_GET_RUNNING_CONTEXT,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+};
+
+static int __init_vconf(void)
+{
+ int r;
+
+ r = vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
+ &limit_bg_uiapps);
+ if (r != VCONF_OK)
+ _W("Failed to get %s", VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS);
+
+ r = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
+ __vconf_cb, NULL);
+ if (r != VCONF_OK) {
+ _E("Failed to register callback for %s",
+ VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS);
+ return -1;
+ }
+
+ home_appid = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
+ r = vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME,
+ __home_appid_vconf_cb, NULL);
+ if (r != VCONF_OK) {
+ _E("Failed to register callback for %s",
+ VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
+ __vconf_cb);
+ return -1;
+ }
+
+ __vconf.initialized = true;
+
+ return 0;
+}
+
+static void __finish_vconf(void)
+{
+ if (!__vconf.initialized)
+ return;
+
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS,
+ __vconf_cb);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME,
+ __home_appid_vconf_cb);
+
+ __vconf.initialized = false;
+}
+
+static gboolean __vconf_init_handler(gpointer data)
+{
+ static int retry_count;
+
+ retry_count++;
+ if (__init_vconf() < 0 && retry_count <= 10) {
+ _W("Retry count(%d)", retry_count);
+ return G_SOURCE_CONTINUE;
+ }
+
+ __vconf.timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+int _app_status_init(void)
+{
+ int ret;
+
+ __wd_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __remove_inotify_watch);
+ if (__wd_table == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ __wh = _inotify_add_watch(PATH_AUL_APPS, IN_CREATE, __dir_monitor_cb, NULL);
+ if (!__wh) {
+ _E("Failed to add watch(%s)", PATH_AUL_APPS);
+ return -1;
+ }
+
+ ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ ret = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ __vconf.timer = g_timeout_add(500, __vconf_init_handler, NULL);
+
+ return 0;
+}
+
+int _app_status_finish(void)
+{
+ GSList *iter;
+ GSList *iter_next;
+ app_status_h app_status;
+
+ GSLIST_FOREACH_SAFE(app_status_list, iter, iter_next) {
+ app_status = (app_status_h)iter->data;
+ _app_status_cleanup(app_status);
+ }
+
+ if (__vconf.timer)
+ g_source_remove(__vconf.timer);
+
+ __finish_vconf();
+
+ free(home_appid);
+
+ if (__wh)
+ _inotify_rm_watch(__wh);
+
+ if (__wd_table)
+ g_hash_table_destroy(__wd_table);
+
+ return 0;
+}
+
+bool _app_status_is_debug_mode(app_status_h app_status)
+{
+ return app_status->debug_mode;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_STATUS_H__
+#define __AMD_APP_STATUS_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <glib.h>
+#include <stdbool.h>
+
+#include "amd_appinfo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ AT_SERVICE_APP,
+ AT_UI_APP,
+ AT_WIDGET_APP,
+ AT_WATCH_APP,
+ AT_COMPONENT_BASED_APP,
+} app_type_e;
+
+typedef struct app_status_s *app_status_h;
+
+int _app_status_register_pid(int pid, const char *appid, uid_t uid);
+
+int _app_status_set_extra(app_status_h app_status, const char *key, void *data);
+
+int _app_status_remove_extra(app_status_h app_status, const char *key);
+
+void *_app_status_get_extra(app_status_h app_status, const char *key);
+
+int _app_status_add_app_info(const struct appinfo *ai, int pid,
+ bool is_subapp, uid_t uid, int caller_pid,
+ bool bg_launch, const char *instance_id,
+ bool debug_mode);
+
+int _app_status_remove_all_app_info_with_uid(uid_t uid);
+
+int _app_status_remove(app_status_h app_status);
+
+int _app_status_update_status(app_status_h app_status, int status, bool force,
+ bool update_group_info);
+
+int _app_status_update_last_caller_pid(app_status_h app_status, int caller_pid);
+
+int _app_status_update_bg_launch(app_status_h app_status, bool bg_launch);
+
+int _app_status_get_process_cnt(const char *appid);
+
+bool _app_status_is_home_app(app_status_h app_status);
+
+int _app_status_get_pid(app_status_h app_status);
+
+int _app_status_get_last_caller_pid(app_status_h app_status);
+
+int _app_status_is_running(app_status_h app_status);
+
+int _app_status_get_status(app_status_h app_status);
+
+uid_t _app_status_get_uid(app_status_h app_status);
+
+const char *_app_status_get_appid(app_status_h app_status);
+
+const char *_app_status_get_pkgid(app_status_h app_status);
+
+int _app_status_get_leader_pid(app_status_h app_status);
+
+int _app_status_set_leader_pid(app_status_h app_status, int pid);
+
+int _app_status_get_fg_cnt(app_status_h app_status);
+
+int _app_status_get_timestamp(app_status_h app_status);
+
+int _app_status_term_bg_apps(GCompareFunc func);
+
+bool _app_status_get_bg_launch(app_status_h app_status);
+
+const char *_app_status_get_instance_id(app_status_h app_stauts);
+
+int _app_status_get_app_type(app_status_h app_status);
+
+bool _app_status_socket_exists(app_status_h app_status);
+
+bool _app_status_is_starting(app_status_h app_status);
+
+int _app_status_update_is_starting(app_status_h app_status, bool is_starting);
+
+bool _app_status_is_exiting(app_status_h app_status);
+
+int _app_status_update_is_exiting(app_status_h app_status, bool is_exiting);
+
+const char *_app_status_get_app_path(app_status_h app_status);
+
+app_status_h _app_status_find(int pid);
+
+app_status_h _app_status_find_v2(int pid);
+
+app_status_h _app_status_find_by_appid(const char *appid, uid_t uid);
+
+app_status_h _app_status_find_by_appid_v2(const char *appid, uid_t uid);
+
+app_status_h _app_status_find_with_org_caller(const char *appid, uid_t uid,
+ int caller_pid);
+
+app_status_h _app_status_find_by_instance_id(const char *appid,
+ const char *instance_id, uid_t uid);
+
+void _app_status_find_service_apps(app_status_h app_status, int status,
+ void (*send_event_to_svc_core)(int, uid_t), bool suspend);
+
+void _app_status_check_service_only(app_status_h app_status,
+ void (*send_event_to_svc_core)(int, uid_t));
+
+int _app_status_send_running_appinfo(int fd, int cmd, uid_t uid);
+
+int _app_status_foreach_running_appinfo(void (*callback)(app_status_h, void *),
+ void *data);
+
+int _app_status_terminate_apps(const char *appid, uid_t uid);
+
+int _app_status_terminate_apps_by_pkgid(const char *pkgid, uid_t uid);
+
+int _app_status_get_appid_bypid(int fd, int pid);
+
+int _app_status_get_pkgid_bypid(int fd, int pid);
+
+int _app_status_get_instance_id_bypid(int fd, int pid);
+
+int _app_status_get_org_caller_pid(app_status_h app_status);
+
+int _app_status_publish_status(int pid, int context_status);
+
+void _app_status_cleanup(app_status_h app_status);
+
+int _app_status_usr_init(uid_t uid);
+
+void _app_status_usr_fini(uid_t uid);
+
+int _app_status_init(void);
+
+int _app_status_finish(void);
+
+const char *_app_status_get_leader_id(app_status_h app_status);
+
+int _app_status_set_leader_id(app_status_h app_status, const char *leader_id);
+
+bool _app_status_is_debug_mode(app_status_h app_status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_APP_STATUS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <glib.h>
+#include <dirent.h>
+#include <package-manager.h>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+#include <aul_sock.h>
+#include <aul.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+
+#include "amd_api_noti.h"
+#include "amd_util.h"
+#include "amd_appinfo.h"
+#include "amd_launch.h"
+#include "amd_app_status.h"
+#include "amd_signal.h"
+#include "amd_app_property.h"
+#include "amd_suspend.h"
+#include "amd_login_monitor.h"
+#include "amd_noti.h"
+
+#define CATEGORY_IME "http://tizen.org/category/ime"
+
+typedef int (*appinfo_handler_add_cb)(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data);
+typedef void (*appinfo_handler_remove_cb)(void *data);
+
+typedef struct _appinfo_vft {
+ appinfo_handler_add_cb constructor;
+ appinfo_handler_remove_cb destructor;
+} appinfo_vft;
+
+struct user_appinfo {
+ uid_t uid;
+ GHashTable *tbl; /* key is appid, value is struct appinfo */
+};
+
+struct app_event_info {
+ int req_id;
+ int type;
+ uid_t uid;
+};
+
+struct pkg_event_info {
+ uid_t target_uid;
+ uid_t uid;
+ const char *pkgid;
+};
+
+struct callback_info {
+ appinfo_iter_callback cb;
+ void *user_data;
+};
+
+static pkgmgr_client *pc;
+static GHashTable *user_tbl;
+static GHashTable *pkg_pending;
+static GList *app_event_list;
+static int gles = 1;
+
+static void __free_appinfo_splash_image(gpointer data)
+{
+ struct appinfo_splash_image *splash_image = data;
+
+ if (splash_image == NULL)
+ return;
+
+ if (splash_image->color_depth)
+ free(splash_image->color_depth);
+ if (splash_image->indicatordisplay)
+ free(splash_image->indicatordisplay);
+ if (splash_image->type)
+ free(splash_image->type);
+ if (splash_image->src)
+ free(splash_image->src);
+ free(splash_image);
+}
+
+static void __free_user_appinfo(gpointer data)
+{
+ struct user_appinfo *info = (struct user_appinfo *)data;
+
+ g_hash_table_destroy(info->tbl);
+ free(info);
+}
+
+static int __read_background_category(const char *category_name,
+ void *user_data)
+{
+ struct appinfo *c = user_data;
+ int category = (intptr_t)(c->val[AIT_BG_CATEGORY]);
+
+ if (!category_name)
+ return 0;
+
+ if (strcmp(category_name, "disable") == 0) {
+ c->val[AIT_BG_CATEGORY] = 0x00;
+ return -1;
+ }
+
+ if (strcmp(category_name, "media") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_MEDIA));
+ } else if (strcmp(category_name, "download") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_DOWNLOAD));
+ } else if (strcmp(category_name, "background-network") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_BACKGROUND_NETWORK));
+ } else if (strcmp(category_name, "location") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_LOCATION));
+ } else if (strcmp(category_name, "sensor") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_SENSOR));
+ } else if (strcmp(category_name, "iot-communication") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_IOT_COMMUNICATION));
+ } else if (strcmp(category_name, "system") == 0) {
+ c->val[AIT_BG_CATEGORY] = (char *)((intptr_t)(category |
+ BACKGROUND_CATEGORY_SYSTEM));
+ }
+
+ return 0;
+}
+
+static void __appinfo_remove_splash_screen(void *data)
+{
+ struct appinfo_splash_screen *splash_screen =
+ (struct appinfo_splash_screen *)data;
+
+ if (splash_screen == NULL)
+ return;
+
+ if (splash_screen->portrait)
+ g_hash_table_destroy(splash_screen->portrait);
+ if (splash_screen->landscape)
+ g_hash_table_destroy(splash_screen->landscape);
+ free(splash_screen);
+}
+
+static int __appinfo_add_exec(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *exec = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get exec");
+ return -1;
+ }
+
+ info->val[AIT_EXEC] = strdup(exec);
+ if (info->val[AIT_EXEC] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_pkgtype(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *pkgtype = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_pkgtype(handle, &pkgtype);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get pkgtype");
+ return -1;
+ }
+
+ info->val[AIT_PKGTYPE] = strdup(pkgtype);
+ if (info->val[AIT_PKGTYPE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_onboot(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool onboot = false;
+
+ ret = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get onboot");
+ return -1;
+ }
+
+ info->val[AIT_ONBOOT] = strdup(onboot ? "true" : "false");
+ if (info->val[AIT_ONBOOT] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_restart(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool restart = false;
+
+ ret = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get restart");
+ return -1;
+ }
+
+ info->val[AIT_RESTART] = GINT_TO_POINTER(restart ? 1 : 0);
+
+ return 0;
+}
+
+static int __appinfo_add_multi(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool multiple = false;
+
+ ret = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get multiple");
+ return -1;
+ }
+
+ info->val[AIT_MULTI] = strdup(multiple ? "true" : "false");
+ if (info->val[AIT_MULTI] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_hwacc(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ pkgmgrinfo_app_hwacceleration hwacc;
+
+ ret = pkgmgrinfo_appinfo_get_hwacceleration(handle, &hwacc);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get hwacc");
+ return -1;
+ }
+
+ info->val[AIT_HWACC] = strdup(
+ (gles == 0 ||
+ hwacc == PMINFO_HWACCELERATION_OFF) ?
+ "NOT_USE" :
+ (hwacc == PMINFO_HWACCELERATION_ON) ?
+ "USE" :
+ "SYS");
+ if (info->val[AIT_HWACC] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_perm(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ pkgmgrinfo_permission_type permission;
+
+ ret = pkgmgrinfo_appinfo_get_permission_type(handle, &permission);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get permission type");
+ return -1;
+ }
+
+ info->val[AIT_PERM] = strdup(
+ (permission == PMINFO_PERMISSION_SIGNATURE) ?
+ "signature" :
+ (permission == PMINFO_PERMISSION_PRIVILEGE) ?
+ "privilege" :
+ "normal");
+ if (info->val[AIT_PERM] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_pkgid(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *pkgid = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get pkgid");
+ return -1;
+ }
+
+ info->val[AIT_PKGID] = strdup(pkgid);
+ if (info->val[AIT_PKGID] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_preload(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool preload = false;
+
+ ret = pkgmgrinfo_appinfo_is_preload(handle, &preload);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get preload");
+ return -1;
+ }
+
+ info->val[AIT_PRELOAD] = strdup(preload ? "true" : "false");
+ if (info->val[AIT_PRELOAD] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_status(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ info->val[AIT_STATUS] = strdup("installed");
+ if (info->val[AIT_STATUS] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_pool(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool process_pool = false;
+
+ ret = pkgmgrinfo_appinfo_is_process_pool(handle, &process_pool);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get process_pool");
+ return -1;
+ }
+
+ info->val[AIT_POOL] = strdup(process_pool ? "true" : "false");
+ if (info->val[AIT_POOL] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_comptype(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *component_type = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get component type");
+ return -1;
+ }
+
+ info->val[AIT_COMPTYPE] = strdup(component_type);
+ if (info->val[AIT_COMPTYPE] == NULL) {
+ _E("Ouf ot memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_tep(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ char *tep_name = NULL;
+
+ pkgmgrinfo_appinfo_get_tep_name(handle, &tep_name);
+ if (tep_name && strlen(tep_name) > 0) {
+ info->val[AIT_TEP] = strdup(tep_name);
+ if (info->val[AIT_TEP] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_mountable_pkg(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ char *tpk_name = NULL;
+
+ pkgmgrinfo_appinfo_get_zip_mount_file(handle, &tpk_name);
+ if (tpk_name && strlen(tpk_name) > 0) {
+ info->val[AIT_MOUNTABLE_PKG] = strdup(tpk_name);
+ if (info->val[AIT_MOUNTABLE_PKG] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_storage_type(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ pkgmgrinfo_installed_storage installed_storage;
+
+ ret = pkgmgrinfo_appinfo_get_installed_storage_location(handle,
+ &installed_storage);
+ if (ret == PMINFO_R_OK) {
+ if (installed_storage == PMINFO_INTERNAL_STORAGE)
+ info->val[AIT_STORAGE_TYPE] = strdup("internal");
+ else if (installed_storage == PMINFO_EXTERNAL_STORAGE)
+ info->val[AIT_STORAGE_TYPE] = strdup("external");
+ } else {
+ info->val[AIT_STORAGE_TYPE] = strdup("internal");
+ }
+
+ if (info->val[AIT_STORAGE_TYPE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_bg_category(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+
+ ret = pkgmgrinfo_appinfo_foreach_background_category(handle,
+ __read_background_category, info);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get background category");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_launch_mode(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *mode = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_launch_mode(handle, &mode);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get launch_mode");
+ return -1;
+ }
+
+ info->val[AIT_LAUNCH_MODE] = strdup(mode ? mode : "single");
+ if (info->val[AIT_LAUNCH_MODE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_global(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool is_global = false;
+
+ ret = pkgmgrinfo_appinfo_is_global(handle, &is_global);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get is_global info");
+ return -1;
+ }
+
+ info->val[AIT_GLOBAL] = strdup(is_global ? "true" : "false");
+ if (info->val[AIT_GLOBAL] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_effective_appid(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ char *effective_appid = NULL;
+
+ pkgmgrinfo_appinfo_get_effective_appid(handle, &effective_appid);
+ if (effective_appid && strlen(effective_appid) > 0) {
+ info->val[AIT_EFFECTIVE_APPID] = strdup(effective_appid);
+ if (info->val[AIT_EFFECTIVE_APPID] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_taskmanage(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool taskmanage = false;
+
+ ret = pkgmgrinfo_appinfo_is_taskmanage(handle, &taskmanage);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get taskmanage");
+ return -1;
+ }
+
+ info->val[AIT_TASKMANAGE] = strdup(taskmanage ? "true" : "false");
+ if (info->val[AIT_TASKMANAGE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_apptype(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *apptype = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_apptype(handle, &apptype);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get apptype");
+ return -1;
+ }
+
+ info->val[AIT_APPTYPE] = strdup(apptype);
+ if (info->val[AIT_APPTYPE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_root_path(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *path = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_root_path(handle, &path);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get root path");
+ return -1;
+ }
+
+ if (path) {
+ info->val[AIT_ROOT_PATH] = strdup(path);
+ if (info->val[AIT_ROOT_PATH] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int __add_splash_screen_list_cb(const char *src, const char *type,
+ const char *orientation, const char *indicatordisplay,
+ const char *operation, const char *color_depth, void *user_data)
+{
+ struct appinfo *info = (struct appinfo *)user_data;
+ struct appinfo_splash_screen *splash_screen;
+ struct appinfo_splash_image *splash_image;
+ char *key;
+
+ splash_image = (struct appinfo_splash_image *)calloc(1,
+ sizeof(struct appinfo_splash_image));
+ if (splash_image == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ splash_image->src = strdup(src);
+ if (splash_image->src == NULL) {
+ _E("Out of memory");
+ free(splash_image);
+ return -1;
+ }
+
+ splash_image->type = strdup(type);
+ if (splash_image->type == NULL) {
+ _E("Out of memory");
+ __free_appinfo_splash_image(splash_image);
+ return -1;
+ }
+
+ splash_image->indicatordisplay = strdup(indicatordisplay);
+ if (splash_image->indicatordisplay == NULL) {
+ _E("Out of memory");
+ __free_appinfo_splash_image(splash_image);
+ return -1;
+ }
+
+ splash_image->color_depth = strdup(color_depth);
+ if (splash_image->color_depth == NULL) {
+ _E("Out of memory");
+ __free_appinfo_splash_image(splash_image);
+ return -1;
+ }
+
+ key = strdup(operation);
+ if (key == NULL) {
+ _E("Out of memory");
+ __free_appinfo_splash_image(splash_image);
+ return -1;
+ }
+
+ splash_screen = (struct appinfo_splash_screen *)
+ info->val[AIT_SPLASH_SCREEN];
+ if (splash_screen == NULL) {
+ splash_screen = (struct appinfo_splash_screen *)calloc(1,
+ sizeof(struct appinfo_splash_screen));
+ if (splash_screen == NULL) {
+ _E("out of memory");
+ __free_appinfo_splash_image(splash_image);
+ free(key);
+ return -1;
+ }
+ info->val[AIT_SPLASH_SCREEN] = (char *)splash_screen;
+ }
+
+ if (strcasecmp(orientation, "portrait") == 0) {
+ if (splash_screen->portrait == NULL) {
+ splash_screen->portrait = g_hash_table_new_full(
+ g_str_hash, g_str_equal, free,
+ __free_appinfo_splash_image);
+ }
+ g_hash_table_insert(splash_screen->portrait, key, splash_image);
+ } else if (strcasecmp(orientation, "landscape") == 0) {
+ if (splash_screen->landscape == NULL) {
+ splash_screen->landscape = g_hash_table_new_full(
+ g_str_hash, g_str_equal, free,
+ __free_appinfo_splash_image);
+ }
+ g_hash_table_insert(splash_screen->landscape, key,
+ splash_image);
+ } else {
+ __free_appinfo_splash_image(splash_image);
+ free(key);
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_splash_screens(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+
+ ret = pkgmgrinfo_appinfo_foreach_splash_screen(handle,
+ __add_splash_screen_list_cb, info);
+ if (ret < 0) {
+ _E("Failed to get splash screen");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_splash_screen_display(
+ const pkgmgrinfo_appinfo_h handle, struct appinfo *info,
+ void *data)
+{
+ bool splash_screen_display = true;
+ int ret;
+
+ ret = pkgmgrinfo_appinfo_get_splash_screen_display(handle,
+ &splash_screen_display);
+ if (ret < 0)
+ _D("Failed to get splash screen display");
+
+ info->val[AIT_SPLASH_SCREEN_DISPLAY] =
+ GINT_TO_POINTER(splash_screen_display ? 1 : 0);
+
+ return 0;
+}
+
+static int __appinfo_add_api_version(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ char *api_version;
+
+ ret = pkgmgrinfo_appinfo_get_api_version(handle, &api_version);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get api version");
+ return -1;
+ }
+
+ info->val[AIT_API_VERSION] = strdup(api_version);
+ if (info->val[AIT_API_VERSION] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_enablement(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool disabled = false;
+
+ ret = pkgmgrinfo_appinfo_is_disabled(handle, &disabled);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get enablement");
+ return -1;
+ }
+
+ info->val[AIT_ENABLEMENT] = GINT_TO_POINTER(disabled ? 0 : 1);
+
+ return 0;
+}
+
+static int __appinfo_add_cooldown_mode(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ int support_mode = 0;
+
+ ret = pkgmgrinfo_appinfo_get_support_mode(handle, &support_mode);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get support mode value");
+ return -1;
+ }
+
+ if (support_mode & APP_SUPPORT_MODE_COOL_DOWN_VAL)
+ info->val[AIT_COOLDOWN] = strdup("true");
+ else
+ info->val[AIT_COOLDOWN] = strdup("false");
+ if (info->val[AIT_COOLDOWN] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_system(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool system = false;
+
+ ret = pkgmgrinfo_appinfo_is_system(handle, &system);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get support mode value");
+ return -1;
+ }
+
+ if (system)
+ info->val[AIT_SYSTEM] = strdup("true");
+ else
+ info->val[AIT_SYSTEM] = strdup("false");
+ if (info->val[AIT_SYSTEM] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_ime(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ int ret;
+ bool exist = false;
+
+ ret = pkgmgrinfo_appinfo_is_category_exist(handle, CATEGORY_IME,
+ &exist);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to check ime category");
+ return -1;
+ }
+
+ info->val[AIT_IME] = strdup(exist ? "true" : "false");
+ if (info->val[AIT_IME] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __appinfo_add_ignore(const pkgmgrinfo_appinfo_h handle,
+ struct appinfo *info, void *data)
+{
+ /*
+ * The default value of the ignore flag is "false".
+ * If the flag is 'true', AMD doesn't block the launch request.
+ */
+ info->val[AIT_IGNORE] = strdup("false");
+ if (info->val[AIT_IGNORE] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static appinfo_vft appinfo_table[AIT_MAX] = {
+ [AIT_NAME] = {
+ .constructor = NULL,
+ .destructor = NULL
+ },
+ [AIT_EXEC] = {
+ .constructor = __appinfo_add_exec,
+ .destructor = free
+ },
+ [AIT_PKGTYPE] = {
+ .constructor = __appinfo_add_pkgtype,
+ .destructor = free
+ },
+ [AIT_ONBOOT] = {
+ .constructor = __appinfo_add_onboot,
+ .destructor = free
+ },
+ [AIT_RESTART] = {
+ .constructor = __appinfo_add_restart,
+ .destructor = NULL
+ },
+ [AIT_MULTI] = {
+ .constructor = __appinfo_add_multi,
+ .destructor = free
+ },
+ [AIT_HWACC] = {
+ .constructor = __appinfo_add_hwacc,
+ .destructor = free
+ },
+ [AIT_PERM] = {
+ .constructor = __appinfo_add_perm,
+ .destructor = free
+ },
+ [AIT_PKGID] = {
+ .constructor = __appinfo_add_pkgid,
+ .destructor = free
+ },
+ [AIT_PRELOAD] = {
+ .constructor = __appinfo_add_preload,
+ .destructor = free
+ },
+ [AIT_STATUS] = {
+ .constructor = __appinfo_add_status,
+ .destructor = free
+ },
+ [AIT_POOL] = {
+ .constructor = __appinfo_add_pool,
+ .destructor = free
+ },
+ [AIT_COMPTYPE] = {
+ .constructor = __appinfo_add_comptype,
+ .destructor = free
+ },
+ [AIT_TEP] = {
+ .constructor = __appinfo_add_tep,
+ .destructor = free
+ },
+ [AIT_MOUNTABLE_PKG] = {
+ .constructor = __appinfo_add_mountable_pkg,
+ .destructor = free
+ },
+ [AIT_STORAGE_TYPE] = {
+ .constructor = __appinfo_add_storage_type,
+ .destructor = free
+ },
+ [AIT_BG_CATEGORY] = {
+ .constructor = __appinfo_add_bg_category,
+ .destructor = NULL
+ },
+ [AIT_LAUNCH_MODE] = {
+ .constructor = __appinfo_add_launch_mode,
+ .destructor = free
+ },
+ [AIT_GLOBAL] = {
+ .constructor = __appinfo_add_global,
+ .destructor = free
+ },
+ [AIT_EFFECTIVE_APPID] = {
+ .constructor = __appinfo_add_effective_appid,
+ .destructor = free
+ },
+ [AIT_TASKMANAGE] = {
+ .constructor = __appinfo_add_taskmanage,
+ .destructor = free
+ },
+ [AIT_VISIBILITY] = {
+ .constructor = NULL,
+ .destructor = free
+ },
+ [AIT_APPTYPE] = {
+ .constructor = __appinfo_add_apptype,
+ .destructor = free
+ },
+ [AIT_ROOT_PATH] = {
+ .constructor = __appinfo_add_root_path,
+ .destructor = free
+ },
+ [AIT_SPLASH_SCREEN] = {
+ .constructor = __appinfo_add_splash_screens,
+ .destructor = __appinfo_remove_splash_screen
+ },
+ [AIT_SPLASH_SCREEN_DISPLAY] = {
+ .constructor = __appinfo_add_splash_screen_display,
+ .destructor = NULL
+ },
+ [AIT_API_VERSION] = {
+ .constructor = __appinfo_add_api_version,
+ .destructor = free
+ },
+ [AIT_ENABLEMENT] = {
+ .constructor = __appinfo_add_enablement,
+ .destructor = NULL
+ },
+ [AIT_COOLDOWN] = {
+ .constructor = __appinfo_add_cooldown_mode,
+ .destructor = free
+ },
+ [AIT_SYSTEM] = {
+ .constructor = __appinfo_add_system,
+ .destructor = free
+ },
+ [AIT_IME] = {
+ .constructor = __appinfo_add_ime,
+ .destructor = free
+ },
+ [AIT_IGNORE] = {
+ .constructor = __appinfo_add_ignore,
+ .destructor = free
+ },
+};
+
+static void __appinfo_remove_handler(gpointer data)
+{
+ struct appinfo *c = data;
+ int i;
+
+ if (!c)
+ return;
+
+ for (i = AIT_START; i < AIT_MAX; i++) {
+ if (appinfo_table[i].destructor && c->val[i] != NULL)
+ appinfo_table[i].destructor(c->val[i]);
+ }
+
+ free(c);
+}
+
+static int __appinfo_insert_handler (const pkgmgrinfo_appinfo_h handle,
+ void *data)
+{
+ int i;
+ struct appinfo *c;
+ struct user_appinfo *info = (struct user_appinfo *)data;
+ char *appid;
+ int ret;
+ char err_buf[1024];
+
+ if (!handle || !info) {
+ _E("null app handle");
+ return -1;
+ }
+
+ if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK) {
+ _E("fail to get appinfo");
+ return -1;
+ }
+
+ g_hash_table_remove(info->tbl, appid);
+
+ c = calloc(1, sizeof(struct appinfo));
+ if (!c) {
+ _E("create appinfo: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return -1;
+ }
+
+ c->val[AIT_NAME] = strdup(appid);
+ if (c->val[AIT_NAME] == NULL) {
+ _E("Out of memory");
+ free(c);
+ return -1;
+ }
+
+ for (i = AIT_START; i < AIT_MAX; i++) {
+ if (appinfo_table[i].constructor) {
+ ret = appinfo_table[i].constructor(handle, c, info);
+ if (ret < 0) {
+ _E("failed to load appinfo of %s", appid);
+ __appinfo_remove_handler(c);
+ return 0;
+ }
+ }
+ }
+
+ SECURE_LOGD("%s : %s : %s : %s", c->val[AIT_NAME], c->val[AIT_COMPTYPE],
+ c->val[AIT_PKGTYPE], c->val[AIT_APPTYPE]);
+
+ g_hash_table_insert(info->tbl, c->val[AIT_NAME], c);
+ _app_property_insert(info->uid, c->val[AIT_NAME], handle);
+ _noti_send(AMD_NOTI_MSG_APPINFO_INSERT, info->uid, 0, handle, NULL);
+
+ return 0;
+}
+
+static int __appinfo_update_handler(const pkgmgrinfo_appinfo_h handle,
+ void *data)
+{
+ int i;
+ struct appinfo *c;
+ struct user_appinfo *info = (struct user_appinfo *)data;
+ char *appid;
+ int ret;
+ bool restart;
+ int auto_restart;
+
+ if (!handle || !info) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get appinfo");
+ return -1;
+ }
+
+ c = (struct appinfo *)g_hash_table_lookup(info->tbl, appid);
+ if (!c) {
+ c = calloc(1, sizeof(struct appinfo));
+ if (!c) {
+ _E("Failed to create appinfo(%s)", appid);
+ return -1;
+ }
+
+ c->val[AIT_NAME] = strdup(appid);
+ if (c->val[AIT_NAME] == NULL) {
+ _E("Out of memory");
+ free(c);
+ return -1;
+ }
+
+ g_hash_table_insert(info->tbl, c->val[AIT_NAME], c);
+ }
+
+ if (c->val[AIT_STATUS] && strcmp(c->val[AIT_STATUS], "restart") == 0)
+ restart = true;
+ else
+ restart = false;
+
+ _app_property_delete(info->uid, appid);
+ _noti_send(AMD_NOTI_MSG_APPINFO_REMOVE, info->uid, 0, appid, NULL);
+ for (i = AIT_START + 1; i < AIT_MAX; i++) {
+ if (appinfo_table[i].destructor && c->val[i])
+ appinfo_table[i].destructor(c->val[i]);
+ c->val[i] = NULL;
+
+ if (appinfo_table[i].constructor) {
+ ret = appinfo_table[i].constructor(handle, c, info);
+ if (ret < 0) {
+ g_hash_table_remove(info->tbl, appid);
+ return -1;
+ }
+ }
+ }
+ SECURE_LOGD("%s : %s : %s : %s",
+ c->val[AIT_NAME], c->val[AIT_COMPTYPE],
+ c->val[AIT_PKGTYPE], c->val[AIT_APPTYPE]);
+ _app_property_insert(info->uid, appid, handle);
+ _noti_send(AMD_NOTI_MSG_APPINFO_INSERT, info->uid, 0, handle, NULL);
+
+ auto_restart = GPOINTER_TO_INT(c->val[AIT_RESTART]);
+ if (auto_restart && restart)
+ _launch_start_app_local(info->uid, c->val[AIT_NAME]);
+ else
+ _launch_start_onboot_app_local(info->uid, c->val[AIT_NAME], c);
+
+ return 0;
+}
+
+static int __insert_appinfo(const pkgmgrinfo_appinfo_h handle, void *data)
+{
+ int ret;
+ struct appinfo *ai;
+ struct user_appinfo *info = (struct user_appinfo *)data;
+ char *appid = NULL;
+
+ ret = __appinfo_insert_handler(handle, data);
+ if (ret < 0)
+ return -1;
+
+ ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (ret != PMINFO_R_OK)
+ return -1;
+
+ ai = (struct appinfo *)g_hash_table_lookup(info->tbl, appid);
+ if (ai == NULL)
+ return -1;
+
+ _launch_start_onboot_app_local(info->uid, appid, ai);
+
+ return 0;
+}
+
+static void __remove_user_appinfo(uid_t uid)
+{
+ g_hash_table_remove(user_tbl, GINT_TO_POINTER(uid));
+}
+
+static struct user_appinfo *__add_user_appinfo(uid_t uid)
+{
+ int r;
+ struct user_appinfo *info;
+
+ info = calloc(1, sizeof(struct user_appinfo));
+ if (info == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ info->uid = uid;
+ info->tbl = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ __appinfo_remove_handler);
+ if (info->tbl == NULL) {
+ _E("out of memory");
+ free(info);
+ return NULL;
+ }
+
+ g_hash_table_insert(user_tbl, GINT_TO_POINTER(uid), info);
+
+ r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
+ __appinfo_insert_handler, uid,
+ PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
+ if (r != PMINFO_R_OK) {
+ __remove_user_appinfo(uid);
+ return NULL;
+ }
+
+ _D("loaded appinfo table for uid %d", uid);
+
+ return info;
+}
+
+static struct user_appinfo *__find_user_appinfo(uid_t uid)
+{
+ return g_hash_table_lookup(user_tbl, GINT_TO_POINTER(uid));
+}
+
+static void __appinfo_set_blocking_cb(void *user_data,
+ const char *appid, struct appinfo *info)
+{
+ struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
+
+ if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
+ return;
+
+ if (pkg_info->target_uid == GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "false"))
+ return;
+ else if (pkg_info->target_uid != GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "true"))
+ return;
+
+ free(info->val[AIT_STATUS]);
+ info->val[AIT_STATUS] = strdup("blocking");
+ _D("%s status changed: blocking", appid);
+}
+
+static void __appinfo_unset_blocking_cb(void *user_data,
+ const char *appid, struct appinfo *info)
+{
+ struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
+
+ if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
+ return;
+
+ if (pkg_info->target_uid == GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "false"))
+ return;
+ else if (pkg_info->target_uid != GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "true"))
+ return;
+
+ free(info->val[AIT_STATUS]);
+ info->val[AIT_STATUS] = strdup("installed");
+ if (info->val[AIT_STATUS] == NULL)
+ _W("Out of memory");
+ _D("%s status changed: installed", appid);
+}
+
+static void __appinfo_restart_cb(void *user_data,
+ const char *appid, struct appinfo *info)
+{
+ bool restart;
+ int auto_restart;
+ struct pkg_event_info *pkg_info = (struct pkg_event_info *)user_data;
+
+ if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
+ return;
+
+ if (info->val[AIT_STATUS] && !strcmp(info->val[AIT_STATUS], "restart"))
+ restart = true;
+ else
+ restart = false;
+
+ __appinfo_unset_blocking_cb(user_data, appid, info);
+
+ auto_restart = GPOINTER_TO_INT(info->val[AIT_RESTART]);
+ if (auto_restart && restart)
+ _launch_start_app_local(pkg_info->uid, info->val[AIT_NAME]);
+}
+
+static gboolean __appinfo_remove_cb(gpointer key, gpointer value, gpointer data)
+{
+ struct pkg_event_info *pkg_info = (struct pkg_event_info *)data;
+ struct appinfo *info = (struct appinfo *)value;
+
+ if (strcmp(info->val[AIT_PKGID], pkg_info->pkgid))
+ return FALSE;
+
+ if (pkg_info->target_uid == GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "false"))
+ return FALSE;
+ else if (pkg_info->target_uid != GLOBAL_USER &&
+ !strcmp(info->val[AIT_GLOBAL], "true"))
+ return FALSE;
+
+ _app_property_delete(GPOINTER_TO_UINT(key), info->val[AIT_NAME]);
+ _noti_send("appnifo.remove", GPOINTER_TO_UINT(key), 0,
+ info->val[AIT_NAME], NULL);
+
+ _D("appinfo removed: %s", info->val[AIT_NAME]);
+ return TRUE;
+}
+
+static void __appinfo_delete_on_event(uid_t uid, void *data)
+{
+ struct user_appinfo *info;
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("cannot find appinfo for uid %d", uid);
+ return;
+ }
+
+ g_hash_table_foreach_remove(info->tbl, __appinfo_remove_cb,
+ (gpointer)data);
+}
+
+static void __appinfo_insert_on_event(uid_t uid, const char *pkgid)
+{
+ _appinfo_insert(uid, pkgid);
+}
+
+static void __appinfo_update_on_event(uid_t uid, void *data)
+{
+ struct pkg_event_info *pkg_info = (struct pkg_event_info *)data;
+ struct user_appinfo *info;
+ pkgmgrinfo_pkginfo_h handle;
+ int ret;
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("cannot find appinfo for uid %d", uid);
+ return;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_info->pkgid, uid, &handle);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to get pkginfo(%s)", pkg_info->pkgid);
+ return;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
+ __appinfo_update_handler, info, info->uid);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to update pkginfo(%s)", pkg_info->pkgid);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return;
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+}
+
+static void __set_blocking(struct pkg_event_info *info)
+{
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ if (info->target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++) {
+ _appinfo_foreach(uids[i],
+ __appinfo_set_blocking_cb, info);
+ _D("terminate apps by PackageID - %s", info->pkgid);
+ _app_status_terminate_apps_by_pkgid(info->pkgid,
+ uids[i]);
+ }
+ free(uids);
+
+ return;
+ }
+
+ _appinfo_foreach(info->target_uid, __appinfo_set_blocking_cb, info);
+ _D("terminate apps by PackageID - %s", info->pkgid);
+ _app_status_terminate_apps_by_pkgid(info->pkgid, info->target_uid);
+}
+
+static void __unset_blocking(struct pkg_event_info *info, bool restart)
+{
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ if (info->target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++) {
+ if (restart) {
+ info->uid = uids[i];
+ _appinfo_foreach(uids[i],
+ __appinfo_restart_cb, info);
+ } else {
+ _appinfo_foreach(uids[i],
+ __appinfo_unset_blocking_cb,
+ info);
+ }
+ }
+ free(uids);
+
+ return;
+ }
+
+ if (restart) {
+ info->uid = info->target_uid;
+ _appinfo_foreach(info->target_uid,
+ __appinfo_restart_cb, info);
+ } else {
+ _appinfo_foreach(info->target_uid,
+ __appinfo_unset_blocking_cb, info);
+ }
+}
+
+static void __delete_on_event(struct pkg_event_info *info)
+{
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ if (info->target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++)
+ __appinfo_delete_on_event(uids[i], info);
+ free(uids);
+
+ return;
+ }
+
+ __appinfo_delete_on_event(info->target_uid, info);
+}
+
+static void __insert_on_event(struct pkg_event_info *info)
+{
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ if (info->target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++)
+ __appinfo_insert_on_event(uids[i], info->pkgid);
+ free(uids);
+
+ return;
+ }
+
+ __appinfo_insert_on_event(info->target_uid, info->pkgid);
+}
+
+static void __update_on_event(struct pkg_event_info *info)
+{
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ if (info->target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++)
+ __appinfo_update_on_event(uids[i], info);
+ free(uids);
+
+ return;
+ }
+
+ __appinfo_update_on_event(info->target_uid, info);
+}
+
+static int __appinfo_is_pkg_exist(uid_t uid, const char *pkgid)
+{
+ int r;
+ struct user_appinfo *info;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ uid_t *uids = NULL;
+ struct appinfo *ai;
+
+ if (pkgid == NULL)
+ return 0;
+
+ if (uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return 0;
+
+ uid = uids[0];
+
+ free(uids);
+ }
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("cannot find appinfo for uid %d", uid);
+ return 0;
+ }
+
+ g_hash_table_iter_init(&iter, info->tbl);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ ai = (struct appinfo *)value;
+ if (strcmp(pkgid, ai->val[AIT_PKGID]) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void __appinfo_enable_pkg_apps(uid_t uid, const char *pkgid, int enable)
+{
+ int r;
+ int i;
+ struct user_appinfo *info;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ uid_t *uids = NULL;
+ struct appinfo *ai;
+ int prev_val;
+ const char *appid;
+
+ if (pkgid == NULL)
+ return;
+
+ if (uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; i++)
+ __appinfo_enable_pkg_apps(uids[i], pkgid, enable);
+
+ free(uids);
+
+ return;
+ }
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("cannot find appinfo for uid %d", uid);
+ return;
+ }
+
+ g_hash_table_iter_init(&iter, info->tbl);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ ai = (struct appinfo *)value;
+ if (strcmp(pkgid, ai->val[AIT_PKGID]) == 0) {
+ _appinfo_get_int_value(ai, AIT_ENABLEMENT, &prev_val);
+ _appinfo_set_int_value(ai, AIT_ENABLEMENT, enable);
+ if (prev_val == 0 && enable == 1) {
+ appid = _appinfo_get_value(ai, AIT_NAME);
+ _launch_start_onboot_app_local(uid, appid, ai);
+ }
+ }
+ }
+}
+
+static int __package_event_cb(uid_t target_uid, int req_id,
+ const char *pkg_type, const char *pkgid,
+ const char *key, const char *val, const void *pmsg, void *data)
+{
+ int ret;
+ char *op;
+ struct pkg_event_info info = {
+ .target_uid = target_uid,
+ .pkgid = pkgid
+ };
+ pkgmgrinfo_pkginfo_h pkginfo;
+
+ if (!strcasecmp(key, "start")) {
+ if (!strcasecmp(val, "uninstall") ||
+ !strcasecmp(val, "update") ||
+ !strcasecmp(val, "move")) {
+ _W("[__PKGMGR__] Package(%s) event(%s) - start",
+ pkgid, val);
+ __set_blocking(&info);
+ }
+
+ g_hash_table_insert(pkg_pending, strdup(pkgid), strdup(val));
+ }
+
+ if (!strcasecmp(key, "error")) {
+ op = g_hash_table_lookup(pkg_pending, pkgid);
+ if (op == NULL)
+ return 0;
+
+ if (!strcasecmp(op, "uninstall") ||
+ !strcasecmp(op, "update") ||
+ !strcasecmp(op, "move")) {
+ _W("[__PKGMGR__] Package(%s) event(%s) - error",
+ pkgid, val);
+ __unset_blocking(&info, true);
+ _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
+ target_uid, 0, (void *)pkgid, NULL);
+ }
+
+ g_hash_table_remove(pkg_pending, pkgid);
+ }
+
+ if (!strcasecmp(key, "end")) {
+ _W("[__PKGMGR__] Package(%s) event(%s) - end", pkgid, val);
+ op = g_hash_table_lookup(pkg_pending, pkgid);
+ if (op == NULL)
+ return 0;
+
+ if (!strcasecmp(op, "uninstall")) {
+ ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(
+ info.pkgid, info.target_uid,
+ &pkginfo);
+ if (ret == PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+ __unset_blocking(&info, false);
+ __appinfo_enable_pkg_apps(info.target_uid,
+ info.pkgid, 0);
+ } else {
+ __delete_on_event(&info);
+ }
+ _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END,
+ target_uid, 0, (void *)pkgid, NULL);
+ } else if (!strcasecmp(op, "install")) {
+ if (!__appinfo_is_pkg_exist(
+ info.target_uid,
+ info.pkgid)) {
+ __insert_on_event(&info);
+ } else {
+ __unset_blocking(&info, false);
+ __appinfo_enable_pkg_apps(info.target_uid,
+ info.pkgid, 1);
+ }
+ _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END,
+ target_uid, 0, (void *)pkgid, NULL);
+ } else if (!strcasecmp(op, "update") ||
+ !strcasecmp(op, "move")) {
+ __update_on_event(&info);
+ _noti_send(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
+ target_uid, 0, (void *)pkgid, NULL);
+ }
+
+ g_hash_table_remove(pkg_pending, pkgid);
+ }
+
+ return 0;
+}
+
+static void __add_app_event_info(int req_id, int type, uid_t uid)
+{
+ struct app_event_info *info;
+
+ info = (struct app_event_info *)malloc(sizeof(struct app_event_info));
+ if (info == NULL) {
+ _E("Out of memory");
+ return;
+ }
+
+ info->req_id = req_id;
+ info->type = type;
+ info->uid = uid;
+
+ app_event_list = g_list_append(app_event_list, (gpointer)info);
+}
+
+static struct app_event_info *__find_app_event_info(int req_id, uid_t uid)
+{
+ GList *iter;
+ struct app_event_info *info;
+
+ iter = g_list_first(app_event_list);
+ while (iter) {
+ info = (struct app_event_info *)iter->data;
+ if (info && info->req_id == req_id && info->uid == uid)
+ return info;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static void __remove_app_event_info(struct app_event_info *info)
+{
+ if (info == NULL)
+ return;
+
+ app_event_list = g_list_remove(app_event_list, info);
+ free(info);
+}
+
+static void __handle_app_event_start(const char *event_name,
+ struct appinfo *ai, const char *appid, int req_id, uid_t uid)
+{
+ int old = 0;
+
+ if (!strcasecmp(event_name, "enable_global_app_for_uid") ||
+ !strcasecmp(event_name, "enable_app")) {
+ if (ai) {
+ _appinfo_get_int_value(ai, AIT_ENABLEMENT, &old);
+ old |= APP_ENABLEMENT_MASK_REQUEST;
+ _appinfo_set_int_value(ai, AIT_ENABLEMENT, old);
+ }
+ __add_app_event_info(req_id, AIT_ENABLEMENT, uid);
+ } else if (!strcasecmp(event_name, "disable_global_app_for_uid") ||
+ !strcasecmp(event_name, "disable_app")) {
+ __add_app_event_info(req_id, AIT_ENABLEMENT, uid);
+ } else if (!strcasecmp(event_name, "enable_app_splash_screen")) {
+ if (ai) {
+ _appinfo_get_int_value(ai, AIT_SPLASH_SCREEN_DISPLAY,
+ &old);
+ old |= APP_ENABLEMENT_MASK_REQUEST;
+ _appinfo_set_int_value(ai, AIT_SPLASH_SCREEN_DISPLAY,
+ old);
+ }
+ __add_app_event_info(req_id, AIT_SPLASH_SCREEN_DISPLAY, uid);
+ } else if (!strcasecmp(event_name, "disable_app_splash_screen")) {
+ __add_app_event_info(req_id, AIT_SPLASH_SCREEN_DISPLAY, uid);
+ }
+}
+
+static void __handle_app_event_end(const char *event_name,
+ struct appinfo *ai, const char *appid, int req_id, uid_t uid)
+{
+ pkgmgrinfo_appinfo_h handle;
+ struct user_appinfo *info;
+ struct app_event_info *ei;
+ int old = 0;
+ int r;
+
+ ei = __find_app_event_info(req_id, uid);
+ if (ei == NULL)
+ return;
+
+ if (!strcasecmp(event_name, "ok")) {
+ if (ei->type == AIT_ENABLEMENT) {
+ if (ai) {
+ _appinfo_get_int_value(ai, ei->type, &old);
+ old >>= 1;
+ _appinfo_set_int_value(ai, ei->type, old);
+ } else {
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("Failed to load appinfo(%d)", uid);
+ __remove_app_event_info(ei);
+ return;
+ }
+
+ r = pkgmgrinfo_appinfo_get_usr_appinfo(appid,
+ uid, &handle);
+ if (r != PMINFO_R_OK) {
+ _E("Failed to get appinfo(%s)", appid);
+ __remove_app_event_info(ei);
+ return;
+ }
+
+ _I("add the new appinfo(%s)", appid);
+ __insert_appinfo(handle, info);
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+ __remove_app_event_info(ei);
+ _noti_send(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
+ uid, 0, (void *)appid, NULL);
+ return;
+ }
+
+ if (!(old & APP_ENABLEMENT_MASK_ACTIVE)) {
+ _E("terminate apps: %s(%d)", appid, uid);
+ _app_status_terminate_apps(appid, uid);
+ _noti_send(AMD_NOTI_MSG_APPINFO_APP_DISABLED_END,
+ uid, 0, (void *)appid, NULL);
+ } else if (old & APP_ENABLEMENT_MASK_ACTIVE) {
+ _launch_start_onboot_app_local(uid, appid, ai);
+ _noti_send(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
+ uid, 0, (void *)appid, NULL);
+ }
+ } else if (ei->type == AIT_SPLASH_SCREEN_DISPLAY) {
+ if (ai) {
+ _appinfo_get_int_value(ai, ei->type, &old);
+ old >>= 1;
+ _appinfo_set_int_value(ai, ei->type, old);
+ }
+ }
+ } else if (!strcasecmp(event_name, "fail")) {
+ if (ei->type == AIT_ENABLEMENT ||
+ ei->type == AIT_SPLASH_SCREEN_DISPLAY) {
+ if (ai) {
+ _appinfo_get_int_value(ai, ei->type, &old);
+ old &= APP_ENABLEMENT_MASK_ACTIVE;
+ _appinfo_set_int_value(ai, ei->type, old);
+ }
+ }
+ }
+ __remove_app_event_info(ei);
+}
+
+static int __package_app_event_cb(uid_t target_uid, int req_id,
+ const char *pkg_type, const char *pkgid, const char *appid,
+ const char *key, const char *val, const void *pmsg, void *data)
+{
+ struct appinfo *ai;
+ uid_t *uids = NULL;
+ int r;
+ int i;
+
+ _D("appid:%s, key:%s, val:%s, req_id: %d, target_uid: %d",
+ appid, key, val, req_id, target_uid);
+ if (target_uid < REGULAR_UID_MIN) {
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return 0;
+ } else {
+ r = 1;
+ }
+
+ for (i = 0; i < r; i++) {
+ if (uids)
+ target_uid = uids[i];
+ ai = _appinfo_find(target_uid, appid);
+
+ if (!strcasecmp(key, "start")) {
+ __handle_app_event_start(val, ai, appid, req_id,
+ target_uid);
+ } else if (!strcasecmp(key, "end")) {
+ __handle_app_event_end(val, ai, appid, req_id,
+ target_uid);
+ }
+ }
+
+ free(uids);
+ return 0;
+}
+
+static int __init_package_event_handler(void *data)
+{
+ int ret;
+
+ pc = pkgmgr_client_new(PC_LISTENING);
+ if (pc == NULL)
+ return -1;
+
+ ret = pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_ALL);
+ if (ret < 0)
+ return -1;
+
+ ret = pkgmgr_client_listen_status(pc, __package_event_cb, NULL);
+ if (ret < 0)
+ return -1;
+
+ ret = pkgmgr_client_listen_app_status(pc, __package_app_event_cb, NULL);
+ if (ret < 0)
+ return -1;
+
+ _W("[__PKGMGR__] Package event handler is initialized");
+ return 0;
+}
+
+static void __fini_package_event_handler(void)
+{
+ pkgmgr_client_free(pc);
+}
+
+static void __reload_appinfo(gpointer key, gpointer value, gpointer user_data)
+{
+ int r;
+ struct user_appinfo *info = (struct user_appinfo *)value;
+
+ g_hash_table_remove_all(info->tbl);
+
+ r = pkgmgrinfo_appinfo_get_usr_installed_list_full(
+ __appinfo_insert_handler, info->uid,
+ PMINFO_APPINFO_GET_SPLASH_SCREEN, info);
+ if (r != PMINFO_R_OK) {
+ __remove_user_appinfo(info->uid);
+ return;
+ }
+
+ _noti_send(AMD_NOTI_MSG_APPINFO_RELOAD, (int)info->uid, 0, NULL, NULL);
+ _D("reloaded appinfo table for uid %d", info->uid);
+}
+
+static int __dispatch_amd_reload_appinfo(request_h req)
+{
+ _D("AMD_RELOAD_APPINFO");
+ g_hash_table_foreach(user_tbl, __reload_appinfo, NULL);
+ _request_send_result(req, 0);
+
+ return 0;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = AMD_RELOAD_APPINFO,
+ .callback = __dispatch_amd_reload_appinfo
+ },
+};
+
+int _appinfo_init(void)
+{
+ FILE *fp;
+ char buf[LINE_MAX];
+ char *tmp;
+ int r;
+
+ fp = fopen("/proc/cmdline", "r");
+ if (fp == NULL) {
+ _E("appinfo init failed: %d", errno);
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), fp) != NULL) {
+ tmp = strstr(buf, "gles");
+ if (tmp != NULL) {
+ if (sscanf(tmp, "gles=%d", &gles) != 1)
+ _D("Failed to convert format");
+ }
+ }
+ fclose(fp);
+
+ user_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+ __free_user_appinfo);
+ if (user_tbl == NULL)
+ return -1;
+
+ pkg_pending = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+ if (pkg_pending == NULL)
+ return -1;
+
+ _signal_add_ready_cb(__init_package_event_handler, NULL);
+
+ r = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _appinfo_fini(void)
+{
+ __fini_package_event_handler();
+ g_hash_table_destroy(user_tbl);
+ g_hash_table_destroy(pkg_pending);
+}
+
+struct appinfo *_appinfo_find(uid_t caller_uid, const char *appid)
+{
+ struct user_appinfo *info;
+
+ if (appid == NULL) {
+ _W("appid is NULL");
+ return NULL;
+ }
+
+ /* search from user table */
+ info = __find_user_appinfo(caller_uid);
+ if (info == NULL)
+ return NULL;
+
+ return g_hash_table_lookup(info->tbl, appid);
+}
+
+int _appinfo_insert(uid_t uid, const char *pkgid)
+{
+ int ret;
+ struct user_appinfo *info;
+ pkgmgrinfo_pkginfo_h handle;
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _E("load appinfo for uid %d failed", uid);
+ return -1;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
+ if (ret != PMINFO_R_OK) {
+ _E("get pkginfo failed: %s", pkgid);
+ return -1;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
+ __insert_appinfo, info, info->uid);
+ if (ret != PMINFO_R_OK) {
+ _E("add appinfo of pkg %s failed", pkgid);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return -1;
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+ return 0;
+}
+
+const char *_appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
+{
+ if (!c) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return NULL;
+
+ return c->val[type];
+}
+
+const void *_appinfo_get_ptr_value(const struct appinfo *c,
+ enum appinfo_type type)
+{
+ if (!c) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return NULL;
+
+ return c->val[type];
+}
+
+int _appinfo_get_int_value(const struct appinfo *c, enum appinfo_type type,
+ int *val)
+{
+ if (!c) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return -1;
+
+ *val = GPOINTER_TO_INT(c->val[type]);
+
+ return 0;
+}
+
+int _appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type,
+ bool *val)
+{
+ if (!c || type < AIT_START || type >= AIT_MAX || c->val[type] == NULL) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (!strcmp(c->val[type], "true") || !strcmp(c->val[type], "1")) {
+ *val = true;
+ } else if (!strcmp(c->val[type], "false") ||
+ !strcmp(c->val[type], "0")) {
+ *val = false;
+ } else {
+ _E("Unexpected appinfo field value");
+ return -1;
+ }
+
+ return 0;
+}
+
+int _appinfo_set_value(struct appinfo *c, enum appinfo_type type,
+ const char *val)
+{
+ if (!c || !val) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return -1;
+
+ _D("%s : %s : %s", c->val[AIT_NAME], c->val[type], val);
+ if (c->val[type])
+ free(c->val[type]);
+
+ c->val[type] = strdup(val);
+ if (c->val[type] == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+int _appinfo_set_ptr_value(struct appinfo *c, enum appinfo_type type, void *val)
+{
+ if (!c || !val) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return -1;
+
+ _D("%s : %p : %p", c->val[AIT_NAME], c->val[type], val);
+ if (appinfo_table[type].destructor && c->val[type] != NULL)
+ appinfo_table[type].destructor(c->val[type]);
+
+ c->val[type] = (char *)val;
+ return 0;
+}
+
+int _appinfo_set_int_value(struct appinfo *c, enum appinfo_type type, int val)
+{
+ if (!c) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (type < AIT_START || type >= AIT_MAX)
+ return -1;
+
+ _D("%s : %p : %d", c->val[AIT_NAME], c->val[type], val);
+
+ c->val[type] = (char *)GINT_TO_POINTER(val);
+ return 0;
+}
+
+static void __iter_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ struct callback_info *cb_info = user_data;
+
+ if (cb_info == NULL)
+ return;
+
+ cb_info->cb(cb_info->user_data, key, value);
+}
+
+void _appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data)
+{
+ struct user_appinfo *info;
+ struct callback_info cb_info = {
+ .cb = cb,
+ .user_data = user_data
+ };
+
+ if (!cb) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL)
+ return;
+
+ g_hash_table_foreach(info->tbl, __iter_cb, &cb_info);
+}
+
+int _appinfo_load(uid_t uid)
+{
+ struct user_appinfo *info;
+
+ info = __find_user_appinfo(uid);
+ if (info) {
+ _D("%d appinfo already exists", uid);
+ return 0;
+ }
+
+ info = __add_user_appinfo(uid);
+ if (info == NULL) {
+ _W("Failed to load appinfo - %d", uid);
+ return -1;
+ }
+
+ _noti_send(AMD_NOTI_MSG_APPINFO_LOAD, (int)uid, 0, NULL, NULL);
+ _D("loaded appinfo table for uid(%d)", uid);
+ return 0;
+}
+
+void _appinfo_unload(uid_t uid)
+{
+ struct user_appinfo *info;
+
+ info = __find_user_appinfo(uid);
+ if (info == NULL) {
+ _D("%d appinfo doesn't exist", uid);
+ return;
+ }
+
+ __remove_user_appinfo(uid);
+ _noti_send(AMD_NOTI_MSG_APPINFO_UNLOAD, (int)uid, 0, NULL, NULL);
+ _D("unloaded appinfo table for uid(%d)", uid);
+}
+
+struct appinfo_splash_image *_appinfo_find_splash_image(struct appinfo *c,
+ const char *name, bool landscape)
+{
+ struct appinfo_splash_screen *splash_screen;
+
+ if (!c || !name) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ splash_screen = (struct appinfo_splash_screen *)_appinfo_get_value(c,
+ AIT_SPLASH_SCREEN);
+ if (!splash_screen)
+ return NULL;
+
+ if (landscape)
+ return g_hash_table_lookup(splash_screen->landscape, name);
+
+ return g_hash_table_lookup(splash_screen->portrait, name);
+}
+
+const char *_appinfo_splash_image_get_source(struct appinfo_splash_image *s)
+{
+ if (!s) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ return s->src;
+}
+
+const char *_appinfo_splash_image_get_type(struct appinfo_splash_image *s)
+{
+ if (!s) {
+ _E("Invalid paramter");
+ return NULL;
+ }
+
+ return s->type;
+}
+
+int _appinfo_splash_image_get_indicator_display(struct appinfo_splash_image *s)
+{
+ if (!s) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (!strcmp(s->indicatordisplay, "true"))
+ return 1;
+
+ return 0;
+}
+
+int _appinfo_splash_image_get_color_depth(struct appinfo_splash_image *s)
+{
+ int color_depth = 24; /* default */
+
+ if (!s) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (isdigit(s->color_depth[0]))
+ color_depth = atoi(s->color_depth);
+
+ return color_depth;
+}
+
+bool _appinfo_is_pkg_updating(const char *pkgid)
+{
+ char *op;
+
+ if (pkg_pending == NULL)
+ return false;
+
+ op = g_hash_table_lookup(pkg_pending, pkgid);
+ if (op != NULL && !strcasecmp(op, "update"))
+ return true;
+
+ return false;
+}
+
+static char *__get_cert_value_from_pkginfo(const char *pkgid, uid_t uid)
+{
+ int ret;
+ const char *cert_value;
+ char *ret_cert;
+ pkgmgrinfo_certinfo_h certinfo;
+
+ ret = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to create certinfo");
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to load certinfo");
+ pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
+ PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
+ if (ret != PMINFO_R_OK || cert_value == NULL) {
+ _E("Failed to get cert value");
+ pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+ return NULL;
+ }
+
+ ret_cert = strdup(cert_value);
+ pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+
+ return ret_cert;
+}
+
+static int __get_visibility_from_certsvc(const char *cert_value)
+{
+ int ret;
+ CertSvcInstance instance;
+ CertSvcCertificate certificate;
+ CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
+
+ if (cert_value == NULL)
+ return (int)visibility;
+
+ ret = certsvc_instance_new(&instance);
+ if (ret != CERTSVC_SUCCESS) {
+ _E("certsvc_instance_new() is failed.");
+ return (int)visibility;
+ }
+
+ ret = certsvc_certificate_new_from_memory(instance,
+ (const unsigned char *)cert_value,
+ strlen(cert_value),
+ CERTSVC_FORM_DER_BASE64,
+ &certificate);
+ if (ret != CERTSVC_SUCCESS) {
+ _E("certsvc_certificate_new_from_memory() is failed.");
+ certsvc_instance_free(instance);
+ return (int)visibility;
+ }
+
+ ret = certsvc_certificate_get_visibility(certificate, &visibility);
+ if (ret != CERTSVC_SUCCESS)
+ _E("certsvc_certificate_get_visibility() is failed.");
+
+ certsvc_certificate_free(certificate);
+ certsvc_instance_free(instance);
+
+ return (int)visibility;
+}
+
+int _appinfo_get_cert_visibility(const char *pkgid, uid_t uid)
+{
+ char *cert_value;
+ int r;
+
+ cert_value = __get_cert_value_from_pkginfo(pkgid, uid);
+ r = __get_visibility_from_certsvc(cert_value);
+
+ if (cert_value)
+ free(cert_value);
+
+ return r;
+}
+
+bool _appinfo_is_platform_app(const char *appid, uid_t uid)
+{
+ struct appinfo *ai;
+ const char *pkgid;
+ const char *v;
+ int vi_num;
+ int visibility;
+ char num[12];
+
+ ai = _appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ v = _appinfo_get_value(ai, AIT_VISIBILITY);
+ if (!v) {
+ pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ vi_num = _appinfo_get_cert_visibility(pkgid, uid);
+ snprintf(num, sizeof(num), "%d", vi_num);
+ _appinfo_set_value(ai, AIT_VISIBILITY, num);
+ v = num;
+ }
+
+ visibility = atoi(v);
+ if (visibility & CERTSVC_VISIBILITY_PLATFORM)
+ return true;
+
+ return false;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_APPINFO_H__
+#define __AMD_APPINFO_H__
+
+#include <sys/types.h>
+#include <glib.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AIT_START 0
+enum appinfo_type {
+ AIT_NAME = AIT_START,
+ AIT_EXEC,
+ AIT_PKGTYPE,
+ AIT_ONBOOT, /* start on boot: boolean */
+ AIT_RESTART, /* auto restart: boolean */
+ AIT_MULTI,
+ AIT_HWACC,
+ AIT_PERM,
+ AIT_PKGID,
+ AIT_PRELOAD,
+ AIT_STATUS,
+ AIT_POOL,
+ AIT_COMPTYPE,
+ AIT_TEP,
+ AIT_MOUNTABLE_PKG,
+ AIT_STORAGE_TYPE,
+ AIT_BG_CATEGORY,
+ AIT_LAUNCH_MODE,
+ AIT_GLOBAL,
+ AIT_EFFECTIVE_APPID,
+ AIT_TASKMANAGE,
+ AIT_VISIBILITY,
+ AIT_APPTYPE,
+ AIT_ROOT_PATH,
+ AIT_SPLASH_SCREEN,
+ AIT_SPLASH_SCREEN_DISPLAY,
+ AIT_API_VERSION,
+ AIT_ENABLEMENT,
+ AIT_COOLDOWN,
+ AIT_SYSTEM,
+ AIT_IME,
+ AIT_IGNORE,
+ AIT_MAX
+};
+
+struct appinfo {
+ char *val[AIT_MAX];
+};
+
+struct appinfo_splash_screen {
+ GHashTable *portrait;
+ GHashTable *landscape;
+};
+
+struct appinfo_splash_image {
+ char *src;
+ char *type;
+ char *indicatordisplay;
+ char *color_depth;
+};
+
+#define APP_TYPE_SERVICE "svcapp"
+
+#define APP_TYPE_UI "uiapp"
+
+#define APP_TYPE_WIDGET "widgetapp"
+
+#define APP_TYPE_WATCH "watchapp"
+
+#define APP_TYPE_COMPONENT_BASED "componentbasedapp"
+
+#define APP_ENABLEMENT_MASK_ACTIVE 0x1
+
+#define APP_ENABLEMENT_MASK_REQUEST 0x2
+
+typedef void (*appinfo_iter_callback)(void *user_data, const char *filename,
+ struct appinfo *c);
+
+int _appinfo_init(void);
+
+void _appinfo_fini(void);
+
+int _appinfo_insert(uid_t uid, const char *pkgid);
+
+struct appinfo *_appinfo_find(uid_t caller_uid, const char *appid);
+
+const char *_appinfo_get_value(const struct appinfo *c, enum appinfo_type type);
+
+const void *_appinfo_get_ptr_value(const struct appinfo *c,
+ enum appinfo_type type);
+
+int _appinfo_get_int_value(const struct appinfo *c, enum appinfo_type type,
+ int *val);
+
+int _appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type,
+ bool *val);
+
+int _appinfo_set_value(struct appinfo *c, enum appinfo_type, const char *val);
+
+int _appinfo_set_ptr_value(struct appinfo *c, enum appinfo_type, void *val);
+
+int _appinfo_set_int_value(struct appinfo *c, enum appinfo_type type, int val);
+
+void _appinfo_foreach(uid_t uid, appinfo_iter_callback cb, void *user_data);
+
+int _appinfo_load(uid_t uid);
+
+void _appinfo_unload(uid_t uid);
+
+struct appinfo_splash_image *_appinfo_find_splash_image(struct appinfo *c,
+ const char *name, bool landscape);
+
+const char *_appinfo_splash_image_get_source(struct appinfo_splash_image *s);
+
+const char *_appinfo_splash_image_get_type(struct appinfo_splash_image *s);
+
+int _appinfo_splash_image_get_indicator_display(struct appinfo_splash_image *s);
+
+int _appinfo_splash_image_get_color_depth(struct appinfo_splash_image *s);
+
+bool _appinfo_is_pkg_updating(const char *pkgid);
+
+int _appinfo_get_cert_visibility(const char *pkgid, uid_t uid);
+
+bool _appinfo_is_platform_app(const char *appid, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_APPINFO_H__ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include "amd_app_property.h"
+#include "amd_app_status.h"
+#include "amd_appinfo.h"
+#include "amd_boot_manager.h"
+#include "amd_config.h"
+#include "amd_launch.h"
+#include "amd_signal.h"
+#include "amd_util.h"
+#include "app_signal.h"
+
+#define METADATA_KEY_ONBOOT_PRIORITY \
+ "http://tizen.org/metadata/on-boot/priority"
+#define MIN_PRIORITY 1
+#define MAX_PRIORITY 99
+
+struct onboot_appinfo_s {
+ char *app_id;
+ uid_t uid;
+ int priority;
+};
+
+static GList *__onboot_list;
+
+static void __destroy_onboot_appinfo(gpointer data)
+{
+ struct onboot_appinfo_s *info = data;
+
+ if (!info)
+ return;
+
+ free(info->app_id);
+ free(info);
+}
+
+static struct onboot_appinfo_s *__create_onboot_appinfo(const char *app_id,
+ uid_t uid, int priority)
+{
+ struct onboot_appinfo_s *info;
+
+ info = calloc(1, sizeof(struct onboot_appinfo_s));
+ if (!info) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->app_id = strdup(app_id);
+ if (!info->app_id) {
+ _E("Failed to duplicate application ID(%s)", app_id);
+ __destroy_onboot_appinfo(info);
+ return NULL;
+ }
+
+ info->uid = uid;
+ info->priority = priority;
+
+ return info;
+}
+
+static gboolean __unlock_display_state(gpointer data)
+{
+ _W("Unlock display state");
+ _signal_send_display_unlock_state(SYSTEM_LCD_OFF, SYSTEM_SLEEP_MARGIN);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean __delay_start_onboot_apps(gpointer data)
+{
+ struct onboot_appinfo_s *info = data;
+ app_status_h app_status;
+ int pid = -1;
+
+ if (!info) {
+ _E("Critical error!");
+ return G_SOURCE_REMOVE;
+ }
+
+ app_status = _app_status_find_by_appid(info->app_id, info->uid);
+ if (app_status)
+ pid = _app_status_is_running(app_status);
+
+ if (pid < 0)
+ pid = _launch_start_app_local(info->uid, info->app_id);
+
+ _W("app_id(%s), pid(%d), uid(%u), priority(%d)",
+ info->app_id, pid, info->uid, info->priority);
+ __destroy_onboot_appinfo(info);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gint __compare_priority(gconstpointer a, gconstpointer b)
+{
+ struct onboot_appinfo_s *info_a = (struct onboot_appinfo_s *)a;
+ struct onboot_appinfo_s *info_b = (struct onboot_appinfo_s *)b;
+
+ if (info_a->priority < info_b->priority)
+ return 1;
+
+ if (info_a->priority > info_b->priority)
+ return -1;
+
+ return 0;
+}
+
+static int __metadata_foreach_cb(const char *value, void *user_data)
+{
+ int *priority = (int *)user_data;
+
+ if (!value)
+ return 0;
+
+ *priority = atoi(value);
+ return -1;
+}
+
+static int __get_priority(const char *app_id, uid_t uid)
+{
+ app_property_h app_property;
+ int priority = MIN_PRIORITY;
+
+ app_property = _app_property_find(uid);
+ if (!app_property)
+ return priority;
+
+ _app_property_metadata_foreach(app_property, app_id,
+ METADATA_KEY_ONBOOT_PRIORITY,
+ __metadata_foreach_cb,
+ (void *)&priority);
+
+ if (priority < MIN_PRIORITY)
+ priority = MIN_PRIORITY;
+ else if (priority > MAX_PRIORITY)
+ priority = MAX_PRIORITY;
+
+ return priority;
+}
+
+static bool __appinfo_check_onboot_cond(struct appinfo *ai)
+{
+ const char *comp_type;
+ const char *onboot;
+
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type == NULL || strcmp(comp_type, APP_TYPE_SERVICE) != 0)
+ return false;
+
+ onboot = _appinfo_get_value(ai, AIT_ONBOOT);
+ if (onboot == NULL || strcmp(onboot, "true") != 0)
+ return false;
+
+ return true;
+}
+
+static void __appinfo_foreach_cb(void *data, const char *app_id,
+ struct appinfo *ai)
+{
+ uid_t uid = GPOINTER_TO_UINT(data);
+ app_status_h app_status;
+ struct onboot_appinfo_s *info;
+ int priority;
+
+ if (!__appinfo_check_onboot_cond(ai))
+ return;
+
+ app_status = _app_status_find_by_appid(app_id, uid);
+ if (_app_status_is_running(app_status) > 0)
+ return;
+
+ priority = __get_priority(app_id, uid);
+ info = __create_onboot_appinfo(app_id, uid, priority);
+ if (!info)
+ return;
+
+ __onboot_list = g_list_append(__onboot_list, info);
+}
+
+static gboolean __load_onboot_apps(gpointer data)
+{
+#define MAX_ONBOOT_INTERVAL 18000
+ GList *iter;
+ guint d = 0;
+ guint i = 0;
+ guint idle_interval;
+ guint interval = 0;
+ guint len;
+ guint max_len;
+ struct onboot_appinfo_s *info;
+ uid_t uid = GPOINTER_TO_UINT(data);
+
+ _W("Onboot uid(%u)", uid);
+ _appinfo_foreach(uid, __appinfo_foreach_cb, data);
+
+ if (!__onboot_list) {
+ _signal_send_display_unlock_state(SYSTEM_LCD_OFF,
+ SYSTEM_SLEEP_MARGIN);
+ return G_SOURCE_REMOVE;
+ }
+
+ __onboot_list = g_list_sort(__onboot_list, __compare_priority);
+
+ idle_interval = MAX_ONBOOT_INTERVAL - _config_get_onboot_interval();
+
+ max_len = idle_interval / _config_get_onboot_interval();
+ len = g_list_length(__onboot_list);
+ if (len > max_len)
+ d = _config_get_onboot_interval() / (len - max_len);
+
+ iter = __onboot_list;
+ while (iter) {
+ info = (struct onboot_appinfo_s *)iter->data;
+ iter = g_list_next(iter);
+
+ if (interval >= idle_interval)
+ interval += d;
+ else
+ interval = _config_get_onboot_interval() * i++;
+
+ g_timeout_add(interval, __delay_start_onboot_apps, info);
+ __onboot_list = g_list_remove(__onboot_list, info);
+ if (!__onboot_list) {
+ g_timeout_add(interval + 5000, __unlock_display_state,
+ NULL);
+ }
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+int _boot_manager_start_onboot_apps(uid_t uid)
+{
+ _I("Lock display state");
+ _signal_send_display_lock_state(SYSTEM_LCD_OFF,
+ SYSTEM_STAY_CUR_STATE, 0);
+ g_idle_add(__load_onboot_apps, GUINT_TO_POINTER(uid));
+
+ return 0;
+}
+
+int _boot_manager_init(void)
+{
+ int ret;
+
+ _W("AMD_BOOT_MANAGER_INIT");
+
+ ret = _app_property_metadata_add_filter(METADATA_KEY_ONBOOT_PRIORITY,
+ NULL);
+ if (ret < 0) {
+ _E("Failed to add metadata filter");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _boot_manager_fini(void)
+{
+ _W("AMD_BOOT_MANAGER_FINI");
+ if (__onboot_list)
+ g_list_free_full(__onboot_list, __destroy_onboot_appinfo);
+}
--- /dev/null
+/*
+ * 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_BOOT_MANAGER_H__
+#define __AMD_BOOT_MANAGER_H__
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _boot_manager_start_onboot_apps(uid_t uid);
+
+int _boot_manager_init(void);
+
+void _boot_manager_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_BOOT_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <uuid/uuid.h>
+
+#include <glib.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_sock.h>
+#include <bundle_internal.h>
+
+#include "amd_api_noti.h"
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_request.h"
+#include "amd_noti.h"
+#include "amd_compinfo.h"
+#include "amd_comp_status.h"
+#include "amd_socket.h"
+#include "amd_app_status.h"
+#include "amd_launch.h"
+#include "amd_cynara.h"
+
+struct comp_status_s {
+ char *comp_id;
+ char *instance_id;
+ char *leader_instance_id;
+ pid_t pid;
+ int comp_type;
+ int window;
+ int status;
+ bool is_subcomp;
+ bool started;
+};
+
+static GList *__comp_list;
+
+const char *_comp_status_generate_instance(const char *comp_id)
+{
+ static char buf[MAX_PACKAGE_STR_SIZE];
+ char uuid[37];
+ uuid_t u;
+
+ if (!comp_id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ uuid_generate(u);
+ uuid_unparse(u, uuid);
+ snprintf(buf, sizeof(buf), "%s:%s", uuid, comp_id);
+ return buf;
+}
+
+static void __destroy_comp_status(gpointer data)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)data;
+
+ if (!comp_status)
+ return;
+
+ if (comp_status->instance_id)
+ free(comp_status->instance_id);
+ if (comp_status->comp_id)
+ free(comp_status->comp_id);
+ free(comp_status);
+}
+
+static int __convert_comp_type(const char *type)
+{
+ if (!type)
+ return -1;
+
+ if (!strcmp(type, "frame"))
+ return CT_FRAME_COMP;
+ else if (!strcmp(type, "service"))
+ return CT_SERVICE_COMP;
+
+ return -1;
+}
+
+static const char *__get_comp_type_string(int comp_type)
+{
+ switch (comp_type) {
+ case CT_FRAME_COMP:
+ return "frame";
+ case CT_SERVICE_COMP:
+ return "service";
+ default:
+ return "Unknown";
+ }
+}
+
+static struct comp_status_s *__create_comp_status(compinfo_h ci,
+ const char *instance_id, pid_t pid, bool is_subcomp)
+{
+ struct comp_status_s *comp_status;
+ const char *comp_id;
+ const char *type;
+
+ comp_status = calloc(1, sizeof(struct comp_status_s));
+ if (!comp_status) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ comp_id = _compinfo_get_value(ci, CIT_NAME);
+ if (!comp_id) {
+ _E("Failed to get component ID");
+ free(comp_status);
+ return NULL;
+ }
+
+ comp_status->comp_id = strdup(comp_id);
+ if (!comp_status->comp_id) {
+ _E("Failed to duplicate component ID(%s)", comp_id);
+ __destroy_comp_status(comp_status);
+ return NULL;
+ }
+
+ comp_status->instance_id = strdup(instance_id);
+ if (!comp_status->instance_id) {
+ _E("Failed to duplicate instance ID(%s)", instance_id);
+ __destroy_comp_status(comp_status);
+ return NULL;
+ }
+
+ comp_status->pid = pid;
+ comp_status->is_subcomp = is_subcomp;
+ comp_status->started = false;
+
+ type = _compinfo_get_value(ci, CIT_TYPE);
+ comp_status->comp_type = __convert_comp_type(type);
+ comp_status->status = COMP_STATUS_INITIALIZED;
+
+ return comp_status;
+}
+
+static gint __compare_window(gconstpointer a, gconstpointer b)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)a;
+ int window = GPOINTER_TO_INT(b);
+
+ return (comp_status->window != window);
+}
+
+static gint __compare_instance(gconstpointer a, gconstpointer b)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)a;
+ const char *instance_id = (const char *)b;
+
+ return strcmp(comp_status->instance_id, instance_id);
+}
+
+int _comp_status_add_comp_info(compinfo_h ci, pid_t pid,
+ const char *instance_id, bool is_subcomp)
+{
+ struct comp_status_s *comp_status;
+ GList *found;
+
+ if (!ci || pid < 0 || !instance_id)
+ return -1;
+
+ found = g_list_find_custom(__comp_list, instance_id,
+ __compare_instance);
+ if (found) {
+ _D("Already exists. %d:%s", pid, instance_id);
+ return 0;
+ }
+
+ comp_status = __create_comp_status(ci, instance_id, pid, is_subcomp);
+ if (!comp_status) {
+ _E("Failed to create component status. %d:%s",
+ pid, instance_id);
+ return -1;
+ }
+
+ __comp_list = g_list_append(__comp_list, comp_status);
+
+ _noti_send(AMD_NOTI_MSG_COMP_STATUS_ADD, 0, 0, (void *)comp_status, NULL);
+
+ return 0;
+}
+
+comp_status_h _comp_status_find(const char *comp_id)
+{
+ struct comp_status_s *comp_status;
+ GList *iter;
+
+ if (!comp_id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ iter = __comp_list;
+ while (iter) {
+ comp_status = (struct comp_status_s *)iter->data;
+ if (!comp_status->is_subcomp &&
+ !strcmp(comp_status->comp_id, comp_id))
+ return comp_status;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+comp_status_h _comp_status_find_by_instance_id(const char *instance_id)
+{
+ GList *found;
+
+ if (!instance_id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ found = g_list_find_custom(__comp_list, instance_id,
+ __compare_instance);
+ if (!found)
+ return NULL;
+
+ return found->data;
+}
+
+comp_status_h _comp_status_find_by_window(int window)
+{
+ GList *found;
+
+ if (window <= 0) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ found = g_list_find_custom(__comp_list, GINT_TO_POINTER(window),
+ __compare_window);
+ if (!found)
+ return NULL;
+
+ return found->data;
+}
+
+comp_status_h _comp_status_find_v2(pid_t pid, const char *instance_id)
+{
+ struct comp_status_s *comp_status;
+ pid_t pgid;
+
+ comp_status = _comp_status_find_by_instance_id(instance_id);
+ if (!comp_status)
+ return NULL;
+
+ if (comp_status->pid != pid) {
+ pgid = getpgid(pid);
+ if (comp_status->pid == pgid) {
+ _E("Process ID(%d:%d) is not equal to %d",
+ pid, pgid, comp_status->pid);
+ return NULL;
+ }
+ }
+
+ return comp_status;
+}
+
+pid_t _comp_status_get_pid(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return -1;
+
+ return comp_status->pid;
+}
+
+const char *_comp_status_get_comp_id(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return NULL;
+
+ return comp_status->comp_id;
+}
+
+const char *_comp_status_get_instance_id(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return NULL;
+
+ return comp_status->instance_id;
+}
+
+int _comp_status_set_leader_id(comp_status_h h, const char *instance_id)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status || instance_id == NULL)
+ return -1;
+
+ if (comp_status->leader_instance_id) {
+ free(comp_status->leader_instance_id);
+ comp_status->leader_instance_id = NULL;
+ }
+
+ comp_status->leader_instance_id = strdup(instance_id);
+ if (comp_status->leader_instance_id == NULL) {
+ _E("Fail to dup id");
+ return -1;
+ }
+
+ return 0;
+}
+
+int _comp_status_set_window(comp_status_h h, int window)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return -1;
+
+ if (window <= 0)
+ return -1;
+
+ comp_status->window = window;
+
+ return 0;
+}
+
+const char *_comp_status_get_leader_id(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return NULL;
+
+ return comp_status->leader_instance_id;
+}
+
+int _comp_status_get_comp_type(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return -1;
+
+ return comp_status->comp_type;
+}
+
+int _comp_status_get_status(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return -1;
+
+ return comp_status->status;
+}
+
+bool _comp_status_is_running(comp_status_h h)
+{
+ struct comp_status_s *comp_status = (struct comp_status_s *)h;
+
+ if (!comp_status)
+ return false;
+
+ if (comp_status->status == COMP_STATUS_DESTROYED)
+ return false;
+
+ return true;
+}
+
+static int __on_main_app_dead(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *b)
+{
+ struct comp_status_s *comp_status;
+ pid_t pid = (pid_t)arg1;
+ GList *iter;
+
+ iter = __comp_list;
+ while (iter) {
+ comp_status = (struct comp_status_s *)iter->data;
+ iter = g_list_next(iter);
+ if (comp_status->pid == pid) {
+ __comp_list = g_list_remove(__comp_list, comp_status);
+ __destroy_comp_status(comp_status);
+ }
+ }
+
+ return NOTI_CONTINUE;
+}
+
+static int __dispatch_comp_notify_start(request_h req)
+{
+ struct comp_status_s *comp_status;
+ pid_t pid = _request_get_pid(req);
+ bundle *b = _request_get_bundle(req);
+ const char *instance_id;
+
+ if (!b) {
+ _E("Failed to get bundle. pid(%d)", pid);
+ return -1;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ comp_status = _comp_status_find_v2(pid, instance_id);
+ if (!comp_status) {
+ _E("Failed to find component status. pid(%d)", pid);
+ return -1;
+ }
+
+ comp_status->started = true;
+
+ _W("[COMP_NOTIFY_START] pid(%d), instance_id(%s)", pid, instance_id);
+
+ return 0;
+}
+
+static int __dispatch_comp_notify_exit(request_h req)
+{
+ struct comp_status_s *comp_status;
+ pid_t pid = _request_get_pid(req);
+ uid_t uid = _request_get_uid(req);
+ bundle *b = _request_get_bundle(req);
+ const char *instance_id;
+
+ if (!b) {
+ _E("Failed to get bundle. pid(%d)", pid);
+ return -1;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ comp_status = _comp_status_find_v2(pid, instance_id);
+ if (!comp_status) {
+ _E("Failed to find component status. pid(%d)", pid);
+ return -1;
+ }
+
+ __comp_list = g_list_remove(__comp_list, comp_status);
+ __destroy_comp_status(comp_status);
+
+ _noti_send(AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT, (int)pid, (int)uid,
+ (void *)instance_id, NULL);
+
+ _W("[COMP_NOTIFY_EXIT] pid(%d), instance_id(%s)", pid, instance_id);
+
+ return 0;
+}
+
+static int __dispatch_comp_status_update(request_h req)
+{
+ struct comp_status_s *comp_status;
+ pid_t pid = _request_get_pid(req);
+ bundle *b = _request_get_bundle(req);
+ const char *instance_id;
+ const char *status_str;
+ bool update_group_info = false;
+ int status;
+
+ if (!b) {
+ _E("Failed to get bundle. pid(%d)", pid);
+ return -1;
+ }
+
+ status_str = bundle_get_val(b, AUL_K_STATUS);
+ if (!status_str) {
+ _E("Invalid request. pid(%d)", pid);
+ return -1;
+ }
+
+ status = atoi(status_str);
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ comp_status = _comp_status_find_v2(pid, instance_id);
+ if (!comp_status) {
+ _E("Failed to find component status. pid(%d)", pid);
+ return -1;
+ }
+
+ comp_status->status = status;
+
+ if (comp_status->comp_type == CT_FRAME_COMP)
+ update_group_info = true;
+
+ _noti_send(AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END,
+ pid, update_group_info, comp_status, NULL);
+
+ _W("[COMP_STATUS_UPDATE] pid(%d), instance(%s), status(%d)",
+ pid, instance_id, comp_status->status);
+
+ return 0;
+}
+
+static bundle *__create_compinfo_bundle(struct comp_status_s *comp_status)
+{
+ char buf[MAX_PID_STR_BUFSZ];
+ const char *comp_type;
+ const char *appid = NULL;
+ app_status_h app_status;
+ bundle *b;
+
+ b = bundle_create();
+ if (!b)
+ return NULL;
+
+ app_status = _app_status_find_v2(comp_status->pid);
+ if (app_status)
+ appid = _app_status_get_appid(app_status);
+
+ if (appid)
+ bundle_add(b, AUL_K_APPID, appid);
+
+ bundle_add(b, AUL_K_COMPONENT_ID, comp_status->comp_id);
+ bundle_add(b, AUL_K_INSTANCE_ID, comp_status->instance_id);
+
+ snprintf(buf, sizeof(buf), "%d", comp_status->pid);
+ bundle_add(b, AUL_K_PID, buf);
+
+ comp_type = __get_comp_type_string(comp_status->comp_type);
+ bundle_add(b, AUL_K_COMPONENT_TYPE, comp_type);
+
+ snprintf(buf, sizeof(buf), "%d", comp_status->status);
+ bundle_add(b, AUL_K_STATUS, buf);
+
+ snprintf(buf, sizeof(buf), "%d", comp_status->is_subcomp);
+ bundle_add(b, AUL_K_IS_SUB_COMP, buf);
+
+ return b;
+}
+
+static int __send_running_compinfo(struct comp_status_s *comp_status, int fd)
+{
+ bundle *b;
+ int ret;
+
+ b = __create_compinfo_bundle(comp_status);
+ if (!b) {
+ _E("Out of memory");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_ASYNC);
+ return -1;
+ }
+
+ ret = aul_sock_send_bundle_with_fd(fd, APP_GET_INFO_OK, b,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send bundle data. error(%d)", ret);
+ bundle_free(b);
+ return -1;
+ }
+ bundle_free(b);
+
+ return 0;
+}
+
+static int __dispatch_comp_context_foreach(request_h req)
+{
+ struct comp_status_s *comp_status;
+ int fd = _request_remove_fd(req);
+ GList *iter;
+ int count;
+ int ret;
+
+ count = g_list_length(__comp_list);
+ if (count == 0) {
+ _E("Components are not running");
+ _send_result_to_client(fd, -ENOENT);
+ return -1;
+ }
+ _send_result_to_client_v2(fd, count);
+
+ for (iter = __comp_list; iter; iter = g_list_next(iter)) {
+ comp_status = (struct comp_status_s *)iter->data;
+ if (!comp_status)
+ continue;
+
+ ret = __send_running_compinfo(comp_status, fd);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+ }
+ close(fd);
+
+ return 0;
+}
+
+static int __dispatch_comp_context_get(request_h req)
+{
+ struct comp_status_s *comp_status;
+ bundle *b = _request_get_bundle(req);
+ int fd = _request_remove_fd(req);
+ const char *comp_id;
+ int ret;
+
+ if (!b) {
+ _E("Invalid parameter");
+ aul_sock_send_raw_with_fd(fd, AUL_R_EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ comp_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
+ if (!comp_id) {
+ _E("Failed to get component ID");
+ aul_sock_send_raw_with_fd(fd, AUL_R_EINVAL, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ comp_status = _comp_status_find(comp_id);
+ if (!comp_status) {
+ _E("Failed to find running component(%s) context",
+ comp_id);
+ aul_sock_send_raw_with_fd(fd, AUL_R_ENOENT, NULL, 0,
+ AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ ret = __send_running_compinfo(comp_status, fd);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ return 0;
+}
+
+static int __dispatch_comp_context_is_running(request_h req)
+{
+ struct comp_status_s *comp_status;
+ bundle *b = _request_get_bundle(req);
+ const char *instance_id;
+ int is_running;
+
+ if (!b) {
+ _E("Invalid parameter");
+ _request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!instance_id) {
+ _E("Failed to get instance ID");
+ _request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ comp_status = _comp_status_find_by_instance_id(instance_id);
+ is_running = (int)_comp_status_is_running(comp_status);
+ _request_send_result(req, is_running);
+ _I("[COMP_CONTEXT_IS_RUNNING] is_running(%s)",
+ is_running ? "true" : "false");
+
+ return 0;
+}
+
+static int __comp_context_process(request_h req)
+{
+ struct comp_status_s *comp_status;
+ bundle *b = _request_get_bundle(req);
+ const char *instance_id;
+ int cmd;
+ int ret;
+
+ if (!b) {
+ _E("Invalid parameter");
+ _request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!instance_id) {
+ _E("Failed to get instance ID");
+ _request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ comp_status = _comp_status_find_by_instance_id(instance_id);
+ if (!comp_status) {
+ _E("Failed to find running context. instance(%s)", instance_id);
+ _request_send_result(req, -ENOENT);
+ return -1;
+ }
+
+ cmd = _request_get_cmd(req);
+ switch (cmd) {
+ case COMP_CONTEXT_RESUME:
+ case COMP_CONTEXT_PAUSE:
+ aul_send_app_resume_request_signal(comp_status->pid, NULL,
+ NULL, NULL);
+ break;
+ case COMP_CONTEXT_TERMINATE_BG_COMP:
+ case COMP_CONTEXT_TERMINATE:
+ aul_send_app_terminate_request_signal(comp_status->pid, NULL,
+ NULL, NULL);
+ break;
+ default:
+ break;
+ }
+
+ switch (cmd) {
+ case COMP_CONTEXT_RESUME:
+ ret = _launch_resume_inst(comp_status->pid, req);
+ break;
+ case COMP_CONTEXT_PAUSE:
+ ret = _launch_pause_inst(comp_status->pid, req);
+ break;
+ case COMP_CONTEXT_TERMINATE_BG_COMP:
+ ret = _launch_terminate_bg_inst(comp_status->pid, req);
+ break;
+ case COMP_CONTEXT_TERMINATE:
+ ret = _launch_terminate_inst(comp_status->pid, req);
+ break;
+ default:
+ _E("Unknown command: %d", cmd);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int __dispatch_comp_context_resume(request_h req)
+{
+ return __comp_context_process(req);
+}
+
+static int __dispatch_comp_context_pause(request_h req)
+{
+ return __comp_context_process(req);
+}
+
+static int __dispatch_comp_context_terminate_bg_comp(request_h req)
+{
+ int fd = _request_remove_fd(req);
+ int ret;
+
+ ret = __comp_context_process(req);
+ _send_result_to_client(fd, ret);
+
+ return ret;
+}
+
+static int __dispatch_comp_context_terminate(request_h req)
+{
+ int fd = _request_remove_fd(req);
+ int ret;
+
+ ret = __comp_context_process(req);
+ _send_result_to_client(fd, ret);
+
+ return ret;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = COMP_NOTIFY_START,
+ .callback = __dispatch_comp_notify_start
+ },
+ {
+ .cmd = COMP_NOTIFY_EXIT,
+ .callback = __dispatch_comp_notify_exit
+ },
+ {
+ .cmd = COMP_STATUS_UPDATE,
+ .callback = __dispatch_comp_status_update
+ },
+ {
+ .cmd = COMP_CONTEXT_FOREACH,
+ .callback = __dispatch_comp_context_foreach
+ },
+ {
+ .cmd = COMP_CONTEXT_GET,
+ .callback = __dispatch_comp_context_get
+ },
+ {
+ .cmd = COMP_CONTEXT_IS_RUNNING,
+ .callback = __dispatch_comp_context_is_running
+ },
+ {
+ .cmd = COMP_CONTEXT_RESUME,
+ .callback = __dispatch_comp_context_resume
+ },
+ {
+ .cmd = COMP_CONTEXT_PAUSE,
+ .callback = __dispatch_comp_context_pause
+ },
+ {
+ .cmd = COMP_CONTEXT_TERMINATE_BG_COMP,
+ .callback = __dispatch_comp_context_terminate_bg_comp
+ },
+ {
+ .cmd = COMP_CONTEXT_TERMINATE,
+ .callback = __dispatch_comp_context_terminate
+ },
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = COMP_CONTEXT_RESUME,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = COMP_CONTEXT_PAUSE,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = COMP_CONTEXT_TERMINATE_BG_COMP,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL_BGAPP
+ },
+ {
+ .cmd = COMP_CONTEXT_TERMINATE,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = COMP_CONTEXT_GET,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_PACKAGEMANAGER_INFO
+ },
+ {
+ .cmd = COMP_CONTEXT_FOREACH,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_PACKAGEMANAGER_INFO
+ }
+};
+
+int _comp_status_init(void)
+{
+ int ret;
+
+ _D("Component status init");
+
+ ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register commands");
+ return -1;
+ }
+
+ ret = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register cynara checkers");
+ return -1;
+ }
+
+ _noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD, __on_main_app_dead);
+
+ return 0;
+}
+
+void _comp_status_fini(void)
+{
+ _D("Component status fini");
+ if (__comp_list)
+ g_list_free_full(__comp_list, __destroy_comp_status);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_COMP_STATUS_H__
+#define __AMD_COMP_STATUS_H__
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <aul_comp_types.h>
+
+#include "amd_compinfo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *comp_status_h;
+
+typedef enum {
+ CT_FRAME_COMP,
+ CT_SERVICE_COMP,
+} comp_type_e;
+
+const char *_comp_status_generate_instance(const char *comp_id);
+
+int _comp_status_add_comp_info(compinfo_h ci, pid_t pid,
+ const char *instance_id, bool is_subcomp);
+
+comp_status_h _comp_status_find(const char *comp_id);
+
+comp_status_h _comp_status_find_by_instance_id(const char *instance_id);
+
+comp_status_h _comp_status_find_by_window(int window);
+
+comp_status_h _comp_status_find_v2(pid_t pid, const char *instance_id);
+
+pid_t _comp_status_get_pid(comp_status_h h);
+
+const char *_comp_status_get_comp_id(comp_status_h h);
+
+const char *_comp_status_get_instance_id(comp_status_h h);
+
+int _comp_status_get_comp_type(comp_status_h h);
+
+const char *_comp_status_get_leader_id(comp_status_h h);
+
+int _comp_status_set_leader_id(comp_status_h h, const char *instance_id);
+
+int _comp_status_get_status(comp_status_h h);
+
+int _comp_status_set_window(comp_status_h h, int window);
+
+bool _comp_status_is_running(comp_status_h h);
+
+int _comp_status_init(void);
+
+void _comp_status_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_COMP_STATUS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <glib.h>
+#include <dirent.h>
+#include <pkgmgr-info.h>
+#include <aul_comp_info_internal.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <bundle_internal.h>
+
+#include "amd_api_noti.h"
+#include "amd_util.h"
+#include "amd_appinfo.h"
+#include "amd_compinfo.h"
+#include "amd_noti.h"
+#include "amd_cynara.h"
+#include "amd_request.h"
+#include "amd_socket.h"
+
+struct compinfo_s {
+ char *val[CIT_MAX];
+};
+
+struct compinfo_localized_info_s {
+ char *locale;
+ char *icon;
+ char *label;
+};
+
+typedef int (*compinfo_handler_add_cb)(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data);
+typedef void (*compinfo_handler_remove_cb)(void *data);
+
+typedef struct _compinfo_vft {
+ compinfo_handler_add_cb constructor;
+ compinfo_handler_remove_cb destructor;
+} compinfo_vft;
+
+struct user_compinfo_s {
+ uid_t uid;
+ GHashTable *tbl;
+};
+
+struct cb_info_s {
+ compinfo_foreach_cb callback;
+ void *user_data;
+};
+
+static GHashTable *__user_table;
+
+static int __compinfo_add_appid(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ const char *appid;
+ int ret;
+
+ ret = aul_compinfo_get_app_id(handle, &appid);
+ if (ret != 0) {
+ _E("Failed to get appid");
+ return -1;
+ }
+
+ info->val[CIT_APPID] = strdup(appid);
+ if (!info->val[CIT_APPID]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __compinfo_add_taskmanage(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ int ret;
+ bool is_taskmanage;
+
+ ret = aul_compinfo_is_taskmanage(handle, &is_taskmanage);
+ if (ret != 0) {
+ _E("Failed to get taskmanage");
+ return -1;
+ }
+
+ info->val[CIT_TASKMANAGE] =
+ is_taskmanage ? strdup("true") : strdup("false");
+ if (!info->val[CIT_TASKMANAGE]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __compinfo_add_type(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ const char *type;
+ int ret;
+
+ ret = aul_compinfo_get_type(handle, &type);
+ if (ret != 0) {
+ _E("Failed to get component type");
+ return -1;
+ }
+
+ info->val[CIT_TYPE] = strdup(type);
+ if (!info->val[CIT_TYPE]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __compinfo_add_launch_mode(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ const char *launch_mode;
+ int ret;
+
+ ret = aul_compinfo_get_launch_mode(handle, &launch_mode);
+ if (ret != 0) {
+ _E("Failed to get launch mode");
+ return -1;
+ }
+
+ info->val[CIT_LAUNCH_MODE] = strdup(launch_mode);
+ if (!info->val[CIT_LAUNCH_MODE]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __compinfo_add_main(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ bool is_main = false;
+ int ret;
+
+ ret = aul_compinfo_is_main_comp(handle, &is_main);
+ if (ret != 0) {
+ _E("Failed to check whether the component is main or not");
+ return -1;
+ }
+
+ info->val[CIT_MAIN] = strdup(is_main ? "true" : "false");
+ if (!info->val[CIT_MAIN]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __compinfo_add_icon_display(aul_compinfo_h handle,
+ struct compinfo_s *info, void *data)
+{
+ bool icon_display = false;
+ int ret;
+
+ ret = aul_compinfo_is_icon_display(handle, &icon_display);
+ if (ret != 0) {
+ _E("Failed to check the icon display");
+ return -1;
+ }
+
+ info->val[CIT_ICON_DISPLAY] = strdup(icon_display ? "true" : "false");
+ if (!info->val[CIT_ICON_DISPLAY]) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ return 0;
+}
+
+static compinfo_vft compinfo_table[CIT_MAX] = {
+ [CIT_NAME] = {
+ .constructor = NULL,
+ .destructor = NULL
+ },
+ [CIT_APPID] = {
+ .constructor = __compinfo_add_appid,
+ .destructor = free
+ },
+ [CIT_TASKMANAGE] = {
+ .constructor = __compinfo_add_taskmanage,
+ .destructor = free
+ },
+ [CIT_TYPE] = {
+ .constructor = __compinfo_add_type,
+ .destructor = free
+ },
+ [CIT_LAUNCH_MODE] = {
+ .constructor = __compinfo_add_launch_mode,
+ .destructor = free
+ },
+ [CIT_MAIN] = {
+ .constructor = __compinfo_add_main,
+ .destructor = free
+ },
+ [CIT_ICON_DISPLAY] = {
+ .constructor = __compinfo_add_icon_display,
+ .destructor = free
+ },
+};
+
+static void __compinfo_remove_handler(gpointer data)
+{
+ struct compinfo_s *info = (struct compinfo_s *)data;
+ int i;
+
+ if (!info)
+ return;
+
+ for (i = CIT_START; i < CIT_MAX; i++) {
+ if (compinfo_table[i].destructor && info->val[i] != NULL)
+ compinfo_table[i].destructor(info->val[i]);
+ }
+
+ free(info);
+}
+
+static bool __compinfo_insert_handler(aul_compinfo_h handle, void *data)
+{
+ struct user_compinfo_s *user_info = (struct user_compinfo_s *)data;
+ struct compinfo_s *info;
+ const char *comp_id;
+ int r;
+ int i;
+
+ if (!handle || !user_info) {
+ _E("Invalid parameter");
+ return false;
+ }
+
+ r = aul_compinfo_get_comp_id(handle, &comp_id);
+ if (r != 0) {
+ _E("Failed to get component ID");
+ return false;
+ }
+
+ g_hash_table_remove(user_info->tbl, comp_id);
+
+ info = calloc(1, sizeof(struct compinfo_s));
+ if (!info) {
+ _E("Out of memory");
+ return false;
+ }
+
+ info->val[CIT_NAME] = strdup(comp_id);
+ if (!info->val[CIT_NAME]) {
+ _E("Failed to duplicate component ID(%s)", comp_id);
+ free(info);
+ return false;
+ }
+
+ for (i = CIT_START; i < CIT_MAX; i++) {
+ if (compinfo_table[i].constructor) {
+ r = compinfo_table[i].constructor(handle, info,
+ user_info);
+ if (r < 0) {
+ _E("Failed to load component info %s", comp_id);
+ __compinfo_remove_handler(info);
+ return true;
+ }
+ }
+ }
+
+ SECURE_LOGD("%s : %s : %s : %s",
+ info->val[CIT_APPID],
+ info->val[CIT_NAME],
+ info->val[CIT_TYPE],
+ info->val[CIT_TASKMANAGE]);
+
+ g_hash_table_insert(user_info->tbl, info->val[CIT_NAME], info);
+
+ return true;
+}
+
+compinfo_h _compinfo_find(uid_t uid, const char *id)
+{
+ struct user_compinfo_s *user_info;
+
+ if (!id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (!user_info) {
+ _E("Failed to find user(%u) info", uid);
+ return NULL;
+ }
+
+ return (struct compinfo_s *)g_hash_table_lookup(user_info->tbl, id);
+}
+
+const char *_compinfo_get_value(compinfo_h handle, compinfo_type type)
+{
+ struct compinfo_s *info = (struct compinfo_s *)handle;
+
+ if (!info) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ if (type >= CIT_MAX) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ return info->val[type];
+}
+
+static void __foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ struct compinfo_s *info = (struct compinfo_s *)value;
+ struct cb_info_s *cb_info = (struct cb_info_s *)user_data;
+
+ cb_info->callback(info, info->val[CIT_APPID],
+ info->val[CIT_NAME], cb_info->user_data);
+}
+
+int _compinfo_foreach(uid_t uid, compinfo_foreach_cb callback,
+ void *user_data)
+{
+ struct user_compinfo_s *user_info;
+ struct cb_info_s cb_info = {callback, user_data};
+
+ if (!callback) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (!user_info) {
+ _E("Failed to find user(%u) info", uid);
+ return -1;
+ }
+
+ g_hash_table_foreach(user_info->tbl, __foreach_cb, &cb_info);
+
+ return 0;
+}
+
+static int __on_appinfo_insert(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ pkgmgrinfo_appinfo_h handle = (pkgmgrinfo_appinfo_h)arg3;
+ struct user_compinfo_s *user_info;
+ char *comp_type = NULL;
+ char *appid = NULL;
+ uid_t uid = (uid_t)arg1;
+ int r;
+
+ r = pkgmgrinfo_appinfo_get_component_type(handle, &comp_type);
+ if (r != PMINFO_R_OK) {
+ _E("Failed to get component type");
+ return NOTI_CONTINUE;
+ }
+
+ if (comp_type && strcmp(comp_type, APP_TYPE_COMPONENT_BASED) != 0)
+ return NOTI_CONTINUE;
+
+ user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (!user_info) {
+ _E("Failed to find user(%u) table", uid);
+ return NOTI_CONTINUE;
+ }
+
+ r = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (r != PMINFO_R_OK) {
+ _E("Failed to get appid");
+ return NOTI_CONTINUE;
+ }
+
+ r = aul_compinfo_usr_foreach_compinfo_from_app(appid, uid,
+ __compinfo_insert_handler, user_info);
+ if (r != 0) {
+ _E("Failed to retrieve component info");
+ return NOTI_CONTINUE;
+ }
+
+ return NOTI_CONTINUE;
+}
+
+static gboolean __foreach_remove_cb(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ const char *appid = (const char *)user_data;
+ struct compinfo_s *info = (struct compinfo_s *)value;
+
+ if (!strcmp(info->val[CIT_APPID], appid))
+ return TRUE;
+
+ return FALSE;
+}
+
+static int __on_appinfo_remove(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ struct user_compinfo_s *user_info;
+ uid_t uid = (uid_t)arg1;
+ char *appid = (char *)arg3;
+
+ user_info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (!user_info) {
+ _E("Failed to find user(%u) info", uid);
+ return NOTI_CONTINUE;
+ }
+
+ g_hash_table_foreach_remove(user_info->tbl, __foreach_remove_cb, appid);
+
+ return NOTI_CONTINUE;
+}
+
+static struct user_compinfo_s *__create_user_compinfo(uid_t uid)
+{
+ struct user_compinfo_s *info;
+
+ info = calloc(1, sizeof(struct user_compinfo_s));
+ if (!info) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->uid = uid;
+ info->tbl = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ __compinfo_remove_handler);
+ if (!info->tbl) {
+ _E("Out of memory");
+ free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+static void __destroy_user_compinfo(gpointer data)
+{
+ struct user_compinfo_s *info = (struct user_compinfo_s *)data;
+
+ if (!info)
+ return;
+
+ if (info->tbl)
+ g_hash_table_destroy(info->tbl);
+ free(info);
+}
+
+static int __on_login_monitor_login_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ struct user_compinfo_s *info;
+ uid_t uid = (uid_t)arg1;
+
+ info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (info)
+ return NOTI_CONTINUE;
+
+ info = __create_user_compinfo(uid);
+ if (!info) {
+ _E("Failed to create user(%u) info", uid);
+ return NOTI_CONTINUE;
+ }
+
+ g_hash_table_insert(__user_table, GUINT_TO_POINTER(uid), info);
+
+ return NOTI_CONTINUE;
+}
+
+static int __on_login_monitor_logout(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ struct user_compinfo_s *info;
+ uid_t uid = (uid_t)arg1;
+
+ info = (struct user_compinfo_s *)g_hash_table_lookup(__user_table,
+ GUINT_TO_POINTER(uid));
+ if (!info)
+ return NOTI_CONTINUE;
+
+ g_hash_table_remove(__user_table, GUINT_TO_POINTER(uid));
+
+ return NOTI_CONTINUE;
+}
+
+int _compinfo_init(void)
+{
+ _D("Component info init");
+
+ __user_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __destroy_user_compinfo);
+ if (!__user_table) {
+ _E("Failed to create user table");
+ return -1;
+ }
+
+ _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START,
+ __on_login_monitor_login_start);
+ _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
+ __on_login_monitor_logout);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT,
+ __on_appinfo_insert);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_REMOVE,
+ __on_appinfo_remove);
+
+ return 0;
+}
+
+void _compinfo_fini(void)
+{
+ _D("Component info fini");
+
+ if (__user_table)
+ g_hash_table_destroy(__user_table);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_COMPINFO_H__
+#define __AMD_COMPINFO_H__
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COMPONENT_TYPE_FRAME "frame"
+
+#define COMPONENT_TYPE_SERVICE "service"
+
+#define CIT_START 0
+typedef enum compinfo_type_e {
+ CIT_NAME = CIT_START,
+ CIT_APPID,
+ CIT_TYPE,
+ CIT_LAUNCH_MODE,
+ CIT_TASKMANAGE,
+ CIT_MAIN,
+ CIT_ICON_DISPLAY,
+ CIT_MAX
+} compinfo_type;
+
+typedef void *compinfo_h;
+
+typedef void (*compinfo_foreach_cb)(compinfo_h info,
+ const char *appid, const char *id, void *user_data);
+
+compinfo_h _compinfo_find(uid_t uid, const char *id);
+
+const char *_compinfo_get_value(compinfo_h handle, compinfo_type type);
+
+int _compinfo_foreach(uid_t uid, compinfo_foreach_cb callback, void *user_data);
+
+int _compinfo_init(void);
+
+void _compinfo_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_COMPINFO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <system_info.h>
+#include <iniparser.h>
+
+#include "amd_config.h"
+#include "amd_util.h"
+
+#define CONFIG_FILE_PATH "/usr/share/amd/conf/amd.conf"
+#define CONFIG_SECTION_NAME "configuration"
+#define CONFIG_SERVICE_APP_ONBOOT_INTERVAL "service_app_onboot_interval"
+#define CONFIG_FG_TIMEOUT "fg_timeout"
+#define CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE "launchpad_max_launch_failure"
+
+typedef struct config_s {
+ tizen_profile_t profile;
+ unsigned int onboot_interval;
+ unsigned int fg_timeout;
+ unsigned int max_launch_failure;
+} config;
+
+static config __config;
+
+tizen_profile_t _config_get_tizen_profile(void)
+{
+ char *profile_name = NULL;
+
+ if (__builtin_expect(__config.profile != TIZEN_PROFILE_UNKNOWN, 1))
+ return __config.profile;
+
+ system_info_get_platform_string("http://tizen.org/feature/profile",
+ &profile_name);
+ if (profile_name == NULL)
+ return __config.profile;
+
+ switch (*profile_name) {
+ case 'm':
+ case 'M':
+ __config.profile = TIZEN_PROFILE_MOBILE;
+ break;
+ case 'w':
+ case 'W':
+ __config.profile = TIZEN_PROFILE_WEARABLE;
+ break;
+ case 't':
+ case 'T':
+ __config.profile = TIZEN_PROFILE_TV;
+ break;
+ case 'i':
+ case 'I':
+ __config.profile = TIZEN_PROFILE_IVI;
+ break;
+ default: /* common or unknown ==> ALL ARE COMMON. */
+ __config.profile = TIZEN_PROFILE_COMMON;
+ break;
+ }
+ free(profile_name);
+
+ return __config.profile;
+}
+
+unsigned int _config_get_onboot_interval(void)
+{
+ return __config.onboot_interval;
+}
+
+unsigned int _config_get_fg_timeout(void)
+{
+ return __config.fg_timeout;
+}
+
+unsigned int _config_get_max_launch_failure(void)
+{
+ return __config.max_launch_failure;
+}
+
+static int __get_config_int(dictionary *d, const char *key)
+{
+ char buf[512];
+ int val;
+
+ snprintf(buf, sizeof(buf), "configuration:%s", key);
+ val = iniparser_getint(d, buf, -1);
+ if (val < 0) {
+ _W("Failed to get %s", buf);
+ return -1;
+ }
+
+ return val;
+}
+
+static int __load_config_file(const char *path)
+{
+ int r;
+ dictionary *d;
+
+ r = access(path, F_OK);
+ if (r != 0) {
+ _W("Failed to access %s, errno(%d)", path, errno);
+ return -1;
+ }
+
+ d = iniparser_load(path);
+ if (!d) {
+ _E("Failed to load %s", path);
+ return -1;
+ }
+
+ r = __get_config_int(d, CONFIG_SERVICE_APP_ONBOOT_INTERVAL);
+ if (r > 0) {
+ __config.onboot_interval = r;
+ _I("[__CONFIG__] Onboot interval: %u",
+ __config.onboot_interval);
+ }
+
+ r = __get_config_int(d, CONFIG_FG_TIMEOUT);
+ if (r > 0) {
+ __config.fg_timeout = r;
+ _I("[__CONFIG__] FG timeout: %u", __config.fg_timeout);
+ }
+
+ r = __get_config_int(d, CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE);
+ if (r > 0) {
+ __config.max_launch_failure = r;
+ _I("[__CONFIG__] Max launch failure : %u",
+ __config.max_launch_failure);
+ }
+
+ iniparser_freedict(d);
+
+ return 0;
+}
+
+int _config_init(void)
+{
+ _D("config init");
+
+ __config.profile = TIZEN_PROFILE_UNKNOWN;
+ __config.onboot_interval = 3000;
+ __config.fg_timeout = 5000;
+ __config.max_launch_failure = 5;
+
+ if (__load_config_file(CONFIG_FILE_PATH) < 0)
+ _W("Failed to load config file");
+
+ return 0;
+}
+
+void _config_fini(void)
+{
+ _D("config fini");
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_CONFIG_H__
+#define __AMD_CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ TIZEN_PROFILE_UNKNOWN = 0,
+ TIZEN_PROFILE_MOBILE = 0x1,
+ TIZEN_PROFILE_WEARABLE = 0x2,
+ TIZEN_PROFILE_TV = 0x4,
+ TIZEN_PROFILE_IVI = 0x8,
+ TIZEN_PROFILE_COMMON = 0x10,
+} tizen_profile_t;
+
+tizen_profile_t _config_get_tizen_profile(void);
+
+#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_AUTO_ROTATION \
+ (!(_config_get_tizen_profile() & (TIZEN_PROFILE_TV | TIZEN_PROFILE_IVI)))
+
+unsigned int _config_get_onboot_interval(void);
+
+unsigned int _config_get_fg_timeout(void);
+
+unsigned int _config_get_max_launch_failure(void);
+
+int _config_init(void);
+
+void _config_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <malloc.h>
+#include <stdlib.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <glib.h>
+#include <glib-unix.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <aul_svc_priv_key.h>
+#include <amd_request.h>
+#include <amd_appinfo.h>
+#include <aul.h>
+
+#include "amd_cynara.h"
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_app_status.h"
+
+static cynara_ops __cynara_ops;
+static cynara_caller_info_ops __cynara_ci_ops;
+static GList *__pending_checkers;
+static GList *__pending_sub_checkers;
+
+struct checker_info {
+ const cynara_checker *checkers;
+ int cnt;
+};
+
+struct sub_checker_info {
+ char *name;
+ sub_checker_func func;
+};
+
+int _cynara_simple_checker(caller_info_h info, request_h req, void *data)
+{
+ if (__cynara_ops.check)
+ return __cynara_ops.check(info, req, data);
+
+ return AMD_CYNARA_ALLOWED;
+}
+
+int _cynara_check_privilege(request_h req, cynara_response_cb callback)
+{
+ if (__cynara_ops.check_async)
+ return __cynara_ops.check_async(req, callback);
+
+ return AMD_CYNARA_ALLOWED;
+}
+
+int _cynara_check_privilege_offline(request_h req, const char *appid, const char *privilege)
+{
+ if (__cynara_ops.check_offline)
+ return __cynara_ops.check_offline(req, appid, privilege);
+
+ return AMD_CYNARA_ALLOWED;
+}
+
+int _cynara_register_checkers(const cynara_checker *checkers, int cnt)
+{
+ struct checker_info *info;
+
+ if (__cynara_ops.register_checkers)
+ return __cynara_ops.register_checkers(checkers, cnt);
+
+ info = calloc(1, sizeof(struct checker_info));
+ if (!info) {
+ _E("Out-of-memory");
+ return -1;
+ }
+
+ info->checkers = checkers;
+ info->cnt = cnt;
+ __pending_checkers = g_list_append(__pending_checkers, info);
+
+ return 0;
+}
+
+const char *_cynara_caller_info_get_client(caller_info_h info)
+{
+ if (__cynara_ci_ops.get_client)
+ return __cynara_ci_ops.get_client(info);
+
+ return NULL;
+}
+
+int _cynara_sub_checker_add(const char *name, sub_checker_func func)
+{
+ struct sub_checker_info *sub_info;
+
+ if (__cynara_ops.sub_checker_add)
+ return __cynara_ops.sub_checker_add(name, func);
+
+ sub_info = calloc(1, sizeof(struct sub_checker_info));
+ if (!sub_info) {
+ _E("Out-of-memory");
+ return -1;
+ }
+
+ sub_info->name = strdup(name);
+ sub_info->func = func;
+
+ if (!sub_info->name) {
+ _E("Out-of-memory");
+ free(sub_info);
+ return -1;
+ }
+
+ __pending_sub_checkers = g_list_append(__pending_sub_checkers, sub_info);
+
+ return 0;
+}
+
+int _cynara_sub_checker_check(const char *name, caller_info_h info, request_h req)
+{
+ if (__cynara_ops.sub_checker_check)
+ return __cynara_ops.sub_checker_check(name, info, req);
+
+ return AMD_CYNARA_CONTINUE;
+}
+
+static void __clear_sub_checker_info(gpointer data)
+{
+ struct sub_checker_info *sub_info = data;
+
+ if (!data)
+ return;
+
+ free(sub_info->name);
+ free(sub_info);
+}
+
+static void __clear_pending_list(void)
+{
+ if (__pending_checkers) {
+ g_list_free_full(__pending_checkers, free);
+ __pending_checkers = NULL;
+ }
+
+ if (__pending_sub_checkers) {
+ g_list_free_full(__pending_sub_checkers, __clear_sub_checker_info);
+ __pending_sub_checkers = NULL;
+ }
+}
+
+int _cynara_register_ops(cynara_ops ops, cynara_caller_info_ops ci_ops)
+{
+ GList *i = __pending_checkers;
+ struct checker_info *info;
+ struct sub_checker_info *sub_info;
+
+ __cynara_ops = ops;
+ __cynara_ci_ops = ci_ops;
+ while (i) {
+ info = i->data;
+ if (__cynara_ops.register_checkers)
+ __cynara_ops.register_checkers(info->checkers, info->cnt);
+
+ i = g_list_next(i);
+ }
+
+ i = __pending_sub_checkers;
+ while (i) {
+ sub_info = i->data;
+ if (__cynara_ops.sub_checker_add)
+ __cynara_ops.sub_checker_add(sub_info->name, sub_info->func);
+
+ i = g_list_next(i);
+ }
+
+ __clear_pending_list();
+
+ return 0;
+}
+
+int _cynara_init(void)
+{
+ _D("cynara init");
+
+ return 0;
+}
+
+void _cynara_finish(void)
+{
+ _D("cynara fini");
+ __clear_pending_list();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_CYNARA_H__
+#define __AMD_CYNARA_H__
+
+#include "amd_request.h"
+
+#define SYSPOPUP_NAME "_INTERNAL_SYSPOPUP_NAME_"
+#define PRIVILEGE_WIDGET_VIEWER \
+ "http://tizen.org/privilege/widget.viewer"
+#define PRIVILEGE_APPMANAGER_LAUNCH \
+ "http://tizen.org/privilege/appmanager.launch"
+#define PRIVILEGE_APPMANAGER_KILL \
+ "http://tizen.org/privilege/appmanager.kill"
+#define PRIVILEGE_APPMANAGER_KILL_BGAPP \
+ "http://tizen.org/privilege/appmanager.kill.bgapp"
+#define PRIVILEGE_DOWNLOAD \
+ "http://tizen.org/privilege/download"
+#define PRIVILEGE_CALL \
+ "http://tizen.org/privilege/call"
+#define PRIVILEGE_SYSTEM_SETTING \
+ "http://tizen.org/privilege/systemsettings.admin"
+#define PRIVILEGE_PLATFORM \
+ "http://tizen.org/privilege/internal/default/platform"
+#define PRIVILEGE_PACKAGEMANAGER_INFO \
+ "http://tizen.org/privilege/packagemanager.info"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum amd_cynara_res {
+ AMD_CYNARA_ERROR = -2,
+ AMD_CYNARA_DENIED,
+ AMD_CYNARA_ALLOWED,
+ AMD_CYNARA_UNKNOWN,
+ AMD_CYNARA_CONTINUE,
+};
+
+typedef struct caller_info *caller_info_h;
+
+typedef int (*checker_func)(caller_info_h info, request_h req,
+ void *data);
+
+typedef int (*sub_checker_func)(caller_info_h info, request_h req);
+
+typedef struct _cynara_checker {
+ int cmd;
+ checker_func checker;
+ void *data;
+ int priority;
+} cynara_checker;
+
+typedef void (*cynara_response_cb)(enum amd_cynara_res res, request_h request);
+
+typedef int (*cynara_register_checkers_cb)(const cynara_checker *checkers,
+ int cnt);
+
+typedef int (*cynara_sub_checker_add_cb)(const char *name,
+ sub_checker_func func);
+
+typedef int (*cynara_sub_checker_check_cb)(const char *name, caller_info_h info,
+ request_h req);
+
+typedef int (*cynara_check_async_cb)(request_h req,
+ cynara_response_cb callback);
+
+typedef int (*cynara_check_cb)(caller_info_h info, request_h req, void *data);
+
+typedef int (*cynara_check_offline_cb)(request_h req, const char *appid,
+ const char *privilege);
+
+typedef struct _cynara_ops {
+ cynara_register_checkers_cb register_checkers;
+ cynara_sub_checker_add_cb sub_checker_add;
+ cynara_sub_checker_check_cb sub_checker_check;
+ cynara_check_async_cb check_async;
+ cynara_check_cb check;
+ cynara_check_offline_cb check_offline;
+} cynara_ops;
+
+typedef struct _cynara_caller_info_ops {
+ const char *(*get_client)(caller_info_h info);
+} cynara_caller_info_ops;
+
+int _cynara_init(void);
+
+void _cynara_finish(void);
+
+int _cynara_check_privilege(request_h req, cynara_response_cb callback);
+
+int _cynara_check_privilege_offline(request_h req, const char *appid,
+ const char *privilege);
+
+int _cynara_register_checkers(const cynara_checker *checkers, int cnt);
+
+int _cynara_simple_checker(caller_info_h info, request_h req, void *data);
+
+const char *_cynara_caller_info_get_client(caller_info_h info);
+
+int _cynara_sub_checker_add(const char *name, sub_checker_func func);
+
+int _cynara_sub_checker_check(const char *name, caller_info_h info,
+ request_h req);
+
+int _cynara_register_ops(cynara_ops ops, cynara_caller_info_ops ci_ops);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_CYNARA_H__ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <aul_key.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+
+#include "amd_appinfo.h"
+#include "amd_app_property.h"
+#include "amd_direct_launch.h"
+#include "amd_noti.h"
+#include "amd_util.h"
+
+#define KEY_DIRECT_LAUNCH "http://tizen.org/metadata/direct-launch"
+
+static int __on_check_direct_launch(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ const struct appinfo *ai = (const struct appinfo *)arg3;
+ uid_t target_uid = (uid_t)arg2;
+ app_property_h app_property;
+ const char *appid;
+ const char *loader_id;
+
+ loader_id = bundle_get_val(b, AUL_K_LOADER_ID);
+ if (loader_id)
+ return NOTI_CONTINUE;
+
+ appid = _appinfo_get_value(ai, AIT_NAME);
+ app_property = _app_property_find(target_uid);
+ if (_app_property_metadata_match(app_property, appid,
+ KEY_DIRECT_LAUNCH, "yes"))
+ aul_svc_set_loader_id(b, PAD_LOADER_ID_DIRECT);
+
+ return NOTI_CONTINUE;
+}
+
+int _direct_launch_init(void)
+{
+ int r;
+
+ _D("direct launch init");
+ r = _app_property_metadata_add_filter(KEY_DIRECT_LAUNCH, "yes");
+ if (r < 0) {
+ _E("Failed to add metadata filter");
+ return -1;
+ }
+
+ _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
+ __on_check_direct_launch);
+ return 0;
+}
+
+void _direct_launch_fini(void)
+{
+ _D("direct launch fini");
+ _app_property_metadata_remove_filter(KEY_DIRECT_LAUNCH, "yes");
+}
+
+
--- /dev/null
+/*
+ * 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_DIRECT_LAUNCH_H__
+#define __AMD_DIRECT_LAUNCH_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _direct_launch_init(void);
+
+void _direct_launch_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_DIRECT_LAUNCH_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/inotify.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_inotify.h"
+
+struct inotify_watch_info_s {
+ int fd;
+ int wd;
+ GIOChannel *io;
+ guint tag;
+ uint32_t mask;
+ inotify_watch_cb cb;
+ void *data;
+};
+
+static GList *__watch_list;
+
+static gboolean __inotify_cb(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+#define ALIGN_INOTIFY_EVENT \
+ __attribute__ ((aligned(__alignof__(struct inotify_event))))
+ int fd = g_io_channel_unix_get_fd(source);
+ char buf[4096] ALIGN_INOTIFY_EVENT;
+ const struct inotify_event *event;
+ struct inotify_watch_info_s *info = data;
+ ssize_t len;
+ char *ptr;
+ char *nptr;
+
+ while ((len = read(fd, buf, sizeof(buf))) > 0) {
+ for (ptr = buf; ptr < buf + len;
+ ptr += sizeof(struct inotify_event) + event->len) {
+ event = (const struct inotify_event *)ptr;
+ nptr = ptr + sizeof(struct inotify_event) + event->len;
+ if (nptr > buf + len)
+ break;
+
+ if (event->mask & info->mask) {
+ if (!info->cb(event->name, info->data)) {
+ _inotify_rm_watch(info);
+ return G_SOURCE_CONTINUE;
+ }
+ }
+ }
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void __destroy_inotify_watch_info(gpointer data)
+{
+ struct inotify_watch_info_s *info = (struct inotify_watch_info_s *)data;
+
+ if (info == NULL)
+ return;
+
+ if (info->tag > 0)
+ g_source_remove(info->tag);
+
+ if (info->io)
+ g_io_channel_unref(info->io);
+
+ if (info->wd > 0)
+ inotify_rm_watch(info->fd, info->wd);
+
+ if (info->fd > 0)
+ close(info->fd);
+
+ free(info);
+}
+
+static struct inotify_watch_info_s *__create_inotify_watch_info(
+ const char *path, uint32_t mask, inotify_watch_cb cb,
+ void *data)
+{
+ GIOCondition cond = G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP;
+ struct inotify_watch_info_s *info;
+
+ info = calloc(1, sizeof(struct inotify_watch_info_s));
+ if (info == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (info->fd < 0) {
+ _E("inotify_init1() is failed. errno(%d)", errno);
+ __destroy_inotify_watch_info(info);
+ return NULL;
+ }
+
+ info->wd = inotify_add_watch(info->fd, path, mask);
+ if (info->wd < 0) {
+ _E("inotify_add_watch() is failed. path(%s), errno(%d)",
+ path, errno);
+ __destroy_inotify_watch_info(info);
+ return NULL;
+ }
+
+ info->io = g_io_channel_unix_new(info->fd);
+ if (!info->io) {
+ _E("g_io_channel_unix_new() is failed");
+ __destroy_inotify_watch_info(info);
+ return NULL;
+ }
+
+ info->tag = g_io_add_watch(info->io, cond,
+ __inotify_cb, info);
+ if (!info->tag) {
+ _E("g_io_add_watch() is failed");
+ __destroy_inotify_watch_info(info);
+ return NULL;
+ }
+
+ info->mask = mask;
+ info->cb = cb;
+ info->data = data;
+
+ return info;
+}
+
+inotify_watch_info_h _inotify_add_watch(const char *path, uint32_t mask,
+ inotify_watch_cb callback, void *data)
+{
+ struct inotify_watch_info_s *info;
+
+ if (path == NULL || callback == NULL) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ info = __create_inotify_watch_info(path, mask, callback, data);
+ if (info == NULL)
+ return NULL;
+
+ __watch_list = g_list_append(__watch_list, info);
+
+ return info;
+}
+
+void _inotify_rm_watch(inotify_watch_info_h handle)
+{
+ if (handle == NULL)
+ return;
+
+ __watch_list = g_list_remove(__watch_list, handle);
+ __destroy_inotify_watch_info(handle);
+}
+
+int _inotify_init(void)
+{
+ _D("inotify init");
+
+ return 0;
+}
+
+void _inotify_fini(void)
+{
+ _D("inotify fini");
+
+ if (__watch_list)
+ g_list_free_full(__watch_list, __destroy_inotify_watch_info);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_INOTIFY_H__
+#define __AMD_INOTIFY_H__
+
+#include <stdbool.h>
+#include <sys/inotify.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct inotify_watch_info_s *inotify_watch_info_h;
+
+typedef bool (*inotify_watch_cb)(const char *event_name, void *data);
+
+inotify_watch_info_h _inotify_add_watch(const char *path, uint32_t mask,
+ inotify_watch_cb callback, void *data);
+
+void _inotify_rm_watch(inotify_watch_info_h handle);
+
+int _inotify_init(void);
+
+void _inotify_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_INOTIFY_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <aul.h>
+#include <aul_rpc_port.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <aul_svc_priv_key.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <glib.h>
+#include <pkgmgr-info.h>
+#include <ttrace.h>
+#include <tzplatform_config.h>
+#include <vconf.h>
+
+#include "amd_anr_monitor.h"
+#include "amd_api_noti.h"
+#include "amd_app_com.h"
+#include "amd_app_property.h"
+#include "amd_app_status.h"
+#include "amd_appinfo.h"
+#include "amd_boot_manager.h"
+#include "amd_comp_status.h"
+#include "amd_compinfo.h"
+#include "amd_config.h"
+#include "amd_cynara.h"
+#include "amd_launch.h"
+#include "amd_launchpad.h"
+#include "amd_login_monitor.h"
+#include "amd_noti.h"
+#include "amd_proc.h"
+#include "amd_request.h"
+#include "amd_signal.h"
+#include "amd_socket.h"
+#include "amd_suspend.h"
+#include "amd_util.h"
+#include "app_signal.h"
+
+#define DAC_ACTIVATE
+
+#define TERM_WAIT_SEC 3
+#define INIT_PID 1
+
+#define AUL_PR_NAME 16
+#define OSP_K_LAUNCH_TYPE "__OSP_LAUNCH_TYPE__"
+#define OSP_V_LAUNCH_TYPE_DATACONTROL "datacontrol"
+#define PENDING_REQUEST_TIMEOUT 5000 /* msec */
+#define SYSTEM_REQUEST_TIMEOUT 90000 /* msec */
+#define PENDING_MESSAGE_MAX_CNT 100
+
+#define APPID_WIDGET_VIEWER_SDK "org.tizen.widget_viewer_sdk"
+
+struct launch_s {
+ const char *appid;
+ struct appinfo *ai;
+ const char *instance_id;
+ int pid;
+ bool new_process;
+ bool is_subapp;
+ int prelaunch_attr;
+ int bg_category;
+ bool bg_allowed;
+ bool bg_launch;
+ bool new_instance;
+ app_status_h app_status;
+ bool debug_mode;
+ const char *comp_id;
+ compinfo_h ci;
+ comp_status_h comp_status;
+ bool is_custom_effect;
+};
+
+struct fgmgr {
+ guint tid;
+ int pid;
+};
+
+struct result_info_s {
+ int pid;
+ int fd;
+ char *seq;
+ guint timer;
+};
+
+static GList *_fgmgr_list;
+static int __pid_of_last_launched_ui_app;
+static int __focused_pid;
+static GList *__result_info_list;
+static int __poweroff_state;
+static launch_mode_e __launch_mode = LAUNCH_MODE_NORMAL;
+static unsigned int __failure_count;
+
+static void __set_reply_handler(int fd, int pid, request_h req, int cmd);
+static int __nofork_processing(int cmd, int pid, bundle *kb, request_h req);
+
+static void __poweroff_state_cb(int state, void *user_data)
+{
+ _W("[__POWEROFF__] state: %d -> %d", __poweroff_state, state);
+ __poweroff_state = state;
+ if (__poweroff_state == POWEROFF_DIRECT ||
+ __poweroff_state == POWEROFF_RESTART) {
+ _W("System shutdown");
+ __launch_mode = LAUNCH_MODE_BLOCK;
+ }
+ _noti_send(AMD_NOTI_MSG_LAUNCH_POWEROFF_STATE_CHANGE, state, 0, NULL, NULL);
+}
+
+static void __add_result_info(struct result_info_s *info)
+{
+ __result_info_list = g_list_append(__result_info_list, info);
+}
+
+static void __remove_result_info(struct result_info_s *info)
+{
+ __result_info_list = g_list_remove(__result_info_list, info);
+}
+
+static void __destroy_result_info(gpointer data)
+{
+ struct result_info_s *info = (struct result_info_s *)data;
+
+ if (!info)
+ return;
+ if (info->timer)
+ g_source_remove(info->timer);
+ if (info->seq)
+ free(info->seq);
+ free(info);
+}
+
+static gboolean __result_info_timeout_handler(gpointer data)
+{
+ struct result_info_s *info = (struct result_info_s *)data;
+
+ if (!info)
+ return G_SOURCE_REMOVE;
+
+ _W("[__WARNING__] timed out. pid(%d), fd(%d), seq(%s)",
+ info->pid, info->fd, info->seq);
+ info->timer = 0;
+ __remove_result_info(info);
+ __destroy_result_info(info);
+
+ return G_SOURCE_REMOVE;
+}
+
+static guint __get_timeout_interval(struct timespec *start,
+ struct timespec *end)
+{
+ guint interval;
+
+ interval = (end->tv_sec - start->tv_sec) * 1e3 +
+ (end->tv_nsec - start->tv_nsec) / 1e6;
+ if (interval >= PENDING_REQUEST_TIMEOUT)
+ return 0;
+
+ return PENDING_REQUEST_TIMEOUT - interval;
+}
+
+static struct result_info_s *__create_result_info(unsigned int interval,
+ int pid, int fd, const char *seq)
+{
+ struct result_info_s *info;
+
+ info = calloc(1, sizeof(struct result_info_s));
+ if (!info) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->seq = strdup(seq);
+ if (!info->seq) {
+ _E("Failed to duplicate sequence");
+ free(info);
+ return NULL;
+ }
+
+ info->timer = g_timeout_add(interval, __result_info_timeout_handler,
+ info);
+ if (info->timer == 0) {
+ _E("Failed to add timer");
+ __destroy_result_info(info);
+ return NULL;
+ }
+
+ info->pid = pid;
+ info->fd = fd;
+
+ return info;
+}
+
+static struct result_info_s *__find_result_info(const char *seq)
+{
+ struct result_info_s *info;
+ GList *iter;
+
+ iter = __result_info_list;
+ while (iter) {
+ info = (struct result_info_s *)iter->data;
+ if (!strcmp(info->seq, seq))
+ return info;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static void __set_stime(bundle *kb)
+{
+ struct timespec start;
+ char tmp[MAX_LOCAL_BUFSZ];
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", start.tv_sec, start.tv_nsec);
+ bundle_add(kb, AUL_K_STARTTIME, tmp);
+}
+
+int _launch_start_app_local_with_bundle(uid_t uid, const char *appid,
+ bundle *kb)
+{
+ request_h req;
+ int r;
+ bool dummy;
+ bool dummy_mode;
+
+ __set_stime(kb);
+ bundle_add(kb, AUL_K_APPID, appid);
+ req = _request_create_local(APP_START, uid, getpid(), kb);
+ if (req == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ r = _launch_start_app(appid, req, &dummy, &dummy_mode, false);
+ _request_free_local(req);
+
+ return r;
+}
+
+int _launch_start_app_local(uid_t uid, const char *appid)
+{
+ int pid;
+ bundle *kb;
+
+ kb = bundle_create();
+ if (kb == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ pid = _launch_start_app_local_with_bundle(uid, appid, kb);
+ bundle_free(kb);
+
+ return pid;
+}
+
+static bool __check_onboot_cond(uid_t uid, const char *appid,
+ struct appinfo *ai)
+{
+ app_status_h app_status;
+ const char *comp_type;
+ const char *onboot;
+
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type == NULL || strcmp(comp_type, APP_TYPE_SERVICE) != 0)
+ return false;
+
+ onboot = _appinfo_get_value(ai, AIT_ONBOOT);
+ if (onboot == NULL || strcmp(onboot, "true") != 0)
+ return false;
+
+ app_status = _app_status_find_by_appid(appid, uid);
+ if (_app_status_is_running(app_status) > 0)
+ return false;
+
+ return true;
+}
+
+int _launch_start_onboot_app_local(uid_t uid, const char *appid,
+ struct appinfo *ai)
+{
+ if (appid == NULL || ai == NULL)
+ return -1;
+
+ if (!__check_onboot_cond(uid, appid, ai))
+ return -1;
+
+ _D("start app %s from user %d by onboot", appid, uid);
+ return _launch_start_app_local(uid, appid);
+}
+
+int _terminate_app_local(uid_t uid, int pid)
+{
+ request_h req;
+ int ret;
+
+ req = _request_create_local(APP_TERM_BY_PID, uid, getpid(), NULL);
+ if (req == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
+ ret = _term_app(pid, req);
+ _request_free_local(req);
+
+ return ret;
+}
+
+static int __send_sigkill(int pid, uid_t uid)
+{
+ int pgid;
+ pid_t launchpad_pid;
+
+ if (pid <= 1)
+ return -1;
+
+ pgid = getpgid(pid);
+ if (pgid <= 1)
+ return -1;
+
+ launchpad_pid = _login_monitor_get_launchpad_pid(uid);
+ if (launchpad_pid == pgid) {
+ SECURE_LOGE("pgid(%d) of pid(%d) is launchpad", pgid, pid);
+ if (kill(pid, SIGKILL) < 0) {
+ _E("Failed to send SIGKILL to %d", pid);
+ return -1;
+ }
+ return 0;
+ }
+
+ _W("Kill Process Group: pid(%d), pgid(%d)", pid, pgid);
+ if (killpg(pgid, SIGKILL) < 0)
+ return -1;
+
+ return 0;
+}
+
+int _resume_app(int pid, request_h req)
+{
+ int dummy;
+ int ret;
+ uid_t target_uid = _request_get_target_uid(req);
+
+ ret = aul_sock_send_raw(pid, target_uid,
+ APP_RESUME_BY_PID, (unsigned char *)&dummy, 0,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ _E("resume packet timeout error");
+ } else {
+ _E("raise failed - %d resume fail\n", pid);
+ _E("we will term the app - %d\n", pid);
+ __send_sigkill(pid, target_uid);
+ ret = -1;
+ }
+ _request_send_result(req, ret);
+ }
+ _D("resume done\n");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_RESUME_BY_PID);
+
+ return ret;
+}
+
+int _launch_resume_inst(int pid, request_h req)
+{
+ uid_t uid = _request_get_target_uid(req);
+ bundle *b = _request_get_bundle(req);
+ int ret;
+
+ if (!b) {
+ _E("Invalid parameter");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_sock_send_bundle(pid, uid, APP_RESUME_INSTANCE,
+ b, AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send resume request. pid(%d)", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _D("Resume done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_RESUME_INSTANCE);
+
+ return 0;
+}
+
+int _pause_app(int pid, request_h req)
+{
+ int dummy;
+ int ret;
+ uid_t target_uid = _request_get_target_uid(req);
+
+ ret = aul_sock_send_raw(pid, target_uid,
+ APP_PAUSE_BY_PID, (unsigned char *)&dummy, 0,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ _E("pause packet timeout error");
+ } else {
+ _E("iconify failed - %d pause fail", pid);
+ _E("we will term the app - %d", pid);
+ __send_sigkill(pid, target_uid);
+ ret = -1;
+ }
+ _request_send_result(req, ret);
+ }
+ _D("pause done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_PAUSE_BY_PID);
+
+ return ret;
+}
+
+int _launch_pause_inst(int pid, request_h req)
+{
+ uid_t uid = _request_get_target_uid(req);
+ bundle *b = _request_get_bundle(req);
+ int ret;
+
+ if (!b) {
+ _E("Invalid parameter");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_sock_send_bundle(pid, uid, APP_PAUSE_INSTANCE,
+ b, AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send pause request. pid(%d)", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _D("Resume done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_PAUSE_INSTANCE);
+
+ return 0;
+}
+
+int _term_sub_app(int pid, uid_t uid)
+{
+ int dummy;
+ int ret;
+
+ ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID_ASYNC,
+ (unsigned char *)&dummy, 0, AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("terminate packet send error - use SIGKILL pid(%d)", pid);
+ if (__send_sigkill(pid, uid) < 0) {
+ _E("fail to killing - %d\n", pid);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int _term_sub_inst(pid_t pid, const char *inst_id, uid_t uid)
+{
+ bundle *b;
+ int ret;
+
+ b = bundle_create();
+ if (!b) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ if (inst_id)
+ bundle_add(b, AUL_K_INSTANCE_ID, inst_id);
+
+ ret = aul_sock_send_bundle(pid, uid,
+ APP_TERM_INSTANCE_ASYNC,
+ b, AUL_SOCK_NOREPLY);
+ bundle_free(b);
+ if (ret < 0) {
+ SECURE_LOGE("Failed to send terminate request. "
+ "pid(%d), inst_id(%s)", pid, inst_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+int _term_app(int pid, request_h req)
+{
+ int dummy;
+ int ret;
+ uid_t uid = _request_get_target_uid(req);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_APP_START, pid, 0, req, NULL);
+ ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID,
+ (unsigned char *)&dummy, 0, AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("terminate packet send error - use SIGKILL pid(%d)", pid);
+ if (__send_sigkill(pid, uid) < 0) {
+ _E("fail to killing - %d\n", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _request_send_result(req, 0);
+ }
+ _D("term done\n");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_TERM_BY_PID);
+
+ return 0;
+}
+
+int _launch_terminate_inst(int pid, request_h req)
+{
+ uid_t uid = _request_get_target_uid(req);
+ bundle *b = _request_get_bundle(req);
+ int ret;
+
+ if (!b) {
+ _E("Invalid parameter");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = aul_sock_send_bundle(pid, uid, APP_TERM_INSTANCE_ASYNC,
+ b, AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send terminate request. pid(%d)", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _D("Terminate instance done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_TERM_INSTANCE_ASYNC);
+
+ return 0;
+}
+
+int _term_req_app(int pid, request_h req)
+{
+ int dummy;
+ int ret;
+
+ ret = aul_sock_send_raw(pid, _request_get_target_uid(req),
+ APP_TERM_REQ_BY_PID, (unsigned char *)&dummy, 0,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _D("terminate req send error");
+ _request_send_result(req, ret);
+ }
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_TERM_REQ_BY_PID);
+
+ return 0;
+}
+
+int _term_bgapp(int pid, request_h req)
+{
+ int dummy;
+ int ret;
+ uid_t uid = _request_get_target_uid(req);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START, pid, 0, req, NULL);
+ ret = aul_sock_send_raw(pid, uid, APP_TERM_BGAPP_BY_PID,
+ (unsigned char *)&dummy, sizeof(int), AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("terminate packet send error - use SIGKILL pid(%d)", pid);
+ if (__send_sigkill(pid, uid) < 0) {
+ _E("fail to killing - %d", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _request_send_result(req, 0);
+ }
+ _D("term_bgapp done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_TERM_BGAPP_BY_PID);
+
+ return 0;
+}
+
+int _launch_terminate_bg_inst(int pid, request_h req)
+{
+ uid_t uid = _request_get_target_uid(req);
+ bundle *b = _request_get_bundle(req);
+ int ret;
+
+ ret = aul_sock_send_bundle(pid, uid, APP_TERM_BG_INSTANCE,
+ b, AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send terminate bg inst. pid(%d)", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ _D("Terminate bg instance done");
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, APP_TERM_BG_INSTANCE);
+
+ return 0;
+}
+
+int _term_app_v2(int pid, request_h req, bool *pend)
+{
+ int dummy;
+ int ret;
+ uid_t uid = _request_get_target_uid(req);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_TERM_APP_START, pid, 0, req, NULL);
+ ret = aul_sock_send_raw(pid, uid, APP_TERM_BY_PID_SYNC,
+ (unsigned char *)&dummy, 0,
+ AUL_SOCK_ASYNC | AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("Failed to send the terminate packet - use SIGKILL pid(%d)",
+ pid);
+ if (__send_sigkill(pid, uid) < 0) {
+ _E("Failed to kill - %d\n", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+ }
+ _D("term v2 done");
+
+ if (pend)
+ *pend = true;
+
+ return 0;
+}
+
+static int __fake_launch_app(int cmd, int pid, bundle *kb, request_h req)
+{
+ int ret;
+
+ ret = aul_sock_send_bundle(pid, _request_get_target_uid(req), cmd, kb,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("error request fake launch - error code = %d", ret);
+ _request_send_result(req, ret);
+ }
+
+ if (ret > 0)
+ __set_reply_handler(ret, pid, req, cmd);
+
+ return ret;
+}
+
+static int __fake_launch_app_async(int cmd, int pid, bundle *kb, request_h req)
+{
+ int ret;
+
+ ret = aul_sock_send_bundle(pid, _request_get_target_uid(req), cmd, kb,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("error request fake launch - error code = %d", ret);
+ _request_send_result(req, ret);
+ }
+
+ if (ret > 0) {
+ _send_result_to_client(_request_remove_fd(req), pid);
+ __set_reply_handler(ret, pid, req, cmd);
+ }
+
+ return ret;
+}
+
+static gboolean __au_glib_check(GSource *src)
+{
+ GSList *fd_list;
+ GPollFD *tmp;
+
+ fd_list = src->poll_fds;
+ do {
+ tmp = (GPollFD *) fd_list->data;
+ if ((tmp->revents & (POLLIN | POLLPRI)))
+ return TRUE;
+ fd_list = fd_list->next;
+ } while (fd_list);
+
+ return FALSE;
+}
+
+static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
+ gpointer data)
+{
+ callback(data);
+ return TRUE;
+}
+
+static gboolean __au_glib_prepare(GSource *src, gint *timeout)
+{
+ return FALSE;
+}
+
+static GSourceFuncs funcs = {
+ .prepare = __au_glib_prepare,
+ .check = __au_glib_check,
+ .dispatch = __au_glib_dispatch,
+ .finalize = NULL
+};
+
+struct reply_info {
+ GSource *src;
+ GPollFD *gpollfd;
+ guint timer_id;
+ int clifd;
+ int pid;
+ int cmd;
+ bundle *kb;
+ uid_t uid;
+};
+
+static gboolean __reply_handler(gpointer data)
+{
+ struct reply_info *r_info = (struct reply_info *)data;
+ int fd = r_info->gpollfd->fd;
+ int len;
+ int res = 0;
+ int clifd = r_info->clifd;
+ int pid = r_info->pid;
+ char err_buf[1024];
+
+ len = recv(fd, &res, sizeof(int), 0);
+ if (len == -1) {
+ if (errno == EAGAIN) {
+ _E("recv timeout : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ res = -EAGAIN;
+ } else {
+ _E("recv error : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ res = -ECOMM;
+ }
+ } else if (len == 0) {
+ _E("A stream socket peer(%d) has performed an orderly shutdown",
+ pid);
+ res = -ECOMM;
+ }
+
+ if (res < 0 && r_info->cmd == APP_START_ASYNC) {
+ _noti_send(AMD_NOTI_MSG_LAUNCH_RECV_ERROR, r_info->pid, r_info->uid,
+ NULL, r_info->kb);
+ }
+
+ close(fd);
+
+ if (res >= 0)
+ res = pid;
+ _send_result_to_client(clifd, res);
+
+ _D("listen fd : %d , send fd : %d, pid : %d", fd, clifd, pid);
+
+ g_source_remove(r_info->timer_id);
+ g_source_remove_poll(r_info->src, r_info->gpollfd);
+ g_source_destroy(r_info->src);
+ g_source_unref(r_info->src);
+ g_free(r_info->gpollfd);
+ if (r_info->kb)
+ bundle_free(r_info->kb);
+ free(r_info);
+
+ _anr_monitor_remove_timer(pid);
+
+ return TRUE;
+}
+
+static gboolean __recv_timeout_handler(gpointer data)
+{
+ struct reply_info *r_info = (struct reply_info *)data;
+ int fd = r_info->gpollfd->fd;
+ int clifd = r_info->clifd;
+ app_status_h app_status;
+ uid_t uid;
+ int ret = -EAGAIN;
+
+ _E("application is not responding: pid(%d) cmd(%d)",
+ r_info->pid, r_info->cmd);
+ close(fd);
+
+ switch (r_info->cmd) {
+ case APP_OPEN:
+ case APP_RESUME:
+ case APP_RESUME_BY_PID:
+ case APP_START:
+ case APP_START_RES:
+ case APP_START_ASYNC:
+ case APP_START_RES_ASYNC:
+ case APP_SEND_LAUNCH_REQUEST:
+ case APP_SEND_LAUNCH_REQUEST_SYNC:
+ case APP_SEND_RESUME_REQUEST:
+ app_status = _app_status_find(r_info->pid);
+ if (app_status == NULL)
+ break;
+
+ uid = _app_status_get_uid(app_status);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT,
+ r_info->pid, uid, NULL, r_info->kb);
+ break;
+ case APP_TERM_BY_PID:
+ case APP_TERM_BGAPP_BY_PID:
+ if (__send_sigkill(r_info->pid, r_info->uid) == 0)
+ ret = 0;
+ break;
+ }
+
+ _send_result_to_client(clifd, ret);
+ g_source_remove_poll(r_info->src, r_info->gpollfd);
+ g_source_destroy(r_info->src);
+ g_source_unref(r_info->src);
+ g_free(r_info->gpollfd);
+ if (r_info->kb)
+ bundle_free(r_info->kb);
+ free(r_info);
+
+ return FALSE;
+}
+
+static void __set_reply_handler(int fd, int pid, request_h req, int cmd)
+{
+ GPollFD *gpollfd;
+ GSource *src;
+ struct reply_info *r_info;
+ struct timeval tv;
+ bundle *kb = _request_get_bundle(req);
+
+ src = g_source_new(&funcs, sizeof(GSource));
+ if (src == NULL) {
+ _E("Out of memory");
+ return;
+ }
+
+ gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
+ if (gpollfd == NULL) {
+ _E("Out of memory");
+ g_source_unref(src);
+ return;
+ }
+
+ gpollfd->events = POLLIN;
+ gpollfd->fd = fd;
+
+ r_info = malloc(sizeof(*r_info));
+ if (r_info == NULL) {
+ _E("out of memory");
+ g_free(gpollfd);
+ g_source_unref(src);
+ return;
+ }
+
+ if (kb) {
+ r_info->kb = bundle_dup(kb);
+ if (r_info->kb == NULL) {
+ _E("Out of memory");
+ free(r_info);
+ g_free(gpollfd);
+ g_source_unref(src);
+ return;
+ }
+ } else {
+ r_info->kb = NULL;
+ }
+
+ if (cmd == APP_SEND_LAUNCH_REQUEST_SYNC)
+ r_info->clifd = -1;
+ else
+ r_info->clifd = _request_remove_fd(req);
+ r_info->pid = pid;
+ r_info->src = src;
+ r_info->gpollfd = gpollfd;
+ r_info->cmd = cmd;
+ r_info->uid = _request_get_target_uid(req);
+
+ tv = aul_sock_get_rcv_timeval();
+ r_info->timer_id = g_timeout_add_seconds(tv.tv_sec,
+ __recv_timeout_handler, (gpointer)r_info);
+ g_source_add_poll(src, gpollfd);
+ g_source_set_callback(src, (GSourceFunc)__reply_handler,
+ (gpointer)r_info, NULL);
+ g_source_set_priority(src, G_PRIORITY_DEFAULT);
+ g_source_attach(src, NULL);
+
+ _anr_monitor_add_timer(pid);
+
+ _D("listen fd : %d, send fd : %d", fd, r_info->clifd);
+}
+
+static int __nofork_processing(int cmd, int pid, bundle *kb, request_h req)
+{
+ int ret;
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START,
+ cmd, pid, req, kb);
+
+ switch (cmd) {
+ case APP_OPEN:
+ case APP_RESUME:
+ case APP_SEND_RESUME_REQUEST:
+ _D("resume app's pid : %d\n", pid);
+ ret = _resume_app(pid, req);
+ if (ret < 0)
+ _E("__resume_app failed. error code = %d", ret);
+ _D("resume app done");
+ break;
+ case APP_START:
+ case APP_START_RES:
+ case APP_SEND_LAUNCH_REQUEST:
+ case APP_SEND_LAUNCH_REQUEST_SYNC:
+ _D("fake launch pid : %d\n", pid);
+ ret = __fake_launch_app(cmd, pid, kb, req);
+ if (ret < 0)
+ _E("fake_launch failed. error code = %d", ret);
+ _D("fake launch done");
+ break;
+ case APP_START_ASYNC:
+ case APP_START_RES_ASYNC:
+ ret = __fake_launch_app_async(cmd, pid, kb, req);
+ if (ret < 0)
+ _E("fake_launch_async failed. error code = %d", ret);
+ _D("fake launch async done");
+ break;
+ default:
+ _E("unknown command: %d", cmd);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int __compare_signature(const struct appinfo *ai, int cmd,
+ uid_t caller_uid, const char *appid, const char *caller_appid)
+{
+ const char *permission;
+ const struct appinfo *caller_ai;
+ const char *preload;
+ const char *api_version;
+ pkgmgrinfo_cert_compare_result_type_e compare_result;
+
+ permission = _appinfo_get_value(ai, AIT_PERM);
+ if (permission && strcmp(permission, "signature") == 0) {
+ if (caller_uid != 0 && (cmd == APP_START ||
+ cmd == APP_START_RES ||
+ cmd == APP_START_ASYNC ||
+ cmd == APP_START_RES_ASYNC ||
+ cmd == APP_SEND_LAUNCH_REQUEST ||
+ cmd == APP_SEND_LAUNCH_REQUEST_SYNC)) {
+ caller_ai = _appinfo_find(caller_uid, caller_appid);
+ preload = _appinfo_get_value(caller_ai, AIT_PRELOAD);
+ if (!preload || strcmp(preload, "true") == 0)
+ return 0;
+
+ api_version = _appinfo_get_value(caller_ai,
+ AIT_API_VERSION);
+ if (api_version && strverscmp(api_version, "2.4") < 0)
+ return 0;
+
+ /* is admin is global */
+ if (caller_uid != GLOBAL_USER) {
+ pkgmgrinfo_pkginfo_compare_usr_app_cert_info(
+ caller_appid, appid,
+ caller_uid, &compare_result);
+ } else {
+ pkgmgrinfo_pkginfo_compare_app_cert_info(
+ caller_appid, appid,
+ &compare_result);
+ }
+
+ if (compare_result != PMINFO_CERT_COMPARE_MATCH)
+ return -EILLEGALACCESS;
+ }
+ }
+
+ return 0;
+}
+
+static void __prepare_to_suspend(int pid, uid_t uid)
+{
+ int dummy = 0;
+
+ SECURE_LOGD("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
+ aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
+ sizeof(int), AUL_SOCK_NOREPLY);
+}
+
+static void __prepare_to_wake_services(int pid, uid_t uid)
+{
+ int dummy = 0;
+
+ SECURE_LOGD("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
+ aul_sock_send_raw(pid, uid, APP_WAKE, (unsigned char *)&dummy,
+ sizeof(int), AUL_SOCK_NOREPLY);
+}
+
+static gboolean __check_service_only(gpointer user_data)
+{
+ int pid = GPOINTER_TO_INT(user_data);
+ app_status_h app_status;
+
+ SECURE_LOGD("[__SUSPEND__] pid :%d", pid);
+ app_status = _app_status_find(pid);
+ _app_status_check_service_only(app_status,
+ __prepare_to_suspend);
+
+ return FALSE;
+}
+
+static int __check_allowed_appid(const char *callee_appid,
+ const char *caller_appid, uid_t uid)
+{
+ app_property_h app_property;
+ GList *list;
+ GList *iter;
+ char *allowed_appid;
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL)
+ return -1;
+
+ list = _app_property_get_allowed_app_list(app_property, callee_appid);
+ iter = g_list_first(list);
+ while (iter) {
+ allowed_appid = (char *)iter->data;
+ if (allowed_appid && strcmp(allowed_appid, caller_appid) == 0) {
+ _D("allowed appid(%s), appid(%s)",
+ allowed_appid, callee_appid);
+ return 0;
+ }
+
+ iter = g_list_next(iter);
+ }
+
+ return -1;
+}
+
+static int __check_execute_permission(const char *callee_pkgid,
+ const char *caller_appid, uid_t caller_uid, request_h req)
+{
+ bundle *kb = _request_get_bundle(req);
+ struct appinfo *ai;
+ const char *caller_pkgid;
+ const char *launch_type;
+ const char *callee_appid = bundle_get_val(kb, AUL_K_APPID);
+ const char *req_type;
+ int ret;
+
+ if (callee_pkgid == NULL)
+ return -1;
+
+ ai = _appinfo_find(caller_uid, caller_appid);
+ if (ai == NULL)
+ return 0;
+
+ caller_pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ if (caller_pkgid == NULL)
+ return 0;
+
+ if (strcmp(caller_pkgid, callee_pkgid) == 0)
+ return 0;
+
+ ret = __check_allowed_appid(callee_appid, caller_appid, caller_uid);
+ if (ret == 0)
+ return 0;
+
+ req_type = _request_get_request_type(req);
+ if (req_type &&
+ (!strcmp(req_type, "rpc-port") ||
+ !strcmp(req_type, "complication") ||
+ !strcmp(req_type, "bypass")))
+ return 0;
+
+ launch_type = bundle_get_val(kb, OSP_K_LAUNCH_TYPE);
+ if (launch_type == NULL
+ || strcmp(launch_type, OSP_V_LAUNCH_TYPE_DATACONTROL) != 0) {
+ if (!_appinfo_is_platform_app(caller_appid, caller_uid)) {
+ _E("Couldn't launch service app in other packages");
+ return -EREJECTED;
+ }
+ }
+
+ return 0;
+}
+
+static gboolean __fg_timeout_handler(gpointer data)
+{
+ struct fgmgr *fg = data;
+ app_status_h app_status;
+
+ if (!fg)
+ return FALSE;
+
+ app_status = _app_status_find(fg->pid);
+ if (app_status) {
+ if (_app_status_get_status(app_status) != STATUS_VISIBLE) {
+ _W("%d is running in the background", fg->pid);
+ _app_status_update_status(app_status, STATUS_BG,
+ true, true);
+ }
+ }
+
+ _fgmgr_list = g_list_remove(_fgmgr_list, fg);
+ free(fg);
+
+ return FALSE;
+}
+
+struct fgmgr *__launch_find_fgmgr(int pid)
+{
+ struct fgmgr *fg;
+ GList *iter;
+
+ iter = _fgmgr_list;
+ while (iter) {
+ fg = (struct fgmgr *)iter->data;
+ if (fg->pid == pid)
+ return fg;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static int __launch_add_fgmgr(int pid)
+{
+ struct fgmgr *fg;
+
+ _W("Add timer. pid(%d)", pid);
+ fg = __launch_find_fgmgr(pid);
+ if (fg) {
+ g_source_remove(fg->tid);
+ } else {
+ fg = calloc(1, sizeof(struct fgmgr));
+ if (!fg) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ fg->pid = pid;
+ _fgmgr_list = g_list_append(_fgmgr_list, fg);
+ }
+
+ fg->tid = g_timeout_add(_config_get_fg_timeout(),
+ __fg_timeout_handler, fg);
+
+ return 0;
+}
+
+static void __launch_remove_fgmgr(int pid)
+{
+ struct fgmgr *fg;
+
+ if (pid < 0)
+ return;
+
+ fg = __launch_find_fgmgr(pid);
+ if (!fg)
+ return;
+
+ _W("Remove timer. pid(%d)", pid);
+ g_source_remove(fg->tid);
+ _fgmgr_list = g_list_remove(_fgmgr_list, fg);
+ free(fg);
+}
+
+static int __send_hint_for_visibility(uid_t uid)
+{
+ bundle *b;
+ int ret;
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
+ PAD_CMD_VISIBILITY, b);
+ bundle_free(b);
+ __pid_of_last_launched_ui_app = 0;
+
+ return ret;
+}
+
+static int __app_status_handler(int pid, int status, void *data)
+{
+ const char *appid;
+ int old_status;
+ const struct appinfo *ai;
+ app_status_h app_status;
+ uid_t uid;
+
+ _W("pid(%d) status(%d)", pid, status);
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return 0;
+
+ old_status = _app_status_get_status(app_status);
+ if (old_status == STATUS_DYING && old_status != PROC_STATUS_LAUNCH)
+ return 0;
+
+ uid = _app_status_get_uid(app_status);
+ switch (status) {
+ case PROC_STATUS_FG:
+ __launch_remove_fgmgr(pid);
+ _app_status_update_status(app_status, STATUS_VISIBLE, false,
+ true);
+ _suspend_remove_timer(pid);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
+ pid, uid, app_status, NULL);
+ break;
+ case PROC_STATUS_BG:
+ _app_status_update_status(app_status, STATUS_BG, false, true);
+ appid = _app_status_get_appid(app_status);
+ ai = _appinfo_find(uid, appid);
+ if (!_suspend_is_excluded(pid) &&
+ !_suspend_is_allowed_background(ai)) {
+ __prepare_to_suspend(pid, uid);
+ _suspend_add_timer(pid);
+ }
+ _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_BG,
+ pid, uid, app_status, NULL);
+ break;
+ case PROC_STATUS_FOCUS:
+ __focused_pid = pid;
+ _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
+ pid, uid, app_status, NULL);
+ break;
+
+ case PROC_STATUS_HIDE:
+ _app_status_update_status(app_status, STATUS_BG, false, true);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_HIDE,
+ pid, uid, app_status, NULL);
+ break;
+
+ case PROC_STATUS_LAUNCH:
+ appid = _app_status_get_appid(app_status);
+ if (appid) {
+ LOG(LOG_DEBUG, "LAUNCH",
+ "[%s:Application:Launching:done]",
+ appid);
+ }
+ if (pid == __pid_of_last_launched_ui_app)
+ __send_hint_for_visibility(uid);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH,
+ pid, uid, app_status, NULL);
+ break;
+
+ }
+
+ return 0;
+}
+
+void _launch_set_focused_pid(int pid)
+{
+ __focused_pid = pid;
+}
+
+int _launch_get_focused_pid(void)
+{
+ return __focused_pid;
+}
+
+static int __listen_app_status_signal(void *data)
+{
+ int ret;
+
+ ret = aul_listen_app_status_signal(__app_status_handler, data);
+ if (ret < 0)
+ return -1;
+
+ return 0;
+}
+
+static int __listen_poweroff_state_signal(void *data)
+{
+ int ret;
+
+ ret = _signal_subscribe_poweroff_state(__poweroff_state_cb, data);
+ if (ret < 0)
+ return -1;
+
+ return 0;
+}
+
+static void __set_effective_appid(uid_t uid, bundle *kb)
+{
+ const struct appinfo *ai;
+ const struct appinfo *effective_ai;
+ const char *appid;
+ const char *effective_appid;
+ const char *pkgid;
+ const char *effective_pkgid;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL)
+ return;
+
+ ai = _appinfo_find(uid, appid);
+ if (ai == NULL)
+ return;
+
+ bundle_del(kb, AUL_SVC_K_PKG_NAME);
+ bundle_add(kb, AUL_SVC_K_PKG_NAME, appid);
+
+ effective_appid = _appinfo_get_value(ai, AIT_EFFECTIVE_APPID);
+ if (effective_appid == NULL)
+ return;
+
+ effective_ai = _appinfo_find(uid, effective_appid);
+ if (effective_ai == NULL)
+ return;
+
+ pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ effective_pkgid = _appinfo_get_value(effective_ai, AIT_PKGID);
+ if (pkgid && effective_pkgid && strcmp(pkgid, effective_pkgid) == 0) {
+ _D("use effective appid instead of the real appid");
+ bundle_del(kb, AUL_K_APPID);
+ bundle_add(kb, AUL_K_APPID, effective_appid);
+ }
+}
+
+static void __set_real_appid(uid_t uid, bundle *kb)
+{
+ const char *alias_appid;
+ const char *appid;
+ const char *alias_info;
+ app_property_h app_property;
+
+ alias_appid = bundle_get_val(kb, AUL_K_APPID);
+ if (alias_appid == NULL)
+ return;
+
+ alias_info = bundle_get_val(kb, AUL_SVC_K_ALIAS_INFO);
+ if (alias_info && strcmp(alias_info, "disable") == 0)
+ return;
+
+ app_property = _app_property_find(uid);
+ if (app_property == NULL)
+ return;
+
+ appid = _app_property_get_real_appid(app_property, alias_appid);
+ if (appid == NULL)
+ return;
+
+ _D("alias_appid(%s), appid(%s)", alias_appid, appid);
+ bundle_del(kb, AUL_K_ORG_APPID);
+ bundle_add(kb, AUL_K_ORG_APPID, alias_appid);
+ bundle_del(kb, AUL_K_APPID);
+ bundle_add(kb, AUL_K_APPID, appid);
+}
+
+static void __check_new_instance(bundle *kb, bool *new_instance)
+{
+ const char *str;
+
+ str = bundle_get_val(kb, AUL_K_NEW_INSTANCE);
+ if (str && !strcmp(str, "true"))
+ *new_instance = true;
+ else
+ *new_instance = false;
+}
+
+static void __pend_result_info(request_h req, int pid)
+{
+ struct result_info_s *info;
+ bundle *kb;
+ const char *seq;
+ struct timespec end;
+ unsigned int interval;
+
+ if (pid <= 0)
+ return;
+
+ kb = _request_get_bundle(req);
+ seq = bundle_get_val(kb, AUL_K_SEQ_NUM);
+ if (!seq) {
+ _E("Failed to get sequence");
+ return;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ interval = __get_timeout_interval(_request_get_start_time(req), &end);
+ info = __create_result_info(interval, pid,
+ _request_remove_fd(req), seq);
+ if (!info) {
+ _E("Failed to create result info");
+ return;
+ }
+
+ __add_result_info(info);
+}
+
+static int __dispatch_app_start(request_h req)
+{
+ const char *appid;
+ int ret;
+ bundle *kb;
+ bool pending = false;
+ bool bg_launch = false;
+ bool new_instance = false;
+ request_reply_h reply;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ __set_real_appid(_request_get_target_uid(req), kb);
+ __set_effective_appid(_request_get_target_uid(req), kb);
+
+ bundle_del(kb, AUL_K_NEW_INSTANCE);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req, kb);
+ __check_new_instance(kb, &new_instance);
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ ret = _launch_start_app(appid, req, &pending, &bg_launch, new_instance);
+ if (ret <= 0)
+ _noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, ret, 0, NULL, NULL);
+
+ if (_request_get_cmd(req) == APP_SEND_LAUNCH_REQUEST_SYNC)
+ __pend_result_info(req, ret);
+
+ /* add pending list to wait app launched successfully */
+ if (pending) {
+ reply = _request_reply_create(req, ret, ret,
+ _request_get_cmd(req));
+ if (reply == NULL)
+ return -1;
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_PEND,
+ ret, bg_launch, req, (bundle *)reply);
+
+ if (_request_reply_append(ret, reply) < 0) {
+ _request_send_result(req, ret);
+ return -1;
+ }
+
+ return 0;
+ }
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END, ret, bg_launch, req, kb);
+
+ return 0;
+}
+
+static int __get_caller_uid(bundle *kb, uid_t *uid)
+{
+ const char *val;
+
+ val = bundle_get_val(kb, AUL_K_ORG_CALLER_UID);
+ if (val == NULL)
+ val = bundle_get_val(kb, AUL_K_CALLER_UID);
+
+ if (val == NULL) {
+ _E("Failed to get caller uid");
+ return -1;
+ }
+
+ *uid = atol(val);
+ _D("caller uid(%d)", *uid);
+
+ return 0;
+}
+
+static void __set_instance_id(bundle *kb)
+{
+ app_status_h app_status;
+ const char *instance_id;
+ const char *callee_pid;
+ int pid;
+
+ callee_pid = bundle_get_val(kb, AUL_K_FWD_CALLEE_PID);
+ if (callee_pid == NULL)
+ callee_pid = bundle_get_val(kb, AUL_K_CALLEE_PID);
+
+ if (callee_pid == NULL) {
+ _E("Failed to get callee pid");
+ return;
+ }
+
+ pid = atoi(callee_pid);
+ if (pid <= 0)
+ return;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return;
+
+ instance_id = _app_status_get_instance_id(app_status);
+ if (instance_id == NULL)
+ return;
+
+ bundle_del(kb, AUL_K_INSTANCE_ID);
+ bundle_add(kb, AUL_K_INSTANCE_ID, instance_id);
+ _D("instance_id(%s)", instance_id);
+}
+
+static int __get_caller_pid(bundle *kb)
+{
+ const char *pid_str;
+ int pid;
+
+ pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+ if (pid_str)
+ goto end;
+
+ pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
+ if (pid_str == NULL)
+ return -1;
+
+end:
+ pid = atoi(pid_str);
+ if (pid <= 1)
+ return -1;
+
+ return pid;
+}
+
+static int __dispatch_app_result(request_h req)
+{
+ bundle *kb;
+ int pid;
+ int pgid;
+ char tmp_pid[MAX_PID_STR_BUFSZ];
+ int res;
+ const char *appid;
+ uid_t target_uid = _request_get_target_uid(req);
+ app_status_h app_status;
+ struct result_info_s *info = NULL;
+ const char *seq;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ pid = __get_caller_pid(kb);
+ if (pid < 0)
+ return AUL_R_ERROR;
+
+ pgid = getpgid(_request_get_pid(req));
+ if (pgid > 0) {
+ snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pgid);
+ bundle_del(kb, AUL_K_CALLEE_PID);
+ bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
+ }
+
+ if (__get_caller_uid(kb, &target_uid) < 0)
+ return AUL_R_ERROR;
+
+ __set_instance_id(kb);
+ app_status = _app_status_find(getpgid(pid));
+ appid = _app_status_get_appid(app_status);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_RESULT_START,
+ pgid, target_uid, (void *)appid, kb);
+
+ seq = bundle_get_val(kb, AUL_K_SEQ_NUM);
+ if (seq)
+ info = __find_result_info(seq);
+
+ if (info) {
+ res = aul_sock_send_bundle_with_fd(info->fd, pid, kb,
+ AUL_SOCK_NOREPLY);
+ __remove_result_info(info);
+ __destroy_result_info(info);
+ } else {
+ res = aul_sock_send_bundle(pid, target_uid,
+ _request_get_cmd(req), kb,
+ AUL_SOCK_NOREPLY);
+ }
+ if (res < 0)
+ res = AUL_R_ERROR;
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_RESULT_END,
+ pid, target_uid, GINT_TO_POINTER(res), NULL);
+
+ return 0;
+}
+
+static int __dispatch_app_pause(request_h req)
+{
+ const char *appid;
+ bundle *kb;
+ int ret;
+ app_status_h app_status;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ ret = _app_status_get_pid(app_status);
+ if (ret > 0)
+ ret = _pause_app(ret, req);
+ else
+ _E("%s is not running", appid);
+
+ return 0;
+}
+
+static int __app_process_by_pid(request_h req, const char *pid_str,
+ bool *pending)
+{
+ int pid;
+ int ret;
+ int dummy;
+ const char *appid;
+ const char *pkgid;
+ const char *type;
+ const struct appinfo *ai;
+ uid_t target_uid = _request_get_target_uid(req);
+ app_status_h app_status;
+
+ if (pid_str == NULL)
+ return -1;
+
+ pid = atoi(pid_str);
+ if (pid <= 1) {
+ _E("invalid pid");
+ return -1;
+ }
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL) {
+ _E("pid %d is not an application", pid);
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = _app_status_get_appid(app_status);
+ ai = _appinfo_find(target_uid, appid);
+ if (ai == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ type = _appinfo_get_value(ai, AIT_COMPTYPE);
+
+ switch (_request_get_cmd(req)) {
+ case APP_RESUME_BY_PID:
+ case APP_RESUME_BY_PID_ASYNC:
+ case APP_PAUSE_BY_PID:
+ aul_send_app_resume_request_signal(pid, appid, pkgid, type);
+ break;
+ default:
+ aul_send_app_terminate_request_signal(pid, appid, pkgid, type);
+ break;
+ }
+
+ switch (_request_get_cmd(req)) {
+ case APP_RESUME_BY_PID_ASYNC:
+ _request_send_result(req, 0);
+ ret = _resume_app(pid, req);
+ break;
+ case APP_RESUME_BY_PID:
+ ret = _resume_app(pid, req);
+ break;
+ case APP_TERM_BY_PID:
+ ret = _term_app(pid, req);
+ break;
+ case APP_TERM_BY_PID_WITHOUT_RESTART:
+ if (_app_status_get_app_type(app_status) == AT_WIDGET_APP)
+ _app_status_update_is_exiting(app_status, true);
+ ret = _term_app(pid, req);
+ break;
+ case APP_TERM_BGAPP_BY_PID:
+ ret = _term_bgapp(pid, req);
+ break;
+ case APP_KILL_BY_PID:
+ ret = __send_sigkill(pid, target_uid);
+ if (ret < 0)
+ _E("fail to killing - %d\n", pid);
+ _app_status_update_status(app_status, STATUS_DYING, false, true);
+ _request_send_result(req, ret);
+ break;
+ case APP_TERM_REQ_BY_PID:
+ ret = _term_req_app(pid, req);
+ break;
+ case APP_TERM_BY_PID_ASYNC:
+ ret = aul_sock_send_raw(pid, target_uid, _request_get_cmd(req),
+ (unsigned char *)&dummy, sizeof(int),
+ AUL_SOCK_NOREPLY);
+ if (ret < 0)
+ _D("terminate req packet send error");
+
+ _request_send_result(req, ret);
+ break;
+ case APP_PAUSE_BY_PID:
+ ret = _pause_app(pid, req);
+ break;
+ case APP_TERM_BY_PID_SYNC:
+ case APP_TERM_BY_PID_SYNC_WITHOUT_RESTART:
+ if (_app_status_get_status(app_status) == STATUS_DYING) {
+ _W("%d is dying", pid);
+ if (pending)
+ *pending = true;
+ ret = 0;
+ break;
+ }
+ ret = _term_app_v2(pid, req, pending);
+ break;
+ case APP_TERM_INSTANCE_ASYNC:
+ ret = _launch_terminate_inst(pid, req);
+ break;
+ default:
+ _E("unknown command: %d", _request_get_cmd(req));
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int __dispatch_app_process_by_pid(request_h req)
+{
+ const char *appid;
+ bundle *kb;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ __app_process_by_pid(req, appid, NULL);
+
+ return 0;
+}
+
+static int __dispatch_app_term_async(request_h req)
+{
+ const char *appid;
+ bundle *kb;
+ const char *term_pid;
+ struct appinfo *ai;
+ app_status_h app_status;
+ const char *ai_status;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ term_pid = bundle_get_val(kb, AUL_K_APPID);
+ app_status = _app_status_find(atoi(term_pid));
+ appid = _app_status_get_appid(app_status);
+ ai = _appinfo_find(_request_get_target_uid(req), appid);
+ if (ai) {
+ ai_status = _appinfo_get_value(ai, AIT_STATUS);
+ if (ai_status && strcmp(ai_status, "blocking") != 0)
+ _appinfo_set_value(ai, AIT_STATUS, "norestart");
+ __app_process_by_pid(req, term_pid, NULL);
+ }
+
+ return 0;
+}
+
+static int __dispatch_app_term(request_h req)
+{
+ const char *appid;
+ bundle *kb;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ __app_process_by_pid(req, appid, NULL);
+
+ return 0;
+}
+
+static int __dispatch_app_term_sync(request_h req)
+{
+ int ret;
+ int pid;
+ const char *appid;
+ bundle *kb;
+ bool pending = false;
+ request_reply_h reply;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ ret = __app_process_by_pid(req, appid, &pending);
+ if (ret < 0)
+ return -1;
+
+ /* add pending list to wait app terminated successfully */
+ if (pending) {
+ pid = atoi(appid);
+ reply = _request_reply_create(req, pid, -EAGAIN,
+ _request_get_cmd(req));
+ if (reply == NULL)
+ return -1;
+
+ _request_reply_append(pid, reply);
+ _request_reply_reset_pending_timer(req, -1, pid);
+ }
+
+ return 0;
+}
+
+static int __dispatch_app_term_sync_without_restart(request_h req)
+{
+ int ret = -1;
+ const char *appid;
+ const char *term_pid;
+ const char *component_type;
+ struct appinfo *ai;
+ app_status_h app_status;
+ const char *ai_status;
+
+ term_pid = bundle_get_val(_request_get_bundle(req), AUL_K_APPID);
+ if (term_pid == NULL)
+ goto exception;
+
+ app_status = _app_status_find(atoi(term_pid));
+ if (app_status == NULL)
+ goto exception;
+
+ appid = _app_status_get_appid(app_status);
+ if (appid == NULL)
+ goto exception;
+
+ ai = _appinfo_find(_request_get_target_uid(req), appid);
+ if (ai == NULL)
+ goto exception;
+
+ component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (!component_type)
+ goto exception;
+
+ ret = __dispatch_app_term_sync(req);
+ if (ret < 0)
+ return ret;
+
+ if (strcmp(component_type, APP_TYPE_SERVICE) == 0) {
+ ai_status = _appinfo_get_value(ai, AIT_STATUS);
+ if (ai_status && strcmp(ai_status, "blocking") != 0)
+ _appinfo_set_value(ai, AIT_STATUS, "norestart");
+ }
+ return 0;
+
+exception:
+ _request_send_result(req, ret);
+ return ret;
+}
+
+static int __dispatch_app_startup_signal(request_h req)
+{
+ int pid = _request_get_pid(req);
+ app_status_h app_status;
+
+ _W("[START] pid(%d)", pid);
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return -1;
+
+ _app_status_update_is_starting(app_status, true);
+ if (_app_status_get_app_type(app_status) == AT_UI_APP &&
+ _app_status_get_status(app_status) != STATUS_VISIBLE)
+ __launch_add_fgmgr(pid);
+
+ _request_reply_reset_pending_timer(req, PENDING_REQUEST_TIMEOUT, pid);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END, pid, 0, req, NULL);
+ _W("[END] pid(%d)", pid);
+
+ return 0;
+}
+
+static int __dispatch_app_term_instance_async(request_h req)
+{
+ const char *appid;
+ bundle *kb;
+ int clifd;
+ int ret;
+
+ kb = _request_get_bundle(req);
+ if (!kb) {
+ _E("Invalid request");
+ _request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ clifd = _request_remove_fd(req);
+ ret = __app_process_by_pid(req, appid, NULL);
+ _send_result_to_client(clifd, ret);
+ _I("[APP_TERM_INSTANCE_ASYNC] result: %d", ret);
+
+ return 0;
+}
+
+static int __dispatch_app_terminate(request_h req)
+{
+ app_status_h app_status;
+ const char *instance_id;
+ const char *appid;
+ uid_t target_uid;
+ bundle *kb;
+ int pid;
+ int ret;
+ int fd;
+
+ kb = _request_get_bundle(req);
+ if (!kb) {
+ _E("Invalid request");
+ _request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ target_uid = _request_get_target_uid(req);
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ if (instance_id) {
+ app_status = _app_status_find_by_instance_id(appid,
+ instance_id, target_uid);
+ } else {
+ app_status = _app_status_find_by_appid(appid, target_uid);
+ }
+
+ if (!app_status) {
+ _E("Failed to find app status");
+ _request_send_result(req, -ENOENT);
+ return -ENOENT;
+ }
+
+ fd = _request_remove_fd(req);
+ pid = _app_status_get_pid(app_status);
+ aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
+ ret = _term_req_app(pid, req);
+ _send_result_to_client(fd, ret);
+ _I("[APP_TERMINATE] result: %d", ret);
+
+ return 0;
+}
+
+static const char *__convert_operation_to_privilege(const char *operation)
+{
+ if (operation == NULL)
+ return NULL;
+ else if (!strcmp(operation, AUL_SVC_OPERATION_DOWNLOAD))
+ return PRIVILEGE_DOWNLOAD;
+ else if (!strcmp(operation, AUL_SVC_OPERATION_CALL))
+ return PRIVILEGE_CALL;
+
+ return NULL;
+}
+
+struct checker_info {
+ caller_info_h caller;
+ request_h req;
+ int result;
+};
+
+static int __appcontrol_privilege_func(const char *privilege_name,
+ void *user_data)
+{
+ int ret;
+ struct checker_info *info = (struct checker_info *)user_data;
+
+ ret = _cynara_simple_checker(info->caller, info->req,
+ (void *)privilege_name);
+ if (ret >= 0 && info->result == AMD_CYNARA_UNKNOWN)
+ return ret;
+
+ info->result = ret;
+ return ret;
+}
+
+static int __appcontrol_checker(caller_info_h info, request_h req,
+ void *data)
+{
+ bundle *appcontrol;
+ const char *op_priv = NULL;
+ const char *appid = NULL;
+ char *op = NULL;
+ int ret;
+ const char *target_appid;
+ bool unknown = false;
+ const char *syspopup;
+ const char *below;
+ struct checker_info checker = {
+ .caller = info,
+ .req = req,
+ .result = AMD_CYNARA_ALLOWED
+ };
+
+ appcontrol = _request_get_bundle(req);
+ if (appcontrol == NULL)
+ return AMD_CYNARA_ALLOWED;
+
+ if (bundle_get_type(appcontrol, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
+ target_appid = bundle_get_val(appcontrol, AUL_K_APPID);
+
+ if (target_appid && strcmp(target_appid, APPID_WIDGET_VIEWER_SDK) != 0) {
+ ret = _cynara_check_privilege_offline(req, target_appid,
+ "http://tizen.org/privilege/internal/appdebugging");
+ if (ret != AMD_CYNARA_ALLOWED) {
+ _E("appdebugging privilege is needed to debug");
+ return ret;
+ }
+ }
+ }
+
+ ret = _cynara_sub_checker_check("appcontrol", info, req);
+ if (ret != AMD_CYNARA_CONTINUE)
+ return ret;
+
+ ret = bundle_get_str(appcontrol, AUL_SVC_K_OPERATION, &op);
+ if (ret == BUNDLE_ERROR_NONE)
+ op_priv = __convert_operation_to_privilege(op);
+ if (op_priv) {
+ ret = _cynara_simple_checker(info, req, (void *)op_priv);
+ if (ret < 0)
+ return ret;
+ if (ret == AMD_CYNARA_UNKNOWN)
+ unknown = true;
+ }
+
+ appid = bundle_get_val(appcontrol, AUL_K_APPID);
+ if (appid && op) {
+ ret = pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(
+ appid, op, __appcontrol_privilege_func,
+ &checker, _request_get_target_uid(req));
+ if (ret < 0) {
+ _E("Failed to get appcontrol privileges");
+ return ret;
+ }
+
+ if (checker.result < 0)
+ return checker.result;
+ else if (checker.result == AMD_CYNARA_UNKNOWN)
+ unknown = true;
+ }
+
+ syspopup = bundle_get_val(appcontrol, SYSPOPUP_NAME);
+ below = bundle_get_val(appcontrol, AUL_SVC_K_RELOCATE_BELOW);
+ if (below || syspopup) {
+ ret = _cynara_simple_checker(info, req, PRIVILEGE_PLATFORM);
+ if (ret < 0)
+ return ret;
+ if (ret == AMD_CYNARA_UNKNOWN)
+ unknown = true;
+ }
+
+ ret = _cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
+ if (unknown && ret >= 0)
+ return AMD_CYNARA_UNKNOWN;
+
+ return ret;
+}
+
+static int __term_req_checker(caller_info_h info, request_h req,
+ void *data)
+{
+ app_status_h app_status;
+ int caller_pid = _request_get_pid(req);
+ int target_pid = -1;
+ int first_caller_pid;
+ const char *pid_str;
+ bundle *b;
+
+ b = _request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ return AMD_CYNARA_DENIED;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_APPID);
+ if (!pid_str) {
+ _E("Failed to get process ID");
+ return AMD_CYNARA_DENIED;
+ }
+
+ target_pid = atoi(pid_str);
+ if (target_pid < 1) {
+ _E("Process ID: %d", target_pid);
+ return AMD_CYNARA_DENIED;
+ }
+
+ app_status = _app_status_find(target_pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", target_pid);
+ return AMD_CYNARA_DENIED;
+ }
+
+ if (_app_status_get_app_type(app_status) != AT_UI_APP) {
+ _E("Target application is not UI application");
+ return AMD_CYNARA_DENIED;
+ }
+
+ first_caller_pid = _app_status_get_org_caller_pid(app_status);
+ if (first_caller_pid != caller_pid &&
+ first_caller_pid != getpgid(caller_pid)) {
+ _E("Request denied. caller(%d)", caller_pid);
+ return AMD_CYNARA_DENIED;
+ }
+
+ return AMD_CYNARA_ALLOWED;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_START,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_START_ASYNC,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_START_RES_ASYNC,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_START_RES,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_OPEN,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_RESUME,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_RESUME_BY_PID,
+ .callback = __dispatch_app_process_by_pid
+ },
+ {
+ .cmd = APP_RESUME_BY_PID_ASYNC,
+ .callback = __dispatch_app_process_by_pid
+ },
+ {
+ .cmd = APP_TERM_BY_PID,
+ .callback = __dispatch_app_term
+ },
+ {
+ .cmd = APP_TERM_BY_PID_WITHOUT_RESTART,
+ .callback = __dispatch_app_term_async
+ },
+ {
+ .cmd = APP_TERM_BY_PID_SYNC,
+ .callback = __dispatch_app_term_sync
+ },
+ {
+ .cmd = APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
+ .callback = __dispatch_app_term_sync_without_restart
+ },
+ {
+ .cmd = APP_TERM_REQ_BY_PID,
+ .callback = __dispatch_app_process_by_pid
+ },
+ {
+ .cmd = APP_TERM_BY_PID_ASYNC,
+ .callback = __dispatch_app_term_async
+ },
+ {
+ .cmd = APP_TERM_BGAPP_BY_PID,
+ .callback = __dispatch_app_term
+ },
+ {
+ .cmd = APP_RESULT,
+ .callback = __dispatch_app_result
+ },
+ {
+ .cmd = APP_CANCEL,
+ .callback = __dispatch_app_result
+ },
+ {
+ .cmd = APP_PAUSE,
+ .callback = __dispatch_app_pause
+ },
+ {
+ .cmd = APP_PAUSE_BY_PID,
+ .callback = __dispatch_app_process_by_pid
+ },
+ {
+ .cmd = APP_KILL_BY_PID,
+ .callback = __dispatch_app_term
+ },
+ {
+ .cmd = APP_STARTUP_SIGNAL,
+ .callback = __dispatch_app_startup_signal
+ },
+ {
+ .cmd = APP_SEND_LAUNCH_REQUEST,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_SEND_LAUNCH_REQUEST_SYNC,
+ .callback = __dispatch_app_start
+ },
+ {
+ .cmd = APP_TERM_INSTANCE_ASYNC,
+ .callback = __dispatch_app_term_instance_async
+ },
+ {
+ .cmd = APP_TERMINATE,
+ .callback = __dispatch_app_terminate
+ },
+ {
+ .cmd = APP_SEND_RESUME_REQUEST,
+ .callback = __dispatch_app_start
+ },
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_OPEN,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_RESUME,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_START,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_START_RES,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_TERM_BY_PID_WITHOUT_RESTART,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_TERM_BY_PID_ASYNC,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_TERM_BY_PID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_KILL_BY_PID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_TERM_BGAPP_BY_PID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL_BGAPP
+ },
+ {
+ .cmd = APP_START_ASYNC,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_TERM_BY_PID_SYNC,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_START_RES_ASYNC,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_TERM_REQ_BY_PID,
+ .checker = __term_req_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_RESUME_BY_PID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = APP_RESUME_BY_PID_ASYNC,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = APP_PAUSE,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = APP_PAUSE_BY_PID,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+ {
+ .cmd = APP_SEND_LAUNCH_REQUEST,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_SEND_LAUNCH_REQUEST_SYNC,
+ .checker = __appcontrol_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_TERMINATE,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL
+ },
+ {
+ .cmd = APP_SEND_RESUME_REQUEST,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_APPMANAGER_LAUNCH
+ },
+};
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ app_status_h app_status = arg3;
+ int pid;
+
+ pid = _app_status_get_pid(app_status);
+ __launch_remove_fgmgr(pid);
+
+ return 0;
+}
+
+static int __default_launcher(bundle *b, uid_t uid, void *data)
+{
+ int r;
+
+ if (!b) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ r = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
+ PAD_CMD_LAUNCH, b);
+ return r;
+}
+
+int _launch_init(void)
+{
+ int ret;
+
+ _D("_launch_init");
+
+ _launchpad_set_launcher(__default_launcher, NULL);
+
+ _signal_add_ready_cb(__listen_app_status_signal, NULL);
+ _signal_add_ready_cb(__listen_poweroff_state_signal, NULL);
+
+ ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ ret = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ _noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP, __on_app_status_cleanup);
+
+ return 0;
+}
+
+static int __check_ver(const char *required, const char *actual)
+{
+ int ret;
+
+ if (required && actual) {
+ ret = strverscmp(required, actual);
+ if (ret < 1)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int __get_prelaunch_attribute(struct appinfo *ai,
+ const char *appid, uid_t uid)
+{
+ int attribute_val = RESOURCED_BG_MANAGEMENT_ATTRIBUTE;
+ const char *api_version;
+ const char *comp;
+ const char *pkg_type;
+ bool system = false;
+ app_property_h prop;
+ bool activate;
+
+ api_version = _appinfo_get_value(ai, AIT_API_VERSION);
+ if (api_version && __check_ver("2.4", api_version))
+ attribute_val |= RESOURCED_API_VER_2_4_ATTRIBUTE;
+
+ comp = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp && !strcmp(comp, APP_TYPE_SERVICE))
+ attribute_val |= RESOURCED_ATTRIBUTE_SERVICE_APP;
+
+ pkg_type = _appinfo_get_value(ai, AIT_PKGTYPE);
+ if (pkg_type && !strcmp(pkg_type, "wgt")) {
+ attribute_val |= RESOURCED_ATTRIBUTE_LARGEMEMORY;
+ attribute_val |= RESOURCED_ATTRIBUTE_WEB_APP;
+ }
+
+ _appinfo_get_boolean(ai, AIT_SYSTEM, &system);
+ if (!system)
+ attribute_val |= RESOURCED_ATTRIBUTE_DOWNLOAD_APP;
+
+ prop = _app_property_find(uid);
+ if (prop) {
+ activate = _app_property_metadata_query_activation(prop, appid,
+ METADATA_LARGEMEMORY);
+ if (activate)
+ attribute_val |= RESOURCED_ATTRIBUTE_LARGEMEMORY;
+ activate = _app_property_metadata_query_activation(prop, appid,
+ METADATA_OOMTERMINATION);
+ if (activate)
+ attribute_val |= RESOURCED_ATTRIBUTE_OOMTERMINATION;
+ activate = _app_property_metadata_query_activation(prop, appid,
+ METADATA_VIPAPP);
+ if (activate && _appinfo_is_platform_app(appid, uid))
+ attribute_val |= RESOURCED_ATTRIBUTE_VIP_APP;
+
+ }
+
+ _D("api-version: %s", api_version);
+ _D("prelaunch attribute %d%d%d%d%d%d",
+ (attribute_val & 0x20) >> 5,
+ (attribute_val & 0x10) >> 4,
+ (attribute_val & 0x8) >> 3,
+ (attribute_val & 0x4) >> 2,
+ (attribute_val & 0x2) >> 1,
+ (attribute_val & 0x1));
+
+ return attribute_val;
+}
+
+static int __get_background_category(const struct appinfo *ai)
+{
+ int category = 0x0;
+
+ category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
+
+ _D("background category: %#x", category);
+
+ return category;
+}
+
+static void __set_caller_appinfo(const char *caller_appid, int caller_pid,
+ uid_t caller_uid, bundle *kb)
+{
+ char buf[MAX_PID_STR_BUFSZ];
+
+ snprintf(buf, sizeof(buf), "%d", caller_pid);
+ bundle_del(kb, AUL_K_CALLER_PID);
+ bundle_add(kb, AUL_K_CALLER_PID, buf);
+
+ snprintf(buf, sizeof(buf), "%d", caller_uid);
+ bundle_del(kb, AUL_K_CALLER_UID);
+ bundle_add(kb, AUL_K_CALLER_UID, buf);
+
+ if (caller_appid) {
+ bundle_del(kb, AUL_K_CALLER_APPID);
+ bundle_add(kb, AUL_K_CALLER_APPID, caller_appid);
+ }
+}
+
+static const char *__get_caller_appid(int caller_pid, uid_t caller_uid)
+{
+ app_status_h app_status;
+
+ app_status = _app_status_find(caller_pid);
+ if (app_status == NULL && caller_uid >= REGULAR_UID_MIN)
+ app_status = _app_status_find(getpgid(caller_pid));
+
+ return _app_status_get_appid(app_status);
+}
+
+static int __check_caller(pid_t caller_pid)
+{
+ char attr[512] = { 0, };
+ int r;
+
+ r = _proc_get_attr(caller_pid, attr, sizeof(attr));
+ if (r < 0) {
+ _E("Failed to get attr. pid(%d)", caller_pid);
+ return -EILLEGALACCESS;
+ }
+
+ if (!strncmp(attr, "User::Pkg::", strlen("User::Pkg::"))) {
+ _E("Reject request. caller(%d:%s)", caller_pid, attr);
+ return -EILLEGALACCESS;
+ }
+
+ return 0;
+}
+
+static int __check_executable(const struct appinfo *ai)
+{
+ const char *status;
+ const char *ignore;
+ int enable;
+ int ret;
+
+ status = _appinfo_get_value(ai, AIT_STATUS);
+ if (status == NULL) {
+ _E("Failed to get status value");
+ return -1;
+ }
+
+ if (!strcmp(status, "blocking") || !strcmp(status, "restart")) {
+ ignore = _appinfo_get_value(ai, AIT_IGNORE);
+ if (!ignore || strcmp(ignore, "true") != 0) {
+ _W("Blocking");
+ return -ENOENT;
+ }
+ _W("Ignore blocking");
+ }
+
+ ret = _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
+ if (ret == 0 && !(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
+ _W("Disabled");
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+static void __set_appinfo_for_launchpad(const struct appinfo *ai, bundle *kb)
+{
+ const char *str;
+
+ str = _appinfo_get_value(ai, AIT_HWACC);
+ if (str) {
+ bundle_del(kb, AUL_K_HWACC);
+ bundle_add(kb, AUL_K_HWACC, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_ROOT_PATH);
+ if (str) {
+ bundle_del(kb, AUL_K_ROOT_PATH);
+ bundle_add(kb, AUL_K_ROOT_PATH, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_EXEC);
+ if (str) {
+ bundle_del(kb, AUL_K_EXEC);
+ bundle_add(kb, AUL_K_EXEC, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_PKGTYPE);
+ if (str) {
+ bundle_del(kb, AUL_K_PACKAGETYPE);
+ bundle_add(kb, AUL_K_PACKAGETYPE, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_PKGID);
+ if (str) {
+ bundle_del(kb, AUL_K_PKGID);
+ bundle_add(kb, AUL_K_PKGID, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_POOL);
+ if (str) {
+ bundle_del(kb, AUL_K_INTERNAL_POOL);
+ bundle_add(kb, AUL_K_INTERNAL_POOL, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (str) {
+ bundle_del(kb, AUL_K_COMP_TYPE);
+ bundle_add(kb, AUL_K_COMP_TYPE, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_APPTYPE);
+ if (str) {
+ bundle_del(kb, AUL_K_APP_TYPE);
+ bundle_add(kb, AUL_K_APP_TYPE, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_API_VERSION);
+ if (str) {
+ bundle_del(kb, AUL_K_API_VERSION);
+ bundle_add(kb, AUL_K_API_VERSION, str);
+ }
+
+ if (_config_get_tizen_profile() == TIZEN_PROFILE_WEARABLE) {
+ bundle_del(kb, AUL_K_PROFILE);
+ bundle_add(kb, AUL_K_PROFILE, "wearable");
+ }
+
+ str = _appinfo_get_value(ai, AIT_GLOBAL);
+ if (str) {
+ bundle_del(kb, AUL_K_IS_GLOBAL);
+ bundle_add(kb, AUL_K_IS_GLOBAL, str);
+ }
+
+ str = _appinfo_get_value(ai, AIT_STORAGE_TYPE);
+ if (str) {
+ bundle_del(kb, AUL_K_INSTALLED_STORAGE);
+ bundle_add(kb, AUL_K_INSTALLED_STORAGE, str);
+ }
+}
+
+static int __get_comp_status(struct launch_s *handle, request_h req)
+{
+ int status;
+
+ if (handle->instance_id) {
+ handle->comp_status = _comp_status_find_by_instance_id(
+ handle->instance_id);
+ } else {
+ handle->comp_status = _comp_status_find(handle->comp_id);
+ }
+
+ status = _comp_status_get_status(handle->comp_status);
+ if (status == COMP_STATUS_DESTROYED) {
+ SECURE_LOGW("%s is destroyed", handle->instance_id);
+ if (handle->instance_id)
+ return -1;
+
+ handle->comp_status = NULL;
+ }
+
+ if (handle->comp_status == NULL)
+ handle->new_instance = true;
+
+ return 0;
+}
+
+static int __compare_compinfo_appid(struct launch_s *handle)
+{
+ const char *appid;
+
+ appid = _compinfo_get_value(handle->ci, CIT_APPID);
+ if (!appid) {
+ _E("Failed to get application ID. component(%s)",
+ handle->comp_id);
+ return -EREJECTED;
+ }
+
+ if (strcmp(appid, handle->appid) != 0) {
+ _E("Invalid request(%s:%s)", appid, handle->appid);
+ return -EREJECTED;
+ }
+
+ return 0;
+}
+
+void __find_main_compinfo(compinfo_h info, const char *appid,
+ const char *id, void *user_data)
+{
+ struct launch_s *handle = (struct launch_s *)user_data;
+ const char *val;
+
+ if (strcmp(appid, handle->appid) != 0)
+ return;
+
+ val = _compinfo_get_value(info, CIT_MAIN);
+ if (val && !strcmp(val, "true")) {
+ handle->ci = info;
+ handle->comp_id = id;
+ }
+}
+
+static int __set_main_comp_id(struct launch_s *handle, bundle *kb, uid_t uid)
+{
+ int ret;
+
+ ret = _compinfo_foreach(uid, __find_main_compinfo, handle);
+ if (ret != 0) {
+ _E("Failed to retrieve compinfo");
+ return -EREJECTED;
+ }
+
+ if (handle->ci == NULL || handle->comp_id == NULL) {
+ _E("Failed to find compinfo");
+ return -EREJECTED;
+ }
+
+ bundle_add(kb, AUL_K_COMPONENT_ID, handle->comp_id);
+ SECURE_LOGW("Set Main Component ID(%s) of App ID(%s)",
+ handle->comp_id, handle->appid);
+
+ return 0;
+}
+
+static int __get_app_status(struct launch_s *handle, request_h req,
+ const char *comp_type, const char *caller_appid)
+{
+ const char *widget_viewer;
+ const char *multiple;
+ int *target_pid = NULL;
+ size_t target_pid_sz;
+ bundle *kb = _request_get_bundle(req);
+ int caller_pid = _request_get_pid(req);
+ uid_t target_uid = _request_get_target_uid(req);
+ int ret;
+
+ if (caller_appid && strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
+ handle->is_subapp = true;
+ widget_viewer = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
+ if (widget_viewer && strcmp(widget_viewer, caller_appid) == 0) {
+ _D("widget_viewer(%s)", widget_viewer);
+ handle->app_status = _app_status_find_with_org_caller(
+ handle->appid, target_uid, caller_pid);
+ } else {
+ ret = bundle_get_byte(kb, AUL_K_TARGET_PID,
+ (void **)&target_pid, &target_pid_sz);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Cannot launch widget app");
+ return -EREJECTED;
+ }
+
+ handle->app_status = _app_status_find(*target_pid);
+ if (handle->app_status == NULL) {
+ _E("Cannot find widget app(%d)", *target_pid);
+ return -EREJECTED;
+ }
+
+ if (_app_status_get_status(handle->app_status)
+ == STATUS_DYING) {
+ _E("Dying widget(%s) reject launching",
+ handle->appid);
+ return -EREJECTED;
+ }
+ }
+ } else if (strcmp(comp_type, APP_TYPE_WATCH) == 0) {
+ handle->is_subapp = true;
+ widget_viewer = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
+ if (widget_viewer && caller_appid &&
+ !strcmp(widget_viewer, caller_appid)) {
+ _D("watch_viewer(%s)", widget_viewer);
+ handle->app_status = _app_status_find_with_org_caller(
+ handle->appid, target_uid, caller_pid);
+ } else {
+ ret = bundle_get_byte(kb, AUL_K_TARGET_PID,
+ (void **)&target_pid, &target_pid_sz);
+ if (ret != BUNDLE_ERROR_NONE) {
+ handle->app_status =
+ _app_status_find_by_appid_v2(
+ handle->appid,
+ target_uid);
+ } else {
+ handle->app_status =
+ _app_status_find(*target_pid);
+ }
+
+ if (handle->app_status == NULL) {
+ _E("Cannot find watch app(%s)", handle->appid);
+ return -EREJECTED;
+ }
+ }
+ } else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0) {
+ handle->comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ if (!handle->comp_id) {
+ ret = __set_main_comp_id(handle, kb, target_uid);
+ if (ret < 0)
+ return ret;
+ }
+
+ handle->instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ SECURE_LOGD("component(%s), instance(%s)",
+ handle->comp_id, handle->instance_id);
+
+ if (!handle->ci) {
+ handle->ci = _compinfo_find(target_uid,
+ handle->comp_id);
+ }
+
+ if (!handle->ci) {
+ _E("Failed to find component(%s)", handle->comp_id);
+ return -EREJECTED;
+ }
+
+ ret = __compare_compinfo_appid(handle);
+ if (ret < 0)
+ return ret;
+
+ handle->app_status = _app_status_find_by_appid(handle->appid,
+ target_uid);
+ if (handle->app_status) {
+ ret = __get_comp_status(handle, req);
+ if (ret < 0) {
+ _E("Failed to get component(%s) status",
+ handle->appid);
+ return -EREJECTED;
+ }
+ } else {
+ handle->new_instance = true;
+ }
+ } else {
+ handle->instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ if (handle->instance_id) {
+ handle->app_status = _app_status_find_by_instance_id(
+ handle->appid, handle->instance_id,
+ target_uid);
+ if (!handle->app_status && !handle->new_instance) {
+ _E("Failed to find app instance(%s)",
+ handle->instance_id);
+ return -EREJECTED;
+ }
+ } else {
+ multiple = _appinfo_get_value(handle->ai, AIT_MULTI);
+ if (multiple == NULL || !strcmp(multiple, "false")) {
+ handle->app_status = _app_status_find_by_appid(
+ handle->appid, target_uid);
+ }
+ }
+ }
+
+ handle->pid = _app_status_get_pid(handle->app_status);
+
+ return 0;
+}
+
+static void __set_comp_instance_info(struct launch_s *handle, bundle *kb)
+{
+ if (!handle->comp_status) {
+ handle->instance_id = _comp_status_generate_instance(
+ handle->comp_id);
+ } else {
+ handle->instance_id = _comp_status_get_instance_id(
+ handle->comp_status);
+ }
+
+ bundle_del(kb, AUL_K_INSTANCE_ID);
+ bundle_add(kb, AUL_K_INSTANCE_ID, handle->instance_id);
+}
+
+static int __prepare_starting_app(struct launch_s *handle, request_h req,
+ const char *appid, bool new_instance)
+{
+ int ret;
+ int status;
+ const char *pkgid;
+ const char *comp_type;
+ const char *caller_appid = NULL;
+ const char *bg_launch;
+ int cmd = _request_get_cmd(req);
+ int caller_pid = _request_get_pid(req);
+ uid_t caller_uid = _request_get_uid(req);
+ uid_t target_uid = _request_get_target_uid(req);
+ bundle *kb = _request_get_bundle(req);
+ const struct appinfo *caller_ai;
+
+ if (__launch_mode != LAUNCH_MODE_NORMAL) {
+ _E("Launch mode is not normal: %d", __launch_mode);
+ return -EREJECTED;
+ }
+
+ handle->new_instance = new_instance;
+ handle->appid = appid;
+ handle->ai = _appinfo_find(target_uid, appid);
+ if (handle->ai == NULL) {
+ _E("Failed to find appinfo of %s", appid);
+ return -ENOENT;
+ }
+
+ ret = __check_executable(handle->ai);
+ if (ret < 0)
+ return ret;
+
+ if (caller_uid >= REGULAR_UID_MIN) {
+ caller_appid = __get_caller_appid(caller_pid, caller_uid);
+ if (!caller_appid) {
+ ret = __check_caller(caller_pid);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ if (caller_appid) {
+ caller_ai = _appinfo_find(caller_uid, caller_appid);
+ if (caller_ai) {
+ comp_type = _appinfo_get_value(caller_ai, AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI))
+ bundle_del(kb, AUL_SVC_K_CAN_BE_LEADER);
+ }
+ }
+ __set_caller_appinfo(caller_appid, caller_pid, caller_uid, kb);
+
+ ret = __compare_signature(handle->ai, cmd, target_uid, appid,
+ caller_appid);
+ if (ret < 0)
+ return ret;
+
+ ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
+ (int)target_uid, 0, (void *)(handle->ai), NULL);
+ if (ret < 0) {
+ _E("Unable to launch %s (Some listeners don't want to continue)",
+ handle->appid);
+ return -1;
+ }
+
+ bg_launch = bundle_get_val(kb, AUL_SVC_K_BG_LAUNCH);
+ if (bg_launch && strcmp(bg_launch, "enable") == 0)
+ handle->bg_launch = true;
+
+ comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
+ if (comp_type == NULL)
+ return -1;
+
+ ret = __get_app_status(handle, req, comp_type, caller_appid);
+ if (ret < 0)
+ return ret;
+
+ if (strcmp(comp_type, APP_TYPE_UI) == 0) {
+ status = _app_status_get_status(handle->app_status);
+ ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
+ status, target_uid, handle, kb);
+ if (ret < 0)
+ return -EILLEGALACCESS;
+
+ if (handle->pid > 0) {
+ handle->app_status = _app_status_find(handle->pid);
+ status = _app_status_get_status(handle->app_status);
+ }
+
+ if (handle->pid <= 0 || status == STATUS_DYING)
+ handle->new_process = true;
+
+ if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END,
+ handle->bg_launch, caller_pid,
+ (void *)(handle->app_status), NULL) < 0)
+ return -1;
+ } else if (caller_appid && strcmp(comp_type, APP_TYPE_SERVICE) == 0) {
+ pkgid = _appinfo_get_value(handle->ai, AIT_PKGID);
+ ret = __check_execute_permission(pkgid, caller_appid,
+ target_uid, req);
+ if (ret < 0)
+ return ret;
+ if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_SERVICE,
+ 0, 0, req, NULL) < 0)
+ return -1;
+ } else if (caller_appid && strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
+ if (_noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET,
+ 0, 0, req, NULL) < 0)
+ return -1;
+ } else if (strcmp(comp_type, APP_TYPE_COMPONENT_BASED) == 0) {
+ status = _app_status_get_status(handle->app_status);
+ ret = _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
+ status, target_uid, handle, kb);
+ if (ret < 0)
+ return -EILLEGALACCESS;
+
+ if (handle->pid > 0) {
+ handle->app_status = _app_status_find(handle->pid);
+ status = _app_status_get_status(handle->app_status);
+ }
+
+ if (handle->pid <= 0 || status == STATUS_DYING)
+ handle->new_process = true;
+
+ if (!handle->comp_status)
+ handle->new_instance = true;
+
+ if (!handle->instance_id)
+ __set_comp_instance_info(handle, kb);
+ }
+
+ if (cmd == APP_START_RES ||
+ cmd == APP_START_RES_ASYNC ||
+ cmd == APP_SEND_LAUNCH_REQUEST ||
+ cmd == APP_SEND_LAUNCH_REQUEST_SYNC) {
+ bundle_del(kb, AUL_K_WAIT_RESULT);
+ bundle_add(kb, AUL_K_WAIT_RESULT, "1");
+ }
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
+ caller_pid, target_uid, (void *)(handle->ai), kb);
+ handle->prelaunch_attr = __get_prelaunch_attribute(
+ handle->ai, appid, target_uid);
+ handle->bg_category = __get_background_category(handle->ai);
+ handle->bg_allowed = _suspend_is_allowed_background(handle->ai);
+ if (handle->bg_allowed) {
+ _D("[__SUSPEND__] allowed background, appid: %s, app-type: %s",
+ appid, comp_type);
+ bundle_del(kb, AUL_K_ALLOWED_BG);
+ bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
+ }
+
+ _request_set_request_type(req, NULL);
+
+ return 0;
+}
+
+
+static void __kill_and_cleanup_status(struct launch_s *handle, uid_t uid)
+{
+ app_type_e type;
+ char buf[12];
+
+ type = _app_status_get_app_type(handle->app_status);
+ if (type == AT_WIDGET_APP || type == AT_WATCH_APP) {
+ _W("Dead %s:%d", handle->appid, handle->pid);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_MAIN_APP_DEAD,
+ handle->pid, uid, handle->app_status, NULL);
+ }
+
+ if (!_app_status_is_debug_mode(handle->app_status))
+ __send_sigkill(handle->pid, uid);
+
+ snprintf(buf, sizeof(buf), "%d", handle->pid);
+ _util_save_log("TERMINATED", buf);
+
+ _app_status_cleanup(handle->app_status);
+ handle->app_status = NULL;
+}
+
+static int __do_starting_app(struct launch_s *handle, request_h req,
+ bool *pending, bool *bg_launch)
+{
+ int status = -1;
+ int cmd = _request_get_cmd(req);
+ int caller_pid = _request_get_pid(req);
+ uid_t target_uid = _request_get_target_uid(req);
+ bundle *kb = _request_get_bundle(req);
+ const char *pkgid;
+ const char *comp_type;
+ int ret;
+ bool socket_exists;
+ bool is_ime = false;
+
+ pkgid = _appinfo_get_value(handle->ai, AIT_PKGID);
+ comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
+ status = _app_status_get_status(handle->app_status);
+ if (handle->pid > 0 && status != STATUS_DYING) {
+ if (handle->pid == caller_pid) {
+ SECURE_LOGD("caller & callee process are same. %s:%d,",
+ handle->appid, handle->pid);
+ if (comp_type &&
+ strcmp(comp_type, APP_TYPE_COMPONENT_BASED))
+ return -ELOCALLAUNCH_ID;
+ }
+
+ _util_save_log("RESUMING", handle->appid);
+
+ aul_send_app_resume_request_signal(handle->pid,
+ handle->appid, pkgid, comp_type);
+ _suspend_remove_timer(handle->pid);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_SERVICE)) {
+ if (handle->bg_allowed == false) {
+ __prepare_to_wake_services(handle->pid,
+ target_uid);
+ }
+ }
+
+ ret = __nofork_processing(cmd, handle->pid, kb, req);
+ if (ret < 0) {
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL,
+ ret, 0, NULL, NULL);
+ socket_exists =
+ _app_status_socket_exists(handle->app_status);
+ if ((ret == -ECOMM && socket_exists) ||
+ getpgid(handle->pid) < 0) {
+ _E("ECOMM error, we will term the app - %s:%d",
+ handle->appid, handle->pid);
+ __kill_and_cleanup_status(handle, target_uid);
+ return -1;
+ }
+ }
+
+ _app_status_update_last_caller_pid(
+ handle->app_status, caller_pid);
+ _app_status_update_bg_launch(
+ handle->app_status, handle->bg_launch);
+ *bg_launch = _app_status_get_bg_launch(handle->app_status);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END,
+ handle->pid, handle->bg_launch, handle,
+ (bundle *)req);
+
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI) &&
+ status != STATUS_VISIBLE)
+ __launch_add_fgmgr(handle->pid);
+ return ret;
+ }
+
+ if (handle->pid > 0 && status == STATUS_DYING)
+ __kill_and_cleanup_status(handle, target_uid);
+
+ __set_appinfo_for_launchpad(handle->ai, kb);
+ if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) {
+ aul_svc_set_loader_id(kb, PAD_LOADER_ID_DIRECT);
+ handle->debug_mode = true;
+ }
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START, cmd, 0, handle, kb);
+ _signal_send_proc_prelaunch(handle->appid, pkgid,
+ handle->prelaunch_attr, handle->bg_category);
+
+ ret = _launchpad_launch(kb, target_uid);
+ if (ret < 0) {
+ __failure_count++;
+ _E("[%u] Failed to send launch request. appid(%s), error(%d)",
+ __failure_count, handle->appid, ret);
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
+ ret, 0, NULL, NULL);
+ if (__failure_count > _config_get_max_launch_failure()) {
+ _launchpad_recover_launcher(target_uid);
+ __failure_count = 0;
+ }
+ return ret;
+ }
+
+ __failure_count = 0;
+ handle->pid = ret;
+ *pending = true;
+ *bg_launch = handle->bg_launch;
+ handle->new_process = true;
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
+ handle->pid, handle->bg_launch, handle, (bundle *)req);
+ _suspend_add_proc(handle->pid);
+ aul_send_app_launch_request_signal(handle->pid, handle->appid,
+ pkgid, comp_type);
+ _appinfo_get_boolean(handle->ai, AIT_IME, &is_ime);
+ if (is_ime)
+ _signal_send_system_service(handle->pid);
+
+ _util_save_log("LAUNCHING", handle->appid);
+ if (handle->debug_mode) {
+ _W("Exclude - %s(%d)", handle->appid, handle->pid);
+ _suspend_exclude(handle->pid);
+ return ret;
+ }
+
+ if (handle->bg_category == BACKGROUND_CATEGORY_BACKGROUND_NETWORK) {
+ if (!handle->bg_allowed)
+ _suspend_include(handle->pid);
+ }
+
+ if (comp_type && !strcmp(comp_type, APP_TYPE_SERVICE)) {
+ if (!handle->bg_allowed)
+ g_idle_add(__check_service_only, GINT_TO_POINTER(ret));
+ }
+
+ return ret;
+}
+
+static int __complete_starting_app(struct launch_s *handle, request_h req)
+{
+ bundle *kb = _request_get_bundle(req);
+ uid_t target_uid = _request_get_target_uid(req);
+ int caller_pid = _request_get_pid(req);
+ const char *comp_type;
+ char log_status[AUL_PR_NAME];
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ handle->pid, handle->new_process,
+ (void *)(handle->ai), kb);
+ comp_type = _appinfo_get_value(handle->ai, AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ if (handle->new_process) {
+ __pid_of_last_launched_ui_app = handle->pid;
+ }
+ }
+
+ _app_status_add_app_info(handle->ai, handle->pid, handle->is_subapp,
+ target_uid, caller_pid, handle->bg_launch,
+ handle->instance_id, handle->debug_mode);
+ _comp_status_add_comp_info(handle->ci, handle->pid, handle->instance_id,
+ handle->is_subapp);
+
+ _noti_send(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
+ handle->pid, target_uid, handle->ai, kb);
+ snprintf(log_status, sizeof(log_status), "SUCCESS: %d", handle->pid);
+ _util_save_log(log_status, handle->appid);
+ return handle->pid;
+}
+
+int _launch_start_onboot_apps(uid_t uid)
+{
+ return _boot_manager_start_onboot_apps(uid);
+}
+
+int _launch_start_app(const char *appid, request_h req, bool *pending,
+ bool *bg_launch, bool new_instance)
+{
+ int ret;
+ struct launch_s launch_data = {0,};
+ int caller_pid = _request_get_pid(req);
+ uid_t caller_uid = _request_get_uid(req);
+ int cmd = _request_get_cmd(req);
+
+ traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AMD:START_APP");
+ _W("_launch_start_app: appid=%s caller pid=%d uid=%d",
+ appid, caller_pid, caller_uid);
+
+ ret = __prepare_starting_app(&launch_data, req, appid, new_instance);
+ if (ret < 0) {
+ _request_send_result(req, ret);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+ _util_save_log("FAILURE", appid);
+ return -1;
+ }
+
+ ret = __do_starting_app(&launch_data, req, pending, bg_launch);
+ if (ret < 0) {
+ _request_send_result(req, ret);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+ _util_save_log("FAILURE", appid);
+ return -1;
+ }
+
+ if (cmd == APP_START_ASYNC || cmd == APP_START_RES_ASYNC)
+ _request_send_result(req, ret);
+
+ ret = __complete_starting_app(&launch_data, req);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+ if (ret < 0)
+ _util_save_log("FAILURE", appid);
+
+ return ret;
+}
+
+int _launch_context_get_pid(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return -1;
+
+ return h->pid;
+}
+
+int _launch_context_set_pid(launch_h h, int pid)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return -1;
+
+ h->pid = pid;
+
+ return 0;
+}
+
+const char *_launch_context_get_appid(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return NULL;
+
+ return h->appid;
+}
+
+bool _launch_context_is_new_instance(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return false;
+
+ return h->new_instance;
+}
+
+int _launch_context_set_subapp(launch_h h, bool is_subapp)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return -1;
+
+ h->is_subapp = is_subapp;
+
+ return 0;
+}
+
+int _launch_context_set_app_status(launch_h h, app_status_h status)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return -1;
+
+ h->app_status = status;
+
+ return 0;
+}
+
+int _launch_context_set_comp_status(launch_h h, comp_status_h status)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return -1;
+
+ h->comp_status = status;
+
+ return 0;
+}
+
+const char *_launch_context_get_instance_id(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return NULL;
+
+ return h->instance_id;
+}
+
+bool _launch_context_is_subapp(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return false;
+
+ return h->is_subapp;
+}
+
+bool _launch_context_is_bg_launch(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return false;
+
+ return h->bg_launch;
+}
+
+const struct appinfo *_launch_context_get_appinfo(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return NULL;
+
+ return h->ai;
+}
+
+void _launch_context_set_custom_effect(launch_h h, bool is_custom_effect)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return;
+
+ h->is_custom_effect = is_custom_effect;
+}
+
+bool _launch_context_is_custom_effect(launch_h h)
+{
+ struct launch_s *context = h;
+
+ if (!context)
+ return false;
+
+ return h->is_custom_effect;
+}
+
+void _launch_set_mode(launch_mode_e mode)
+{
+ if (mode > LAUNCH_MODE_BLOCK) {
+ _E("Invalid mode: %d", mode);
+ return;
+ }
+
+ __launch_mode = mode;
+ _W("Mode: %d", __launch_mode);
+}
+
+int _launch_send_sigkill(int pid, uid_t uid)
+{
+ return __send_sigkill(pid, uid);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_LAUNCH_H__
+#define __AMD_LAUNCH_H__
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <bundle.h>
+
+#include "amd_request.h"
+#include "amd_util.h"
+#include "amd_appinfo.h"
+#include "amd_app_status.h"
+#include "amd_comp_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROC_STATUS_LAUNCH 0
+#define PROC_STATUS_FG 3
+#define PROC_STATUS_BG 4
+#define PROC_STATUS_FOCUS 5
+#define PROC_STATUS_HIDE 7
+
+typedef struct launch_s *launch_h;
+
+typedef enum {
+ LAUNCH_MODE_NORMAL,
+ LAUNCH_MODE_BLOCK,
+} launch_mode_e;
+
+int _resume_app(int pid, request_h req);
+
+int _pause_app(int pid, request_h req);
+
+int _term_app(int pid, request_h req);
+
+int _term_req_app(int pid, request_h req);
+
+int _term_bgapp(int pid, request_h req);
+
+int _term_sub_app(int pid, uid_t uid);
+
+int _term_sub_inst(pid_t pid, const char *inst_id, uid_t uid);
+
+int _launch_start_app(const char *appid, request_h req, bool *pending,
+ bool *bg_launch, bool new_instance);
+
+int _launch_start_app_local(uid_t uid, const char *appid);
+
+int _launch_start_app_local_with_bundle(uid_t uid, const char *appid,
+ bundle *kb);
+
+int _launch_start_onboot_app_local(uid_t uid, const char *appid,
+ struct appinfo *ai);
+
+int _launch_init(void);
+
+void _launch_set_focused_pid(int pid);
+
+int _launch_get_focused_pid(void);
+
+int _term_app_v2(int pid, request_h req, bool *pend);
+
+int _launch_start_onboot_apps(uid_t uid);
+
+int _terminate_app_local(uid_t uid, int pid);
+
+int _launch_context_get_pid(launch_h h);
+
+int _launch_context_set_pid(launch_h h, int pid);
+
+const char *_launch_context_get_appid(launch_h h);
+
+bool _launch_context_is_new_instance(launch_h h);
+
+int _launch_context_set_subapp(launch_h h, bool is_subapp);
+
+int _launch_context_set_app_status(launch_h h, app_status_h status);
+
+int _launch_context_set_comp_status(launch_h h, comp_status_h status);
+
+const char *_launch_context_get_instance_id(launch_h h);
+
+bool _launch_context_is_subapp(launch_h h);
+
+bool _launch_context_is_bg_launch(launch_h h);
+
+const struct appinfo *_launch_context_get_appinfo(launch_h h);
+
+void _launch_context_set_custom_effect(launch_h h, bool is_custom_effect);
+
+bool _launch_context_is_custom_effect(launch_h h);
+
+void _launch_set_mode(launch_mode_e mode);
+
+int _launch_resume_inst(int pid, request_h req);
+
+int _launch_pause_inst(int pid, request_h req);
+
+int _launch_terminate_bg_inst(int pid, request_h req);
+
+int _launch_terminate_inst(int pid, request_h req);
+
+int _launch_send_sigkill(int pid, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LAUNCH_H__ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <aul.h>
+#include <system_info.h>
+#include <aul_comp_types.h>
+
+#include "amd_appinfo.h"
+#include "amd_compinfo.h"
+#include "amd_launch_mode.h"
+#include "aul_svc_priv_key.h"
+
+#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+
+bool _launch_mode_is_group_mode(bundle *kb, uid_t uid)
+{
+ const char *str;
+ const char *mode = NULL;
+ const char *appid;
+ const char *comp_type;
+ const char *comp_id;
+ const char *type;
+ struct appinfo *ai;
+ compinfo_h ci;
+
+ if (!kb)
+ return false;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (!appid)
+ return false;
+
+ ai = _appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ mode = _appinfo_get_value(ai, AIT_LAUNCH_MODE);
+ } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
+ comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ if (!comp_id)
+ return false;
+
+ ci = _compinfo_find(uid, comp_id);
+ if (!ci)
+ return false;
+
+ type = _compinfo_get_value(ci, CIT_TYPE);
+ if (!type || strcmp(type, "frame") != 0)
+ return false;
+
+ mode = _compinfo_get_value(ci, CIT_LAUNCH_MODE);
+ }
+
+ if (mode && !strcmp(mode, "caller")) {
+ str = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
+ if (str && !strcmp(str, "group"))
+ return true;
+ } else if (mode && !strcmp(mode, "group")) {
+ return true;
+ }
+
+ return false;
+}
--- /dev/null
+/*
+ * 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_LAUNCH_MODE_H__
+#define __AMD_LAUNCH_MODE_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include <bundle_internal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool _launch_mode_is_group_mode(bundle *kb, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LAUNCH_MODE_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <bundle_internal.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_sock.h>
+
+#include "amd_api_noti.h"
+#include "amd_app_com.h"
+#include "amd_app_status.h"
+#include "amd_launch.h"
+#include "amd_launcher_service.h"
+#include "amd_noti.h"
+#include "amd_request.h"
+#include "amd_util.h"
+
+struct launcher_service_context_s {
+ char *launcher_service;
+ char *serial;
+};
+
+static struct launcher_service_context_s __context;
+
+static bundle *__create_bundle(const char *app_id, const char *instance_id,
+ int pid)
+{
+ char pid_str[MAX_PID_STR_BUFSZ];
+ bundle *b;
+
+ b = bundle_create();
+ if (!b) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ bundle_add(b, AUL_K_APPID, app_id);
+ bundle_add(b, AUL_K_INSTANCE_ID, instance_id ? instance_id : "");
+
+ snprintf(pid_str, sizeof(pid_str), "%d", pid);
+ bundle_add(b, AUL_K_PID, pid_str);
+
+ return b;
+}
+
+static void __publish_launcher_service(const char *endpoint,
+ const char *app_id, const char *instance_id, int pid,
+ const char *serial, uid_t uid)
+{
+ bundle *b;
+
+ b = __create_bundle(app_id, instance_id, pid);
+ if (!b)
+ return;
+
+ bundle_add(b, AUL_K_LAUNCHER_SERVICE_SERIAL, serial);
+
+ _app_com_send(endpoint, pid, b, uid);
+ bundle_free(b);
+}
+
+static const char *__get_instance_id(int pid)
+{
+ app_status_h app_status;
+
+ app_status = _app_status_find_v2(pid);
+ if (!app_status)
+ return NULL;
+
+ return _app_status_get_instance_id(app_status);
+}
+
+static int __on_launch_do_starting_app_end(const char *msg,
+ int arg1, int arg2, void *arg3, bundle *data)
+{
+ int pid = arg1;
+ int bg_launch = arg2;
+ request_h req = (request_h)data;
+ bundle *b = _request_get_bundle(req);
+ int caller_pid = _request_get_pid(req);
+ uid_t uid = _request_get_uid(req);
+ char endpoint[MAX_LOCAL_BUFSZ];
+ const char *instance_id;
+ const char *app_id;
+
+ if (pid < 0 || uid < REGULAR_UID_MIN)
+ return NOTI_CONTINUE;
+
+ if (bg_launch) {
+ _W("Background launch");
+ return NOTI_CONTINUE;
+ }
+
+ if (!__context.launcher_service || !__context.serial)
+ return NOTI_CONTINUE;
+
+ snprintf(endpoint, sizeof(endpoint), "launcher_service:%s:%d",
+ __context.launcher_service, caller_pid);
+ if (!_app_com_endpoint_exists(endpoint))
+ return NOTI_CONTINUE;
+
+ app_id = bundle_get_val(b, AUL_K_APPID);
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!instance_id)
+ instance_id = __get_instance_id(pid);
+
+ __publish_launcher_service(endpoint, app_id, instance_id, pid,
+ __context.serial, uid);
+
+ return NOTI_CONTINUE;
+}
+
+static int __on_launch_prepare_start(const char *msg,
+ int arg1, int arg2, void *arg3, bundle *data)
+{
+ launch_h h = arg3;
+ const char *val;
+
+ if (__context.launcher_service) {
+ free(__context.launcher_service);
+ __context.launcher_service = NULL;
+ }
+
+ if (__context.serial) {
+ free(__context.serial);
+ __context.serial = NULL;
+ }
+
+ val = bundle_get_val(data, AUL_K_LAUNCHER_SERVICE);
+ if (val) {
+ __context.launcher_service = strdup(val);
+ bundle_del(data, AUL_K_LAUNCHER_SERVICE);
+ }
+
+ val = bundle_get_val(data, AUL_K_LAUNCHER_SERVICE_SERIAL);
+ if (val) {
+ __context.serial = strdup(val);
+ bundle_del(data, AUL_K_LAUNCHER_SERVICE_SERIAL);
+ }
+
+ if (__context.launcher_service && __context.serial) {
+ _launch_context_set_custom_effect(h, true);
+ _D("launcher_service(%s), serial(%s)",
+ __context.launcher_service, __context.serial);
+ }
+
+ return NOTI_CONTINUE;
+}
+
+static void __publish_launcher_service_event(const char *endpoint,
+ const char *app_id, const char *instance_id, int pid,
+ int event, uid_t uid)
+{
+ char event_str[MAX_PID_STR_BUFSZ];
+ bundle *b;
+
+ b = __create_bundle(app_id, instance_id, pid);
+ if (!b)
+ return;
+
+ snprintf(event_str, sizeof(event_str), "%d", event);
+ bundle_add(b, AUL_K_LAUNCHER_SERVICE_EVENT, event_str);
+
+ _app_com_send(endpoint, pid, b, uid);
+ bundle_free(b);
+}
+
+static int __dispatch_launcher_service_notify_status(request_h req)
+{
+ app_status_h app_status;
+ const char *instance_id;
+ const char *app_id;
+ char endpoint[512];
+ int event;
+ uid_t uid;
+ int cmd;
+ int pid;
+
+ uid = _request_get_uid(req);
+ pid = _request_get_pid(req);
+ app_status = _app_status_find_v2(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return -1;
+ }
+
+ instance_id = _app_status_get_instance_id(app_status);
+ app_id = _app_status_get_appid(app_status);
+ snprintf(endpoint, sizeof(endpoint), "launcher_service_event:%s",
+ app_id);
+ cmd = _request_get_cmd(req);
+ event = (cmd == LAUNCHER_SERVICE_NOTIFY_ANIMATION_STARTED) ? 0 : 1;
+ __publish_launcher_service_event(endpoint, app_id, instance_id,
+ pid, event, uid);
+
+ _I("[__LAUNCHER_SERVICE__] pid(%d), cmd(%d)", pid, cmd);
+ return 0;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = LAUNCHER_SERVICE_NOTIFY_ANIMATION_STARTED,
+ .callback = __dispatch_launcher_service_notify_status,
+ },
+ {
+ .cmd = LAUNCHER_SERVICE_NOTIFY_ANIMATION_FINISHED,
+ .callback = __dispatch_launcher_service_notify_status,
+ },
+};
+
+int _launcher_service_init(void)
+{
+ int ret;
+
+ _D("init");
+
+ ret = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register cmds. error(%d)", ret);
+ return ret;
+ }
+
+ _noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END,
+ __on_launch_do_starting_app_end);
+ _noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
+ __on_launch_do_starting_app_end);
+ _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
+ __on_launch_prepare_start);
+ _noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
+ __on_launch_prepare_start);
+
+
+ return 0;
+}
+
+void _launcher_service_fini(void)
+{
+ _D("fini");
+
+ if (__context.launcher_service)
+ free(__context.launcher_service);
+
+ if (__context.serial)
+ free(__context.serial);
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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_LAUNCHER_SERVICE_H__
+#define __AMD_LAUNCHER_SERVICE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _launcher_service_init(void);
+
+void _launcher_service_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LAUNCHER_SERVICE_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <aul.h>
+#include <glib.h>
+
+#include "amd_app_status.h"
+#include "amd_config.h"
+#include "amd_launch.h"
+#include "amd_launchpad.h"
+#include "amd_login_monitor.h"
+#include "amd_signal.h"
+#include "amd_util.h"
+#include "amd_socket.h"
+
+#define TIMEOUT_INTERVAL 1000
+#define LAUNCHPAD_RECOVERY_SOCK ".launchpad-recovery-sock"
+
+struct launchpad_info {
+ int (*launcher)(bundle *, uid_t t, void *);
+ void *data;
+};
+
+static struct launchpad_info __launchpad;
+static GHashTable *__timer_tbl;
+
+int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
+ void *user_data)
+{
+ __launchpad.launcher = callback;
+ __launchpad.data = user_data;
+
+ return 0;
+}
+
+int _launchpad_launch(bundle *kb, uid_t uid)
+{
+ if (!__launchpad.launcher) {
+ _E("Launcher is not prepared");
+ return -1;
+ }
+
+ return __launchpad.launcher(kb, uid, __launchpad.data);
+}
+
+static void __remove_recovery_timer(gpointer data)
+{
+ guint timer = GPOINTER_TO_UINT(data);
+
+ g_source_remove(timer);
+}
+
+static void __unset_recovery_timer(uid_t uid)
+{
+ if (!g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid)))
+ return;
+
+ g_hash_table_remove(__timer_tbl, GUINT_TO_POINTER(uid));
+ _W("[__RECOVERY__] timer is removed. uid(%u)", uid);
+}
+
+static gboolean __launchpad_recovery_cb(gpointer data)
+{
+ uid_t uid = GPOINTER_TO_UINT(data);
+ bundle *b;
+ pid_t pgid;
+ pid_t pid;
+ int ret;
+
+ pid = _login_monitor_get_launchpad_pid(uid);
+ if (pid > 0) {
+ pgid = getpgid(pid);
+ if (pgid > 0) {
+ _W("[__RECOVERY__] launchpad(%d) is running", pid);
+ return G_SOURCE_CONTINUE;
+ }
+ }
+
+ b = bundle_create();
+ ret = _send_cmd_to_launchpad_async(LAUNCHPAD_RECOVERY_SOCK, uid,
+ 0, b);
+ bundle_free(b);
+ if (ret < 0) {
+ _E("[__RECOVERY__] Failed to send recovery request. error(%d)",
+ ret);
+ return G_SOURCE_CONTINUE;
+ }
+
+ _W("[__RECOVERY__] Recovery launchpad");
+ __unset_recovery_timer(uid);
+ return G_SOURCE_CONTINUE;
+}
+
+static void __set_recovery_timer(uid_t uid)
+{
+ guint timer;
+
+ timer = g_timeout_add(TIMEOUT_INTERVAL, __launchpad_recovery_cb,
+ GUINT_TO_POINTER(uid));
+ g_hash_table_insert(__timer_tbl, GUINT_TO_POINTER(uid),
+ GUINT_TO_POINTER(timer));
+ _W("[__RECOVERY__] timer(%u) is removed. uid(%u)", timer, uid);
+}
+
+static bool __is_recovering(uid_t uid)
+{
+ return g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid));
+}
+
+static void __running_appinfo_cb(app_status_h app_status, void *user_data)
+{
+ const char *appid;
+ uid_t uid;
+ pid_t pid;
+ int ret;
+
+ appid = _app_status_get_appid(app_status);
+ pid = _app_status_get_pid(app_status);
+ uid = _app_status_get_uid(app_status);
+
+ aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
+ ret = _launch_send_sigkill(pid, uid);
+ _E("[__RECOVERY__] appid(%s), pid(%d), result(%d)", appid, pid, ret);
+
+ ret = _signal_send_app_dead(pid);
+ if (ret < 0) {
+ _W("Failed to send app dead signal. pid(%d)", pid);
+ _app_status_cleanup(app_status);
+ }
+}
+
+int _launchpad_recover_launcher(uid_t uid)
+{
+ pid_t pid;
+ int ret;
+
+ if (__is_recovering(uid))
+ return 0;
+
+ _W("[__RECOVERY__] uid(%u)", uid);
+ pid = _login_monitor_get_launchpad_pid(uid);
+ if (pid < 0) {
+ _E("Failed to get launchpad pid. uid(%u)", uid);
+ return -1;
+ }
+
+ _app_status_foreach_running_appinfo(__running_appinfo_cb, NULL);
+
+ ret = kill(pid, SIGABRT);
+ _E("[__RECOVERY__] launchpad pid(%d), uid(%d), result(%d)",
+ pid, uid, ret);
+
+ __set_recovery_timer(uid);
+ return ret;
+}
+
+int _launchpad_init(void)
+{
+ _D("LAUNCHPAD_INIT");
+
+ __timer_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __remove_recovery_timer);
+ if (!__timer_tbl) {
+ _E("g_hash_table_new() is failed");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void _launchpad_fini(void)
+{
+ _D("LAUNCHPAD_FINI");
+ if (__timer_tbl)
+ g_hash_table_destroy(__timer_tbl);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_LAUNCHPAD_H__
+#define __AMD_LAUNCHPAD_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
+ void *user_data);
+
+int _launchpad_launch(bundle *kb, uid_t uid);
+
+int _launchpad_recover_launcher(uid_t uid);
+
+int _launchpad_init(void);
+
+void _launchpad_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LAUNCHPAD_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "amd_logger.h"
+#include "amd_util.h"
+
+#define LOG_MAX_SIZE 2500
+#define LOG_APPFW_PATH "/var/log/appfw"
+#define LOG_PATH "/var/log/appfw/amd"
+
+struct logger_s {
+ int fd;
+ int index;
+};
+
+static gid_t __get_gid(const char *group_name)
+{
+ char buf[sysconf(_SC_GETGR_R_SIZE_MAX)];
+ struct group grp;
+ struct group *result;
+ int ret;
+
+ ret = getgrnam_r(group_name, &grp, buf, sizeof(buf), &result);
+ if (ret < 0) {
+ _E("Failed to get group(%s) file entry. errno(%d)",
+ group_name, errno);
+ return -1;
+ }
+
+ return grp.gr_gid;
+}
+
+static int __set_ownership(const char *path, uid_t uid, gid_t gid)
+{
+ int ret;
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ _E("Failed to open directory(%s). errno(%d)", path, errno);
+ return -1;
+ }
+
+ ret = fchown(fd, uid, gid);
+ close(fd);
+ if (ret < 0) {
+ _E("Failed to change ownership. path(%s), errno(%d)",
+ path, errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+int _logger_create(const char *path, logger_h *handle)
+{
+ struct logger_s *logger;
+ off_t offset;
+
+ if (!path || !handle) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ logger = calloc(1, sizeof(struct logger_s));
+ if (!logger) {
+ _E("Out of memory");
+ return -ENOMEM;
+ }
+
+ logger->fd = open(path, O_CREAT | O_WRONLY, 0640);
+ if (logger->fd < 0) {
+ _E("Failed to open path(%s), errno(%d)", path, errno);
+ _logger_destroy(logger);
+ return -1;
+ }
+
+ __set_ownership(path, getuid(), __get_gid("system_share"));
+
+ offset = lseek(logger->fd, 0, SEEK_END);
+ if (offset != 0) {
+ logger->index = (int)(offset / LOG_MAX_STRING_SIZE);
+ if (logger->index >= LOG_MAX_SIZE) {
+ logger->index = 0;
+ lseek(logger->fd, 0, SEEK_SET);
+ }
+ }
+
+ *handle = logger;
+
+ return 0;
+}
+
+int _logger_destroy(logger_h handle)
+{
+ if (!handle) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ if (handle->fd > 0)
+ close(handle->fd);
+
+ free(handle);
+
+ return 0;
+}
+
+int _logger_print(logger_h handle, const char *tag, const char *format, ...)
+{
+ char format_buf[128];
+ char buf[LOG_MAX_STRING_SIZE];
+ struct tm tm = { 0, };
+ time_t t;
+ ssize_t ret;
+ va_list ap;
+ off_t offset;
+
+ if (!handle || !tag || !format) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ t = time(NULL);
+ localtime_r(&t, &tm);
+
+ if (handle->index != 0)
+ offset = lseek(handle->fd, 0, SEEK_CUR);
+ else
+ offset = lseek(handle->fd, 0, SEEK_SET);
+
+ if (offset == -1)
+ _E("lseek() is failed. errno(%d)", errno);
+
+ va_start(ap, format);
+ vsnprintf(format_buf, sizeof(format_buf), format, ap);
+ va_end(ap);
+
+ snprintf(buf, sizeof(buf),
+ "[%6d] %04d-%02d-%02d %02d:%02d:%02d %-16s %-100s\n",
+ handle->index,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ tag, format_buf);
+ ret = write(handle->fd, buf, strlen(buf));
+ if (ret < 0) {
+ _E("Failed to write log message. errno(%d)", errno);
+ return -1;
+ }
+
+ if (++handle->index >= LOG_MAX_SIZE)
+ handle->index = 0;
+
+ return ret;
+}
+
+int _logger_get_fd(logger_h handle, int *fd)
+{
+ if (!handle || !fd) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ *fd = handle->fd;
+
+ return 0;
+}
+
+static int __create_directory(const char *path)
+{
+ gid_t gid;
+ int ret;
+
+ ret = access(path, F_OK);
+ if (ret == 0)
+ return 0;
+
+ ret = mkdir(path, (S_IRUSR | S_IWUSR | S_IXUSR |
+ S_IRGRP | S_IWGRP | S_IXGRP));
+ if (ret < 0) {
+ _E("Failed to create directory(%s). errno(%d)", path, errno);
+ return -1;
+ }
+
+ gid = __get_gid("system_share");
+ if (gid == (gid_t)-1) {
+ _E("Failed to get gid");
+ return -1;
+ }
+
+ return __set_ownership(path, getuid(), gid);
+}
+
+int _logger_init(void)
+{
+ int ret;
+
+ ret = __create_directory(LOG_APPFW_PATH);
+ if (ret < 0)
+ return ret;
+
+ ret = __create_directory(LOG_PATH);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_LOGGER_H__
+#define __AMD_LOGGER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef LOG_MAX_STRING_SIZE
+#define LOG_MAX_STRING_SIZE 256
+
+typedef struct logger_s *logger_h;
+
+int _logger_create(const char *path, logger_h *handle);
+
+int _logger_destroy(logger_h handle);
+
+int _logger_print(logger_h handle, const char *tag, const char *format, ...);
+
+int _logger_get_fd(logger_h handle, int *fd);
+
+int _logger_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <mntent.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <systemd/sd-login.h>
+#include <tzplatform_config.h>
+#include <bundle_internal.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <vconf.h>
+
+#include "amd_api_noti.h"
+#include "amd_util.h"
+#include "amd_login_monitor.h"
+#include "amd_appinfo.h"
+#include "amd_app_property.h"
+#include "amd_app_status.h"
+#include "amd_socket.h"
+#include "amd_request.h"
+#include "amd_launch.h"
+#include "amd_signal.h"
+#include "amd_cynara.h"
+#include "amd_noti.h"
+
+#define PATH_AUL_DAEMONS "/run/aul/daemons"
+#define LOGIN_TIMEOUT_SEC 90
+
+typedef int (*login_cb)(uid_t uid);
+typedef void (*logout_cb)(uid_t uid);
+
+typedef struct login_handler_s {
+ uid_state state;
+ login_cb login;
+} login_handler;
+
+typedef struct logout_handler_s {
+ uid_state state;
+ logout_cb logout;
+} logout_handler;
+
+struct login_monitor_s {
+ sd_login_monitor *m;
+ GIOChannel *io;
+ guint sid;
+ bool booting_status;
+};
+
+struct user_s {
+ uid_t uid;
+ uid_state state;
+ guint timer;
+ guint app_counter_timer;
+ GList *app_counter_list;
+ pid_t launchpad_pid;
+};
+
+struct app_counter_s {
+ char *app_type;
+ int number[AT_WATCH_APP + 1];
+};
+
+static guint sid;
+static struct login_monitor_s *login_monitor;
+static GList *user_list;
+static login_handler login_table[] = {
+ {
+ .state = UID_STATE_OPENING | UID_STATE_ONLINE |
+ UID_STATE_ACTIVE,
+ .login = _appinfo_load
+ },
+ {
+ .state = UID_STATE_OPENING | UID_STATE_ONLINE |
+ UID_STATE_ACTIVE,
+ .login = _app_property_load
+ },
+ {
+ .state = UID_STATE_OPENING | UID_STATE_ONLINE |
+ UID_STATE_ACTIVE,
+ .login = _app_status_usr_init
+ },
+ {
+ .state = UID_STATE_ONLINE | UID_STATE_ACTIVE,
+ .login = _request_usr_init
+ },
+ {
+ .state = UID_STATE_ACTIVE,
+ .login = _launch_start_onboot_apps
+ }
+};
+static logout_handler logout_table[] = {
+ {
+ .state = UID_STATE_OFFLINE,
+ .logout = _appinfo_unload
+ },
+ {
+ .state = UID_STATE_OFFLINE,
+ .logout = _app_property_unload
+ },
+ {
+ .state = UID_STATE_CLOSING | UID_STATE_OFFLINE,
+ .logout = _app_status_usr_fini
+ }
+};
+
+static int __connect_to_launchpad(uid_t uid);
+static void __user_login(struct user_s *user);
+static struct user_s *__find_user(uid_t uid);
+
+pid_t _login_monitor_get_launchpad_pid(uid_t uid)
+{
+ struct user_s *user;
+
+ if (uid < REGULAR_UID_MIN)
+ return -1;
+
+ user = __find_user(uid);
+ if (!user)
+ return -1;
+
+ return user->launchpad_pid;
+}
+
+static void __set_launchpad_pid(uid_t uid, pid_t pid)
+{
+ struct user_s *user;
+
+ if (uid < REGULAR_UID_MIN)
+ return;
+
+ user = __find_user(uid);
+ if (!user)
+ return;
+
+ if (user->launchpad_pid == pid)
+ return;
+
+ user->launchpad_pid = pid;
+ SECURE_LOGD("User(%u), Launchpad pid(%d)", uid, pid);
+}
+
+static void __destroy_app_counter(gpointer data)
+{
+ struct app_counter_s *ac = (struct app_counter_s *)data;
+
+ if (!ac) {
+ _E("Critical error!");
+ return;
+ }
+
+ free(ac->app_type);
+ free(ac);
+}
+
+static struct app_counter_s *__create_app_counter(const char *app_type)
+{
+ struct app_counter_s *ac;
+
+ ac = (struct app_counter_s *)calloc(1, sizeof(struct app_counter_s));
+ if (!ac) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ ac->app_type = strdup(app_type);
+ if (!ac->app_type) {
+ _E("Out of memory");
+ free(ac);
+ return NULL;
+ }
+
+ return ac;
+}
+
+static void __reset_app_counter(gpointer data, gpointer user_data)
+{
+ struct app_counter_s *ac = (struct app_counter_s *)data;
+ int i;
+
+ if (!ac)
+ return;
+
+ for (i = 0; i <= AT_WATCH_APP; ++i)
+ ac->number[i] = 0;
+}
+
+static int __update_app_type_info(const char *app_type, int total, uid_t uid)
+{
+ bundle *b;
+ int r;
+
+ b = bundle_create();
+ if (!b) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ r = bundle_add(b, AUL_K_APP_TYPE, app_type);
+ if (r != BUNDLE_ERROR_NONE) {
+ _E("Failed to add app type(%s)", app_type);
+ bundle_free(b);
+ return -1;
+ }
+
+ r = bundle_add(b, AUL_K_IS_INSTALLED, total > 0 ? "true" : "false");
+ if (r != BUNDLE_ERROR_NONE) {
+ _E("Failed to add install info");
+ bundle_free(b);
+ return -1;
+ }
+
+ r = _send_cmd_to_launchpad_async(LAUNCHPAD_PROCESS_POOL_SOCK, uid,
+ PAD_CMD_UPDATE_APP_TYPE, b);
+ bundle_free(b);
+
+ return r;
+}
+
+static void __foreach_app_counter(gpointer data, gpointer user_data)
+{
+ struct app_counter_s *ac = (struct app_counter_s *)data;
+ struct user_s *user = (struct user_s *)user_data;
+ int total;
+ int r;
+
+ total = ac->number[AT_UI_APP] + ac->number[AT_WIDGET_APP] +
+ ac->number[AT_WATCH_APP];
+
+ r = __update_app_type_info(ac->app_type, total, user->uid);
+ if (r < 0)
+ _W("Failed to update app type info");
+
+ _D("app type(%s), total(%d)", ac->app_type, total);
+}
+
+static struct app_counter_s *__find_app_counter(GList *list,
+ const char *app_type)
+{
+ struct app_counter_s *ac;
+ GList *iter;
+
+ iter = g_list_first(list);
+ while (iter) {
+ ac = (struct app_counter_s *)iter->data;
+ if (ac && ac->app_type && !strcmp(ac->app_type, app_type))
+ return ac;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static int __convert_to_component_type(const char *str)
+{
+ if (!str)
+ return -1;
+
+ if (!strcmp(str, APP_TYPE_SERVICE))
+ return AT_SERVICE_APP;
+ else if (!strcmp(str, APP_TYPE_UI))
+ return AT_UI_APP;
+ else if (!strcmp(str, APP_TYPE_WIDGET))
+ return AT_WIDGET_APP;
+ else if (!strcmp(str, APP_TYPE_WATCH))
+ return AT_WATCH_APP;
+
+ return -1;
+}
+
+static void __foreach_appinfo(void *data, const char *appid, struct appinfo *ai)
+{
+ struct user_s *user = (struct user_s *)data;
+ struct app_counter_s *ac;
+ const char *app_type;
+ const char *str;
+ int enable = 0;
+ int component_type;
+
+ _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
+ if (!(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
+ return;
+ }
+
+ app_type = _appinfo_get_value(ai, AIT_APPTYPE);
+ ac = __find_app_counter(user->app_counter_list, app_type);
+ if (!ac) {
+ ac = __create_app_counter(app_type);
+ if (!ac)
+ return;
+
+ user->app_counter_list = g_list_append(
+ user->app_counter_list, ac);
+ }
+
+ str = _appinfo_get_value(ai, AIT_COMPTYPE);
+ component_type = __convert_to_component_type(str);
+ if (component_type < 0) {
+ _W("Error! component type(%s)", str);
+ return;
+ }
+
+ ac->number[component_type]++;
+}
+
+static gboolean __app_counter_cb(gpointer data)
+{
+ struct user_s *user = (struct user_s *)data;
+
+ if (user->app_counter_list) {
+ g_list_foreach(user->app_counter_list,
+ __reset_app_counter, user);
+ }
+
+ _appinfo_foreach(user->uid, __foreach_appinfo, user);
+
+ if ((user->state & (UID_STATE_ONLINE | UID_STATE_ACTIVE))) {
+ g_list_foreach(user->app_counter_list,
+ __foreach_app_counter, user);
+ }
+
+ user->app_counter_timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static int __on_appinfo_handler(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ struct user_s *user;
+ GList *iter;
+
+ _D("message(%s), uid(%u)", msg, uid);
+ iter = user_list;
+ while (iter) {
+ user = (struct user_s *)iter->data;
+ iter = g_list_next(iter);
+ if (uid >= REGULAR_UID_MIN && uid != user->uid)
+ continue;
+
+ if (user->app_counter_timer)
+ g_source_remove(user->app_counter_timer);
+
+ user->app_counter_timer = g_timeout_add(500,
+ __app_counter_cb, user);
+ }
+
+ return 0;
+}
+
+static void __destroy_user(gpointer data)
+{
+ struct user_s *user = (struct user_s *)data;
+
+ if (!user) {
+ _E("Critical error!");
+ return;
+ }
+
+ if (user->app_counter_list)
+ g_list_free_full(user->app_counter_list, __destroy_app_counter);
+
+ if (user->app_counter_timer)
+ g_source_remove(user->app_counter_timer);
+
+ if (user->timer)
+ g_source_remove(user->timer);
+
+ free(user);
+}
+
+static struct user_s *__create_user(uid_t uid)
+{
+ struct user_s *user;
+
+ user = (struct user_s *)calloc(1, sizeof(struct user_s));
+ if (!user) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ user->uid = uid;
+ user->state = UID_STATE_OPENING;
+
+ return user;
+}
+
+static struct user_s *__find_user(uid_t uid)
+{
+ struct user_s *user;
+ GList *iter;
+
+ iter = user_list;
+ while (iter) {
+ user = (struct user_s *)iter->data;
+ if (user && user->uid == uid)
+ return user;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static bool __is_mounted(const char *dir)
+{
+ struct mntent *ent;
+ FILE *fp;
+ bool is_mounted = false;
+
+ if (!dir)
+ return false;
+
+ fp = setmntent("/etc/mtab", "r");
+ if (!fp) {
+ _E("Failed to open /etc/mtab");
+ return false;
+ }
+
+ ent = getmntent(fp);
+ while (ent) {
+ if (strstr(ent->mnt_dir, dir)) {
+ is_mounted = true;
+ break;
+ }
+
+ ent = getmntent(fp);
+ }
+
+ endmntent(fp);
+
+ return is_mounted;
+}
+
+static gboolean __login_timeout_handler(gpointer data)
+{
+ struct user_s *user = (struct user_s *)data;
+
+ if (user->state == UID_STATE_ACTIVE) {
+ _W("User(%u) is already active state", user->uid);
+ user->timer = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ if (!__is_mounted("/opt/usr")) {
+ _W("/opt/usr is not mounted");
+ return G_SOURCE_CONTINUE;
+ }
+
+ user->timer = 0;
+ user->state = UID_STATE_ACTIVE;
+ __user_login(user);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void __remove_login_timer(struct user_s *user)
+{
+ if (user->timer == 0)
+ return;
+
+ g_source_remove(user->timer);
+ user->timer = 0;
+}
+
+static void __add_login_timer(struct user_s *user)
+{
+ if (user->timer != 0)
+ return;
+
+ user->timer = g_timeout_add_seconds(LOGIN_TIMEOUT_SEC,
+ __login_timeout_handler, user);
+}
+
+static void __user_login(struct user_s *user)
+{
+ unsigned int i;
+
+ if (user->state == UID_STATE_OPENING) {
+ if (__connect_to_launchpad(user->uid) == 0)
+ user->state = UID_STATE_ONLINE;
+
+ __add_login_timer(user);
+ }
+
+ if (user->state == UID_STATE_ONLINE) {
+ if (user->app_counter_list) {
+ g_list_foreach(user->app_counter_list,
+ __foreach_app_counter, user);
+ }
+
+ __add_login_timer(user);
+ }
+
+ _W("[__LOGIN_MONITOR__] user login - uid(%d), state(%d)",
+ user->uid, user->state);
+ _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START,
+ user->uid, user->state, NULL, NULL);
+ for (i = 0; i < ARRAY_SIZE(login_table); i++) {
+ if (login_table[i].state & user->state) {
+ if (login_table[i].login)
+ login_table[i].login(user->uid);
+ }
+ }
+
+ _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN,
+ user->uid, user->state, NULL, NULL);
+}
+
+static void __user_logout(struct user_s *user)
+{
+ unsigned int i;
+
+ _D("user logout - uid(%d), state(%d)", user->uid, user->state);
+ for (i = 0; i < ARRAY_SIZE(logout_table); i++) {
+ if (logout_table[i].state & user->state) {
+ if (logout_table[i].logout)
+ logout_table[i].logout(user->uid);
+ }
+ }
+
+ _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
+ user->uid, user->state, NULL, NULL);
+}
+
+void _login_monitor_set_uid_state(uid_t uid, uid_state state)
+{
+ struct user_s *user;
+
+ if (uid < REGULAR_UID_MIN)
+ return;
+
+ user = __find_user(uid);
+ if (!user)
+ return;
+
+ if (user->state != state) {
+ user->state = state;
+ if (user->state == UID_STATE_ONLINE)
+ __user_login(user);
+ else
+ __user_logout(user);
+ }
+}
+
+uid_state _login_monitor_get_uid_state(uid_t uid)
+{
+ uid_state res = UID_STATE_UNKNOWN;
+ struct user_s *user;
+
+ if (uid < REGULAR_UID_MIN)
+ return res;
+
+ user = __find_user(uid);
+ if (!user)
+ return res;
+
+ return user->state;
+}
+
+int _login_monitor_get_uids(uid_t **uids)
+{
+ int r;
+ uid_t *l;
+ GList *iter;
+ unsigned int i = 0;
+ struct user_s *user;
+
+ if (uids == NULL) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ if (user_list == NULL)
+ return -1;
+
+ r = g_list_length(user_list);
+ if (r == 0)
+ return 0;
+
+ l = calloc(r, sizeof(uid_t));
+ if (l == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ iter = g_list_first(user_list);
+ while (iter) {
+ user = (struct user_s *)iter->data;
+ l[i++] = user->uid;
+ iter = g_list_next(iter);
+ }
+
+ *uids = l;
+
+ return r;
+}
+
+static int __connect_to_launchpad(uid_t uid)
+{
+ int r;
+ bundle *b;
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "%s/%d/%s",
+ PATH_AUL_DAEMONS, uid, LAUNCHPAD_PROCESS_POOL_SOCK);
+ if (access(path, F_OK) != 0) {
+ _D("%s doesn't exist", path);
+ return -1;
+ }
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ r = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
+ uid, PAD_CMD_PING, b);
+ bundle_free(b);
+ if (r < 0) {
+ _E("Failed to connect launchpad - uid(%d), result(%d)", uid, r);
+ return -1;
+ }
+
+ __set_launchpad_pid(uid, r);
+
+ return 0;
+}
+
+static void __check_user_state(void)
+{
+ uid_t *uids = NULL;
+ int ret;
+ int i;
+ char *state = NULL;
+ struct user_s *user;
+
+ ret = sd_get_uids(&uids);
+ if (ret <= 0) {
+ _W("Failed to get uids - %d", ret);
+ return;
+ }
+
+ for (i = 0; i < ret; i++) {
+ if (uids[i] < REGULAR_UID_MIN)
+ continue;
+
+ if (sd_uid_get_state(uids[i], &state) < 0)
+ continue;
+
+ user = __find_user(uids[i]);
+
+ if (strcmp(state, "opening") == 0 ||
+ strcmp(state, "online") == 0) {
+ if (!user) {
+ user = __create_user(uids[i]);
+ if (!user) {
+ free(uids);
+ return;
+ }
+ user_list = g_list_append(user_list, user);
+ __user_login(user);
+ }
+ } else if (strcmp(state, "closing") == 0) {
+ if (user) {
+ user->state = UID_STATE_CLOSING;
+ __user_logout(user);
+ }
+ } else if (strcmp(state, "offline") == 0) {
+ if (user) {
+ user_list = g_list_remove(user_list,
+ user);
+ user->state = UID_STATE_OFFLINE;
+ __user_logout(user);
+ __destroy_user(user);
+ }
+ }
+ _D("uid(%d), state(%s)", uids[i], state);
+ free(state);
+ state = NULL;
+ }
+ free(uids);
+}
+
+static gboolean __monitor_login_cb(GIOChannel *io, GIOCondition condition,
+ gpointer data)
+{
+ _D("login monitor");
+ sd_login_monitor_flush(login_monitor->m);
+
+ __check_user_state();
+
+ return TRUE;
+}
+
+static int __init_login_monitor(void)
+{
+ int r;
+ int fd;
+
+ login_monitor = (struct login_monitor_s *)calloc(1,
+ sizeof(struct login_monitor_s));
+ if (login_monitor == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ r = sd_login_monitor_new("uid", &login_monitor->m);
+ if (r < 0) {
+ _E("Failed to create sd login monitor");
+ return -1;
+ }
+
+ fd = sd_login_monitor_get_fd(login_monitor->m);
+ if (fd < 0) {
+ _E("Failed to get file descriptor");
+ return -1;
+ }
+
+ login_monitor->io = g_io_channel_unix_new(fd);
+ if (login_monitor->io == NULL) {
+ _E("Failed to create GIOChannel");
+ return -1;
+ }
+
+ login_monitor->sid = g_io_add_watch(login_monitor->io,
+ G_IO_IN | G_IO_HUP, __monitor_login_cb, NULL);
+ if (login_monitor->sid == 0) {
+ _E("Failed to add gio watch");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __fini_login_monitor(void)
+{
+ if (login_monitor == NULL)
+ return;
+
+ if (login_monitor->sid) {
+ g_source_remove(login_monitor->sid);
+ login_monitor->sid = 0;
+ }
+
+ if (login_monitor->io) {
+ g_io_channel_unref(login_monitor->io);
+ login_monitor->io = NULL;
+ }
+
+ if (login_monitor->m) {
+ sd_login_monitor_unref(login_monitor->m);
+ login_monitor->m = NULL;
+ }
+
+ free(login_monitor);
+ login_monitor = NULL;
+}
+
+static int __on_startup_finished(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ struct user_s *user;
+
+ _W("uid(%d)", uid);
+ if (uid < REGULAR_UID_MIN)
+ return -1;
+
+ user = __find_user(uid);
+ if (!user) {
+ user = __create_user(uid);
+ if (!user)
+ return -1;
+
+ user_list = g_list_append(user_list, user);
+ } else {
+ if (user->state == UID_STATE_ACTIVE) {
+ _W("The user(%u) is already active state.", uid);
+ return 0;
+ }
+ }
+
+ __remove_login_timer(user);
+ user->state = UID_STATE_ACTIVE;
+ __user_login(user);
+
+ return 0;
+}
+
+static int __startup_finished_cb(uid_t uid, void *user_data)
+{
+ _noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
+ (int)uid, 0, user_data, NULL);
+
+ return 0;
+}
+
+static int __subscribe_startup_finished(void *data)
+{
+ return _signal_subscribe_startup_finished(__startup_finished_cb, data);
+}
+
+static int __dispatch_app_add_loader(request_h req)
+{
+ bundle *kb;
+ int ret;
+ char tmpbuf[MAX_PID_STR_BUFSZ];
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ snprintf(tmpbuf, sizeof(tmpbuf), "%d", getpgid(_request_get_pid(req)));
+ bundle_add(kb, AUL_K_CALLER_PID, tmpbuf);
+ ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
+ _request_get_target_uid(req), PAD_CMD_ADD_LOADER, kb);
+ _request_send_result(req, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_remove_loader(request_h req)
+{
+ bundle *kb;
+ int ret;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL)
+ return -1;
+
+ ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
+ _request_get_target_uid(req), PAD_CMD_REMOVE_LOADER,
+ kb);
+ _request_send_result(req, ret);
+
+ return ret;
+}
+
+static int __dispatch_launchpad_dead_signal(request_h req)
+{
+ uid_t target_uid = _request_get_target_uid(req);
+ pid_t pid = _request_get_pid(req);
+
+ _W("uid(%d), pid(%d)", target_uid, pid);
+ _login_monitor_set_uid_state(target_uid, UID_STATE_CLOSING);
+ __set_launchpad_pid(target_uid, 0);
+ close(_request_remove_fd(req));
+
+ return 0;
+}
+
+static int __dispatch_app_prepare_candidate_process(request_h req)
+{
+ bundle *b = NULL;
+ int ret;
+
+ b = bundle_create();
+ if (b == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ ret = _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
+ _request_get_target_uid(req), PAD_CMD_DEMAND, b);
+ bundle_free(b);
+
+ _request_send_result(req, ret);
+ return 0;
+}
+
+static int __dispatch_launchpad_launch_signal(request_h req)
+{
+ uid_t target_uid = _request_get_target_uid(req);
+ pid_t pid = _request_get_pid(req);
+
+ _D("uid(%d), pid(%d)", target_uid, pid);
+ _login_monitor_set_uid_state(target_uid, UID_STATE_ONLINE);
+ __set_launchpad_pid(target_uid, pid);
+ close(_request_remove_fd(req));
+
+ return 0;
+}
+
+static int __label_checker(caller_info_h info, request_h req,
+ void *data)
+{
+ if (strcmp(_cynara_caller_info_get_client(info), "System::Privileged") == 0)
+ return 0;
+
+ return -1;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_ADD_LOADER,
+ .callback = __dispatch_app_add_loader
+ },
+ {
+ .cmd = APP_REMOVE_LOADER,
+ .callback = __dispatch_app_remove_loader
+ },
+ {
+ .cmd = LAUNCHPAD_DEAD_SIGNAL,
+ .callback = __dispatch_launchpad_dead_signal
+ },
+ {
+ .cmd = APP_PREPARE_CANDIDATE_PROCESS,
+ .callback = __dispatch_app_prepare_candidate_process
+ },
+ {
+ .cmd = LAUNCHPAD_LAUNCH_SIGNAL,
+ .callback = __dispatch_launchpad_launch_signal
+ },
+
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = LAUNCHPAD_LAUNCH_SIGNAL,
+ .checker = __label_checker,
+ .data = NULL
+ },
+ {
+ .cmd = LAUNCHPAD_DEAD_SIGNAL,
+ .checker = __label_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_ADD_LOADER,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+ {
+ .cmd = APP_REMOVE_LOADER,
+ .checker = _cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+};
+
+static void __booting_status_changed_cb(keynode_t *node, void *user_data)
+{
+ int booting_status;
+ struct user_s *user;
+ GList *iter;
+
+ booting_status = vconf_keynode_get_int(node);
+ if (booting_status != login_monitor->booting_status) {
+ _W("Booting status is changed. %d -> %d",
+ login_monitor->booting_status,
+ booting_status);
+ login_monitor->booting_status = booting_status;
+ if (booting_status != VCONFKEY_SYSMAN_BOOTING_SUCCESS)
+ return;
+
+ iter = user_list;
+ while (iter) {
+ user = (struct user_s *)iter->data;
+ if (user->state != UID_STATE_ACTIVE &&
+ user->state != UID_STATE_CLOSING &&
+ user->state != UID_STATE_OFFLINE) {
+ user->state = UID_STATE_ACTIVE;
+ __remove_login_timer(user);
+ __user_login(user);
+ }
+
+ iter = g_list_next(iter);
+ }
+ }
+}
+
+static bool __check_system_boot_finished(void)
+{
+ bool boot_finished = false;
+ int booting_status;
+ int ret;
+
+ if (login_monitor->booting_status == VCONFKEY_SYSMAN_BOOTING_SUCCESS)
+ return true;
+
+ ret = vconf_get_int(VCONFKEY_SYSMAN_BOOTINGSTATUS, &booting_status);
+ if (ret == 0 && booting_status == VCONFKEY_SYSMAN_BOOTING_SUCCESS) {
+ _W("Booting success");
+ login_monitor->booting_status = booting_status;
+ return true;
+ }
+
+ _signal_check_system_boot_finished(&boot_finished);
+ return boot_finished;
+}
+
+static gboolean __login_default_user(gpointer data)
+{
+ struct user_s *user;
+ uid_t uid;
+
+ sid = 0;
+ __check_user_state();
+
+ uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+ _W("default user(%d)", uid);
+
+ user = __find_user(uid);
+ if (!user) {
+ _E("Failed to find default user info");
+ return G_SOURCE_REMOVE;
+ }
+
+ if (user->state == UID_STATE_ACTIVE) {
+ _W("Already active state");
+ return G_SOURCE_REMOVE;
+ }
+
+ if (user->state == UID_STATE_UNKNOWN)
+ user->state = UID_STATE_OPENING;
+
+ if (__check_system_boot_finished())
+ user->state = UID_STATE_ACTIVE;
+
+ __user_login(user);
+ return G_SOURCE_REMOVE;
+}
+
+int _login_monitor_init(void)
+{
+ int r;
+ uid_t uid;
+ struct user_s *user;
+ int booting_status;
+
+ _D("login monitor init");
+ if (__init_login_monitor()) {
+ _E("Failed to initialize login monitor");
+ __fini_login_monitor();
+ return -1;
+ }
+
+ r = vconf_get_int(VCONFKEY_SYSMAN_BOOTINGSTATUS, &booting_status);
+ if (r == 0) {
+ _W("booting status(%d)", booting_status);
+ login_monitor->booting_status = booting_status;
+ }
+
+ r = vconf_notify_key_changed(VCONFKEY_SYSMAN_BOOTINGSTATUS,
+ __booting_status_changed_cb, NULL);
+ if (r != 0)
+ _W("Failed to register callback for checking booting");
+
+ _noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
+ __on_startup_finished);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_LOAD,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_UNLOAD,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_RELOAD,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END,
+ __on_appinfo_handler);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_APP_DISABLED_END,
+ __on_appinfo_handler);
+
+ uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+ _D("default user(%d)", uid);
+ user = __create_user(uid);
+ if (!user)
+ return -1;
+
+ user_list = g_list_append(user_list, user);
+ sid = g_idle_add_full(G_PRIORITY_HIGH, __login_default_user,
+ NULL, NULL);
+
+ _signal_add_ready_cb(__subscribe_startup_finished, NULL);
+
+ r = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _login_monitor_fini(void)
+{
+ _D("login monitor fini");
+
+ if (sid)
+ g_source_remove(sid);
+
+ _signal_unsubscribe_startup_finished();
+
+ if (user_list)
+ g_list_free_full(user_list, __destroy_user);
+
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_BOOTINGSTATUS,
+ __booting_status_changed_cb);
+
+ __fini_login_monitor();
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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_LOGIN_MONITOR_H__
+#define __AMD_LOGIN_MOINTOR_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum uid_state_e {
+ UID_STATE_UNKNOWN = 0x00,
+ UID_STATE_OPENING = 0x01,
+ UID_STATE_LINGERING = 0x02,
+ UID_STATE_ONLINE = 0x04,
+ UID_STATE_ACTIVE = 0x08,
+ UID_STATE_CLOSING = 0x10,
+ UID_STATE_OFFLINE = 0x20,
+} uid_state;
+
+pid_t _login_monitor_get_launchpad_pid(uid_t uid);
+
+void _login_monitor_set_uid_state(uid_t uid, uid_state state);
+
+uid_state _login_monitor_get_uid_state(uid_t uid);
+
+int _login_monitor_get_uids(uid_t **uids);
+
+int _login_monitor_init(void);
+
+void _login_monitor_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LOGIN_MONITOR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <aul.h>
+#include <glib.h>
+#include <systemd/sd-daemon.h>
+#include <tzplatform_config.h>
+
+#include "amd_anr_monitor.h"
+#include "amd_api.h"
+#include "amd_api_noti.h"
+#include "amd_app_com.h"
+#include "amd_app_property.h"
+#include "amd_app_status.h"
+#include "amd_appinfo.h"
+#include "amd_boot_manager.h"
+#include "amd_comp_status.h"
+#include "amd_compinfo.h"
+#include "amd_config.h"
+#include "amd_cynara.h"
+#include "amd_direct_launch.h"
+#include "amd_inotify.h"
+#include "amd_launch.h"
+#include "amd_launcher_service.h"
+#include "amd_launchpad.h"
+#include "amd_logger.h"
+#include "amd_login_monitor.h"
+#include "amd_main.h"
+#include "amd_noti.h"
+#include "amd_request.h"
+#include "amd_signal.h"
+#include "amd_socket.h"
+#include "amd_suspend.h"
+#include "amd_unix_signal.h"
+#include "amd_util.h"
+
+#define AMD_MOD_PATH "/usr/share/amd/mod"
+#define NAME_AMD_MOD_INIT "AMD_MOD_INIT"
+#define NAME_AMD_MOD_FINI "AMD_MOD_FINI"
+
+typedef int (*amd_mod_init_cb)(void);
+typedef void (*amd_mod_fini_cb)(void);
+
+struct restart_info {
+ char *appid;
+ int count;
+ guint timer;
+};
+
+static GHashTable *restart_tbl;
+static GList *so_handles;
+static sigset_t old_mask;
+
+static gboolean __restart_timeout_handler(void *data)
+{
+ struct restart_info *ri = (struct restart_info *)data;
+
+ _D("ri (%p)", ri);
+ _D("appid (%s)", ri->appid);
+
+ g_hash_table_remove(restart_tbl, ri->appid);
+ free(ri->appid);
+ free(ri);
+
+ return FALSE;
+}
+
+static bool __check_restart(const char *appid)
+{
+ struct restart_info *ri = NULL;
+ char err_buf[1024];
+
+ ri = g_hash_table_lookup(restart_tbl, appid);
+ if (!ri) {
+ ri = calloc(1, sizeof(struct restart_info));
+ if (!ri) {
+ _E("create restart info: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return false;
+ }
+ ri->appid = strdup(appid);
+ if (ri->appid == NULL) {
+ _E("Out of memory");
+ free(ri);
+ return false;
+ }
+ ri->count = 1;
+ g_hash_table_insert(restart_tbl, ri->appid, ri);
+
+ _D("ri (%p)", ri);
+ _D("appid (%s)", appid);
+
+ ri->timer = g_timeout_add(10 * 1000, __restart_timeout_handler,
+ ri);
+ } else {
+ ri->count++;
+ _D("count (%d)", ri->count);
+ if (ri->count > 5) {
+ g_source_remove(ri->timer);
+ g_hash_table_remove(restart_tbl, ri->appid);
+ free(ri->appid);
+ free(ri);
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool __can_restart_app(const char *appid, uid_t uid)
+{
+ const char *pkg_status;
+ const char *component_type;
+ struct appinfo *ai;
+ int r;
+ int val = 0;
+ int enable = 1;
+
+ _D("appid: %s", appid);
+ ai = _appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ component_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (!component_type)
+ return false;
+
+ if (strcmp(component_type, APP_TYPE_SERVICE) != 0)
+ return false;
+
+ r = _appinfo_get_int_value(ai, AIT_ENABLEMENT, &enable);
+ if (r == 0 && !(enable & APP_ENABLEMENT_MASK_ACTIVE)) {
+ _D("Disabled");
+ return false;
+ }
+
+ pkg_status = _appinfo_get_value(ai, AIT_STATUS);
+ if (pkg_status && strcmp(pkg_status, "blocking") == 0) {
+ _appinfo_set_value(ai, AIT_STATUS, "restart");
+ } else if (pkg_status && strcmp(pkg_status, "norestart") == 0) {
+ _appinfo_set_value(ai, AIT_STATUS, "installed");
+ } else {
+ r = _appinfo_get_int_value(ai, AIT_RESTART, &val);
+ if (r == 0 && val && __check_restart(appid))
+ return true;
+ }
+
+ return false;
+}
+
+static int __app_dead_handler(int pid, void *data)
+{
+ bool restart = false;
+ char *appid = NULL;
+ const char *tmp_appid;
+ app_status_h app_status;
+ uid_t uid;
+ char buf[MAX_LOCAL_BUFSZ];
+
+ if (pid <= 0)
+ return 0;
+
+ _W("APP_DEAD_SIGNAL : %d", pid);
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return 0;
+
+ uid = _app_status_get_uid(app_status);
+ _noti_send(AMD_NOTI_MSG_MAIN_APP_DEAD, pid, uid, app_status, NULL);
+ tmp_appid = _app_status_get_appid(app_status);
+ if (tmp_appid == NULL)
+ return 0;
+
+ uid = _app_status_get_uid(app_status);
+ restart = __can_restart_app(tmp_appid, uid);
+ if (restart) {
+ appid = strdup(tmp_appid);
+ if (appid == NULL)
+ _W("Out of memory");
+ }
+
+ _request_flush_pending_request(pid);
+ _app_status_publish_status(pid, STATUS_TERMINATE);
+ _app_status_cleanup(app_status);
+
+ if (restart)
+ _launch_start_app_local(uid, appid);
+ if (appid)
+ free(appid);
+
+ snprintf(buf, sizeof(buf), "%d", pid);
+ _util_save_log("TERMINATED", buf);
+ return 0;
+}
+
+static int __listen_app_dead_signal(void *data)
+{
+ int ret;
+
+ ret = aul_listen_app_dead_signal(__app_dead_handler, data);
+ if (ret < 0)
+ return -1;
+
+ return 0;
+}
+
+static void __ignore_app_dead_signal(void)
+{
+ aul_listen_app_dead_signal(NULL, NULL);
+}
+
+static int __load_modules(const char *path)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ char buf[PATH_MAX];
+ char *ext;
+ void *handle;
+ amd_mod_init_cb init_cb;
+
+ if (path == NULL)
+ return -1;
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return -1;
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (dentry->d_name[0] == '.')
+ continue;
+
+ ext = strrchr(dentry->d_name, '.');
+ if (ext && strcmp(ext, ".so") != 0)
+ continue;
+ snprintf(buf, sizeof(buf), "%s/%s",
+ path, dentry->d_name);
+
+ handle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
+ if (!handle) {
+ _E("Failed to load - %s", dlerror());
+ continue;
+ }
+
+ init_cb = dlsym(handle, NAME_AMD_MOD_INIT);
+ if (!init_cb) {
+ _E("Failed to find entry point");
+ dlclose(handle);
+ continue;
+ }
+
+ if (init_cb() < 0) {
+ _E("Failed to init %s", dentry->d_name);
+ dlclose(handle);
+ closedir(dp);
+ return -1;
+ }
+
+ so_handles = g_list_append(so_handles, handle);
+ }
+ closedir(dp);
+
+ return 0;
+}
+
+static void __unload_modules()
+{
+ GList *i = so_handles;
+ amd_mod_fini_cb fini_cb;
+
+ while (i) {
+ fini_cb = dlsym(i->data, NAME_AMD_MOD_FINI);
+ if (fini_cb)
+ fini_cb();
+ else
+ _E("Failed to find entry point");
+
+ dlclose(i->data);
+ i = g_list_next(i);
+ }
+
+ g_list_free(so_handles);
+ so_handles = NULL;
+}
+
+static void __block_sigchld(void)
+{
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+
+ if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+ _E("Failed to chagne blocked signal");
+}
+
+static void __unblock_sigchld(void)
+{
+ if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0)
+ _E("Failed to change blocked signal");
+}
+
+static int __init(void)
+{
+ int r;
+
+ __block_sigchld();
+ _logger_init();
+ _unix_signal_init();
+ _request_init();
+ _noti_init();
+ _compinfo_init();
+ _direct_launch_init();
+ if (_appinfo_init()) {
+ _E("_appinfo_init failed");
+ return -1;
+ }
+
+ _signal_add_ready_cb(__listen_app_dead_signal, NULL);
+
+ restart_tbl = g_hash_table_new(g_str_hash, g_str_equal);
+
+ r = _cynara_init();
+ if (r != 0) {
+ _E("cynara initialize failed.");
+ return -1;
+ }
+
+ _app_status_init();
+ _comp_status_init();
+ _app_com_broker_init();
+ _boot_manager_init();
+ _launch_init();
+ _suspend_init();
+ _app_property_init();
+ _login_monitor_init();
+ _util_init();
+ _inotify_init();
+ _config_init();
+ _anr_monitor_init();
+ _launcher_service_init();
+ _signal_init();
+ _launchpad_init();
+
+ if (access(AMD_MOD_PATH, F_OK) == 0) {
+ if (__load_modules(AMD_MOD_PATH) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __ready(void)
+{
+ int fd;
+
+ _D("AMD is ready");
+
+ fd = creat("/run/.amd_ready",
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if (fd != -1)
+ close(fd);
+
+ sd_notify(0, "READY=1");
+}
+
+static void __finish(void)
+{
+ __unload_modules();
+
+ _launchpad_fini();
+ _launcher_service_fini();
+ _anr_monitor_fini();
+ _config_fini();
+ _inotify_fini();
+ _util_fini();
+ _login_monitor_fini();
+ _app_property_fini();
+ _suspend_fini();
+ _boot_manager_fini();
+ _app_com_broker_fini();
+ _comp_status_fini();
+ _app_status_finish();
+ _request_fini();
+ _cynara_finish();
+
+ if (restart_tbl) {
+ g_hash_table_destroy(restart_tbl);
+ restart_tbl = NULL;
+ }
+
+ __ignore_app_dead_signal();
+
+ _appinfo_fini();
+ _direct_launch_fini();
+ _compinfo_fini();
+ _noti_fini();
+ _unix_signal_fini();
+ __unblock_sigchld();
+}
+
+EXPORT int amd_main(int argc, char *argv[])
+{
+ GMainLoop *mainloop = NULL;
+
+ if (__init() != 0) {
+ _E("AMD Initialization failed!\n");
+ return -1;
+ }
+
+ __ready();
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ if (!mainloop) {
+ _E("failed to create glib main loop");
+ return -1;
+ }
+ g_main_loop_run(mainloop);
+
+ __finish();
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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 <bundle.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <list>
+#include <string>
+#include <unordered_map>
+
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_noti.h"
+
+namespace {
+ std::unordered_map<std::string, std::list<noti_cb>> __listeners;
+}
+
+int _noti_send(const char* msg, int arg1, int arg2, void* arg3, bundle* data) {
+ int ret;
+
+ if (!msg) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ auto iter = __listeners.find(msg);
+ if (iter == __listeners.end())
+ return 0;
+
+ auto& li = iter->second;
+ for (noti_cb noti_callback : li) {
+ if (noti_callback) {
+ ret = noti_callback(msg, arg1, arg2, arg3, data);
+ if (ret != NOTI_CONTINUE)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int _noti_listen(const char* msg, noti_cb callback) {
+ if (!msg) {
+ _E("Invalid parameter");
+ return -1;
+ }
+ auto& li = __listeners[msg];
+ li.push_back(callback);
+ return 0;
+}
+
+int _noti_init(void) {
+ return 0;
+}
+
+void _noti_fini(void) {
+ __listeners.clear();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_NOTI_H__
+#define __AMD_NOTI_H__
+
+#include <bundle.h>
+
+#include "amd_api_noti_msg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NOTI_CONTINUE 0
+
+#define NOTI_STOP -2
+
+typedef int (*noti_cb)(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data);
+
+int _noti_send(const char *msg, int arg1, int arg2, void *arg3, bundle *data);
+
+int _noti_listen(const char *msg, noti_cb callback);
+
+int _noti_init(void);
+
+void _noti_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_NOTI_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_proc.h"
+
+int _proc_get_attr(pid_t pid, char *buf, int buf_size)
+{
+ char path[PATH_MAX];
+ int fd;
+ ssize_t s;
+
+ if (pid < 1 || !buf) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ snprintf(path, sizeof(path), "/proc/%d/attr/current", pid);
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ _E("Failed to open %s. errno(%d)", path, errno);
+ return -1;
+ }
+
+ s = read(fd, buf, buf_size -1);
+ if (s <= 0) {
+ _E("Failed to read %s. errno(%d)", path, errno);
+ close(fd);
+ return -1;
+ }
+
+ buf[s] = 0;
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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_PROC_H__
+#define __AMD_PROC_H__
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _proc_get_attr(pid_t pid, char *buf, int buf_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_PROC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <poll.h>
+#include <ctype.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <tzplatform_config.h>
+#include <systemd/sd-login.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <aul_app_com.h>
+
+#include "amd_api_noti.h"
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_request.h"
+#include "amd_app_status.h"
+#include "amd_cynara.h"
+#include "amd_socket.h"
+#include "aul_svc_priv_key.h"
+#include "amd_signal.h"
+#include "amd_login_monitor.h"
+#include "amd_noti.h"
+
+#define PENDING_REQUEST_TIMEOUT 5000 /* msec */
+#define SYSTEM_REQUEST_TIMEOUT 90000 /* msec */
+#define PENDING_MESSAGE_MAX_CNT 100
+
+static int amd_fd;
+static GIOChannel *amd_io;
+static guint amd_wid;
+static GHashTable *pending_table;
+static GHashTable *__dispatch_table;
+
+struct pending_item {
+ int pid;
+ guint timer;
+ GList *pending_list;
+ GList *reply_list;
+};
+
+struct request_s {
+ struct timespec start;
+ guint timer;
+ int cmd;
+ int clifd;
+ pid_t pid;
+ pid_t t_pid;
+ uid_t uid;
+ uid_t t_uid;
+ bundle *kb;
+ int len;
+ int opt;
+ bool critical;
+ unsigned char data[1];
+};
+
+struct extra_info {
+ char *key;
+ void *extra;
+ void (*free_cb)(void *data);
+};
+
+struct reply_info {
+ guint timer;
+ pid_t pid;
+ int result;
+ int cmd;
+ int clifd;
+ GList *extra_list;
+};
+
+static gboolean __timeout_pending_item(gpointer user_data);
+static gboolean __dispatch_request(gpointer data);
+static gboolean __timeout_request(gpointer data);
+static int __add_request_on_pending_list(request_h req);
+
+static void __free_extra_info(gpointer data)
+{
+ struct extra_info *info = data;
+
+ if (info->free_cb)
+ info->free_cb(info->extra);
+ free(info->key);
+ free(info);
+}
+
+static void __free_reply_info(gpointer data)
+{
+ struct reply_info *reply = (struct reply_info *)data;
+
+ if (reply == NULL)
+ return;
+
+ if (reply->extra_list)
+ g_list_free_full(reply->extra_list, __free_extra_info);
+ if (reply->clifd)
+ close(reply->clifd);
+ if (reply->timer)
+ g_source_remove(reply->timer);
+ free(reply);
+}
+
+static gboolean __timeout_reply(gpointer data)
+{
+ struct reply_info *reply = (struct reply_info *)data;
+
+ if (reply == NULL)
+ return FALSE;
+
+ _request_reply_remove(reply->pid, reply);
+ _send_result_to_client(reply->clifd, reply->result);
+ reply->clifd = 0;
+ reply->timer = 0;
+ __free_reply_info(reply);
+
+ return FALSE;
+}
+
+static struct reply_info *__create_reply_info(guint interval, pid_t pid,
+ int result, int cmd, int clifd)
+{
+ struct reply_info *reply;
+
+ reply = malloc(sizeof(struct reply_info));
+ if (reply == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ reply->pid = pid;
+ reply->result = result;
+ reply->cmd = cmd;
+ reply->clifd = clifd;
+ reply->timer = g_timeout_add(interval, __timeout_reply, reply);
+ reply->extra_list = NULL;
+
+ return reply;
+}
+
+static void __free_request(gpointer data)
+{
+ request_h req = (request_h)data;
+
+ if (req == NULL)
+ return;
+
+ if (req->clifd)
+ close(req->clifd);
+ if (req->timer)
+ g_source_remove(req->timer);
+ if (req->kb)
+ bundle_free(req->kb);
+
+ free(req);
+}
+
+static void __free_pending_item(gpointer user_data)
+{
+ struct pending_item *item = (struct pending_item *)user_data;
+
+ if (item == NULL)
+ return;
+
+ if (item->reply_list)
+ g_list_free_full(item->reply_list, __free_reply_info);
+ if (item->pending_list)
+ g_list_free_full(item->pending_list, __free_request);
+ if (g_main_context_find_source_by_user_data(NULL, item))
+ g_source_remove(item->timer);
+ free(item);
+}
+
+static void __timeout_pending_reply(gpointer data, gpointer user_data)
+{
+ struct reply_info *reply = (struct reply_info *)data;
+
+ if (reply == NULL)
+ return;
+
+ _send_result_to_client(reply->clifd, reply->result);
+ reply->clifd = 0;
+}
+
+static void __timeout_pending_request(gpointer data, gpointer user_data)
+{
+ request_h req = (request_h)data;
+
+ if (req == NULL)
+ return;
+
+ _request_send_result(req, -EAGAIN);
+}
+
+static gboolean __timeout_pending_item(gpointer user_data)
+{
+ struct pending_item *item = (struct pending_item *)user_data;
+
+ if (item == NULL)
+ return FALSE;
+
+ g_list_foreach(item->reply_list, __timeout_pending_reply, NULL);
+ g_list_foreach(item->pending_list, __timeout_pending_request, NULL);
+ g_hash_table_remove(pending_table, GINT_TO_POINTER(item->pid));
+
+ return FALSE;
+}
+
+static void __flush_pending_reply_list(GList **reply_list, bool is_dead)
+{
+ GList *iter;
+ struct reply_info *reply;
+
+ if (reply_list == NULL)
+ return;
+
+ iter = g_list_first(*reply_list);
+ while (iter) {
+ reply = (struct reply_info *)iter->data;
+ iter = g_list_next(iter);
+ if (reply == NULL)
+ continue;
+
+ if (reply->cmd == APP_TERM_BY_PID_SYNC_WITHOUT_RESTART ||
+ reply->cmd == APP_TERM_BY_PID_SYNC) {
+ if (!is_dead)
+ continue;
+
+ reply->result = 0;
+ }
+
+ *reply_list = g_list_remove(*reply_list, reply);
+ _send_result_to_client(reply->clifd, reply->result);
+ reply->clifd = 0;
+ __free_reply_info(reply);
+ }
+}
+
+static void __flush_pending_request_list(GList **pending_list)
+{
+ GList *iter;
+ request_h req;
+
+ if (pending_list == NULL)
+ return;
+
+ iter = g_list_first(*pending_list);
+ while (iter) {
+ req = (request_h)iter->data;
+ iter = g_list_next(iter);
+ if (req == NULL)
+ continue;
+
+ *pending_list = g_list_remove(*pending_list, req);
+ if (req->timer) {
+ g_source_remove(req->timer);
+ req->timer = 0;
+ }
+ g_idle_add(__dispatch_request, req);
+ }
+}
+
+int _request_flush_pending_request(int pid)
+{
+ struct pending_item *item;
+
+ item = (struct pending_item *)g_hash_table_lookup(pending_table,
+ GINT_TO_POINTER(pid));
+ if (item == NULL)
+ return -1;
+
+ __flush_pending_reply_list(&item->reply_list, true);
+ __timeout_pending_item((gpointer)item);
+
+ return 0;
+}
+
+int _request_reply_for_pending_request(int pid)
+{
+ struct pending_item *item;
+
+ _app_status_publish_status(pid, STATUS_LAUNCHING);
+
+ item = (struct pending_item *)g_hash_table_lookup(pending_table,
+ GINT_TO_POINTER(pid));
+ if (item == NULL)
+ return -1;
+
+ __flush_pending_reply_list(&item->reply_list, false);
+ __flush_pending_request_list(&item->pending_list);
+
+ return 0;
+}
+
+static struct timespec __get_start_time(request_h req)
+{
+ int r;
+ struct timespec start;
+ const char *start_time = NULL;
+
+ if (req->kb)
+ start_time = bundle_get_val(req->kb, AUL_K_STARTTIME);
+
+ if (start_time) {
+ r = sscanf(start_time, "%ld/%ld",
+ &start.tv_sec, &start.tv_nsec);
+ if (r != 2)
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ } else {
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ }
+
+ return start;
+}
+
+static request_h __get_request(int clifd, app_pkt_t *pkt,
+ struct ucred cr)
+{
+ request_h req;
+ const char *target_uid;
+
+ req = (request_h)malloc(sizeof(struct request_s) + pkt->len);
+ if (req == NULL)
+ return NULL;
+
+ req->timer = 0;
+ req->clifd = clifd;
+ req->pid = cr.pid;
+ req->t_pid = 0;
+ req->uid = cr.uid;
+ req->cmd = pkt->cmd;
+ req->len = pkt->len;
+ req->opt = pkt->opt;
+ req->critical = false;
+ memcpy(req->data, pkt->data, pkt->len + 1);
+
+ if (pkt->opt & AUL_SOCK_BUNDLE) {
+ req->kb = bundle_decode(pkt->data, pkt->len);
+ if (req->kb == NULL) {
+ free(req);
+ return NULL;
+ }
+
+ target_uid = bundle_get_val(req->kb, AUL_K_TARGET_UID);
+ if (target_uid && isdigit(target_uid[0]))
+ req->t_uid = atoi(target_uid);
+ else
+ req->t_uid = cr.uid;
+ } else {
+ req->kb = NULL;
+ req->t_uid = cr.uid;
+ }
+
+ req->start = __get_start_time(req);
+
+ return req;
+}
+
+static gboolean __timeout_request(gpointer data)
+{
+ request_h req = (request_h)data;
+ struct pending_item *item;
+ app_status_h app_status;
+
+ if (req == NULL)
+ return FALSE;
+
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(req->t_pid));
+ if (item)
+ item->pending_list = g_list_remove(item->pending_list, req);
+
+ if (req->clifd)
+ _request_send_result(req, -EAGAIN);
+ req->timer = 0;
+
+ if (req->critical) {
+ _E("App is not responding");
+ app_status = _app_status_find(req->t_pid);
+ if (app_status)
+ _app_status_update_status(app_status, STATUS_DYING, false, true);
+ }
+
+ __free_request(req);
+
+ return FALSE;
+}
+
+static app_status_h __get_app_status(request_h req, const char *appid)
+{
+ int pid;
+ app_status_h app_status;
+ int status;
+ struct appinfo *ai;
+ const char *comp_type;
+
+ switch (req->cmd) {
+ case APP_RESUME_BY_PID:
+ case APP_TERM_BY_PID:
+ case APP_TERM_BY_PID_WITHOUT_RESTART:
+ case APP_KILL_BY_PID:
+ case APP_TERM_REQ_BY_PID:
+ case APP_TERM_BY_PID_ASYNC:
+ case APP_TERM_BGAPP_BY_PID:
+ case APP_PAUSE_BY_PID:
+ case APP_TERM_BY_PID_SYNC:
+ case APP_TERM_BY_PID_SYNC_WITHOUT_RESTART:
+ /* get pid */
+ pid = atoi(appid);
+ app_status = _app_status_find(pid);
+ break;
+ case APP_START_ASYNC:
+ case APP_START_RES_ASYNC:
+ ai = _appinfo_find(_request_get_target_uid(req), appid);
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type && (strcmp(comp_type, APP_TYPE_WIDGET) == 0 ||
+ strcmp(comp_type, APP_TYPE_WATCH) == 0)) {
+ app_status = _app_status_find_with_org_caller(appid,
+ _request_get_target_uid(req),
+ _request_get_pid(req));
+ } else {
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ }
+ break;
+ default:
+ app_status = _app_status_find_by_appid(appid,
+ _request_get_target_uid(req));
+ break;
+ }
+
+ if (app_status == NULL)
+ return NULL;
+
+ status = _app_status_get_status(app_status);
+ if (status == STATUS_DYING)
+ return NULL;
+
+ return app_status;
+}
+
+static int __check_request(request_h req)
+{
+ int pid;
+ struct pending_item *item;
+ app_status_h app_status;
+ const char *appid;
+
+ if (req->opt & AUL_SOCK_NOREPLY)
+ close(_request_remove_fd(req));
+
+ if ((req->opt & AUL_SOCK_QUEUE) == 0)
+ return 0;
+
+ if (req->kb == NULL)
+ return -1;
+
+ appid = bundle_get_val(req->kb, AUL_K_APPID);
+ if (appid == NULL)
+ return -1;
+
+ app_status = __get_app_status(req, appid);
+ if (app_status == NULL)
+ return 0;
+
+ if (_app_status_socket_exists(app_status))
+ return 0;
+
+ pid = _app_status_get_pid(app_status);
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
+ if (item == NULL)
+ return 0;
+
+ if (!_app_status_is_starting(app_status)) {
+ req->t_pid = pid;
+ _W("%s(%d) is waiting to be started.", appid, pid);
+ req->critical = true;
+ req->timer = g_timeout_add(PENDING_REQUEST_TIMEOUT,
+ __timeout_request, req);
+ }
+
+ item->pending_list = g_list_append(item->pending_list, req);
+
+ return 1;
+}
+
+static int __check_target_user(request_h req)
+{
+ int r;
+ uid_t *uids;
+ int i;
+ uid_state state;
+
+ if (req->t_uid >= REGULAR_UID_MIN) {
+ state = _login_monitor_get_uid_state(req->t_uid);
+ if (state == UID_STATE_ONLINE || state == UID_STATE_ACTIVE)
+ return 0;
+
+ if (state == UID_STATE_OPENING)
+ return 1;
+
+ return -1;
+ }
+
+ r = _login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return -1;
+
+ for (i = 0; i < r; i++) {
+ state = _login_monitor_get_uid_state(uids[i]);
+ if (state == UID_STATE_ONLINE || state == UID_STATE_ACTIVE) {
+ req->t_uid = uids[i];
+ break;
+ }
+ }
+ free(uids);
+
+ if (req->t_uid < REGULAR_UID_MIN)
+ return -1;
+
+ return 0;
+}
+
+static gboolean __dispatch_request(gpointer data)
+{
+ request_h req = (request_h)data;
+ request_cmd_dispatch *dispatcher;
+
+ if (req == NULL)
+ return FALSE;
+
+ _I("cmd(%s:%d), caller_pid(%d), caller_uid(%u), clifd(%d)",
+ aul_cmd_convert_to_string(req->cmd),
+ req->cmd, req->pid, req->uid, req->clifd);
+ dispatcher = g_hash_table_lookup(__dispatch_table,
+ GINT_TO_POINTER(req->cmd));
+ if (dispatcher) {
+ if (dispatcher->callback(req) != 0) {
+ _E("callback returns FALSE : cmd(%s:%d)",
+ aul_cmd_convert_to_string(req->cmd),
+ req->cmd);
+ }
+ } else {
+ _E("Invalid request or not supported command(%d). caller(%d)",
+ req->cmd, req->pid);
+ }
+
+ __free_request(req);
+
+ return FALSE;
+}
+
+static guint __get_pending_interval(struct timespec *start,
+ struct timespec *end)
+{
+ unsigned int elapsed_time;
+
+ elapsed_time = (end->tv_sec - start->tv_sec) * 1e3 +
+ (end->tv_nsec - start->tv_nsec) / 1e6;
+ if (elapsed_time >= PENDING_REQUEST_TIMEOUT)
+ return 0;
+
+ return PENDING_REQUEST_TIMEOUT - elapsed_time;
+}
+
+int _request_reply_reset_pending_timer(request_h req, unsigned int interval,
+ int pid)
+{
+ struct pending_item *item;
+ struct timespec end;
+
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
+ if (item == NULL) {
+ _W("pending item doesn't exist - pid(%d)", pid);
+ return -1;
+ }
+
+ if (item->timer)
+ g_source_remove(item->timer);
+
+ if (interval <= 0) {
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ interval = __get_pending_interval(_request_get_start_time(req),
+ &end);
+ }
+
+ item->timer = g_timeout_add(interval, __timeout_pending_item, item);
+
+ return 0;
+}
+
+int _request_reply_append(int pid, void *reply)
+{
+ struct pending_item *item;
+
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
+ if (item == NULL) {
+ item = calloc(1, sizeof(struct pending_item));
+ if (item == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ item->pid = pid;
+ g_hash_table_insert(pending_table, GINT_TO_POINTER(pid),
+ item);
+ } else {
+ if (item->timer) {
+ g_source_remove(item->timer);
+ item->timer = 0;
+ }
+ }
+
+ item->reply_list = g_list_append(item->reply_list, reply);
+
+ return 0;
+}
+
+int _request_reply_remove(int pid, void *reply)
+{
+ struct pending_item *item;
+
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
+ if (item)
+ item->reply_list = g_list_remove(item->reply_list, reply);
+
+ return 0;
+}
+
+request_reply_h _request_reply_create(request_h req, pid_t pid, int result, int cmd)
+{
+ request_reply_h reply;
+ unsigned int interval;
+ struct timespec end;
+ int clifd = _request_remove_fd(req);
+
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ interval = __get_pending_interval(_request_get_start_time(req), &end);
+ reply = __create_reply_info(interval, pid, result, cmd, clifd);
+
+ if (reply == NULL) {
+ _send_result_to_client(clifd, -1);
+ return NULL;
+ }
+
+ return reply;
+}
+
+int _request_reply_add_extra(request_reply_h handle, const char *key,
+ void *extra, void (*extra_free_cb)(void *data))
+{
+ struct reply_info *reply = handle;
+ struct extra_info *info = malloc(sizeof(struct extra_info));
+
+ if (!info) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ info->extra = extra;
+ info->free_cb = extra_free_cb;
+ info->key = strdup(key);
+ if (!info->key) {
+ _E("Out of memory");
+ free(info);
+ return -1;
+ }
+
+ reply->extra_list = g_list_append(reply->extra_list, info);
+
+ return 0;
+}
+
+int _request_reply_foreach_extra(int pid, int (*callback)(const char *key, void *data))
+{
+ struct pending_item *item;
+ GList *iter;
+ struct reply_info *info;
+ struct extra_info *extra_info;
+ GList *extra_iter;
+
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(pid));
+ if (!item)
+ return -1;
+
+ iter = item->reply_list;
+ while (iter) {
+ info = iter->data;
+ extra_iter = info->extra_list;
+ while (extra_iter) {
+ extra_info = extra_iter->data;
+ if (!callback(extra_info->key, extra_info->extra))
+ extra_info->extra = NULL;
+ extra_iter = g_list_next(extra_iter);
+ }
+
+ iter = g_list_next(iter);
+ }
+
+ return 0;
+}
+
+int _request_usr_init(uid_t uid)
+{
+ GList *iter;
+ request_h req;
+ int r;
+ struct pending_item *item;
+
+ _noti_send(AMD_NOTI_MSG_REQUEST_USER_INIT, uid, 0, NULL, NULL);
+ item = g_hash_table_lookup(pending_table, GINT_TO_POINTER(getpid()));
+ if (item == NULL || item->pending_list == NULL)
+ return 0;
+
+ iter = g_list_first(item->pending_list);
+ while (iter) {
+ req = (request_h)iter->data;
+ iter = g_list_next(iter);
+ if (req == NULL)
+ continue;
+
+ req->t_pid = 0;
+ if (req->t_uid < REGULAR_UID_MIN)
+ req->t_uid = uid;
+
+ if (req->t_uid == uid) {
+ g_source_remove(req->timer);
+ req->timer = 0;
+ item->pending_list = g_list_remove(item->pending_list,
+ req);
+
+ _request_set_request_type(req, NULL);
+ r = __check_request(req);
+ if (r == 0)
+ g_idle_add(__dispatch_request, (gpointer)req);
+ else if (r < 0)
+ __free_request(req);
+ }
+ }
+
+ return 0;
+}
+
+static void __cynara_response_callback(enum amd_cynara_res res, request_h req)
+{
+ int ret;
+
+ if (res == AMD_CYNARA_ALLOWED) {
+ ret = __check_target_user(req);
+ if (ret > 0) {
+ ret = __add_request_on_pending_list(req);
+ if (ret < 0) {
+ _E("Failed to add request on pending list");
+ _request_send_result(req, -EAGAIN);
+ __free_request(req);
+ }
+
+ return;
+ }
+
+ _request_set_request_type(req, NULL);
+ ret = __check_request(req);
+ if (ret < 0) {
+ _request_send_result(req, ret);
+ __free_request(req);
+ return;
+ } else if (ret > 0) {
+ return;
+ }
+ __dispatch_request((gpointer)req);
+ } else {
+ _E("request has been denied by cynara");
+ ret = -EILLEGALACCESS;
+ _request_send_result(req, ret);
+ __free_request(req);
+ }
+
+ return;
+}
+
+static bool __is_indirect_request(request_h req)
+{
+ const char *req_type;
+
+ req_type = _request_get_request_type(req);
+ if (!req_type)
+ return false;
+
+ if (!strcmp(req_type, "indirect-request"))
+ return true;
+
+ return false;
+}
+
+static int __add_request_on_pending_list(request_h req)
+{
+ struct pending_item *item;
+ unsigned int interval;
+ struct timespec end;
+ int len;
+
+ item = g_hash_table_lookup(pending_table,
+ GINT_TO_POINTER(getpid()));
+ if (item == NULL) {
+ item = calloc(1, sizeof(struct pending_item));
+ if (item == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ item->pid = getpid();
+ g_hash_table_insert(pending_table,
+ GINT_TO_POINTER(getpid()),
+ item);
+ }
+
+ len = g_list_length(item->pending_list);
+ if (len <= PENDING_MESSAGE_MAX_CNT) {
+ /*
+ * To find the request from pending table, the target request
+ * is set to the process ID of amd.
+ */
+ req->t_pid = getpid();
+
+ if (req->uid >= REGULAR_UID_MIN || __is_indirect_request(req)) {
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ interval = __get_pending_interval(
+ _request_get_start_time(req), &end);
+ req->timer = g_timeout_add(interval,
+ __timeout_request, req);
+ } else {
+ _request_send_result(req, 0);
+ req->timer = g_timeout_add(SYSTEM_REQUEST_TIMEOUT,
+ __timeout_request, req);
+ }
+
+ item->pending_list = g_list_append(item->pending_list,
+ req);
+ _W("request(%s[%d]:%d:%u) is added on pending list",
+ aul_cmd_convert_to_string(req->cmd),
+ req->cmd, req->pid, req->t_uid);
+ } else {
+ _W("user(%u) not logged", req->t_uid);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __check_request_time(request_h req)
+{
+ struct timespec current;
+ struct timespec *start;
+ unsigned int elapsed_time;
+
+ start = _request_get_start_time(req);
+ clock_gettime(CLOCK_MONOTONIC, ¤t);
+
+ elapsed_time = (current.tv_sec - start->tv_sec) * 1e3 +
+ (current.tv_nsec - start->tv_nsec) / 1e6;
+ if (elapsed_time > PENDING_REQUEST_TIMEOUT) {
+ _E("Timeout. elapsed_time(%u)", elapsed_time);
+ return -1;
+ }
+
+ return 0;
+}
+
+static bool __is_async(request_h req)
+{
+ return req->opt & AUL_SOCK_NOREPLY;
+}
+
+static gboolean __request_handler(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ int fd = g_io_channel_unix_get_fd(io);
+ app_pkt_t *pkt;
+ int ret;
+ int clifd;
+ struct ucred cr;
+ request_h req;
+
+ pkt = aul_sock_recv_pkt(fd, &clifd, &cr);
+ if (pkt == NULL) {
+ _E("recv error");
+ return G_SOURCE_CONTINUE;
+ }
+
+ req = __get_request(clifd, pkt, cr);
+ if (req == NULL) {
+ close(clifd);
+ free(pkt);
+ return G_SOURCE_CONTINUE;
+ }
+ free(pkt);
+
+ ret = __check_request_time(req);
+ if (ret < 0 && !__is_indirect_request(req) && !__is_async(req)) {
+ _E("Reject request. cmd(%d), caller(%d)", req->cmd, req->pid);
+ _request_send_result(req, -EAGAIN);
+ __free_request(req);
+ return G_SOURCE_CONTINUE;
+ }
+
+ if (req->uid >= REGULAR_UID_MIN || __is_indirect_request(req)) {
+ if (req->uid >= REGULAR_UID_MIN && req->uid != req->t_uid) {
+ _E("request has been deined - uid(%d), target_uid(%d)",
+ req->uid, req->t_uid);
+ ret = -EILLEGALACCESS;
+ _request_send_result(req, ret);
+ __free_request(req);
+ return G_SOURCE_CONTINUE;
+ }
+
+ ret = _cynara_check_privilege(req, __cynara_response_callback);
+ if (ret < 0) {
+ _E("request has been denied by cynara");
+ ret = -EILLEGALACCESS;
+ _request_send_result(req, ret);
+ __free_request(req);
+ return G_SOURCE_CONTINUE;
+ } else if (ret == AMD_CYNARA_UNKNOWN) {
+ return G_SOURCE_CONTINUE;
+ } else {
+ ret = __check_target_user(req);
+ if (ret > 0 && req->cmd != LAUNCHPAD_LAUNCH_SIGNAL) {
+ ret = __add_request_on_pending_list(req);
+ if (ret < 0) {
+ _E("Failed to add request on pending list");
+ _request_send_result(req, -EAGAIN);
+ __free_request(req);
+ }
+
+ return G_SOURCE_CONTINUE;
+ }
+ }
+ } else {
+ ret = __check_target_user(req);
+ if (ret != 0 && (req->cmd == APP_START_ASYNC ||
+ req->cmd == APP_START_RES_ASYNC)) {
+ ret = __add_request_on_pending_list(req);
+ if (ret < 0) {
+ _E("Failed to add request on pending list");
+ _request_send_result(req, -EAGAIN);
+ __free_request(req);
+ }
+
+ return G_SOURCE_CONTINUE;
+ }
+ }
+
+ _request_set_request_type(req, NULL);
+ ret = __check_request(req);
+ if (ret < 0) {
+ _request_send_result(req, ret);
+ __free_request(req);
+ return G_SOURCE_CONTINUE;
+ } else if (ret > 0) {
+ return G_SOURCE_CONTINUE;
+ }
+
+ __dispatch_request((gpointer)req);
+
+ return G_SOURCE_CONTINUE;
+}
+
+int _request_get_fd(request_h req)
+{
+ return req->clifd;
+}
+
+int _request_get_pid(request_h req)
+{
+ return req->pid;
+}
+
+pid_t _request_get_target_pid(request_h req)
+{
+ return req->t_pid;
+}
+
+bundle *_request_get_bundle(request_h req)
+{
+ return req->kb;
+}
+
+int _request_get_len(request_h req)
+{
+ return req->len;
+}
+
+unsigned char *_request_get_raw(request_h req)
+{
+ return req->data;
+}
+
+struct timespec *_request_get_start_time(request_h req)
+{
+ return &req->start;
+}
+
+int _request_set_request_type(request_h req, const char *req_type)
+{
+ if (!req || !req->kb)
+ return -1;
+
+ bundle_del(req->kb, AUL_K_REQUEST_TYPE);
+
+ if (req_type)
+ bundle_add(req->kb, AUL_K_REQUEST_TYPE, req_type);
+
+ return 0;
+}
+
+const char *_request_get_request_type(request_h req)
+{
+ if (!req || !req->kb)
+ return NULL;
+
+ return bundle_get_val(req->kb, AUL_K_REQUEST_TYPE);
+}
+
+request_h _request_create_local(int cmd, uid_t uid, int pid, bundle *kb)
+{
+ request_h req;
+
+ req = (request_h)malloc(sizeof(struct request_s));
+ if (req == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &req->start);
+ req->timer = 0;
+ req->clifd = -1;
+ req->pid = pid;
+ req->t_pid = 0;
+ req->uid = getuid();
+ req->t_uid = uid;
+ req->cmd = cmd;
+ req->len = 0;
+ req->opt = AUL_SOCK_NONE;
+ req->kb = bundle_dup(kb);
+
+ return req;
+}
+
+void _request_free_local(request_h req)
+{
+ if (req == NULL)
+ return;
+
+ if (req->kb)
+ bundle_free(req->kb);
+
+ free(req);
+}
+
+int _request_get_cmd(request_h req)
+{
+ return req->cmd;
+}
+
+int _request_set_cmd(request_h req, int cmd)
+{
+ req->cmd = cmd;
+
+ return 0;
+}
+
+int _request_remove_fd(request_h req)
+{
+ int r = req->clifd;
+
+ req->clifd = 0;
+
+ return r;
+}
+
+uid_t _request_get_target_uid(request_h req)
+{
+ return req->t_uid;
+}
+
+uid_t _request_get_uid(request_h req)
+{
+ return req->uid;
+}
+
+int _request_send_raw(request_h req, int cmd, unsigned char *data, int len)
+{
+ return aul_sock_send_raw_with_fd(_request_remove_fd(req), cmd, data,
+ len, AUL_SOCK_NOREPLY);
+}
+
+int _request_send_result(request_h req, int res)
+{
+ if (req->clifd && (req->opt & AUL_SOCK_NOREPLY))
+ close(_request_remove_fd(req));
+ else if (req->clifd)
+ _send_result_to_client(_request_remove_fd(req), res);
+
+ return 0;
+}
+
+int _request_register_cmds(const request_cmd_dispatch *cmds, int cnt)
+{
+ int i;
+
+ if (cnt <= 0 || !__dispatch_table || !cmds)
+ return -1;
+
+ for (i = 0; i < cnt; i++) {
+ g_hash_table_insert(__dispatch_table,
+ GINT_TO_POINTER(cmds[i].cmd),
+ (gpointer)(&cmds[i]));
+ }
+
+ return 0;
+}
+
+int _request_init(void)
+{
+ _D("request init");
+ pending_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __free_pending_item);
+ if (pending_table == NULL) {
+ _E("Failed to create pending table");
+ _request_fini();
+ return -1;
+ }
+
+ amd_fd = _create_sock_activation();
+ if (amd_fd == -1) {
+ _D("Create server socket without socket activation");
+ amd_fd = _create_server_sock();
+ if (amd_fd == -1) {
+ _E("Create server socket failed.");
+ _request_fini();
+ return -1;
+ }
+ }
+
+ amd_io = g_io_channel_unix_new(amd_fd);
+ if (amd_io == NULL) {
+ _E("Failed to create gio channel");
+ _request_fini();
+ return -1;
+ }
+
+ amd_wid = g_io_add_watch(amd_io, G_IO_IN, __request_handler, NULL);
+ if (amd_wid == 0) {
+ _E("Failed to add gio watch");
+ _request_fini();
+ return -1;
+ }
+
+ __dispatch_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, NULL);
+
+ return 0;
+}
+
+void _request_fini(void)
+{
+ _D("request fini");
+ if (amd_wid) {
+ g_source_remove(amd_wid);
+ amd_wid = 0;
+ }
+
+ if (amd_io) {
+ g_io_channel_unref(amd_io);
+ amd_io = NULL;
+ }
+
+ if (amd_fd > 0) {
+ close(amd_fd);
+ amd_fd = 0;
+ }
+
+ if (pending_table) {
+ g_hash_table_destroy(pending_table);
+ pending_table = NULL;
+ }
+
+ if (__dispatch_table) {
+ g_hash_table_destroy(__dispatch_table);
+ __dispatch_table = NULL;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_REQUEST_H__
+#define __AMD_REQUEST_H__
+
+#include <bundle.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct request_s *request_h;
+
+typedef int (*request_cmd_dispatch_cb)(request_h req);
+
+typedef struct _request_cmd_dispatch {
+ int cmd;
+ request_cmd_dispatch_cb callback;
+} request_cmd_dispatch;
+
+typedef void* request_reply_h;
+
+int _request_send_result(request_h req, int res);
+
+int _request_send_raw(request_h req, int cmd, unsigned char *data, int len);
+
+int _request_get_fd(request_h req);
+
+int _request_get_pid(request_h req);
+
+int _request_get_cmd(request_h req);
+
+int _request_set_cmd(request_h req, int cmd);
+
+bundle *_request_get_bundle(request_h req);
+
+request_h _request_create_local(int cmd, uid_t uid, int pid, bundle *kb);
+
+void _request_free_local(request_h req);
+
+int _request_remove_fd(request_h req);
+
+int _request_reply_for_pending_request(int pid);
+
+int _request_flush_pending_request(int pid);
+
+uid_t _request_get_target_uid(request_h req);
+
+uid_t _request_get_uid(request_h req);
+
+pid_t _request_get_target_pid(request_h req);
+
+int _request_usr_init(uid_t uid);
+
+int _request_register_cmds(const request_cmd_dispatch *cmds, int cnt);
+
+int _request_init(void);
+
+void _request_fini(void);
+
+int _request_reply_reset_pending_timer(request_h req, unsigned int interval,
+ int pid);
+
+int _request_reply_append(int pid, void *reply);
+
+int _request_reply_remove(int pid, void *reply);
+
+request_reply_h _request_reply_create(request_h req, pid_t pid, int result,
+ int cmd);
+
+int _request_reply_add_extra(request_reply_h handle, const char *key,
+ void *extra, void (*extra_free_cb)(void *data));
+
+int _request_reply_foreach_extra(int pid,
+ int (*callback)(const char *key, void *data));
+
+int _request_get_len(request_h req);
+
+unsigned char *_request_get_raw(request_h req);
+
+struct timespec *_request_get_start_time(request_h req);
+
+int _request_set_request_type(request_h req, const char *req_type);
+
+const char *_request_get_request_type(request_h req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_REQUEST_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <gio/gio.h>
+#include <glib.h>
+
+#include "amd_api_noti.h"
+#include "amd_noti.h"
+#include "amd_signal.h"
+#include "amd_util.h"
+#include "app_signal.h"
+
+#define MAX_LABEL_BUFSZ 1024
+#define RETRY_INTERVAL 3
+
+typedef struct {
+ int pid;
+ void (*callback)(int, int, int, void *);
+ void *data;
+} proc_status_t;
+
+typedef struct {
+ signal_ready_cb callback;
+ void *user_data;
+} ready_cb_info_t;
+
+static GDBusConnection *system_conn;
+static guint startup_finished_sid;
+static guint user_session_startup_finished_sid;
+static int (*startup_finished_callback)(uid_t, void *);
+static void *startup_finished_data;
+static uid_t startup_finished_uid;
+static bool system_boot_completed;
+static bool user_boot_completed;
+static guint poweroff_state_sid;
+static void (*poweroff_state_callback)(int, void *);
+static void *poweroff_state_data;
+
+static GList *__ready_cbs;
+
+static gboolean __dispatch_ready_cb(gpointer data);
+
+static GDBusConnection *__get_system_conn(void)
+{
+ GError *err = NULL;
+
+ if (system_conn)
+ return system_conn;
+
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (system_conn == NULL) {
+ _E("g_bus_get_sync() is failed: %s", err->message);
+ g_error_free(err);
+ return NULL;
+ }
+
+ if (__dispatch_ready_cb(NULL)) {
+ g_timeout_add_seconds(RETRY_INTERVAL, __dispatch_ready_cb,
+ NULL);
+ }
+
+ return system_conn;
+}
+
+static int __send_signal(const char *object_path, const char *interface_name,
+ const char *signal_name, GVariant *parameters)
+{
+ GError *err = NULL;
+ GDBusConnection *conn;
+
+ conn = __get_system_conn();
+ if (conn == NULL) {
+ if (parameters)
+ g_variant_unref(parameters);
+ return -1;
+ }
+
+ if (g_dbus_connection_emit_signal(conn,
+ NULL,
+ object_path,
+ interface_name,
+ signal_name,
+ parameters,
+ &err) == FALSE) {
+ _E("g_dbus_connection_emit_signal() is failed: %s",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
+ _E("g_dbus_connection_flush_sync() is failed: %s",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ return 0;
+}
+
+int _signal_send_watchdog(int pid, int signal_num)
+{
+ int r;
+ GVariant *param;
+
+ r = _noti_send(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START, pid, signal_num,
+ NULL, NULL);
+ if (r< 0) {
+ _E("Some listeners don't want to continue (pid:%d)", pid);
+ return -1;
+ }
+
+ param = g_variant_new("(ii)", pid, signal_num);
+ if (!param) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ r = __send_signal(RESOURCED_PROC_OBJECT,
+ RESOURCED_PROC_INTERFACE,
+ RESOURCED_PROC_WATCHDOG_SIGNAL,
+ param);
+ if (r < 0) {
+ _E("Failed to send a watchdog signal - pid(%d)", pid);
+ return -1;
+ }
+
+ _W("Send a watchdog signal done - pid(%d)", pid);
+
+ return 0;
+}
+
+int _signal_send_proc_prelaunch(const char *appid, const char *pkgid,
+ int attribute, int category)
+{
+ int r;
+ GVariant *param;
+
+ param = g_variant_new("(ssii)", appid, pkgid, attribute, category);
+ if (!param) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ r = __send_signal(RESOURCED_PROC_OBJECT,
+ RESOURCED_PROC_INTERFACE,
+ RESOURCED_PROC_PRELAUNCH_SIGNAL,
+ param);
+ if (r < 0) {
+ _E("Failed to send a prelaunch signal - appid(%s)", appid);
+ return -1;
+ }
+
+ _W("send a prelaunch signal done: " \
+ "appid(%s) pkgid(%s) attribute(%x) category(%x)",
+ appid, pkgid, attribute, category);
+
+ return 0;
+}
+
+int _signal_send_tep_mount(char *mnt_path[], const char *pkgid)
+{
+ GError *err = NULL;
+ GDBusMessage *msg;
+ GDBusConnection *conn;
+ int ret = 0;
+ int rv = 0;
+ struct stat link_buf = {0,};
+ GVariant *param;
+ char buf[MAX_LABEL_BUFSZ];
+
+ if (pkgid == NULL) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ rv = lstat(mnt_path[0], &link_buf);
+ if (rv == 0) {
+ rv = unlink(mnt_path[0]);
+ if (rv)
+ _E("Unable tp remove link file %s", mnt_path[0]);
+ }
+
+ msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
+ TEP_OBJECT_PATH,
+ TEP_INTERFACE_NAME,
+ TEP_MOUNT_METHOD);
+ if (msg == NULL) {
+ _E("g_dbus_message_new_method_call() is failed.");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "User::Pkg::%s::RO", pkgid);
+ param = g_variant_new("(sss)", mnt_path[0], mnt_path[1], buf);
+ g_dbus_message_set_body(msg, param);
+
+ if (g_dbus_connection_send_message(conn,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ NULL,
+ &err) == FALSE) {
+ _E("g_dbus_connection_send_message() is failed: %s",
+ err->message);
+ ret = -1;
+ }
+
+ if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
+ _E("g_dbus_connection_flush_sync() is failed: %s",
+ err->message);
+ ret = -1;
+ }
+
+ g_object_unref(msg);
+ g_clear_error(&err);
+
+ return ret;
+}
+
+int _signal_send_tep_unmount(const char *mnt_path)
+{
+ GError *err = NULL;
+ GDBusMessage *msg;
+ GDBusConnection *conn;
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
+ TEP_OBJECT_PATH,
+ TEP_INTERFACE_NAME,
+ TEP_UNMOUNT_METHOD);
+ if (msg == NULL) {
+ _E("g_dbus_message_new_method_call() is failed.");
+ return -1;
+ }
+
+ g_dbus_message_set_body(msg, g_variant_new("(s)", mnt_path));
+ if (g_dbus_connection_send_message(conn,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ NULL,
+ &err) == FALSE) {
+ _E("g_dbus_connection_send_message() is failed: %s",
+ err->message);
+ g_object_unref(msg);
+ g_clear_error(&err);
+ return -1;
+ }
+
+ g_dbus_connection_flush(conn, NULL, NULL, NULL);
+ g_object_unref(msg);
+ g_clear_error(&err);
+
+ return 0;
+}
+
+int _signal_send_proc_suspend(int pid)
+{
+ GError *err = NULL;
+ GDBusConnection *conn;
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ if (g_dbus_connection_emit_signal(conn,
+ NULL,
+ APPFW_SUSPEND_HINT_PATH,
+ APPFW_SUSPEND_HINT_INTERFACE,
+ APPFW_SUSPEND_HINT_SIGNAL,
+ g_variant_new("(i)", pid),
+ &err) == FALSE) {
+ _E("g_dbus_connection_emit_signal() is failed: %s",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) {
+ _E("g_dbus_connection_flush_sync() is failed: %s",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ _D("[__SUSPEND__] Send suspend hint, pid: %d", pid);
+
+ return 0;
+}
+
+static void __system_bus_signal_handler(GDBusConnection *connection,
+ const gchar *sender_name, const gchar *object_path,
+ const gchar *interface_name, const char *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+ guint64 uid = 0;
+ int state = -1;
+
+ _W("[SIGNAL_HANDLER] signal(%s)", signal_name);
+ if (g_strcmp0(signal_name, SD_STARTUP_FINISHED_SIGNAL) == 0) {
+ system_boot_completed = true;
+ _D("[SIGNAL_HANDLER] system boot completed");
+ } else if (g_strcmp0(signal_name,
+ SD_USER_SESSION_STARTUP_FINISHED_SIGNAL) == 0) {
+ user_boot_completed = true;
+ g_variant_get(parameters, "(t)", &uid);
+ startup_finished_uid = (uid_t)uid;
+ _D("[SIGNAL_HANDLER] user boot completed");
+ } else if (g_strcmp0(signal_name, SYSTEM_POWEROFF_STATE_SIGNAL) == 0) {
+ g_variant_get(parameters, "(i)", &state);
+ if (poweroff_state_callback)
+ poweroff_state_callback(state, poweroff_state_data);
+ _D("[SIGNAL_HANDLER] poweroff state(%d)", state);
+ }
+
+ if (system_boot_completed && user_boot_completed) {
+ if (startup_finished_callback) {
+ startup_finished_callback(startup_finished_uid,
+ startup_finished_data);
+ }
+
+ user_boot_completed = false;
+ }
+}
+
+static guint __subscribe_system_bus(const char *object_path,
+ const char *interface_name, const char *signal_name)
+{
+ guint sid;
+ GError *err = NULL;
+ GDBusConnection *conn;
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return 0;
+
+ sid = g_dbus_connection_signal_subscribe(conn,
+ NULL,
+ interface_name,
+ signal_name,
+ object_path,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ __system_bus_signal_handler,
+ NULL,
+ NULL);
+ if (sid == 0)
+ _E("g_bus_connection_signal_subscribe() is failed");
+
+ g_clear_error(&err);
+
+ return sid;
+}
+
+int _signal_subscribe_startup_finished(int (*callback)(uid_t uid, void *data),
+ void *user_data)
+{
+ if (callback == NULL)
+ return -1;
+
+ startup_finished_sid = __subscribe_system_bus(SD_OBJECT_PATH,
+ SD_MANAGER_INTERFACE,
+ SD_STARTUP_FINISHED_SIGNAL);
+ if (startup_finished_sid == 0) {
+ _E("Failed to subscribe systemd signal");
+ return -1;
+ }
+
+ user_session_startup_finished_sid = __subscribe_system_bus(
+ SD_OBJECT_PATH,
+ SD_MANAGER_INTERFACE,
+ SD_USER_SESSION_STARTUP_FINISHED_SIGNAL);
+ if (user_session_startup_finished_sid == 0) {
+ _E("Failed to subscribe systemd signal");
+ _signal_unsubscribe_startup_finished();
+ return -1;
+ }
+
+ startup_finished_callback = callback;
+ startup_finished_data = user_data;
+ _W("[SIGNAL] subscribe startup finished");
+
+ return 0;
+}
+
+int _signal_unsubscribe_startup_finished(void)
+{
+ GDBusConnection *conn;
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ if (!startup_finished_sid && !user_session_startup_finished_sid)
+ return 0;
+
+ if (startup_finished_sid) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ startup_finished_sid);
+ startup_finished_sid = 0;
+ }
+
+ if (user_session_startup_finished_sid) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ user_session_startup_finished_sid);
+ user_session_startup_finished_sid = 0;
+ }
+
+ startup_finished_callback = NULL;
+ startup_finished_data = NULL;
+ _W("[SIGNAL] unsubscribe startup finished");
+
+ return 0;
+}
+
+int _signal_send_display_lock_state(const char *state, const char *flag,
+ unsigned int timeout)
+{
+ GError *err = NULL;
+ GDBusConnection *conn;
+ GDBusMessage *msg;
+ const char *holdkeyblock_string = "holdkeyblock";
+ int ret = 0;
+
+ _D("Acquring display lock");
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(SYSTEM_BUS_NAME,
+ SYSTEM_PATH_DISPLAY,
+ SYSTEM_INTERFACE_DISPLAY,
+ SYSTEM_LOCK_STATE);
+ if (msg == NULL) {
+ _E("g_dbus_message_new_method_call() is failed");
+ return -1;
+ }
+
+ g_dbus_message_set_body(msg, g_variant_new("(sssi)", state,
+ flag, holdkeyblock_string, timeout));
+ if (!g_dbus_connection_send_message(conn, msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+ _E("Unable to send dbus message for acquring lock as %s",
+ err->message);
+ ret = -1;
+ }
+
+ _D("Display lock acquired");
+ g_object_unref(msg);
+ g_dbus_connection_flush_sync(conn, NULL, NULL);
+ g_clear_error(&err);
+ return ret;
+}
+
+int _signal_send_display_unlock_state(const char *state, const char *flag)
+{
+ GError *err = NULL;
+ GDBusConnection *conn;
+ GDBusMessage *msg;
+ int ret = 0;
+
+ _D("releasing display lock");
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(SYSTEM_BUS_NAME,
+ SYSTEM_PATH_DISPLAY,
+ SYSTEM_INTERFACE_DISPLAY,
+ SYSTEM_UNLOCK_STATE);
+ if (msg == NULL) {
+ _E("g_dbus_message_new_method_call() is failed");
+ return -1;
+ }
+
+ g_dbus_message_set_body(msg, g_variant_new("(ss)", state, flag));
+ if (!g_dbus_connection_send_message(conn, msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+ _E("Unable to send dbus message for releasing lock as %s",
+ err->message);
+ ret = -1;
+ }
+
+ _D("Display lock released");
+ g_object_unref(msg);
+ g_dbus_connection_flush_sync(conn, NULL, NULL);
+ g_clear_error(&err);
+ return ret;
+}
+
+int _signal_send_system_service(int pid)
+{
+ int r;
+ GVariant *param;
+
+ param = g_variant_new("(i)", pid);
+ if (!param) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ r = __send_signal(RESOURCED_PROC_OBJECT,
+ RESOURCED_PROC_INTERFACE,
+ RESOURCED_SYSTEM_SERVICE_SIGNAL,
+ param);
+ if (r < 0) {
+ _E("Failed to send system service signal - pid(%d)", pid);
+ return -1;
+ }
+
+ _D("Send system service signal: pid(%d)", pid);
+
+ return 0;
+}
+
+int _signal_subscribe_poweroff_state(void (*callback)(int state, void *data),
+ void *user_data)
+{
+ if (callback == NULL)
+ return -1;
+
+ poweroff_state_sid = __subscribe_system_bus(SYSTEM_PATH_POWEROFF,
+ SYSTEM_INTERFACE_POWEROFF,
+ SYSTEM_POWEROFF_STATE_SIGNAL);
+ if (poweroff_state_sid == 0) {
+ _E("Failed to subscribe poweroff state signal");
+ return -1;
+ }
+
+ poweroff_state_callback = callback;
+ poweroff_state_data = user_data;
+ _D("[SIGNAL] subscribe poweroff state");
+
+ return 0;
+}
+
+int _signal_check_system_boot_finished(bool *finished)
+{
+ GError *err = NULL;
+ GDBusMessage *msg;
+ GDBusMessage *reply = NULL;
+ GDBusConnection *conn;
+ GVariant *body;
+ GVariant *param;
+ GVariant *v = NULL;
+ gsize length = 0;
+ const gchar *state;
+ int ret = 0;
+
+ if (!finished) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ conn = __get_system_conn();
+ if (!conn)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(SD_BUS_NAME,
+ SD_OBJECT_PATH,
+ SD_PROPERTIES_INTERFACE,
+ SD_GET_METHOD);
+ if (!msg) {
+ _E("g_dbus_message_new_method_call() is failed");
+ return -1;
+ }
+
+ param = g_variant_new("(ss)",
+ SD_MANAGER_INTERFACE,
+ SD_SYSTEM_STATE_METHOD);
+ g_dbus_message_set_body(msg, param);
+
+ reply = g_dbus_connection_send_message_with_reply_sync(conn,
+ msg,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ &err);
+ if (!reply) {
+ _E("Failed to get reply. error(%s)", err->message);
+ ret = -1;
+ goto end;
+ }
+
+ body = g_dbus_message_get_body(reply);
+ g_variant_get(body, "(v)", &v);
+ if (!v) {
+ _E("Failed to get variant");
+ ret = -1;
+ goto end;
+ }
+
+ state = g_variant_get_string(v, &length);
+ if (g_strcmp0(state, "running") == 0 ||
+ g_strcmp0(state, "degraded") == 0)
+ *finished = true;
+ else
+ *finished = false;
+
+ _W("state: %s, length: %d", state, (int)length);
+
+end:
+ if (v)
+ g_variant_unref(v);
+ if (reply)
+ g_object_unref(reply);
+ g_object_unref(msg);
+ g_clear_error(&err);
+
+ return ret;
+}
+
+static void __wm_proc_reply_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+{
+ GDBusConnection *conn = (GDBusConnection *)source_object;
+ proc_status_t *ps = (proc_status_t *)user_data;
+ GDBusMessage *reply;
+ GError *err = NULL;
+ GVariant *var;
+ int status = -1;
+ int focus = -1;
+
+ reply = g_dbus_connection_send_message_with_reply_finish(conn,
+ res, &err);
+ if (!reply) {
+ _E("No reply. err(%s)", err ? err->message : "Unknown");
+ goto end;
+ }
+
+ var = g_dbus_message_get_body(reply);
+ if (!var) {
+ _E("g_dbus_message_get_body() is failed");
+ goto end;
+ }
+
+ g_variant_get(var, "(ii)", &status, &focus);
+ if (status == -1 || focus == -1) {
+ _E("Failed to get proc status info");
+ goto end;
+ }
+
+ if (ps->callback)
+ ps->callback(ps->pid, status, focus, ps->data);
+
+ _D("pid(%d), status(%d), focused(%d)", ps->pid, status, focus);
+end:
+ if (err)
+ g_error_free(err);
+ if (reply)
+ g_object_unref(reply);
+ if (ps)
+ free(ps);
+}
+
+int _signal_get_proc_status_async(int pid,
+ void (*callback)(int, int, int, void *),
+ void *data)
+{
+ GDBusConnection *conn;
+ GDBusMessage *msg;
+ proc_status_t *ps;
+
+ conn = __get_system_conn();
+ if (!conn)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(WM_PROC_NAME,
+ WM_PROC_PATH,
+ WM_PROC_INTERFACE,
+ WM_PROC_METHOD);
+ if (!msg) {
+ _E("g_dbus_message_new_method_call() is failed");
+ return -1;
+ }
+
+ ps = calloc(1, sizeof(proc_status_t));
+ if (!ps) {
+ _E("Out of memory");
+ g_object_unref(msg);
+ return -1;
+ }
+ ps->pid = pid;
+ ps->callback = callback;
+ ps->data = data;
+
+ g_dbus_message_set_body(msg, g_variant_new("(i)", pid));
+ g_dbus_connection_send_message_with_reply(conn, msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1, NULL, NULL, __wm_proc_reply_cb,
+ (gpointer)ps);
+ g_object_unref(msg);
+
+ return 0;
+}
+
+static gboolean __dispatch_ready_cb(gpointer user_data)
+{
+ ready_cb_info_t *info;
+ GList *iter;
+
+ iter = __ready_cbs;
+ while (iter) {
+ info = (ready_cb_info_t *)iter->data;
+ iter = g_list_next(iter);
+ if (info->callback(info->user_data) < 0)
+ continue;
+
+ __ready_cbs = g_list_remove(__ready_cbs, info);
+ free(info);
+ }
+
+ if (!__ready_cbs) {
+ _D("ready cb info is nullptr");
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+int _signal_add_ready_cb(signal_ready_cb callback, void *user_data)
+{
+ ready_cb_info_t *info;
+
+ if (!callback) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ info = malloc(sizeof(ready_cb_info_t));
+ if (!info) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ info->callback = callback;
+ info->user_data = user_data;
+
+ __ready_cbs = g_list_append(__ready_cbs, info);
+
+ return 0;
+}
+
+int _signal_send_app_dead(int pid)
+{
+ int ret;
+
+ ret = __send_signal(AUL_DBUS_PATH,
+ AUL_DBUS_SIGNAL_INTERFACE,
+ AUL_DBUS_APPDEAD_SIGNAL,
+ g_variant_new("(u)", pid));
+ if (ret < 0)
+ return ret;
+
+ _D("App dead. pid(%d)", pid);
+
+ return 0;
+}
+
+static void __get_connection_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+
+ if (system_conn) {
+ _D("Already exists");
+ return;
+ }
+
+ system_conn = g_bus_get_finish(res, &error);
+ if (!system_conn) {
+ _E("g_bus_get_finish() is failed. error(%s)", error->message);
+ g_error_free(error);
+ }
+
+ if (__dispatch_ready_cb(NULL)) {
+ g_timeout_add_seconds(RETRY_INTERVAL, __dispatch_ready_cb,
+ NULL);
+ }
+}
+
+int _signal_init(void)
+{
+ g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __get_connection_cb, NULL);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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_SIGNAL_H__
+#define __AMD_SIGNAL_H__
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RESOURCED_ATTRIBUTE_LARGEMEMORY 0x01
+
+#define RESOURCED_ATTRIBUTE_OOMTERMINATION 0X02
+
+#define RESOURCED_ATTRIBUTE_WEB_APP 0x04
+
+#define RESOURCED_ATTRIBUTE_DOWNLOAD_APP 0x08
+
+#define RESOURCED_ATTRIBUTE_SERVICE_APP 0x10
+
+#define RESOURCED_ATTRIBUTE_VIP_APP 0x20
+
+typedef enum {
+ POWEROFF_NONE = 0,
+ POWEROFF_POPUP,
+ POWEROFF_DIRECT,
+ POWEROFF_RESTART,
+} poweroff_e;
+
+typedef int (*signal_ready_cb)(void *user_data);
+
+int _signal_init(void);
+
+int _signal_send_watchdog(int pid, int signal_num);
+
+int _signal_send_proc_prelaunch(const char *appid, const char *pkgid,
+ int attribute, int category);
+
+int _signal_send_proc_suspend(int pid);
+
+int _signal_send_tep_mount(char *mnt_path[], const char *pkgid);
+
+int _signal_send_tep_unmount(const char *mnt_path);
+
+int _signal_subscribe_startup_finished(int (*callback)(uid_t uid, void *data),
+ void *user_data);
+
+int _signal_unsubscribe_startup_finished(void);
+
+int _signal_send_display_lock_state(const char *state, const char *flag,
+ unsigned int timeout);
+
+int _signal_send_system_service(int pid);
+
+int _signal_send_display_unlock_state(const char *state, const char *flag);
+
+int _signal_subscribe_poweroff_state(void (*callback)(int state, void *data),
+ void *user_data);
+
+int _signal_check_system_boot_finished(bool *finished);
+
+int _signal_get_proc_status_async(int pid,
+ void (*callback)(int pid, int status, int focused, void *data),
+ void *data);
+
+int _signal_add_ready_cb(signal_ready_cb callback, void *user_data);
+
+int _signal_send_app_dead(int pid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_SIGNAL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/xattr.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <systemd/sd-daemon.h>
+#include <bundle.h>
+#include <aul_sock.h>
+
+#include "amd_util.h"
+#include "amd_socket.h"
+
+#define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
+
+int _create_sock_activation(void)
+{
+ int fds;
+
+ fds = sd_listen_fds(0);
+ if (fds == 1)
+ return SD_LISTEN_FDS_START;
+
+ if (fds > 1)
+ _E("Too many file descriptors received.\n");
+ else
+ _D("There is no socket stream");
+
+ return -1;
+}
+
+int _create_server_sock(void)
+{
+ int fd;
+ struct sockaddr_un addr;
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ _E("create socket error: %d", errno);
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
+ unlink(addr.sun_path);
+
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
+ _E("bind error: %d", errno);
+ close(fd);
+ return -1;
+ }
+
+ if (aul_sock_set_sock_option(fd, 0) < 0) {
+ _E("Failed to set sock option");
+ close(fd);
+ return -1;
+ }
+
+ if (listen(fd, 128) == -1) {
+ _E("listen error: %d", errno);
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static int __connect_client_sock(int fd, const struct sockaddr *saptr,
+ socklen_t salen, int nsec)
+{
+ int flags;
+ int ret;
+ int error = 0;
+ socklen_t len;
+ fd_set readfds;
+ fd_set writefds;
+ struct timeval timeout;
+
+ flags = fcntl(fd, F_GETFL, 0);
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ _E("Failed to set the status flags. errno(%d)", errno);
+ return -1;
+ }
+
+ ret = connect(fd, (struct sockaddr *)saptr, salen);
+ if (ret < 0) {
+ if (errno != EAGAIN && errno != EINPROGRESS) {
+ fcntl(fd, F_SETFL, flags);
+ return -2;
+ }
+ }
+
+ /* Do whatever we want while the connect is taking place. */
+ if (ret == 0)
+ goto done; /* connect completed immediately */
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ writefds = readfds;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = nsec;
+
+ ret = select(fd + 1, &readfds, &writefds, NULL,
+ nsec ? &timeout : NULL);
+ if (ret == 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds)) {
+ len = sizeof(error);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+ return -1; /* Solaris pending error */
+ } else {
+ return -1; /* select error: sockfd not set*/
+ }
+
+done:
+ ret = fcntl(fd, F_SETFL, flags);
+ if (ret < 0) {
+ _E("Failed to set the status flags. errno(%d)", errno);
+ return -1;
+ }
+
+ if (error) {
+ errno = error;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __create_launchpad_client_sock(const char *pad_type, uid_t uid)
+{
+ int fd = -1;
+ struct sockaddr_un saddr = { 0, };
+ int retry = 1;
+ int ret = -1;
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ /* support above version 2.6.27*/
+ if (fd < 0) {
+ if (errno == EINVAL) {
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ _E("second chance - socket create error");
+ return -1;
+ }
+ } else {
+ _E("socket error");
+ return -1;
+ }
+ }
+
+ saddr.sun_family = AF_UNIX;
+ snprintf(saddr.sun_path, sizeof(saddr.sun_path),
+ "/run/aul/daemons/%d/%s", uid, pad_type);
+ retry_con:
+ ret = __connect_client_sock(fd, (struct sockaddr *)&saddr,
+ sizeof(saddr), 100 * 1000);
+ if (ret < -1) {
+ _E("maybe peer not launched or peer daed\n");
+ if (retry > 0) {
+ usleep(100 * 1000);
+ retry--;
+ goto retry_con;
+ }
+ }
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+
+ if (aul_sock_set_sock_option(fd, 1) < 0) {
+ _E("Failed to set sock option");
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+int _send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
+{
+ int fd;
+ int len;
+ int res;
+ char err_buf[1024];
+
+ fd = __create_launchpad_client_sock(pad_type, uid);
+ if (fd < 0)
+ return -1;
+
+ res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
+ if (res < 0) {
+ close(fd);
+ return res;
+ }
+
+retry_recv:
+ len = recv(fd, &res, sizeof(int), 0);
+ if (len == -1) {
+ if (errno == EAGAIN) {
+ _E("recv timeout : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ res = -EAGAIN;
+ } else if (errno == EINTR) {
+ _D("recv : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ goto retry_recv;
+ } else {
+ _E("recv error : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ res = -ECOMM;
+ }
+ }
+
+ close(fd);
+
+ return res;
+}
+
+int _send_cmd_to_launchpad_async(const char *pad_type, uid_t uid, int cmd,
+ bundle *kb)
+{
+ int fd;
+ int res;
+
+ fd = __create_launchpad_client_sock(pad_type, uid);
+ if (fd < 0)
+ return -1;
+
+ res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
+ close(fd);
+ return res;
+}
+
+void _send_result_to_client(int fd, int res)
+{
+ if (fd < 3)
+ return;
+
+ if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
+ if (errno == EPIPE)
+ _E("send failed due to EPIPE.");
+ _E("send fail to client fd(%d)", fd);
+ }
+
+ close(fd);
+}
+
+void _send_result_to_client_v2(int fd, int res)
+{
+ if (fd < 3)
+ return;
+
+ if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
+ if (errno == EPIPE)
+ _E("send failed due to EPIPE.");
+ _E("send fail to client fd(%d)", fd);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_SOCKET_H__
+#define __AMD_SOCKET_H__
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LAUNCHPAD_PROCESS_POOL_SOCK ".launchpad-process-pool-sock"
+
+#define PAD_CMD_LAUNCH 0
+
+#define PAD_CMD_VISIBILITY 10
+
+#define PAD_CMD_ADD_LOADER 11
+
+#define PAD_CMD_REMOVE_LOADER 12
+
+#define PAD_CMD_MAKE_DEFAULT_SLOTS 13
+
+#define PAD_CMD_DEMAND 14
+
+#define PAD_CMD_PING 15
+
+#define PAD_CMD_UPDATE_APP_TYPE 16
+
+int _create_sock_activation(void);
+
+int _create_server_sock(void);
+
+int _send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd,
+ bundle *kb);
+
+int _send_cmd_to_launchpad_async(const char *pad_type, uid_t uid, int cmd,
+ bundle *kb);
+
+void _send_result_to_client(int fd, int res);
+
+void _send_result_to_client_v2(int fd, int res);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_SOCKET_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <bundle_internal.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <vconf.h>
+
+#include "amd_config.h"
+#include "amd_signal.h"
+#include "amd_util.h"
+#include "amd_suspend.h"
+#include "amd_app_status.h"
+
+typedef struct proc_info {
+ pid_t pid;
+ guint timer_id;
+ int ex_ref;
+} proc_info_t;
+
+typedef struct network_info {
+ bool vconf_initialized;
+ bool disconnected;
+ guint timer_id;
+} network_info_t;
+
+static GHashTable *proc_info_tbl;
+static network_info_t __net_info;
+static guint __init_timer;
+
+static proc_info_t *__create_proc_info(int pid);
+static proc_info_t *__find_proc_info(int pid);
+static int __add_proc_info(proc_info_t *proc);
+
+int _suspend_exclude(int pid)
+{
+ proc_info_t *info;
+ int ret;
+
+ info = __find_proc_info(pid);
+ if (!info) {
+ info = __create_proc_info(pid);
+ if (!info)
+ return -ENOMEM;
+
+ __add_proc_info(info);
+ }
+
+ info->ex_ref++;
+ if (info->ex_ref == 1) {
+ ret = aul_update_freezer_status(pid, "exclude");
+ _W("[__SUSPEND__] Exclude pid(%d), result(%d)", pid, ret);
+ }
+
+ return 0;
+}
+
+int _suspend_include(int pid)
+{
+ proc_info_t *info;
+ int ret;
+
+ info = __find_proc_info(pid);
+ if (!info) {
+ info = __create_proc_info(pid);
+ if (!info)
+ return -ENOMEM;
+
+ __add_proc_info(info);
+ }
+
+ if (info->ex_ref > 0)
+ info->ex_ref--;
+
+ if (info->ex_ref == 0) {
+ ret = aul_update_freezer_status(pid, "include");
+ _W("[__SUSPEND__] Include pid(%d), result(%d)", pid, ret);
+ }
+
+ return 0;
+}
+
+bool _suspend_is_excluded(int pid)
+{
+ proc_info_t *info;
+
+ info = __find_proc_info(pid);
+ if (info)
+ return (info->ex_ref > 0) ? true : false;
+
+ return false;
+}
+
+static void __destroy_proc_info_value(gpointer data)
+{
+ proc_info_t *proc = (proc_info_t *)data;
+
+ if (proc)
+ free(proc);
+}
+
+static bool __network_is_disconnected(int status)
+{
+ switch (status) {
+ case VCONFKEY_NETWORK_CELLULAR:
+ _D("Cellular type");
+ return false;
+ case VCONFKEY_NETWORK_WIFI:
+ _D("Wi-Fi type");
+ return false;
+ case VCONFKEY_NETWORK_ETHERNET:
+ _D("Ethernet type");
+ return false;
+ case VCONFKEY_NETWORK_BLUETOOTH:
+ _D("Bluetooth type");
+ return false;
+ case VCONFKEY_NETWORK_DEFAULT_PROXY:
+ _D("Proxy type for internet connection");
+ return false;
+ default:
+ _D("Disconnected");
+ return true;
+ }
+}
+
+static void __prepare_to_suspend(int pid, uid_t uid)
+{
+ int ret;
+ int dummy = 0;
+
+ _D("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
+ ret = aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
+ sizeof(int), AUL_SOCK_NOREPLY);
+ if (ret < 0)
+ _E("Failed to send APP_SUSPEND %d", pid);
+}
+
+static void __prepare_to_wake(int pid, uid_t uid)
+{
+ int ret;
+ bundle *kb;
+
+ kb = bundle_create();
+ if (kb == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ bundle_add(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
+
+ _D("[__SUSPEND__] pid: %d, uid: %d", pid, uid);
+ ret = aul_sock_send_bundle(pid, uid, APP_WAKE, kb, AUL_SOCK_NOREPLY);
+ if (ret != AUL_R_OK)
+ _E("Failed to send APP_WAKE %d", pid);
+
+ bundle_free(kb);
+}
+
+static void __wake_bg_apps(app_status_h app_status, void *data)
+{
+ const char *appid;
+ int status;
+ uid_t uid;
+ const struct appinfo *ai;
+ int target_category;
+ int bg_category;
+ bool bg_allowed;
+ int pid;
+
+ if (app_status == NULL)
+ return;
+
+ status = _app_status_get_status(app_status);
+ if (status != STATUS_BG && status != STATUS_SERVICE)
+ return;
+
+ appid = _app_status_get_appid(app_status);
+ uid = _app_status_get_uid(app_status);
+ pid = _app_status_get_pid(app_status);
+
+ ai = _appinfo_find(uid, appid);
+ if (ai == NULL)
+ return;
+
+ if (data) {
+ target_category = GPOINTER_TO_INT(data);
+ bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
+ if (bg_category != target_category)
+ return;
+ } else {
+ bg_allowed = _suspend_is_allowed_background(ai);
+ if (bg_allowed == true)
+ return;
+ }
+
+ _D("[__SUSPEND__] Wake %s %d", appid, pid);
+ _suspend_remove_timer(pid);
+ __prepare_to_wake(pid, uid);
+ _app_status_find_service_apps(app_status, status,
+ __prepare_to_wake, false);
+ _suspend_exclude(pid);
+}
+
+static void __suspend_bg_apps(app_status_h app_status, void *data)
+{
+ const char *appid;
+ int status;
+ uid_t uid;
+ const struct appinfo *ai;
+ int target_category;
+ int bg_category;
+ bool bg_allowed;
+ int pid;
+
+ if (app_status == NULL)
+ return;
+
+ status = _app_status_get_status(app_status);
+ if (status != STATUS_BG && status != STATUS_SERVICE)
+ return;
+
+ appid = _app_status_get_appid(app_status);
+ uid = _app_status_get_uid(app_status);
+ pid = _app_status_get_pid(app_status);
+
+ ai = _appinfo_find(uid, appid);
+ if (ai == NULL)
+ return;
+
+ if (data) {
+ target_category = GPOINTER_TO_INT(data);
+ bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
+ if (bg_category != target_category)
+ return;
+ } else {
+ bg_allowed = _suspend_is_allowed_background(ai);
+ if (bg_allowed == true)
+ return;
+ }
+
+ _D("[__SUSPEND__] Suspend %s %d", appid, pid);
+ _app_status_find_service_apps(app_status, status,
+ __prepare_to_suspend, true);
+ __prepare_to_suspend(pid, uid);
+ _suspend_add_timer(pid);
+ _suspend_include(pid);
+}
+
+static gboolean __handle_bg_network_apps(gpointer data)
+{
+ int bg_category = BACKGROUND_CATEGORY_BACKGROUND_NETWORK;
+
+ if (__net_info.disconnected) {
+ _D("[__SUSPEND__] Network is disconnected");
+ _app_status_foreach_running_appinfo(__suspend_bg_apps,
+ GINT_TO_POINTER(bg_category));
+ } else {
+ _D("[__SUSPEND__] Network is connected");
+ _app_status_foreach_running_appinfo(__wake_bg_apps,
+ GINT_TO_POINTER(bg_category));
+ }
+
+ __net_info.timer_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void __network_info_add_timer(void)
+{
+ if (__net_info.timer_id)
+ g_source_remove(__net_info.timer_id);
+
+ __net_info.timer_id = g_timeout_add(500, __handle_bg_network_apps, NULL);
+}
+
+static void __network_info_remove_timer(void)
+{
+ if (__net_info.timer_id) {
+ g_source_remove(__net_info.timer_id);
+ __net_info.timer_id = 0;
+ }
+}
+
+static void __network_status_changed_cb(keynode_t *key, void *data)
+{
+ int status;
+ bool disconnected;
+
+ status = vconf_keynode_get_int(key);
+ disconnected = __network_is_disconnected(status);
+ if (__net_info.disconnected != disconnected) {
+ _W("[__SUSPEND__] Network status(%d -> %d) is changed",
+ __net_info.disconnected, disconnected);
+ __net_info.disconnected = disconnected;
+ __network_info_add_timer();
+ }
+}
+
+static gboolean __init_network_info(gpointer data)
+{
+ int r;
+ int status = 0;
+
+ r = vconf_get_int(VCONFKEY_NETWORK_STATUS, &status);
+ if (r != VCONF_OK)
+ _E("Failed to get network status");
+ else
+ __net_info.disconnected = __network_is_disconnected(status);
+
+ r = vconf_notify_key_changed(VCONFKEY_NETWORK_STATUS,
+ __network_status_changed_cb, NULL);
+ if (r != VCONF_OK) {
+ _E("Failed to add vconf notify cb");
+ return G_SOURCE_CONTINUE;
+ }
+
+ __network_info_add_timer();
+ __net_info.vconf_initialized = true;
+
+ _D("[__SUSPEND__] Network info is initialized");
+
+ __init_timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void __fini_network_info()
+{
+ __network_info_remove_timer();
+
+ if (__net_info.vconf_initialized) {
+ vconf_ignore_key_changed(VCONFKEY_NETWORK_STATUS,
+ __network_status_changed_cb);
+ __net_info.vconf_initialized = false;
+ }
+ _D("[__SUSPEND__] Network info is finished");
+}
+
+void _suspend_init(void)
+{
+ if (!proc_info_tbl) {
+ proc_info_tbl = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, NULL,
+ __destroy_proc_info_value);
+ }
+
+ __init_timer = g_timeout_add(500, __init_network_info, NULL);
+
+ _D("_amd_proc_init done");
+}
+
+void _suspend_fini(void)
+{
+ if (__init_timer)
+ g_source_remove(__init_timer);
+
+ __fini_network_info();
+
+ g_hash_table_destroy(proc_info_tbl);
+ _D("_amd_proc_fini done");
+}
+
+static proc_info_t *__create_proc_info(int pid)
+{
+ proc_info_t *proc;
+
+ if (pid < 1) {
+ _E("invalid pid");
+ return NULL;
+ }
+
+ proc = (proc_info_t *)calloc(1, sizeof(proc_info_t));
+ if (proc == NULL) {
+ _E("insufficient memory");
+ return NULL;
+ }
+
+ proc->pid = pid;
+ proc->timer_id = 0;
+
+ return proc;
+}
+
+static proc_info_t *__find_proc_info(int pid)
+{
+ proc_info_t *proc;
+
+ if (pid < 1) {
+ _E("invalid pid");
+ return NULL;
+ }
+
+ proc = (proc_info_t *)g_hash_table_lookup(proc_info_tbl,
+ GINT_TO_POINTER(pid));
+ if (proc == NULL) {
+ _E("proc info not found");
+ return NULL;
+ }
+
+ return proc;
+}
+
+static int __add_proc_info(proc_info_t *proc)
+{
+ if (proc == NULL) {
+ _E("invalid proc info");
+ return -1;
+ }
+
+ if (proc->pid < 1) {
+ _E("invalid pid");
+ return -1;
+ }
+
+ g_hash_table_insert(proc_info_tbl, GINT_TO_POINTER(proc->pid), proc);
+
+ return 0;
+}
+
+int _suspend_add_proc(int pid)
+{
+ proc_info_t *proc;
+
+ proc = __create_proc_info(pid);
+ if (proc)
+ return __add_proc_info(proc);
+
+ return -1;
+}
+
+int _suspend_remove_proc(int pid)
+{
+ proc_info_t *proc;
+
+ if (pid < 1) {
+ _E("invalid pid");
+ return -1;
+ }
+
+ proc = (proc_info_t *)g_hash_table_lookup(proc_info_tbl,
+ GINT_TO_POINTER(pid));
+ if (proc == NULL) {
+ _E("proc info not found");
+ return -1;
+ }
+
+ g_hash_table_remove(proc_info_tbl, GINT_TO_POINTER(pid));
+
+ return 0;
+}
+
+static gboolean __send_suspend_hint(gpointer data)
+{
+ proc_info_t *proc;
+ int pid = GPOINTER_TO_INT(data);
+
+ proc = __find_proc_info(pid);
+ if (proc && proc->timer_id > 0) {
+ _signal_send_proc_suspend(pid);
+ proc->timer_id = 0;
+ }
+
+ return FALSE;
+}
+
+bool _suspend_is_allowed_background(const struct appinfo *ai)
+{
+ int bg_category;
+ const char *comp_type;
+
+ comp_type = _appinfo_get_value(ai, AIT_COMPTYPE);
+ if (comp_type == NULL)
+ return false;
+
+ if (strcmp(comp_type, APP_TYPE_UI) &&
+ strcmp(comp_type, APP_TYPE_SERVICE) &&
+ strcmp(comp_type, APP_TYPE_COMPONENT_BASED))
+ return true;
+
+ /*
+ * 2.4 bg-categorized (uiapp || svcapp) || watch || widget -> bg allowed
+ * 2.3 uiapp -> not allowed, 2.3 svcapp -> bg allowed
+ */
+ bg_category = (intptr_t)_appinfo_get_value(ai, AIT_BG_CATEGORY);
+ if (bg_category) {
+ if (__net_info.disconnected) {
+ if (bg_category &
+ (~(int)BACKGROUND_CATEGORY_BACKGROUND_NETWORK))
+ return true;
+ } else {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void _suspend_add_timer(int pid)
+{
+ proc_info_t *proc;
+
+ proc = __find_proc_info(pid);
+ if (proc == NULL) {
+ proc = __create_proc_info(pid);
+ if (proc)
+ __add_proc_info(proc);
+ }
+
+ if (proc) {
+ proc->timer_id = g_timeout_add_seconds(10, __send_suspend_hint,
+ GINT_TO_POINTER(pid));
+ }
+}
+
+void _suspend_remove_timer(int pid)
+{
+ proc_info_t *proc;
+
+ proc = __find_proc_info(pid);
+ if (proc && proc->timer_id > 0) {
+ g_source_remove(proc->timer_id);
+ proc->timer_id = 0;
+ }
+}
+
+int _suspend_update_status(int pid, int status)
+{
+ app_status_h app_status;
+
+ if (pid < 0)
+ return -1;
+
+ app_status = _app_status_find(pid);
+ if (app_status == NULL)
+ return -1;
+
+ if (status == SUSPEND_STATUS_EXCLUDE) {
+ __wake_bg_apps(app_status, NULL);
+ } else if (status == SUSPEND_STATUS_INCLUDE) {
+ __suspend_bg_apps(app_status, NULL);
+ } else {
+ _E("Unknown status(%d)", status);
+ return -1;
+ }
+ _D("[__SUSPEND__] pid(%d), status(%d)", pid, status);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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_SUSPEND_H__
+#define __AMD_SUSPEND_H__
+
+#include <stdbool.h>
+
+#include "amd_appinfo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SUSPEND_TYPE_EXCLUDE "exclude"
+
+#define SUSPEND_TYPE_INCLUDE "include"
+
+enum suspend_status_e {
+ SUSPEND_STATUS_EXCLUDE,
+ SUSPEND_STATUS_INCLUDE,
+};
+
+enum background_category_e {
+ BACKGROUND_CATEGORY_MEDIA = 0x01,
+ BACKGROUND_CATEGORY_DOWNLOAD = 0x02,
+ BACKGROUND_CATEGORY_BACKGROUND_NETWORK = 0x04,
+ BACKGROUND_CATEGORY_LOCATION = 0x08,
+ BACKGROUND_CATEGORY_SENSOR = 0x10,
+ BACKGROUND_CATEGORY_IOT_COMMUNICATION = 0x20,
+ BACKGROUND_CATEGORY_SYSTEM = 0x40
+};
+
+int _suspend_exclude(int pid);
+
+int _suspend_include(int pid);
+
+bool _suspend_is_excluded(int pid);
+
+bool _suspend_is_allowed_background(const struct appinfo *ai);
+
+void _suspend_add_timer(int pid);
+
+void _suspend_remove_timer(int pid);
+
+int _suspend_add_proc(int pid);
+
+int _suspend_remove_proc(int pid);
+
+int _suspend_update_status(int pid, int status);
+
+void _suspend_init(void);
+
+void _suspend_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_SUSPEND_H__ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "amd_logger.h"
+#include "amd_unix_signal.h"
+#include "amd_util.h"
+
+#define BT_BUF_SIZE 128
+#define PATH_AMD_BACKTRACE "/var/log/appfw/amd/amd_backtrace.log"
+
+enum signo_e {
+ SIGNO_HUP,
+ SIGNO_INT,
+ SIGNO_QUIT,
+ SIGNO_ILL,
+ SIGNO_ABRT,
+ SIGNO_FPE,
+ SIGNO_BUS,
+ SIGNO_SEGV,
+ SIGNO_ALRM,
+ SIGNO_TERM,
+ SIGNO_XCPU,
+ SIGNO_XFSZ,
+ SIGNO_SYS,
+ SIGNO_MAX,
+};
+
+struct signo_map_s {
+ const char *key;
+ int value;
+};
+
+static struct signo_map_s signo_map[] = {
+ [SIGNO_HUP] = { "SIGHUP", SIGHUP },
+ [SIGNO_INT] = { "SIGINT", SIGINT },
+ [SIGNO_QUIT] = { "SIGQUIT", SIGQUIT },
+ [SIGNO_ILL] = { "SIGILL", SIGILL },
+ [SIGNO_ABRT] = { "SIGABRT", SIGABRT },
+ [SIGNO_FPE] = { "SIGFPE" , SIGFPE },
+ [SIGNO_BUS] = { "SIGBUS", SIGBUS },
+ [SIGNO_SEGV] = { "SIGSEGV", SIGSEGV },
+ [SIGNO_ALRM] = { "SIGALRM", SIGALRM },
+ [SIGNO_TERM] = { "SIGTERM", SIGTERM },
+ [SIGNO_XCPU] = { "SIGXCPU", SIGXCPU },
+ [SIGNO_XFSZ] = { "SIGXFSZ", SIGXFSZ },
+ [SIGNO_SYS] = { "SIGSYS", SIGSYS },
+};
+
+static struct sigaction old_action[SIGNO_MAX];
+static logger_h logger;
+static int logger_fd = -1;
+
+static const char *__unix_signal_get_signo_string(int signal)
+{
+ int i;
+
+ for (i = 0; i < SIGNO_MAX; ++i) {
+ if (signo_map[i].value == signal)
+ return signo_map[i].key;
+ }
+
+ return "Unknown";
+}
+
+static enum signo_e __unix_signal_get_signo(int signal)
+{
+ int i;
+
+ for (i = 0; i < SIGNO_MAX; ++i) {
+ if (signo_map[i].value == signal)
+ return i;
+ }
+
+ return -1;
+}
+
+static void __unix_signal_handler(int signal, siginfo_t *info, void *arg)
+{
+ enum signo_e signo;
+ int nptrs;
+ void *buffer[BT_BUF_SIZE];
+ sigset_t old_mask;
+ sigset_t mask;
+
+ sigfillset(&mask);
+ sigprocmask(SIG_BLOCK, &mask, &old_mask);
+
+ _W("[__UNIX_SIGNAL__] signal: %d(%s)",
+ signal, __unix_signal_get_signo_string(signal));
+
+ nptrs = backtrace(buffer, BT_BUF_SIZE);
+ backtrace_symbols_fd(buffer, nptrs,
+ (logger_fd > 0) ? logger_fd : STDERR_FILENO);
+
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
+
+ signo = __unix_signal_get_signo(signal);
+ if (signo != -1)
+ sigaction(signal, &old_action[signo], NULL);
+
+ raise(signal);
+}
+
+int _unix_signal_init(void)
+{
+ struct sigaction action = { 0, };
+ int ret;
+ int i;
+
+ _W("UNIX_SIGNAL_INIT");
+
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = __unix_signal_handler;
+ action.sa_flags = SA_RESTART | SA_SIGINFO;
+
+ for (i = 0; i < SIGNO_MAX; ++i) {
+ ret = sigaction(signo_map[i].value, &action, &old_action[i]);
+ if (ret != 0) {
+ _W("Failed to change signal(%s) action. errno(%d)",
+ signo_map[i].key, errno);
+ }
+ }
+
+ ret = _logger_create(PATH_AMD_BACKTRACE, &logger);
+ if (ret != 0)
+ return ret;
+
+ _logger_print(logger, "BACKTRACE", "pid: %d", getpid());
+ _logger_get_fd(logger, &logger_fd);
+
+ return 0;
+}
+
+void _unix_signal_fini(void)
+{
+ int i;
+
+ _W("UNIX_SIGNAL_FINI");
+
+ _logger_destroy(logger);
+
+ for (i = 0; i < SIGNO_MAX; ++i)
+ sigaction(signo_map[i].value, &old_action[i], NULL);
+}
--- /dev/null
+/*
+ * 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_UNIX_SIGNAL_H__
+#define __AMD_UNIX_SIGNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _unix_signal_init(void);
+
+void _unix_signal_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_UNIX_SIGNAL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <time.h>
+#include <fcntl.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+
+#include "amd_api_noti.h"
+#include "amd_config.h"
+#include "amd_util.h"
+#include "amd_request.h"
+#include "amd_appinfo.h"
+#include "amd_app_status.h"
+#include "amd_socket.h"
+#include "amd_cynara.h"
+#include "amd_noti.h"
+#include "amd_logger.h"
+
+#define OSP_K_DATACONTROL_PROVIDER "__OSP_DATACONTROL_PROVIDER__"
+#define MAX_NR_OF_DESCRIPTORS 2
+#define AMD_LOG_FILE "/var/log/appfw/amd/amd.log"
+
+static logger_h __logger;
+static GHashTable *__dc_socket_pair_hash;
+static int datacontrol_result;
+static int __memory_status;
+static bool __vconf_initialized;
+static guint __vconf_init_timer;
+
+int _util_save_log(const char *tag, const char *message)
+{
+ return _logger_print(__logger, tag, message);
+}
+
+static int __send_message(int sock, const struct iovec *vec, int vec_size,
+ const int *desc, int nr_desc)
+{
+ struct msghdr msg = {0,};
+ int sndret;
+ int desclen = 0;
+ struct cmsghdr *cmsg = NULL;
+ char buff[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)] = {0,};
+
+ if (vec == NULL || vec_size < 1)
+ return -EINVAL;
+ if (nr_desc < 0 || nr_desc > MAX_NR_OF_DESCRIPTORS)
+ return -EINVAL;
+ if (desc == NULL)
+ nr_desc = 0;
+
+ msg.msg_iov = (struct iovec *)vec;
+ msg.msg_iovlen = vec_size;
+
+ /* sending ancillary data */
+ if (nr_desc > 0) {
+ msg.msg_control = buff;
+ msg.msg_controllen = sizeof(buff);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg == NULL)
+ return -EINVAL;
+
+ /* packing files descriptors */
+ if (nr_desc > 0) {
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ desclen = cmsg->cmsg_len =
+ CMSG_LEN(sizeof(int) * nr_desc);
+ memcpy((int *)CMSG_DATA(cmsg), desc,
+ sizeof(int) * nr_desc);
+ cmsg = CMSG_NXTHDR(&msg, cmsg);
+ _D("packing file descriptors done");
+ }
+
+ /* finished packing updating the corect length */
+ msg.msg_controllen = desclen;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+
+ sndret = sendmsg(sock, &msg, 0);
+ _D("sendmsg ret : %d", sndret);
+ if (sndret < 0)
+ return -errno;
+
+ return sndret;
+}
+
+static int __dispatch_get_mp_socket_pair(request_h req)
+{
+ int handles[2] = {0, 0};
+ struct iovec vec[3];
+ int msglen = 0;
+ char buffer[1024];
+ int ret = 0;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, handles) != 0) {
+ _E("error create socket pair");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ if (handles[0] == -1) {
+ _E("error socket open");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ _D("amd send mp fd : [%d, %d]", handles[0], handles[1]);
+ vec[0].iov_base = buffer;
+ vec[0].iov_len = strlen(buffer) + 1;
+
+ msglen = __send_message(_request_get_fd(req), vec, 1, handles, 2);
+ if (msglen < 0) {
+ _E("Error[%d]: while sending message\n", -msglen);
+ _request_send_result(req, -1);
+ ret = -1;
+ }
+
+ close(handles[0]);
+ close(handles[1]);
+
+ return ret;
+}
+
+static int *__check_dc_socket_pair_handle(char *socket_pair_key,
+ const char *datacontrol_type)
+{
+ int *handles;
+
+ handles = g_hash_table_lookup(__dc_socket_pair_hash, socket_pair_key);
+ if (handles == NULL)
+ return NULL;
+
+ if (strcmp(datacontrol_type, "consumer") == 0) {
+ if (handles[0] == -1) {
+ g_hash_table_remove(__dc_socket_pair_hash,
+ socket_pair_key);
+ return NULL;
+ }
+ } else {
+ if (handles[1] == -1) {
+ g_hash_table_remove(__dc_socket_pair_hash,
+ socket_pair_key);
+ return NULL;
+ }
+ }
+
+ return handles;
+}
+
+static int __dispatch_get_dc_socket_pair(request_h req)
+{
+ const char *caller;
+ const char *callee;
+ const char *datacontrol_type;
+ char *socket_pair_key = NULL;
+ int socket_pair_key_len;
+ int *handles = NULL;
+ struct iovec vec[3];
+ int msglen = 0;
+ char buffer[1024];
+ bundle *kb = _request_get_bundle(req);
+
+ caller = bundle_get_val(kb, AUL_K_CALLER_APPID);
+ if (caller == NULL)
+ goto err_out;
+ callee = bundle_get_val(kb, AUL_K_CALLEE_APPID);
+ if (callee == NULL)
+ goto err_out;
+ datacontrol_type = bundle_get_val(kb, "DATA_CONTROL_TYPE");
+ if (datacontrol_type == NULL)
+ goto err_out;
+
+ socket_pair_key_len = strlen(caller) + strlen(callee) + 2;
+
+ socket_pair_key = (char *)calloc(socket_pair_key_len, sizeof(char));
+ if (socket_pair_key == NULL) {
+ _E("calloc fail");
+ goto err_out;
+ }
+
+ snprintf(socket_pair_key, socket_pair_key_len, "%s_%s", caller, callee);
+ _D("socket pair key : %s", socket_pair_key);
+
+ handles = __check_dc_socket_pair_handle(socket_pair_key,
+ datacontrol_type);
+ if (handles == NULL) {
+ if (strcmp(datacontrol_type, "consumer") != 0) {
+ _E("Only consumer can create socketpair");
+ goto err_out;
+ }
+
+ handles = (int *)calloc(2, sizeof(int));
+ if (handles == NULL) {
+ _E("calloc fail");
+ goto err_out;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, handles) != 0) {
+ _E("error create socket pair");
+ free(handles);
+ handles = NULL;
+ goto err_out;
+ }
+
+ if (handles[0] == -1 || handles[1] == -1) {
+ _E("error socket open");
+ free(handles);
+ handles = NULL;
+ goto err_out;
+ }
+
+ g_hash_table_insert(__dc_socket_pair_hash,
+ strdup(socket_pair_key), handles);
+ _D("New socket pair insert done.");
+ }
+
+ SECURE_LOGD("amd send fd : [%d, %d]", handles[0], handles[1]);
+ vec[0].iov_base = buffer;
+ vec[0].iov_len = 1;
+
+ _send_result_to_client_v2(_request_get_fd(req), 0);
+
+ if (datacontrol_type != NULL) {
+ _D("datacontrol_type : %s", datacontrol_type);
+ if (strcmp(datacontrol_type, "consumer") == 0) {
+ msglen = __send_message(_request_get_fd(req), vec, 1,
+ &handles[0], 1);
+ if (msglen < 0) {
+ _E("Error[%d]: while sending message", -msglen);
+ goto err_out;
+ }
+ close(handles[0]);
+ handles[0] = -1;
+ if (handles[1] == -1) {
+ _D("remove from hash : %s", socket_pair_key);
+ g_hash_table_remove(__dc_socket_pair_hash,
+ socket_pair_key);
+ }
+
+ } else {
+ msglen = __send_message(_request_get_fd(req), vec, 1,
+ &handles[1], 1);
+ if (msglen < 0) {
+ _E("Error[%d]: while sending message", -msglen);
+ goto err_out;
+ }
+ close(handles[1]);
+ handles[1] = -1;
+ if (handles[0] == -1) {
+ _D("remove from hash : %s", socket_pair_key);
+ g_hash_table_remove(__dc_socket_pair_hash,
+ socket_pair_key);
+ }
+ }
+ }
+ SECURE_LOGD("send_message msglen : [%d]\n", msglen);
+ if (socket_pair_key)
+ free(socket_pair_key);
+
+ return 0;
+
+err_out:
+ _request_send_result(req, -1);
+ if (socket_pair_key) {
+ g_hash_table_remove(__dc_socket_pair_hash, socket_pair_key);
+ free(socket_pair_key);
+ }
+
+ return -1;
+}
+
+static int __dispatch_app_set_process_group(request_h req)
+{
+ int owner_pid;
+ int child_pid;
+ bundle *kb = NULL;
+ const char *child_appid;
+ const char *child_pkgid = NULL;
+ const struct appinfo *ai;
+ const char *str_pid;
+ app_status_h app_status;
+ int ret;
+
+ kb = _request_get_bundle(req);
+ if (kb == NULL) {
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ str_pid = bundle_get_val(kb, AUL_K_OWNER_PID);
+ if (str_pid == NULL) {
+ _E("No owner pid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ owner_pid = atoi(str_pid);
+ str_pid = bundle_get_val(kb, AUL_K_CHILD_PID);
+ if (str_pid == NULL) {
+ _E("No child pid");
+ _request_send_result(req, -1);
+ return -1;
+ }
+
+ child_pid = atoi(str_pid);
+ app_status = _app_status_find(child_pid);
+ if (app_status) {
+ child_appid = _app_status_get_appid(app_status);
+ ai = _appinfo_find(_request_get_target_uid(req), child_appid);
+ child_pkgid = _appinfo_get_value(ai, AIT_PKGID);
+ }
+
+ ret = aul_send_app_group_signal(owner_pid, child_pid, child_pkgid);
+
+ _request_send_result(req, ret);
+ return 0;
+}
+
+struct checker_info {
+ caller_info_h caller;
+ request_h req;
+};
+
+int __datacontrol_privilege_func(const char *privilege_name, void *user_data)
+{
+ int ret;
+ struct checker_info *info = (struct checker_info*)user_data;
+
+ ret = _cynara_simple_checker(info->caller, info->req,
+ (void *)privilege_name);
+ if (ret >= 0 && datacontrol_result == AMD_CYNARA_UNKNOWN)
+ return ret;
+
+ datacontrol_result = ret;
+ return ret;
+}
+
+static int __datacontrol_provider_checker(caller_info_h info, request_h req,
+ void *data)
+{
+ bundle *b;
+ char *provider_id;
+ char *type;
+ char *data_type;
+ int ret;
+ struct checker_info checker = {
+ .caller = info,
+ .req = req
+ };
+
+ b = _request_get_bundle(req);
+ if (b == NULL)
+ return -1;
+
+ ret = bundle_get_str(b, "DATA_CONTROL_TYPE", &type);
+ if (ret < 0)
+ return -1;
+
+ if (strcmp(type, "provider") == 0)
+ return 0;
+
+ ret = bundle_get_str(b, OSP_K_DATACONTROL_PROVIDER, &provider_id);
+ if (ret < 0)
+ return -1;
+
+ ret = bundle_get_str(b, "DATA_CONTROL_DATA_TYPE", &data_type);
+ if (ret < 0)
+ return -1;
+
+ datacontrol_result = 0;
+
+ ret = pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges(provider_id,
+ data_type, __datacontrol_privilege_func,
+ &checker, _request_get_target_uid(req));
+ if (ret < 0) {
+ _E("pkgmgrinfo_appinfo_usr_foreach_datacontrol_privileges failed");
+ return -1;
+ }
+
+ return datacontrol_result;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_GET_DC_SOCKET_PAIR,
+ .callback = __dispatch_get_dc_socket_pair
+ },
+ {
+ .cmd = APP_GET_MP_SOCKET_PAIR,
+ .callback = __dispatch_get_mp_socket_pair
+ },
+ {
+ .cmd = APP_SET_PROCESS_GROUP,
+ .callback = __dispatch_app_set_process_group
+ },
+};
+
+static cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_GET_DC_SOCKET_PAIR,
+ .checker = __datacontrol_provider_checker,
+ .data = NULL,
+ },
+};
+
+static void __free_socket_pair(gpointer data)
+{
+ int *handles = (int *)data;
+
+ if (handles == NULL)
+ return;
+
+ if (handles[0] > 0)
+ close(handles[0]);
+ if (handles[1] > 0)
+ close(handles[1]);
+ free(handles);
+}
+
+static void __memory_status_changed_cb(keynode_t *node, void *data)
+{
+ __memory_status = vconf_keynode_get_int(node);
+ switch (__memory_status) {
+ case VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL:
+ _W("Normal");
+ _noti_send(AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL, 0, 0, NULL, NULL);
+ break;
+ case VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING:
+ _W("Soft warning");
+ break;
+ case VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING:
+ _W("Hard warning");
+ break;
+ default:
+ break;
+ }
+}
+
+bool _util_check_oom(void)
+{
+ if (__memory_status >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
+ _W("low memory");
+ return true;
+ }
+
+ return false;
+}
+
+static int __init_vconf(void)
+{
+ int r;
+
+ vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &__memory_status);
+ r = vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
+ __memory_status_changed_cb, NULL);
+ if (r < 0) {
+ _E("Failed to initialize vconf");
+ return -1;
+ }
+
+ __vconf_initialized = true;
+
+ return 0;
+}
+
+static void __finish_vconf(void)
+{
+ if (!__vconf_initialized)
+ return;
+
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
+ __memory_status_changed_cb);
+ __vconf_initialized = false;
+}
+
+static gboolean __retrying_handler(gpointer data)
+{
+ static int retry_count;
+
+ retry_count++;
+ if (__init_vconf() < 0 && retry_count <= 10) {
+ _W("Retry count(%d)", retry_count);
+ return G_SOURCE_CONTINUE;
+ }
+
+ __vconf_init_timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+int _util_init(void)
+{
+ int r;
+
+ r = _logger_create(AMD_LOG_FILE, &__logger);
+ if (r < 0)
+ return -1;
+
+ __vconf_init_timer = g_timeout_add(500, __retrying_handler, NULL);
+
+ __dc_socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, __free_socket_pair);
+ if (__dc_socket_pair_hash == NULL) {
+ _E("Failed to create socket pair table");
+ return -1;
+ }
+
+ r = _request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = _cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _util_fini(void)
+{
+ if (__vconf_init_timer)
+ g_source_remove(__vconf_init_timer);
+
+ __finish_vconf();
+
+ if (__dc_socket_pair_hash) {
+ g_hash_table_destroy(__dc_socket_pair_hash);
+ __dc_socket_pair_hash = NULL;
+ }
+
+ _logger_destroy(__logger);
+}
+
+static int __delete_dir(const char *path)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ char buf[PATH_MAX];
+ struct stat statbuf;
+ int ret;
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return -1;
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (!strcmp(dentry->d_name, ".") ||
+ !strcmp(dentry->d_name, ".."))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
+ ret = stat(buf, &statbuf);
+ if (ret == 0) {
+ if (S_ISDIR(statbuf.st_mode))
+ __delete_dir(buf);
+ else
+ unlink(buf);
+ }
+ }
+
+ rmdir(path);
+ closedir(dp);
+
+ return 0;
+}
+
+int _util_unlink(const char *path)
+{
+ struct stat statbuf;
+ int ret;
+
+ if (!path) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ ret = stat(path, &statbuf);
+ if (ret < 0) {
+ _E("Failed to get file(%s) status. errno(%d)", path, errno);
+ return -1;
+ }
+
+ if (S_ISDIR(statbuf.st_mode))
+ return __delete_dir(path);
+
+ unlink(path);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_UTIL_H__
+#define __AMD_UTIL_H__
+
+#include <unistd.h>
+#include <dlog.h>
+#include <glib.h>
+#include <stdbool.h>
+#include <tzplatform_config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+#undef LOG_TAG
+#define LOG_TAG "AMD"
+
+#define _E(fmt, arg...) LOGE(fmt, ##arg)
+
+#define _D(fmt, arg...) LOGD(fmt, ##arg)
+
+#define _W(fmt, arg...) LOGW(fmt, ##arg)
+
+#define _I(fmt, arg...) LOGI(fmt, ##arg)
+
+#define MAX_LOCAL_BUFSZ 128
+
+#define MAX_PID_STR_BUFSZ 20
+
+#define MAX_UID_STR_BUFSZ 20
+
+#define MAX_PACKAGE_STR_SIZE 512
+
+#define MAX_PACKAGE_APP_PATH_SIZE 512
+
+#define REGULAR_UID_MIN 5000
+
+#define GSLIST_FOREACH_SAFE(list, l, l_next) \
+ for (l = list, l_next = g_slist_next(l); \
+ l; \
+ l = l_next, l_next = g_slist_next(l))
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+int _util_save_log(const char *tag, const char *message);
+
+int _util_init(void);
+
+void _util_fini(void);
+
+bool _util_check_oom(void);
+
+int _util_unlink(const char *path);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_UTIL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_H__
+#define __AMD_H__
+
+#include <amd_api_app_com.h>
+#include <amd_api_app_property.h>
+#include <amd_api_app_status.h>
+#include <amd_api_appinfo.h>
+#include <amd_api_comp_status.h>
+#include <amd_api_compinfo.h>
+#include <amd_api_config.h>
+#include <amd_api_cynara.h>
+#include <amd_api_inotify.h>
+#include <amd_api_launch.h>
+#include <amd_api_launch_context.h>
+#include <amd_api_launch_mode.h>
+#include <amd_api_launchpad.h>
+#include <amd_api_logger.h>
+#include <amd_api_login_monitor.h>
+#include <amd_api_noti.h>
+#include <amd_api_proc.h>
+#include <amd_api_request.h>
+#include <amd_api_signal.h>
+#include <amd_api_socket.h>
+#include <amd_api_suspend.h>
+#include <amd_api_util.h>
+#include <amd_api_wayland.h>
+
+#endif /* __AMD_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_app_com.h"
+#include "lib/api/amd_api_app_com.h"
+
+extern "C" EXPORT_API int amd_app_com_send(const char* endpoint, int cpid,
+ bundle* envelope, uid_t uid) {
+ return _app_com_send(endpoint, cpid, envelope, uid);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_APP_COM_H__
+#define __AMD_API_APP_COM_H__
+
+#include <bundle.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int amd_app_com_send(const char *endpoint, int cpid, bundle *envelope,
+ uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_APP_COM_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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/amd_api.h"
+#include "lib/amd_app_property.h"
+#include "lib/api/amd_api_app_property.h"
+
+extern "C" EXPORT_API amd_app_property_h amd_app_property_find(uid_t uid) {
+ return _app_property_find(uid);
+}
+
+extern "C" EXPORT_API int amd_app_property_metadata_add_filter(const char* key,
+ const char* value) {
+ return _app_property_metadata_add_filter(key, value);
+}
+
+extern "C" EXPORT_API int amd_app_property_metadata_remove_filter(
+ const char* key, const char* value) {
+ return _app_property_metadata_remove_filter(key, value);
+}
+
+extern "C" EXPORT_API int amd_app_property_metadata_foreach(
+ amd_app_property_h app_property,
+ const char* appid, const char* key,
+ int (*callback)(const char* value, void* user_data),
+ void* user_data) {
+ auto prop = static_cast<app_property_h>(app_property);
+ return _app_property_metadata_foreach(prop, appid, key, callback, user_data);
+}
+
+extern "C" EXPORT_API const char *amd_app_property_get_real_appid(
+ amd_app_property_h app_property, const char* alias_appid) {
+ auto prop = static_cast<app_property_h>(app_property);
+ return _app_property_get_real_appid(prop, alias_appid);
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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_API_APP_PROPERTY_H__
+#define __AMD_API_APP_PROPERTY_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *amd_app_property_h;
+
+amd_app_property_h amd_app_property_find(uid_t uid);
+
+int amd_app_property_metadata_add_filter(const char *key, const char *value);
+
+int amd_app_property_metadata_remove_filter(const char *key,
+ const char *value);
+
+int amd_app_property_metadata_foreach(amd_app_property_h app_property,
+ const char *appid, const char *key,
+ int (*callback)(const char *value, void *user_data),
+ void *user_data);
+
+const char *amd_app_property_get_real_appid(amd_app_property_h app_property,
+ const char *alias_appid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_APP_PROPERTY_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_app_status.h"
+#include "lib/api/amd_api_app_status.h"
+
+extern "C" EXPORT_API amd_app_status_h amd_app_status_find_by_effective_pid(
+ int pid) {
+ return _app_status_find_v2(pid);
+}
+
+extern "C" EXPORT_API amd_app_status_h amd_app_status_find_by_pid(int pid) {
+ return _app_status_find(pid);
+}
+
+extern "C" EXPORT_API amd_app_status_h amd_app_status_find_by_appid(
+ const char* appid, uid_t uid) {
+ return _app_status_find_by_appid(appid, uid);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_pid(amd_app_status_h h) {
+ return _app_status_get_pid(h);
+}
+
+extern "C" EXPORT_API int amd_app_status_is_running(amd_app_status_h h) {
+ return _app_status_is_running(h);
+}
+
+extern "C" EXPORT_API uid_t amd_app_status_get_uid(amd_app_status_h h) {
+ return _app_status_get_uid(h);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_status(amd_app_status_h h) {
+ return _app_status_get_status(h);
+}
+
+extern "C" EXPORT_API bool amd_app_status_is_home_app(amd_app_status_h h) {
+ return _app_status_is_home_app(h);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_first_caller_pid(
+ amd_app_status_h h) {
+ return _app_status_get_org_caller_pid(h);
+}
+
+extern "C" EXPORT_API const char* amd_app_status_get_appid(amd_app_status_h h) {
+ return _app_status_get_appid(h);
+}
+
+extern "C" EXPORT_API const char* amd_app_status_get_pkgid(amd_app_status_h h) {
+ return _app_status_get_pkgid(h);
+}
+
+extern "C" EXPORT_API const char* amd_app_status_get_instance_id(
+ amd_app_status_h h) {
+ return _app_status_get_instance_id(h);
+}
+
+extern "C" EXPORT_API int amd_app_status_foreach_running_info(
+ amd_app_status_cb callback, void* user_data) {
+ return _app_status_foreach_running_appinfo(callback, user_data);
+}
+
+extern "C" EXPORT_API int amd_app_status_terminate_apps(const char* appid,
+ uid_t uid) {
+ return _app_status_terminate_apps(appid, uid);
+}
+
+extern "C" EXPORT_API bool amd_app_status_is_starting(amd_app_status_h h) {
+ return _app_status_is_starting(h);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_app_type(
+ amd_app_status_h app_status) {
+ return _app_status_get_app_type(app_status);
+}
+
+extern "C" EXPORT_API int amd_app_status_set_extra(amd_app_status_h app_status,
+ const char* key, void* data) {
+ return _app_status_set_extra(app_status, key, data);
+}
+
+extern "C" EXPORT_API int amd_app_status_remove_extra(
+ amd_app_status_h app_status, const char* key) {
+ return _app_status_remove_extra(app_status, key);
+}
+
+extern "C" EXPORT_API void* amd_app_status_get_extra(
+ amd_app_status_h app_status, const char* key) {
+ return _app_status_get_extra(app_status, key);
+}
+
+extern "C" EXPORT_API const char* amd_app_status_get_leader_id(
+ amd_app_status_h app_status) {
+ return _app_status_get_leader_id(app_status);
+}
+
+extern "C" EXPORT_API int amd_app_status_set_leader_id(
+ amd_app_status_h app_status, const char* id) {
+ return _app_status_set_leader_id(app_status, id);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_fg_cnt(
+ amd_app_status_h app_status) {
+ return _app_status_get_fg_cnt(app_status);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_timestamp(
+ amd_app_status_h app_status) {
+ return _app_status_get_timestamp(app_status);
+}
+
+extern "C" EXPORT_API int amd_app_status_term_bg_apps(GCompareFunc func) {
+ return _app_status_term_bg_apps(func);
+}
+
+extern "C" EXPORT_API bool amd_app_status_get_bg_launch(
+ amd_app_status_h app_status) {
+ return _app_status_get_bg_launch(app_status);
+}
+
+extern "C" EXPORT_API amd_app_status_h amd_app_status_find_by_instance_id(
+ const char* appid, const char* instance_id, uid_t uid) {
+ return _app_status_find_by_instance_id(appid, instance_id, uid);
+}
+
+extern "C" EXPORT_API void amd_app_status_find_service_apps(
+ amd_app_status_h app_status, int status,
+ void (*send_event_to_svc_core)(int, uid_t),
+ bool suspend) {
+ _app_status_find_service_apps(app_status, status,
+ send_event_to_svc_core, suspend);
+}
+
+extern "C" EXPORT_API int amd_app_status_get_process_cnt(const char* appid) {
+ return _app_status_get_process_cnt(appid);
+}
+
+extern "C" EXPORT_API const char *amd_app_status_get_app_path(
+ amd_app_status_h app_status) {
+ return _app_status_get_app_path(app_status);
+}
+
+extern "C" EXPORT_API bool amd_app_status_is_exiting(
+ amd_app_status_h app_status) {
+ return _app_status_is_exiting(app_status);
+}
+
+extern "C" EXPORT_API int amd_app_status_register_pid(int pid,
+ const char* appid, uid_t uid) {
+ return _app_status_register_pid(pid, appid, uid);
+}
+
+extern "C" EXPORT_API bool amd_app_status_is_debug_mode(
+ amd_app_status_h app_status) {
+ return _app_status_is_debug_mode(app_status);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_APP_STATUS_H__
+#define __AMD_API_APP_STATUS_H__
+
+#include <glib.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ AMD_AT_SERVICE_APP,
+ AMD_AT_UI_APP,
+ AMD_AT_WIDGET_APP,
+ AMD_AT_WATCH_APP,
+ AMD_AT_COMPONENT_BASED_APP,
+} amd_app_type_e;
+
+typedef struct app_status_s *amd_app_status_h;
+
+typedef void (*amd_app_status_cb)(amd_app_status_h h, void *user_data);
+
+amd_app_status_h amd_app_status_find_by_effective_pid(int pid);
+
+amd_app_status_h amd_app_status_find_by_pid(int pid);
+
+amd_app_status_h amd_app_status_find_by_appid(const char *appid, uid_t uid);
+
+int amd_app_status_get_pid(amd_app_status_h h);
+
+int amd_app_status_is_running(amd_app_status_h h);
+
+uid_t amd_app_status_get_uid(amd_app_status_h h);
+
+int amd_app_status_get_status(amd_app_status_h h);
+
+bool amd_app_status_is_home_app(amd_app_status_h h);
+
+int amd_app_status_get_first_caller_pid(amd_app_status_h h);
+
+const char *amd_app_status_get_appid(amd_app_status_h h);
+
+const char *amd_app_status_get_pkgid(amd_app_status_h h);
+
+const char *amd_app_status_get_instance_id(amd_app_status_h h);
+
+int amd_app_status_foreach_running_info(amd_app_status_cb callback,
+ void *user_data);
+
+int amd_app_status_terminate_apps(const char *appid, uid_t uid);
+
+bool amd_app_status_is_starting(amd_app_status_h h);
+
+int amd_app_status_get_app_type(amd_app_status_h app_status);
+
+int amd_app_status_set_extra(amd_app_status_h app_status, const char *key,
+ void *data);
+
+int amd_app_status_remove_extra(amd_app_status_h app_status, const char *key);
+
+void *amd_app_status_get_extra(amd_app_status_h app_status, const char *key);
+
+const char *amd_app_status_get_leader_id(amd_app_status_h app_status);
+
+int amd_app_status_set_leader_id(amd_app_status_h app_status, const char *id);
+
+int amd_app_status_get_fg_cnt(amd_app_status_h app_status);
+
+int amd_app_status_get_timestamp(amd_app_status_h app_status);
+
+int amd_app_status_term_bg_apps(GCompareFunc func);
+
+bool amd_app_status_get_bg_launch(amd_app_status_h app_status);
+
+amd_app_status_h amd_app_status_find_by_instance_id(const char *appid,
+ const char *instance_id, uid_t uid);
+
+void amd_app_status_find_service_apps(amd_app_status_h app_status, int status,
+ void (*send_event_to_svc_core)(int, uid_t), bool suspend);
+
+int amd_app_status_get_process_cnt(const char *appid);
+
+const char *amd_app_status_get_app_path(amd_app_status_h app_status);
+
+bool amd_app_status_is_exiting(amd_app_status_h app_status);
+
+int amd_app_status_register_pid(int pid, const char *appid, uid_t uid);
+
+bool amd_app_status_is_debug_mode(amd_app_status_h app_status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_APP_STATUS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_appinfo.h"
+#include "lib/api/amd_api_appinfo.h"
+
+extern "C" EXPORT_API int amd_appinfo_insert(uid_t uid, const char* pkgid) {
+ return _appinfo_insert(uid, pkgid);
+}
+
+extern "C" EXPORT_API amd_appinfo_h amd_appinfo_find(uid_t caller_uid,
+ const char* appid) {
+ return _appinfo_find(caller_uid, appid);
+}
+
+extern "C" EXPORT_API const char* amd_appinfo_get_value(amd_appinfo_h h,
+ amd_appinfo_type type) {
+ return _appinfo_get_value(h, static_cast<enum appinfo_type>(type));
+}
+
+extern "C" EXPORT_API const void *amd_appinfo_get_ptr_value(amd_appinfo_h h,
+ amd_appinfo_type type) {
+ return _appinfo_get_ptr_value(h, static_cast<enum appinfo_type>(type));
+}
+
+extern "C" EXPORT_API int amd_appinfo_get_int_value(amd_appinfo_h h,
+ amd_appinfo_type type, int* val) {
+ return _appinfo_get_int_value(h, static_cast<enum appinfo_type>(type), val);
+}
+
+extern "C" EXPORT_API int amd_appinfo_get_boolean(amd_appinfo_h h,
+ amd_appinfo_type type, bool* val) {
+ return _appinfo_get_boolean(h, static_cast<enum appinfo_type>(type), val);
+}
+
+extern "C" EXPORT_API int amd_appinfo_set_value(amd_appinfo_h h,
+ amd_appinfo_type type, const char* val) {
+ return _appinfo_set_value(h, static_cast<enum appinfo_type>(type), val);
+}
+
+extern "C" EXPORT_API int amd_appinfo_set_ptr_value(amd_appinfo_h h,
+ amd_appinfo_type type, void* val) {
+ return _appinfo_set_ptr_value(h, static_cast<enum appinfo_type>(type), val);
+}
+
+extern "C" EXPORT_API int amd_appinfo_set_int_value(amd_appinfo_h h,
+ amd_appinfo_type type, int val) {
+ return _appinfo_set_int_value(h, static_cast<enum appinfo_type>(type), val);
+}
+
+extern "C" EXPORT_API void amd_appinfo_foreach(uid_t uid,
+ amd_appinfo_iter_callback cb, void* user_data) {
+ return _appinfo_foreach(uid, cb, user_data);
+}
+
+extern "C" EXPORT_API int amd_appinfo_load(uid_t uid) {
+ return _appinfo_load(uid);
+}
+
+extern "C" EXPORT_API void amd_appinfo_unload(uid_t uid) {
+ return _appinfo_unload(uid);
+}
+
+extern "C" EXPORT_API amd_appinfo_splash_image_h amd_appinfo_find_splash_image(
+ amd_appinfo_h h, const char* name, bool landscape) {
+ return _appinfo_find_splash_image(h, name, landscape);
+}
+
+extern "C" EXPORT_API const char* amd_appinfo_splash_image_get_source(
+ amd_appinfo_splash_image_h h) {
+ return _appinfo_splash_image_get_source(h);
+}
+
+extern "C" EXPORT_API const char* amd_appinfo_splash_image_get_type(
+ amd_appinfo_splash_image_h h) {
+ return _appinfo_splash_image_get_type(h);
+}
+
+extern "C" EXPORT_API int amd_appinfo_splash_image_get_indicator_display(
+ amd_appinfo_splash_image_h h) {
+ return _appinfo_splash_image_get_indicator_display(h);
+}
+
+extern "C" EXPORT_API int amd_appinfo_splash_image_get_color_depth(
+ amd_appinfo_splash_image_h h) {
+ return _appinfo_splash_image_get_color_depth(h);
+}
+
+extern "C" EXPORT_API bool amd_appinfo_is_pkg_updating(const char* pkgid) {
+ return _appinfo_is_pkg_updating(pkgid);
+}
+
+extern "C" EXPORT_API int amd_appinfo_get_cert_visibility(const char* pkgid,
+ uid_t uid) {
+ return _appinfo_get_cert_visibility(pkgid, uid);
+}
+
+extern "C" EXPORT_API bool amd_appinfo_is_platform_app(const char* appid,
+ uid_t uid) {
+ return _appinfo_is_platform_app(appid, uid);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_APPINFO_H__
+#define __AMD_API_APPINFO_H__
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APP_TYPE_SERVICE "svcapp"
+
+#define APP_TYPE_UI "uiapp"
+
+#define APP_TYPE_WIDGET "widgetapp"
+
+#define APP_TYPE_WATCH "watchapp"
+
+#define APP_TYPE_COMPONENT_BASED "componentbasedapp"
+
+#define APP_ENABLEMENT_MASK_ACTIVE 0x1
+
+typedef enum _amd_appinfo_type {
+ AMD_AIT_NAME = 0,
+ AMD_AIT_EXEC,
+ AMD_AIT_PKGTYPE,
+ AMD_AIT_ONBOOT, /* start on boot: boolean */
+ AMD_AIT_RESTART, /* auto restart: boolean */
+ AMD_AIT_MULTI,
+ AMD_AIT_HWACC,
+ AMD_AIT_PERM,
+ AMD_AIT_PKGID,
+ AMD_AIT_PRELOAD,
+ AMD_AIT_STATUS,
+ AMD_AIT_POOL,
+ AMD_AIT_COMPTYPE,
+ AMD_AIT_TEP,
+ AMD_AIT_MOUNTABLE_PKG,
+ AMD_AIT_STORAGE_TYPE,
+ AMD_AIT_BG_CATEGORY,
+ AMD_AIT_LAUNCH_MODE,
+ AMD_AIT_GLOBAL,
+ AMD_AIT_EFFECTIVE_APPID,
+ AMD_AIT_TASKMANAGE,
+ AMD_AIT_VISIBILITY,
+ AMD_AIT_APPTYPE,
+ AMD_AIT_ROOT_PATH,
+ AMD_AIT_SPLASH_SCREEN,
+ AMD_AIT_SPLASH_SCREEN_DISPLAY,
+ AMD_AIT_API_VERSION,
+ AMD_AIT_ENABLEMENT,
+ AMD_AIT_COOLDOWN,
+ AMD_AIT_SYSTEM,
+ AMD_AIT_IME,
+ AMD_AIT_IGNORE,
+ AMD_AIT_MAX
+} amd_appinfo_type;
+
+typedef struct appinfo *amd_appinfo_h;
+
+typedef struct appinfo_splash_image *amd_appinfo_splash_image_h;
+
+typedef void (*amd_appinfo_iter_callback)(void *user_data,
+ const char *filename, amd_appinfo_h h);
+
+int amd_appinfo_insert(uid_t uid, const char *pkgid);
+
+amd_appinfo_h amd_appinfo_find(uid_t caller_uid, const char *appid);
+
+const char *amd_appinfo_get_value(amd_appinfo_h h, amd_appinfo_type type);
+
+const void *amd_appinfo_get_ptr_value(amd_appinfo_h h, amd_appinfo_type type);
+
+int amd_appinfo_get_int_value(amd_appinfo_h h, amd_appinfo_type type, int *val);
+
+int amd_appinfo_get_boolean(amd_appinfo_h h, amd_appinfo_type type, bool *val);
+
+int amd_appinfo_set_value(amd_appinfo_h h, amd_appinfo_type type,
+ const char *val);
+
+int amd_appinfo_set_ptr_value(amd_appinfo_h h, amd_appinfo_type type,
+ void *val);
+
+int amd_appinfo_set_int_value(amd_appinfo_h h, amd_appinfo_type type, int val);
+
+void amd_appinfo_foreach(uid_t uid, amd_appinfo_iter_callback cb,
+ void *user_data);
+
+int amd_appinfo_load(uid_t uid);
+
+void amd_appinfo_unload(uid_t uid);
+
+amd_appinfo_splash_image_h amd_appinfo_find_splash_image(amd_appinfo_h h,
+ const char *name, bool landscape);
+
+const char *amd_appinfo_splash_image_get_source(amd_appinfo_splash_image_h h);
+
+const char *amd_appinfo_splash_image_get_type(amd_appinfo_splash_image_h h);
+
+int amd_appinfo_splash_image_get_indicator_display(
+ amd_appinfo_splash_image_h h);
+
+int amd_appinfo_splash_image_get_color_depth(amd_appinfo_splash_image_h h);
+
+bool amd_appinfo_is_pkg_updating(const char *pkgid);
+
+int amd_appinfo_get_cert_visibility(const char *pkgid, uid_t uid);
+
+bool amd_appinfo_is_platform_app(const char *appid, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_APPINFO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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/amd_api.h"
+#include "lib/amd_comp_status.h"
+#include "lib/api/amd_api_comp_status.h"
+
+extern "C" EXPORT_API amd_comp_status_h amd_comp_status_find(
+ const char* comp_id) {
+ return _comp_status_find(comp_id);
+}
+
+extern "C" EXPORT_API int amd_comp_status_set_leader_id(amd_comp_status_h h,
+ const char* instance_id) {
+ return _comp_status_set_leader_id(h, instance_id);
+}
+
+extern "C" EXPORT_API const char* amd_comp_status_get_leader_id(
+ amd_comp_status_h h) {
+ return _comp_status_get_leader_id(h);
+}
+
+extern "C" EXPORT_API int amd_comp_status_set_window(amd_comp_status_h h,
+ int window) {
+ return _comp_status_set_window(h, window);
+}
+
+extern "C" EXPORT_API amd_comp_status_h amd_comp_status_find_by_instance_id(
+ const char* instance_id) {
+ return _comp_status_find_by_instance_id(instance_id);
+}
+
+extern "C" EXPORT_API amd_comp_status_h amd_comp_status_find_by_window(
+ int window) {
+ return _comp_status_find_by_window(window);
+}
+
+extern "C" EXPORT_API pid_t amd_comp_status_get_pid(amd_comp_status_h h) {
+ return _comp_status_get_pid(h);
+}
+
+extern "C" EXPORT_API const char* amd_comp_status_get_comp_id(
+ amd_comp_status_h h) {
+ return _comp_status_get_comp_id(h);
+}
+
+extern "C" EXPORT_API const char* amd_comp_status_get_instance_id(
+ amd_comp_status_h h) {
+ return _comp_status_get_instance_id(h);
+}
+
+extern "C" EXPORT_API int amd_comp_status_get_comp_type(amd_comp_status_h h) {
+ return _comp_status_get_comp_type(h);
+}
+
+extern "C" EXPORT_API int amd_comp_status_get_status(amd_comp_status_h h) {
+ return _comp_status_get_status(h);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_API_COMP_STATUS_H__
+#define __AMD_API_COMP_STATUS_H__
+
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *amd_comp_status_h;
+
+typedef enum {
+ AMD_CT_FRAME_COMP,
+ AMD_CT_SERVICE_COMP,
+} amd_comp_type_e;
+
+amd_comp_status_h amd_comp_status_find(const char *comp_id);
+
+amd_comp_status_h amd_comp_status_find_by_instance_id(const char *instance_id);
+
+amd_comp_status_h amd_comp_status_find_by_window(int window);
+
+pid_t amd_comp_status_get_pid(amd_comp_status_h h);
+
+const char *amd_comp_status_get_comp_id(amd_comp_status_h h);
+
+int amd_comp_status_set_leader_id(amd_comp_status_h h, const char *instance_id);
+
+const char *amd_comp_status_get_leader_id(amd_comp_status_h h);
+
+const char *amd_comp_status_get_instance_id(amd_comp_status_h h);
+
+int amd_comp_status_get_comp_type(amd_comp_status_h h);
+
+int amd_comp_status_get_status(amd_comp_status_h h);
+
+int amd_comp_status_set_window(amd_comp_status_h h, int window);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_COMP_STATUS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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/amd_api.h"
+#include "lib/amd_compinfo.h"
+#include "lib/api/amd_api_compinfo.h"
+
+extern "C" EXPORT_API amd_compinfo_h amd_compinfo_find(uid_t uid,
+ const char* id) {
+ return _compinfo_find(uid, id);
+}
+
+extern "C" EXPORT_API const char *amd_compinfo_get_value(amd_compinfo_h info,
+ amd_compinfo_type type) {
+ return _compinfo_get_value(info, static_cast<compinfo_type_e>(type));
+}
+
+extern "C" EXPORT_API int amd_compinfo_foreach(uid_t uid,
+ amd_compinfo_foreach_cb callback, void* user_data) {
+ return _compinfo_foreach(uid, callback, user_data);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_API_COMPINFO_H__
+#define __AMD_API_COMPINFO_H__
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COMPONENT_TYPE_FRAME "frame"
+
+#define COMPONENT_TYPE_SERVICE "service"
+
+typedef enum _amd_compinfo_type {
+ AMD_COMPINFO_TYPE_NAME = 0,
+ AMD_COMPINFO_TYPE_APPID,
+ AMD_COMPINFO_TYPE_TYPE,
+ AMD_COMPINFO_TYPE_LAUNCH_MODE,
+ AMD_COMPINFO_TYPE_TASKMANAGE,
+ AMD_COMPINFO_TYPE_MAIN,
+ AMD_COMPINFO_TYPE_ICON_DISPLAY,
+ AMD_COMPINFO_TYPE_MAX
+} amd_compinfo_type;
+
+typedef void *amd_compinfo_h;
+
+typedef void (*amd_compinfo_foreach_cb)(amd_compinfo_h,
+ const char *appid, const char *id, void *user_data);
+
+amd_compinfo_h amd_compinfo_find(uid_t uid, const char *id);
+
+const char *amd_compinfo_get_value(amd_compinfo_h info, amd_compinfo_type type);
+
+int amd_compinfo_foreach(uid_t uid, amd_compinfo_foreach_cb callback,
+ void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_COMPINFO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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/amd_api.h"
+#include "lib/amd_config.h"
+#include "lib/api/amd_api_config.h"
+
+extern "C" EXPORT_API amd_tizen_profile_t amd_config_get_tizen_profile(void) {
+ return static_cast<amd_tizen_profile_t>(_config_get_tizen_profile());
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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_API_CONFIG_H__
+#define __AMD_API_CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ AMD_TIZEN_PROFILE_UNKNOWN = 0,
+ AMD_TIZEN_PROFILE_MOBILE = 0x1,
+ AMD_TIZEN_PROFILE_WEARABLE = 0x2,
+ AMD_TIZEN_PROFILE_TV = 0x4,
+ AMD_TIZEN_PROFILE_IVI = 0x8,
+ AMD_TIZEN_PROFILE_COMMON = 0x10,
+} amd_tizen_profile_t;
+
+amd_tizen_profile_t amd_config_get_tizen_profile(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_cynara.h"
+#include "lib/api/amd_api_cynara.h"
+
+static cynara_ops __ops;
+static cynara_caller_info_ops __ci_ops;
+static amd_cynara_ops __amd_ops;
+static amd_cynara_caller_info_ops __amd_ci_ops;
+
+extern "C" EXPORT_API int amd_cynara_check_privilege(amd_request_h req,
+ amd_cynara_response_cb callback) {
+ return _cynara_check_privilege(req, (cynara_response_cb)callback);
+}
+
+extern "C" EXPORT_API int amd_cynara_check_privilege_offline(amd_request_h req,
+ const char* appid, const char* privilege) {
+ return _cynara_check_privilege_offline(req, appid, privilege);
+}
+
+extern "C" EXPORT_API int amd_cynara_register_checkers(
+ const amd_cynara_checker* checkers, int cnt) {
+ return _cynara_register_checkers(reinterpret_cast<cynara_checker*>(
+ const_cast<amd_cynara_checker*>(checkers)), cnt);
+}
+
+extern "C" EXPORT_API int amd_cynara_simple_checker(
+ amd_cynara_caller_info_h info, amd_request_h req, void* data) {
+ return _cynara_simple_checker(info, req, data);
+}
+
+extern "C" EXPORT_API const char* amd_cynara_caller_info_get_client(
+ amd_cynara_caller_info_h info) {
+ return _cynara_caller_info_get_client(info);
+}
+
+extern "C" EXPORT_API int amd_cynara_sub_checker_add(const char* name,
+ amd_cynara_sub_checker_func func) {
+ return _cynara_sub_checker_add(name, func);
+}
+
+extern "C" EXPORT_API int amd_cynara_sub_checker_check(const char* name,
+ amd_cynara_caller_info_h info, amd_request_h req) {
+ return _cynara_sub_checker_check(name, info, req);
+}
+
+static int __register_checkers(const cynara_checker* checkers, int cnt) {
+ return __amd_ops.register_checkers((amd_cynara_checker *)checkers, cnt);
+}
+
+static int __sub_checker_add(const char* name, sub_checker_func func) {
+ return __amd_ops.sub_checker_add(name, func);
+}
+
+static int __sub_checker_check(const char* name, caller_info_h info,
+ request_h req) {
+ return __amd_ops.sub_checker_check(name, info, req);
+}
+
+static int __check_async(request_h req, cynara_response_cb callback) {
+ return __amd_ops.check_async(req, (amd_cynara_response_cb)callback);
+}
+
+static int __check(caller_info_h info, request_h req, void* data) {
+ return __amd_ops.check(info, req, data);
+}
+
+static int __check_offline(request_h req, const char* appid,
+ const char* privilege) {
+ return __amd_ops.check_offline(req, appid, privilege);
+}
+
+static const char* __get_client(caller_info_h info) {
+ return __amd_ci_ops.get_client(info);
+}
+
+extern "C" EXPORT_API int amd_cynara_register_ops(amd_cynara_ops ops,
+ amd_cynara_caller_info_ops ci_ops) {
+ __amd_ops = ops;
+ __amd_ci_ops = ci_ops;
+
+ __ops.register_checkers = __register_checkers;
+ __ops.sub_checker_add = __sub_checker_add;
+ __ops.sub_checker_check = __sub_checker_check;
+ __ops.check_async = __check_async;
+ __ops.check = __check;
+ __ops.check_offline = __check_offline;
+ __ci_ops.get_client = __get_client;
+
+ return _cynara_register_ops(__ops, __ci_ops);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_CYNARA_H__
+#define __AMD_API_CYNARA_H__
+
+#include <amd_api_request.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PRIVILEGE_WIDGET_VIEWER \
+ "http://tizen.org/privilege/widget.viewer"
+#define PRIVILEGE_APPMANAGER_LAUNCH \
+ "http://tizen.org/privilege/appmanager.launch"
+#define PRIVILEGE_APPMANAGER_KILL \
+ "http://tizen.org/privilege/appmanager.kill"
+#define PRIVILEGE_APPMANAGER_KILL_BGAPP \
+ "http://tizen.org/privilege/appmanager.kill.bgapp"
+#define PRIVILEGE_DOWNLOAD \
+ "http://tizen.org/privilege/download"
+#define PRIVILEGE_CALL \
+ "http://tizen.org/privilege/call"
+#define PRIVILEGE_SYSTEM_SETTING \
+ "http://tizen.org/privilege/systemsettings.admin"
+#define PRIVILEGE_PLATFORM \
+ "http://tizen.org/privilege/internal/default/platform"
+#define PRIVILEGE_PACKAGEMANAGER_INFO \
+ "http://tizen.org/privilege/packagemanager.info"
+#define PRIVILEGE_PACKAGEMANAGER_ADMIN \
+ "http://tizen.org/privilege/packagemanager.admin"
+
+enum amd_cynara_result {
+ AMD_CYNARA_RET_ERROR = -2,
+ AMD_CYNARA_RET_DENIED,
+ AMD_CYNARA_RET_ALLOWED,
+ AMD_CYNARA_RET_UNKNOWN,
+ AMD_CYNARA_RET_CONTINUE,
+};
+
+typedef struct caller_info *amd_cynara_caller_info_h;
+
+typedef int (*amd_cynara_checker_func)(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data);
+
+typedef int (*amd_cynara_sub_checker_func)(amd_cynara_caller_info_h info,
+ amd_request_h req);
+
+typedef struct _amd_cynara_checker {
+ int cmd;
+ amd_cynara_checker_func checker;
+ void *data;
+ int priority;
+} amd_cynara_checker;
+
+typedef void (*amd_cynara_response_cb)(enum amd_cynara_result res,
+ amd_request_h request);
+
+typedef int (*amd_cynara_register_checkers_cb)(
+ const amd_cynara_checker *checkers, int cnt);
+
+typedef int (*amd_cynara_sub_checker_add_cb)(
+ const char *name, amd_cynara_sub_checker_func func);
+
+typedef int (*amd_cynara_sub_checker_check_cb)(
+ const char *name, amd_cynara_caller_info_h info,
+ amd_request_h req);
+
+typedef int (*amd_cynara_check_async_cb)(amd_request_h req,
+ amd_cynara_response_cb callback);
+
+typedef int (*amd_cynara_check_cb)(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data);
+
+typedef int (*amd_cynara_check_offline_cb)(amd_request_h req, const char *appid,
+ const char *privilege);
+
+typedef struct _amd_cynara_ops {
+ amd_cynara_register_checkers_cb register_checkers;
+ amd_cynara_sub_checker_add_cb sub_checker_add;
+ amd_cynara_sub_checker_check_cb sub_checker_check;
+ amd_cynara_check_async_cb check_async;
+ amd_cynara_check_cb check;
+ amd_cynara_check_offline_cb check_offline;
+} amd_cynara_ops;
+
+typedef const char *(*amd_cynara_caller_info_get_client_cb)(
+ amd_cynara_caller_info_h info);
+
+typedef struct _amd_cynara_caller_info_ops {
+ amd_cynara_caller_info_get_client_cb get_client;
+} amd_cynara_caller_info_ops;
+
+int amd_cynara_check_privilege(amd_request_h req,
+ amd_cynara_response_cb callback);
+
+int amd_cynara_check_privilege_offline(amd_request_h req, const char *appid,
+ const char *privilege);
+
+int amd_cynara_register_checkers(const amd_cynara_checker *checkers, int cnt);
+
+int amd_cynara_simple_checker(amd_cynara_caller_info_h info, amd_request_h req,
+ void *data);
+
+const char *amd_cynara_caller_info_get_client(amd_cynara_caller_info_h info);
+
+int amd_cynara_sub_checker_add(const char *name,
+ amd_cynara_sub_checker_func func);
+
+int amd_cynara_sub_checker_check(const char *name,
+ amd_cynara_caller_info_h info, amd_request_h req);
+
+int amd_cynara_register_ops(amd_cynara_ops ops,
+ amd_cynara_caller_info_ops ci_ops);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_CYNARA_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_inotify.h"
+#include "lib/api/amd_api_inotify.h"
+
+extern "C" EXPORT_API amd_inotify_watch_info_h amd_inotify_add_watch(
+ const char* path, uint32_t mask, amd_inotify_watch_cb callback,
+ void* data) {
+ return _inotify_add_watch(path, mask, callback, data);
+}
+
+extern "C" EXPORT_API void amd_inotify_rm_watch(
+ amd_inotify_watch_info_h handle) {
+ _inotify_rm_watch(handle);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_INOTIFY_H__
+#define __AMD_API_INOTIFY_H__
+
+#include <stdbool.h>
+#include <sys/inotify.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct inotify_watch_info_s *amd_inotify_watch_info_h;
+
+typedef bool (*amd_inotify_watch_cb)(const char *event_name, void *data);
+
+amd_inotify_watch_info_h amd_inotify_add_watch(const char *path, uint32_t mask,
+ amd_inotify_watch_cb callback, void *data);
+
+void amd_inotify_rm_watch(amd_inotify_watch_info_h handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_INOTIFY_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_launch.h"
+#include "lib/api/amd_api_launch.h"
+
+extern "C" EXPORT_API int amd_launch_start_app(const char* appid,
+ amd_request_h req, bool* pending, bool* bg_launch, bool new_instance) {
+ return _launch_start_app(appid, req, pending, bg_launch, new_instance);
+}
+
+extern "C" EXPORT_API int amd_launch_term_sub_app(int pid, uid_t uid) {
+ return _term_sub_app(pid, uid);
+}
+
+extern "C" EXPORT_API int amd_launch_start_onboot_apps(uid_t uid) {
+ return _launch_start_onboot_apps(uid);
+}
+
+extern "C" EXPORT_API void amd_launch_set_mode(amd_launch_mode_e mode) {
+ _launch_set_mode(static_cast<launch_mode_e>(mode));
+}
+
+extern "C" EXPORT_API int amd_launch_term_sub_inst(pid_t pid,
+ const char* inst_id, uid_t uid) {
+ return _term_sub_inst(pid, inst_id, uid);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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_API_LAUNCH_H__
+#define __AMD_API_LAUNCH_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <amd_api_request.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ AMD_LAUNCH_MODE_NORMAL,
+ AMD_LAUNCH_MODE_BLOCK,
+} amd_launch_mode_e;
+
+int amd_launch_start_app(const char *appid, amd_request_h req, bool *pending,
+ bool *bg_launch, bool new_instance);
+
+int amd_launch_term_sub_app(int pid, uid_t uid);
+
+int amd_launch_start_onboot_apps(uid_t uid);
+
+void amd_launch_set_mode(amd_launch_mode_e mode);
+
+int amd_launch_term_sub_inst(pid_t pid, const char *inst_id, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LAUNCH_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_launch.h"
+#include "lib/api/amd_api_launch_context.h"
+
+extern "C" EXPORT_API amd_appinfo_h amd_launch_context_get_appinfo(
+ amd_launch_context_h h) {
+ return (amd_appinfo_h)_launch_context_get_appinfo(h);
+}
+
+extern "C" EXPORT_API const char* amd_launch_context_get_appid(
+ amd_launch_context_h h) {
+ return _launch_context_get_appid(h);
+}
+
+extern "C" EXPORT_API const char *amd_launch_context_get_instance_id(
+ amd_launch_context_h h) {
+ return _launch_context_get_instance_id(h);
+}
+
+extern "C" EXPORT_API int amd_launch_context_get_pid(amd_launch_context_h h) {
+ return _launch_context_get_pid(h);
+}
+
+extern "C" EXPORT_API bool amd_launch_context_is_subapp(
+ amd_launch_context_h h) {
+ return _launch_context_is_subapp(h);
+}
+
+extern "C" EXPORT_API bool amd_launch_context_is_bg_launch(
+ amd_launch_context_h h) {
+ return _launch_context_is_bg_launch(h);
+}
+
+extern "C" EXPORT_API int amd_launch_context_set_pid(amd_launch_context_h h,
+ int pid) {
+ return _launch_context_set_pid(h, pid);
+}
+
+extern "C" EXPORT_API bool amd_launch_context_is_new_instance(
+ amd_launch_context_h h) {
+ return _launch_context_is_new_instance(h);
+}
+
+extern "C" EXPORT_API int amd_launch_context_set_subapp(amd_launch_context_h h,
+ bool is_subapp) {
+ return _launch_context_set_subapp(h, is_subapp);
+}
+
+extern "C" EXPORT_API int amd_launch_context_set_app_status(
+ amd_launch_context_h h, amd_app_status_h status) {
+ return _launch_context_set_app_status(h, status);
+}
+
+extern "C" EXPORT_API int amd_launch_context_set_comp_status(
+ amd_launch_context_h h, amd_comp_status_h status) {
+ return _launch_context_set_comp_status(h, status);
+}
+
+extern "C" EXPORT_API void amd_launch_context_set_custom_effect(
+ amd_launch_context_h h, bool is_custom_effect) {
+ _launch_context_set_custom_effect(h, is_custom_effect);
+}
+
+extern "C" EXPORT_API bool amd_launch_context_is_custom_effect(
+ amd_launch_context_h h) {
+ return _launch_context_is_custom_effect(h);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_LAUNCH_CONTEXT_H__
+#define __AMD_API_LAUNCH_CONTEXT_H__
+
+#include <amd_api_app_status.h>
+#include <amd_api_appinfo.h>
+#include <amd_api_comp_status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct launch_s *amd_launch_context_h;
+
+amd_appinfo_h amd_launch_context_get_appinfo(amd_launch_context_h h);
+
+const char *amd_launch_context_get_appid(amd_launch_context_h h);
+
+const char *amd_launch_context_get_instance_id(amd_launch_context_h h);
+
+int amd_launch_context_get_pid(amd_launch_context_h h);
+
+bool amd_launch_context_is_subapp(amd_launch_context_h h);
+
+bool amd_launch_context_is_bg_launch(amd_launch_context_h h);
+
+int amd_launch_context_set_pid(amd_launch_context_h h, int pid);
+
+bool amd_launch_context_is_new_instance(amd_launch_context_h h);
+
+int amd_launch_context_set_subapp(amd_launch_context_h h, bool is_subapp);
+
+int amd_launch_context_set_app_status(amd_launch_context_h h,
+ amd_app_status_h status);
+
+int amd_launch_context_set_comp_status(amd_launch_context_h h,
+ amd_comp_status_h status);
+
+void amd_launch_context_set_custom_effect(amd_launch_context_h h,
+ bool is_custom_effect);
+
+bool amd_launch_context_is_custom_effect(amd_launch_context_h h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LAUNCH_CONTEXT_H__ */
--- /dev/null
+/*
+ * 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/amd_api.h"
+#include "lib/amd_launch_mode.h"
+#include "lib/api/amd_api_launch_mode.h"
+
+extern "C" EXPORT_API bool amd_launch_mode_is_group_mode(bundle* kb,
+ uid_t uid) {
+ return _launch_mode_is_group_mode(kb, uid);
+}
--- /dev/null
+/*
+ * 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_API_LAUNCH_MODE_H__
+#define __AMD_API_LAUNCH_MODE_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include <bundle_internal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool amd_launch_mode_is_group_mode(bundle *kb, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LAUNCH_MODE_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_launchpad.h"
+#include "lib/api/amd_api_launchpad.h"
+
+extern "C" EXPORT_API int amd_launchpad_set_launcher(amd_launcher_cb launcher,
+ void* user_data) {
+ return _launchpad_set_launcher(launcher, user_data);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_LAUNCHPAD_H__
+#define __AMD_API_LAUNCHPAD_H__
+
+#include <bundle.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int (*amd_launcher_cb)(bundle *b, uid_t uid, void *user_data);
+
+int amd_launchpad_set_launcher(amd_launcher_cb launcher, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LAUNCHPAD_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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 <stdarg.h>
+#include <stdio.h>
+
+#include "lib/amd_api.h"
+#include "lib/amd_logger.h"
+#include "lib/api/amd_api_logger.h"
+
+extern "C" EXPORT_API int amd_logger_create(const char* path,
+ amd_logger_h* handle) {
+ return _logger_create(path, reinterpret_cast<logger_h*>(handle));
+}
+
+extern "C" EXPORT_API int amd_logger_destroy(amd_logger_h handle) {
+ return _logger_destroy(reinterpret_cast<logger_h>(handle));
+}
+
+extern "C" EXPORT_API int amd_logger_print(amd_logger_h handle, const char* tag,
+ const char* format, ...) {
+ char format_buf[LOG_MAX_STRING_SIZE];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(format_buf, sizeof(format_buf), format, ap);
+ va_end(ap);
+
+ return _logger_print(reinterpret_cast<logger_h>(handle), tag, format_buf);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_API_LOGGER_H__
+#define __AMD_API_LOGGER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef LOGGER_PATH
+#define LOGGER_PATH "/var/log/appfw/amd"
+
+typedef void *amd_logger_h;
+
+int amd_logger_create(const char *path, amd_logger_h *handle);
+
+int amd_logger_destroy(amd_logger_h handle);
+
+int amd_logger_print(amd_logger_h handle, const char *tag,
+ const char *format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_login_monitor.h"
+#include "lib/api/amd_api_login_monitor.h"
+
+extern "C" EXPORT_API int amd_login_monitor_get_uids(uid_t** uids) {
+ return _login_monitor_get_uids(uids);
+}
+
+extern "C" EXPORT_API amd_uid_state amd_login_monitor_get_uid_state(uid_t uid) {
+ return static_cast<amd_uid_state>(_login_monitor_get_uid_state(uid));
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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_API_LOGIN_MONITOR_H__
+#define __AMD_API_LOGIN_MONITOR_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum amd_uid_state_e {
+ AMD_UID_STATE_UNKNOWN = 0x00,
+ AMD_UID_STATE_OPENING = 0x01,
+ AMD_UID_STATE_LINGERING = 0x02,
+ AMD_UID_STATE_ONLINE = 0x04,
+ AMD_UID_STATE_ACTIVE = 0x08,
+ AMD_UID_STATE_CLOSING = 0x10,
+ AMD_UID_STATE_OFFLINE = 0x20,
+} amd_uid_state;
+
+int amd_login_monitor_get_uids(uid_t **uids);
+
+amd_uid_state amd_login_monitor_get_uid_state(uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_LOGIN_MONITOR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_noti.h"
+#include "lib/api/amd_api_noti.h"
+
+extern "C" EXPORT_API int amd_noti_send(const char *msg, int arg1, int arg2,
+ void* arg3, bundle* data) {
+ return _noti_send(msg, arg1, arg2, arg3, data);
+}
+
+extern "C" EXPORT_API int amd_noti_listen(const char* msg,
+ amd_noti_cb callback) {
+ return _noti_listen(msg, (noti_cb)callback);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_NOTI_H__
+#define __AMD_API_NOTI_H__
+
+#include <bundle.h>
+#include <amd_api_noti_msg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AMD_NOTI_CONTINUE 0
+#define AMD_NOTI_STOP -2
+
+typedef int (*amd_noti_cb)(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data);
+
+int amd_noti_send(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data);
+
+int amd_noti_listen(const char *msg, amd_noti_cb callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_NOTI_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 - 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_API_NOTI_MSG_H__
+#define __AMD_API_NOTI_MSG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Definition for the notification message: The application information is inserted.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(pkgmgrinfo_appinfo_h) The pkgmgr appinfo handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __appinfo_insert_handler()
+ * @see __appinfo_update_handler()
+ */
+#define AMD_NOTI_MSG_APPINFO_INSERT \
+ "appinfo.insert"
+
+/**
+ * @brief Definition for the notification message: The application information is removed.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char*) The application ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __appinfo_update_handler()
+ */
+#define AMD_NOTI_MSG_APPINFO_REMOVE \
+ "appinfo.remove"
+
+/**
+ * @brief Definition for the notification message: The application informations are reloaded.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __reload_appinfo()
+ */
+#define AMD_NOTI_MSG_APPINFO_RELOAD \
+ "appinfo.reload"
+
+/**
+ * @brief Definition for the notification message: The application informations are loaded.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see _appinfo_load()
+ */
+#define AMD_NOTI_MSG_APPINFO_LOAD \
+ "appinfo.load"
+
+/**
+ * @brief Definition for the notification message: The application informations are unloaded.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see _appinfo_unload()
+ */
+#define AMD_NOTI_MSG_APPINFO_UNLOAD \
+ "appinfo.unload"
+/**
+ * @brief Definition for the notification message: The package update is failed.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char *) The package ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __package_event_cb()
+ */
+#define AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR \
+ "appinfo.package.update.error"
+
+/**
+ * @brief Definition for the notification message: The package is deleted.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * arg3(const char *) The package ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __package_event_cb()
+ */
+#define AMD_NOTI_MSG_APPINFO_PACKAGE_UNINSTALL_END \
+ "appinfo.package.uninstall.end"
+
+/**
+ * @brief Definition for the notification message: The package is installed.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char *) The package ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __package_event_cb()
+ */
+#define AMD_NOTI_MSG_APPINFO_PACKAGE_INSTALL_END \
+ "appinfo.package.install.end"
+
+/**
+ * @brief Definition for the notification message: The package is updated.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char *) The package ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __package_event_cb()
+ */
+#define AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END \
+ "appinfo.package.update.end"
+
+/**
+ * @brief Definition for the notification message: The application is enabled.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char *) The application ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __handle_app_event_end()
+ */
+#define AMD_NOTI_MSG_APPINFO_APP_ENABLED_END \
+ "appinfo.app.enabled.end"
+
+/**
+ * @brief Definition for the notification message: The application is disabled.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(const char *) The application ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __handle_app_event_end()
+ */
+#define AMD_NOTI_MSG_APPINFO_APP_DISABLED_END \
+ "appinfo.app.disabled.end"
+
+/**
+ * @brief Definition for the notification message: The running applications in the background should be terminated.
+ * @since_tizen 5.5
+ *
+ * @see __check_running_uiapp_list()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS \
+ "app_status.term_bg_apps"
+
+/**
+ * @brief Definition for the notification message: The status information of the running application will be destroyed.
+ * @details Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __destroy_app_status()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_DESTROY \
+ "app_status.destroy"
+
+/**
+ * @brief Definition for the notification message: The status information is added.
+ * @details Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _app_status_add_app_info()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_ADD \
+ "app_status.add"
+
+/**
+ * @brief Definition for the notification message: The status information will be updated.
+ * @details Input: arg1(int) The status.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _app_status_update_status()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START \
+ "app_status.update_status.start"
+
+/**
+ * @brief Definition for the notification message: The status information is updated.
+ * @details Input: arg1(bool) The flag if true, the status is updated forcedly.\n
+ * Input: arg2(bool) The flag if true, the group info has to be updated.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _app_status_update_status()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END \
+ "app_status.update_status.end"
+
+/**
+ * @brief Definition for the notification message: The status information will be destroyed.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _app_status_cleanup()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_CLEANUP \
+ "app_status.cleanup"
+
+/**
+ * @brief Definition for the notification message: The application is sending the registration request.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg3(amd_appinfo_h) The app info handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _app_status_register_pid()
+ */
+#define AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID \
+ "app_status.app_register_pid"
+
+/**
+ * @brief Definition for the notification message: The status information of the running component is added.
+ * @details Input: arg3(amd_comp_status_h) The comp status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _comp_status_add_comp_info()
+ */
+#define AMD_NOTI_MSG_COMP_STATUS_ADD \
+ "comp_status.add"
+
+/**
+ * @brief Definition for the notification message: The status information of the running component is destroyed.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(const char *) The instance ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_comp_notify_exit()
+ */
+#define AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT \
+ "comp_status.notify.exit"
+
+/**
+ * @brief Definition for the notification message: The status information of the running component is updated.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(bool) The flag if true, the group info has to be updated.\n
+ * Input: arg3(amd_comp_status_h) The comp status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_comp_status_update()
+ */
+#define AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END \
+ "comp_status.update_status.end"
+
+/**
+ * @brief Definition for the notification message: The poweroff state is changed.
+ * @details Input: arg1(int) The state of the poweroff.
+ * @since_tizen 5.5
+ *
+ * @see __poweroff_state_cb()
+ */
+#define AMD_NOTI_MSG_LAUNCH_POWEROFF_STATE_CHANGE \
+ "poweroff.state.change"
+
+/**
+ * @brief Definition for the notification message: The termination request will be sent to the running application.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg3(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _term_app()
+ * @see _term_app_v2()
+ */
+#define AMD_NOTI_MSG_LAUNCH_TERM_APP_START \
+ "launch.term_app.start"
+
+/**
+ * @brief Definition for the notification message: The termination request will be sent to the running application.
+ * @details If the application is running in the background, the application will be terminated.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg3(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see _term_bgapp()
+ */
+#define AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START \
+ "launch.term_bgapp.start"
+
+/**
+ * @brief Definition for the notification message: The recv() is failed.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user Id.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __reply_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_RECV_ERROR \
+ "launch.recv.error"
+
+/**
+ * @brief Definition for the notification message: The recv() is failed by timeout.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __recv_timeout_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT \
+ "launch.recv.timeout"
+
+/**
+ * @brief Definition for the notification message: The launch request will be sent to the running application.
+ * @details The launch request is will be sent to the running application.
+ * This message is occurred before sending the request.
+ * @details Input: arg1(int) The AUL command.\n
+ * Input: arg2(int) The process ID.\n
+ * Input: arg3(amd_request_h) The request handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __nofork_processing()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START \
+ "launch.do_starting_app.relaunch.start"
+
+/**
+ * @brief Definition for the notification message: The application is running in the foreground.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_status_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_STATUS_FG \
+ "launch.status.fg"
+
+/**
+ * @brief Definition for the notification message: The application is running in the background.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_status_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_STATUS_BG \
+ "launch.status.bg"
+
+/**
+ * @brief Definition for the notification message: The application has a focus.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_status_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS \
+ "launch.status.focus"
+
+/**
+ * @brief Definition for the notification message: The window of the application is hidden.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_status_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_STATUS_HIDE \
+ "launch.status.hide"
+
+/**
+ * @brief Definition for the notification message: The application is launched.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_status_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH \
+ "launch.status.launch"
+
+/**
+ * @brief Definition for the notification message: The launch request is started.
+ * @details Input: arg3(amd_request_h) The request handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_start()
+ * @see __dispatch_rpc_port_prepare_stub()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_START_START \
+ "launch.app_start.start"
+
+/**
+ * @brief Definition for the notification message: The launch request is failed.
+ * @details Input: arg1(int) The result.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_start()
+ * @see __dispatch_rpc_port_prepare_stub()
+ */
+#define AMD_NOTI_MSG_LAUNCH_FAIL \
+ "launch.fail"
+
+/**
+ * @brief Definition for the notification message: The launch request is pended.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(bool) The flag if true, the request is for the background launch.
+ * Input: arg3(amd_request_h) The request handle.\n
+ * Input: arg4(amd_request_reply_h) The request reply handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_start()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_START_PEND \
+ "launch.app_start.pend"
+
+/**
+ * @brief Definition for the notification message: The launch request is ended.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(bool) The flag if true, the request is for the background launch.
+ * Input: arg3(amd_request_h) The request handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_start()
+ * @see __dispatch_rpc_port_prepare_stub()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_START_END \
+ "launch.app_start.end"
+
+/**
+ * @brief Definition for the notification message: The app result request is started.
+ * @details Input: arg1(int) The process group ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(const char *) The application ID.\n
+ * Input: arg4(bundle *b) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_result()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_RESULT_START \
+ "launch.app_result.start"
+
+/**
+ * @brief Definition for the notification message: The app result request is ended.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(int) The result.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_result()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_RESULT_END \
+ "launch.app_result.end"
+
+/**
+ * @brief Definition for the notification message: The app startup signal request is ended.
+ * @details The request is received from the launched app process.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg3(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_startup_signal()
+ */
+#define AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END \
+ "launch.app_startup_signal.end"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request is started.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg3(amd_appinfo_h) The appinfo handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_START \
+ "launch.prepare.start"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request that is launching the UI application is started.
+ * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
+ * @details Input: arg1(int) The status of the application.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_launch_context_h) The launch context handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START \
+ "launch.prepare.ui.start"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request that is launching the UI application is ended.
+ * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
+ * @details Input: arg1(bool) The flag if true, the request is for the background launch.
+ * Input: arg2(int) The process ID of the caller.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END \
+ "launch.prepare.ui.end"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request that is launching the Service application is.
+ * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
+ * @details Input: arg3(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_SERVICE \
+ "launch.prepare.service"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request that is launching the Widget application is.
+ * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
+ * @details Input: arg3(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET \
+ "launch.prepare.widget"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request that is launching the Component-based application is started.
+ * @details If the return value is less than AMD_NOTI_STOP, the launch request is stopped. And then, the caller process gets a negative error value.
+ * @details Input: arg1(int) The status of the application.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_launch_context_h) The launch context handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START \
+ "launch.prepare.component-based.start"
+
+/**
+ * @brief Definition for the notification message: Preparing the launch request is ended.
+ * @details Input: arg1(int) The process ID of the caller.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_appinfo_h) The appinfo handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __prepare_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_PREPARE_END \
+ "launch.prepare.end"
+
+/**
+ * @brief Definition for the notification message: The application is dead.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __kill_and_cleanup_status()
+ * @see __app_dead_handler()
+ */
+#define AMD_NOTI_MSG_LAUNCH_MAIN_APP_DEAD \
+ "main.app_dead"
+
+/**
+ * @brief Definition for the notification message: The re-launch request is canceled.
+ * @details Input: arg1(int) The result.\n
+ * @since_tizen 5.5
+ *
+ * @see __do_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL \
+ "launch.do_starting_app.relaunch.cancel"
+
+/**
+ * @brief Definition for the notification message: The re-launch request is end.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg3(amd_launch_context_h) The launch context handle.\n
+ * Input: arg4(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ * @see __do_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_END \
+ "launch.do_starting_app.relaunch.end"
+
+/**
+ * @brief Definition for the notification message: The launch request will be started.
+ * @details This message is occurred before sending the launch request to the launchpad.
+ * While getting the request in the launchpad, the launchpad make a child process to launch the application.
+ * @details Input: arg1(int) The AUL command.\n
+ * Input: arg2(bool) The flag if true, the request is for background launch.\n
+ * Input: arg3(amd_launch_context_h) The launch context handle.\n
+ * Input: arg4(bundle *) The bundel object.\n
+ * @since_tizen 5.5
+ *
+ * @see __do_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START \
+ "launch.do_starting_app.start"
+
+/**
+ * @brief Definition for the notification message: The launch request is canceled.
+ * @details Input: arg1(int) The result.\n
+ * @since_tizen 5.5
+ *
+ * @see __do_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL \
+ "launch.do_starting_app.cancel"
+
+/**
+ * @brief Definition for the notification message: The launch request is ended.
+ * @details The app process is created.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(bool) The flag if true, the request is for background launch.\n
+ * Input: arg3(amd_launch_context_h) The launch context.\n
+ * Input: arg4(amd_request_h) The request handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __do_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END \
+ "launch.do_starting_app.end"
+
+/**
+ * @brief Definition for the notification message: The launch request is completed.
+ * @details This message is occurred before saving some informations(app_status and comp_status).
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(bool) The flag if true, a new process is created.\n
+ * Input: arg3(amd_appinfo_h) The appinfo handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __complete_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_COMPLETE_START \
+ "launch.complete.start"
+
+/**
+ * @brief Definition for the notification message: The launch request is completed.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_appinfo_h) The appinfo handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __complete_starting_app()
+ */
+#define AMD_NOTI_MSG_LAUNCH_COMPLETE_END \
+ "launch.complete.end"
+
+/**
+ * @brief Definition for the notification message: The user login is starting.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg2(int) The state of the user session.\n
+ * @since_tizen 5.5
+ *
+ * @see __user_login()
+ */
+#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN_START \
+ "login_monitor.login.start"
+
+/**
+ * @brief Definition for the notification message: The user logged in.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg2(int) The state of the user session.\n
+ * @since_tizen 5.5
+ *
+ * @see __user_login()
+ */
+#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN \
+ "login_monitor.login"
+
+/**
+ * @brief Definition for the notification message: The user logged out.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * Input: arg2(int) The state of the user session.\n
+ * @since_tizen 5.5
+ *
+ * @see __user_logout()
+ */
+#define AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT \
+ "login_monitor.logout"
+
+/**
+ * @brief Definition for the notification message: The booting is finished.
+ * @details The message is occurred after the system session and the user session are ready.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __startup_finished_cb()
+ */
+#define AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED \
+ "startup.finished"
+
+/**
+ * @brief Definition for the notification message: The app process is dead.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(amd_app_status_h) The app status handle.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_dead_handler()
+ */
+#define AMD_NOTI_MSG_MAIN_APP_DEAD \
+ "main.app_dead"
+
+/**
+ * @brief Definition for the notification message: The user is initialized.
+ * @details Input: arg1(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see _request_usr_init()
+ */
+#define AMD_NOTI_MSG_REQUEST_USER_INIT \
+ "request.user_init"
+
+/**
+ * @brief Definition for the notification message: The watchdog signal will be sent.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(int) The signal number.\n
+ * @since_tizen 5.5
+ *
+ * @see _signal_send_watchdog()
+ */
+#define AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START \
+ "signal.send_watchdog.start"
+
+/**
+ * @brief Definition for the notification message: The memory status is changed to normal.
+ * @since_tizen 5.5
+ *
+ * @see __memory_status_changed_cb()
+ */
+#define AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL \
+ "util.low_memory.normal"
+
+/**
+ * @brief Definition for the notification message: Saving a RUA information is started.
+ * @details If the return value is less than AMD_NOTI_STOP, the RUA information is not saved.
+ * @details Input: arg3(amd_request_h) The request handle.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 5.5
+ *
+ * @see __on_launch_pending()
+ * @see __on_launch_ending()
+ * @remarks This message is sent from the `amd-mod-rua` module.
+ */
+#define AMD_NOTI_MSG_RUA_SAVE_CRITICAL \
+ "rua.save.critical"
+
+/**
+ * @brief Definition for the notification message: The app screen is updated.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(int) The window ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __on_launch_status()
+ * @remarks This message is sent from the `amd-mod-screen-connector` module.
+ */
+#define AMD_NOTI_MSG_SCREEN_CONNECTOR_APP_SCREEN_UPDATE \
+ "screen_connector.app_screen.update"
+
+/**
+ * @brief Definition for the notification message: Recycling the window is ended.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(int) The window ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __app_group_context_do_recycle()
+ * @remarks Thie message is sent from the `amd-mod-ui-core` module.
+ */
+#define AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END \
+ "app_group.do_recycle.end"
+
+/**
+ * @brief Definition for the notification message: The window is set.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(int) The window ID.\n
+ * Input: arg3(const char *) The instance ID.\n
+ * @remarks The instance ID(arg3) can be nullptr.
+ * @since_tizen 5.5
+ *
+ * @see __dispatch_app_group_set_window()
+ * @see __dispatch_app_group_set_window_v2()
+ * @remarks Thie message is sent from the `amd-mod-ui-core` module.
+ */
+#define AMD_NOTI_MSG_APP_GROUP_WINDOW_SET \
+ "app_group.window.set"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `tizen_input_device_manager`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER \
+ "wayland.listener.tizen_input_device_manager"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `tizen_keyrouter`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER \
+ "wayland.listener.tizen_keyrouter"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `wl_seat`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT \
+ "wayland.listener.wl_seat"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `tizen_launch_appinfo`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_APPINFO \
+ "wayland.listener.tizen_launch_appinfo"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `tizen_launch_effect`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_EFFECT \
+ "wayland.listener.tizen_launch_effect"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is added.
+ * @details The interface is `tizen_policy`.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg2(int) The version.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_POLICY \
+ "wayland.listener.tizen_policy"
+
+/**
+ * @brief Definition for the notification message: The wayland interface is removed.
+ * @details Input: arg1(int) The interface ID.\n
+ * Input: arg3(struct wl_registry *) The wayland registry.\n
+ * @since_tizen 5.5
+ *
+ * @see __wl_listener_remove_cb()
+ * @remarks Thie message is sent from the `amd-mod-wayland-core` module.
+ */
+#define AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE \
+ "wayland.listener.remove"
+
+/**
+ * @brief Definition for the notification message: Sending the running widget information is started.
+ * @details Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(const char*) The instance ID.\n
+ * Output: arg1(int *) The window ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __send_running_info()
+ * @remarks Thie message is sent from the `amd-mod-widget` module.
+ */
+#define AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND \
+ "widget.running_info.send"
+
+/**
+ * @brief Definition for the notification message: The widget will be restarted.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * @since_tizen 5.5
+ *
+ * @see __on_app_dead()
+ * @remarks Thie message is sent from the `amd-mod-widget` module.
+ */
+#define AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART \
+ "widget.on_app_dead.restart"
+
+/**
+ * @brief Definition for the notification message: The app group context is destroying.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(int) The window ID.\n
+ * Input: arg3(const char *) The instance ID.\n
+ * @since_tizen 5.5
+ * @see __destroy_app_group_context()
+ */
+#define AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT \
+ "app_group.destroy.app_group_context"
+
+/**
+ * @brief Definition for the notification message: The app group activate below.
+ * @details Input: arg1(int) The process ID.\n
+ * Input: arg2(uid_t) The user ID.\n
+ * Input: arg3(const char *) The application ID.\n
+ * Input: arg4(bundle *) The bundle object.\n
+ * @since_tizen 6.0
+ * @see __dispatch_app_group_activate_below()
+ */
+#define AMD_NOTI_MSG_APP_GROUP_ACTIVATE_BELOW \
+ "app_gorup.activate_below"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_NOTI_MSG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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/amd_api.h"
+#include "lib/amd_proc.h"
+#include "lib/api/amd_api_proc.h"
+
+extern "C" EXPORT_API int amd_proc_get_attr(pid_t pid, char* buf,
+ int buf_size) {
+ return _proc_get_attr(pid, buf, buf_size);
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 - 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_API_PROC_H__
+#define __AMD_API_PROC_H__
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int amd_proc_get_attr(pid_t pid, char *buf, int buf_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_PROC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_request.h"
+#include "lib/api/amd_api_request.h"
+
+extern "C" EXPORT_API int amd_request_send_result(amd_request_h req, int res) {
+ return _request_send_result(req, res);
+}
+
+extern "C" EXPORT_API int amd_request_send_raw(amd_request_h req, int cmd,
+ unsigned char* data, int len) {
+ return _request_send_raw(req, cmd, data, len);
+}
+
+extern "C" EXPORT_API int amd_request_get_fd(amd_request_h req) {
+ return _request_get_fd(req);
+}
+
+extern "C" EXPORT_API int amd_request_get_pid(amd_request_h req) {
+ return _request_get_pid(req);
+}
+
+extern "C" EXPORT_API int amd_request_get_cmd(amd_request_h req) {
+ return _request_get_cmd(req);
+}
+
+extern "C" EXPORT_API int amd_request_set_cmd(amd_request_h req, int cmd) {
+ return _request_set_cmd(req, cmd);
+}
+
+extern "C" EXPORT_API bundle* amd_request_get_bundle(amd_request_h req) {
+ return _request_get_bundle(req);
+}
+
+extern "C" EXPORT_API amd_request_h amd_request_create_local(int cmd, uid_t uid,
+ int pid, bundle* kb) {
+ return _request_create_local(cmd, uid, pid, kb);
+}
+
+extern "C" EXPORT_API void amd_request_free_local(amd_request_h req) {
+ _request_free_local(req);
+}
+
+extern "C" EXPORT_API int amd_request_remove_fd(amd_request_h req) {
+ return _request_remove_fd(req);
+}
+
+extern "C" EXPORT_API int amd_request_reply_for_pending_request(int pid) {
+ return _request_reply_for_pending_request(pid);
+}
+
+extern "C" EXPORT_API int amd_request_flush_pending_request(int pid) {
+ return _request_flush_pending_request(pid);
+}
+
+extern "C" EXPORT_API uid_t amd_request_get_target_uid(amd_request_h req) {
+ return _request_get_target_uid(req);
+}
+
+extern "C" EXPORT_API uid_t amd_request_get_uid(amd_request_h req) {
+ return _request_get_uid(req);
+}
+
+extern "C" EXPORT_API pid_t amd_request_get_target_pid(amd_request_h req) {
+ return _request_get_target_pid(req);
+}
+
+extern "C" EXPORT_API int amd_request_usr_init(uid_t uid) {
+ return _request_usr_init(uid);
+}
+
+extern "C" EXPORT_API int amd_request_register_cmds(
+ const amd_request_cmd_dispatch* cmds, int cnt) {
+ return _request_register_cmds(reinterpret_cast<request_cmd_dispatch*>(
+ const_cast<amd_request_cmd_dispatch*>(cmds)), cnt);
+}
+
+extern "C" EXPORT_API int amd_request_reply_append(int pid, void* reply) {
+ return _request_reply_append(pid, reply);
+}
+
+extern "C" EXPORT_API int amd_request_reply_remove(int pid, void* reply) {
+ return _request_reply_remove(pid, reply);
+}
+
+extern "C" EXPORT_API amd_request_reply_h amd_request_reply_create(
+ amd_request_h req, pid_t pid, int result, int cmd) {
+ return _request_reply_create(req, pid, result, cmd);
+}
+
+extern "C" EXPORT_API int amd_request_reply_add_extra(
+ amd_request_reply_h handle, const char* key, void* extra,
+ void (*extra_free_cb)(void* data)) {
+ return _request_reply_add_extra(handle, key, extra, extra_free_cb);
+}
+
+extern "C" EXPORT_API int amd_request_reply_foreach_extra(int pid,
+ int (*callback)(const char* key, void* data)) {
+ return _request_reply_foreach_extra(pid, callback);
+}
+
+extern "C" EXPORT_API int amd_request_get_len(amd_request_h req) {
+ return _request_get_len(req);
+}
+
+extern "C" EXPORT_API unsigned char* amd_request_get_raw(amd_request_h req) {
+ return _request_get_raw(req);
+}
+
+extern "C" EXPORT_API struct timespec* amd_request_get_start_time(
+ amd_request_h req) {
+ return _request_get_start_time(req);
+}
+
+extern "C" EXPORT_API int amd_request_set_request_type(amd_request_h req,
+ const char* req_type) {
+ return _request_set_request_type(req, req_type);
+}
+
+extern "C" EXPORT_API const char* amd_request_get_request_type(
+ amd_request_h req) {
+ return _request_get_request_type(req);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_REQUEST_H__
+#define __AMD_API_REQUEST_H__
+
+#include <bundle.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct request_s *amd_request_h;
+
+typedef int (*amd_request_cmd_dispatch_cb)(amd_request_h req);
+
+typedef struct _amd_request_cmd_dispatch {
+ int cmd;
+ amd_request_cmd_dispatch_cb callback;
+} amd_request_cmd_dispatch;
+
+typedef void *amd_request_reply_h;
+
+int amd_request_send_result(amd_request_h req, int res);
+
+int amd_request_send_raw(amd_request_h req, int cmd, unsigned char *data,
+ int len);
+
+int amd_request_get_fd(amd_request_h req);
+
+int amd_request_get_pid(amd_request_h req);
+
+int amd_request_get_cmd(amd_request_h req);
+
+int amd_request_set_cmd(amd_request_h req, int cmd);
+
+bundle *amd_request_get_bundle(amd_request_h req);
+
+amd_request_h amd_request_create_local(int cmd, uid_t uid, int pid, bundle *kb);
+
+void amd_request_free_local(amd_request_h req);
+
+int amd_request_remove_fd(amd_request_h req);
+
+int amd_request_reply_for_pending_request(int pid);
+
+int amd_request_flush_pending_request(int pid);
+
+uid_t amd_request_get_target_uid(amd_request_h req);
+
+uid_t amd_request_get_uid(amd_request_h req);
+
+pid_t amd_request_get_target_pid(amd_request_h req);
+
+int amd_request_usr_init(uid_t uid);
+
+int amd_request_register_cmds(const amd_request_cmd_dispatch *cmds, int cnt);
+
+int amd_request_reply_append(int pid, void *reply);
+
+int amd_request_reply_remove(int pid, void *reply);
+
+amd_request_reply_h amd_request_reply_create(amd_request_h req, pid_t pid,
+ int result, int cmd);
+
+int amd_request_reply_add_extra(amd_request_reply_h handle, const char *key,
+ void *extra, void (*extra_free_cb)(void *data));
+
+int amd_request_reply_foreach_extra(int pid,
+ int (*callback)(const char *key, void *data));
+
+int amd_request_get_len(amd_request_h req);
+
+unsigned char *amd_request_get_raw(amd_request_h req);
+
+struct timespec *amd_request_get_start_time(amd_request_h req);
+
+int amd_request_set_request_type(amd_request_h req, const char *req_type);
+
+const char *amd_request_get_request_type(amd_request_h req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_REQUEST_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_signal.h"
+#include "lib/api/amd_api_signal.h"
+
+extern "C" EXPORT_API int amd_signal_send_tep_mount(char* mnt_path[],
+ const char* pkgid) {
+ return _signal_send_tep_mount(mnt_path, pkgid);
+}
+
+extern "C" EXPORT_API int amd_signal_send_tep_unmount(const char* mnt_path) {
+ return _signal_send_tep_unmount(mnt_path);
+}
+
+extern "C" EXPORT_API int amd_signal_send_watchdog(int pid, int signal_num) {
+ return _signal_send_watchdog(pid, signal_num);
+}
+
+extern "C" EXPORT_API int amd_signal_add_ready_cb(amd_signal_ready_cb callback,
+ void* user_data) {
+ return _signal_add_ready_cb(callback, user_data);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_SIGNAL_H__
+#define __AMD_API_SIGNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int (*amd_signal_ready_cb)(void *user_data);
+
+int amd_signal_send_tep_mount(char *mnt_path[], const char *pkgid);
+
+int amd_signal_send_tep_unmount(const char *mnt_path);
+
+int amd_signal_send_watchdog(int pid, int signal_num);
+
+int amd_signal_add_ready_cb(amd_signal_ready_cb callback, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_SIGNAL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_socket.h"
+#include "lib/api/amd_api_socket.h"
+
+extern "C" EXPORT_API void amd_socket_send_result(int fd, int res, bool close) {
+ if (close)
+ _send_result_to_client(fd, res);
+ else
+ _send_result_to_client_v2(fd, res);
+}
+
+extern "C" EXPORT_API int amd_socket_send_cmd_to_launchpad(uid_t uid,
+ pad_cmd_e cmd, bundle* b) {
+ return _send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK, uid, cmd, b);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_SOCKET_H__
+#define __AMD_API_SOCKET_H__
+
+#include <bundle.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ PAD_CMD_PREPARE_APP_DEFINED_LOADER = 17,
+} pad_cmd_e;
+
+void amd_socket_send_result(int fd, int res, bool close);
+
+int amd_socket_send_cmd_to_launchpad(uid_t uid, pad_cmd_e cmd, bundle *b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_SOCKET_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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/amd_api.h"
+#include "lib/amd_suspend.h"
+#include "lib/api/amd_api_suspend.h"
+
+extern "C" EXPORT_API int amd_suspend_add_proc(int pid) {
+ return _suspend_add_proc(pid);
+}
+
+extern "C" EXPORT_API int amd_suspend_remove_proc(int pid) {
+ return _suspend_remove_proc(pid);
+}
+
+extern "C" EXPORT_API bool amd_suspend_is_excluded(int pid) {
+ return _suspend_is_excluded(pid);
+}
+
+extern "C" EXPORT_API bool amd_suspend_is_allowed_background(amd_appinfo_h ai) {
+ return _suspend_is_allowed_background(ai);
+}
+
+extern "C" EXPORT_API void amd_suspend_add_timer(int pid) {
+ _suspend_add_timer(pid);
+}
+
+extern "C" EXPORT_API void amd_suspend_remove_timer(int pid) {
+ _suspend_remove_timer(pid);
+}
+
+extern "C" EXPORT_API int amd_suspend_update_status(int pid, int status) {
+ return _suspend_update_status(pid, status);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_SUSPEND_H__
+#define __AMD_API_SUSPEND_H__
+
+#include <amd_api_appinfo.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AMD_SUSPEND_TYPE_EXCLUDE "exclude"
+
+#define AMD_SUSPEND_TYPE_INCLUDE "include"
+
+enum amd_suspend_status_e {
+ AMD_SUSPEND_STATUS_EXCLUDE,
+ AMD_SUSPEND_STATUS_INCLUDE,
+};
+
+enum amd_background_category_e {
+ AMD_BACKGROUND_CATEGORY_MEDIA = 0x01,
+ AMD_BACKGROUND_CATEGORY_DOWNLOAD = 0x02,
+ AMD_BACKGROUND_CATEGORY_BACKGROUND_NETWORK = 0x04,
+ AMD_BACKGROUND_CATEGORY_LOCATION = 0x08,
+ AMD_BACKGROUND_CATEGORY_SENSOR = 0x10,
+ AMD_BACKGROUND_CATEGORY_IOT_COMMUNICATION = 0x20,
+ AMD_BACKGROUND_CATEGORY_SYSTEM = 0x40
+};
+
+bool amd_suspend_is_excluded(int pid);
+
+bool amd_suspend_is_allowed_background(amd_appinfo_h ai);
+
+void amd_suspend_add_timer(int pid);
+
+void amd_suspend_remove_timer(int pid);
+
+int amd_suspend_add_proc(int pid);
+
+int amd_suspend_remove_proc(int pid);
+
+int amd_suspend_update_status(int pid, int status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_SUSPEND_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/amd_util.h"
+#include "lib/api/amd_api_util.h"
+
+extern "C" EXPORT_API bool amd_util_check_oom(void) {
+ return _util_check_oom();
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_UTIL_H__
+#define __AMD_API_UTIL_H__
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool amd_util_check_oom(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_UTIL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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/amd_api.h"
+#include "lib/api/amd_api_wayland.h"
+
+static void* __display;
+static void* __tizen_policy;
+
+extern "C" EXPORT_API void* amd_wayland_get_display(void) {
+ return __display;
+}
+
+extern "C" EXPORT_API void amd_wayland_set_display(void* display) {
+ __display = display;
+}
+
+extern "C" EXPORT_API void* amd_wayland_get_tizen_policy(void) {
+ return __tizen_policy;
+}
+
+extern "C" EXPORT_API void amd_wayland_set_tizen_policy(void* tizen_policy) {
+ __tizen_policy = tizen_policy;
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 - 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_API_WAYLAND_H__
+#define __AMD_API_WAYLAND_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *amd_wayland_get_display(void);
+
+void amd_wayland_set_display(void *display);
+
+void *amd_wayland_get_tizen_policy(void);
+
+void amd_wayland_set_tizen_policy(void *tizen_policy);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_API_WAYLAND_H__ */
--- /dev/null
+/*
+ * 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_MAIN_H__
+#define __AMD_MAIN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int amd_main(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_MAIN_H__ */
--- /dev/null
+/*
+ * 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_MOD_COMMON_H__
+#define __AMD_MOD_COMMON_H__
+
+#include <dlog.h>
+
+#ifndef _E
+#define _E LOGE
+#endif
+
+#ifndef _W
+#define _W LOGW
+#endif
+
+#ifndef _I
+#define _I LOGI
+#endif
+
+#ifndef _D
+#define _D LOGD
+#endif
+
+#ifndef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef REGULAR_UID_MIN
+#define REGULAR_UID_MIN 5000
+#endif
+
+#endif /* __AMD_MOD_COMMON_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 - 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 __AUL_SVC_PRIV_KEY_H__
+#define __AUL_SVC_PRIV_KEY_H__
+
+#define AUL_SVC_K_OPERATION "__APP_SVC_OP_TYPE__"
+
+#define AUL_SVC_K_URI "__APP_SVC_URI__"
+
+#define AUL_SVC_K_MIME "__APP_SVC_MIME_TYPE__"
+
+#define AUL_SVC_K_DATA "__APP_SVC_DATA__"
+
+#define AUL_SVC_K_PKG_NAME "__APP_SVC_PKG_NAME__"
+
+#define AUL_SVC_K_CATEGORY "__APP_SVC_CATEGORY__"
+
+#define AUL_SVC_K_RES_VAL "__APP_SVC_K_RES_VAL__"
+
+#define AUL_SVC_K_WIN_ID "__APP_SVC_K_WIN_ID__"
+
+#define AUL_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+
+#endif /* __AUL_SVC_PRIV_KEY_H__ */
--- /dev/null
+/*
+ * 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_app_com.h>
+#include <aul_sock.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "lib/app_com/app_com_broker.hh"
+#include "lib/common/log_private.hh"
+#include "lib/common/key_private.hh"
+
+namespace amd {
+
+AppComBroker::~AppComBroker() {
+ if (!disposed_)
+ Dispose();
+}
+
+AppComBroker& AppComBroker::GetInst() {
+ static AppComBroker inst;
+ std::lock_guard<std::recursive_mutex> lock(inst.GetMutex());
+ if (inst.disposed_)
+ inst.Init();
+ return inst;
+}
+
+void AppComBroker::Dispose() {
+ queue_.Push(AppComMessage(true));
+ if (thread_.joinable()) {
+ _W("Join thread");
+ thread_.join();
+ }
+ disposed_ = true;
+}
+
+int AppComBroker::Create(const std::string& endpoint, unsigned int propagate,
+ const std::string& privilege) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ if (Exist(endpoint)) {
+ _W("Already exists");
+ return AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS;
+ }
+
+ auto* new_endpoint = new (std::nothrow) AppComEndpoint(endpoint,
+ propagate, privilege);
+ if (new_endpoint == nullptr) {
+ _E("Out of memory");
+ return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+ }
+
+ endpoints_[endpoint] = std::unique_ptr<AppComEndpoint>(new_endpoint);
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Destroy(const std::string& endpoint) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ if (!Exist(endpoint))
+ return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+
+ endpoints_.erase(endpoint);
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Join(const std::string& endpoint, const std::string& filter,
+ int pid, uid_t uid) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ if (!Exist(endpoint)) {
+ _W("Endpoint(%s) does not exist", endpoint.c_str());
+ return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+ }
+
+ auto* client = new (std::nothrow) AppComClient(filter, pid, uid);
+ if (client == nullptr) {
+ _E("Out of memory");
+ return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+ }
+
+ endpoints_[endpoint]->AddClient(pid, std::shared_ptr<AppComClient>(client));
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Send(const std::string& endpoint,
+ std::shared_ptr<tizen_base::Bundle> envelope,
+ int sender_pid, uid_t sender_uid) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ if (!Exist(endpoint)) {
+ _W("Endpoint(%s) does not exist", endpoint.c_str());
+ return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+ }
+
+ for (auto iter : endpoints_[endpoint]->GetClients()) {
+ auto& client = iter.second;
+ int pid = client->GetPid();
+ if (pid == sender_pid)
+ continue;
+
+ uid_t uid = client->GetUid();
+ if (uid >= REGULAR_UID_MIN && uid != sender_uid)
+ continue;
+
+ queue_.Push(AppComMessage(pid, uid, envelope));
+ }
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Leave(const std::string& endpoint, int pid) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ if (!Exist(endpoint)) {
+ _W("Endpoint(%s) does not exist", endpoint.c_str());
+ return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+ }
+
+ endpoints_[endpoint]->RemoveClient(pid);
+ if (endpoints_[endpoint]->GetClientCount() == 0) {
+ _W("Remove endpoint(%s)", endpoint.c_str());
+ endpoints_.erase(endpoint);
+ }
+ return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Remove(int pid) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ auto iter = endpoints_.begin();
+ while (iter != endpoints_.end()) {
+ auto& key = iter->first;
+ auto& endpoint = iter->second;
+ endpoint->RemoveClient(pid);
+ if (endpoint->GetClientCount() == 0) {
+ _W("Remove endpoint(%s)", key.c_str());
+ iter = endpoints_.erase(iter);
+ } else {
+ iter++;
+ }
+ }
+ return 0;
+}
+
+bool AppComBroker::Exist(const std::string& endpoint) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ auto iter = endpoints_.find(endpoint);
+ if (iter != endpoints_.end())
+ return true;
+ return false;
+}
+
+const std::string& AppComBroker::GetPrivilege(const std::string& endpoint) {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ return endpoints_[endpoint]->GetPrivilege();
+}
+
+void AppComBroker::Init() {
+ thread_ = std::thread([&]() {
+ _W("START");
+ SetComm();
+ do {
+ auto msg = queue_.WaitAndPop();
+ if (msg.Done()) {
+ _W("Done");
+ break;
+ }
+
+ int pid = msg.GetPid();
+ uid_t uid = msg.GetUid();
+ int ret = aul_sock_send_bundle(pid, uid, APP_COM_MESSAGE,
+ msg.GetEnvelope()->GetHandle(), AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ if (ret == -ECOMM) {
+ _E("Remove client. pid(%d), uid(%u)", pid, uid);
+ Remove(pid);
+ } else {
+ _E("Failed to send message. pid(%d), uid(%u), error(%d)",
+ pid, uid, ret);
+ }
+ }
+ } while (true);
+ _W("END");
+ });
+ disposed_ = false;
+}
+
+void AppComBroker::SetComm() {
+ pid_t tid = syscall(__NR_gettid);
+ std::string path = "/proc/" + std::to_string(tid) + "/comm";
+ int fd = open(path.c_str(), O_WRONLY);
+ if (fd < 0) {
+ _E("open(%s) is failed. errno(%d)", path.c_str(), errno);
+ return;
+ }
+
+ std::string name = "AppComBroker";
+ ssize_t bytes_written = write(fd, name.c_str(), name.length() + 1);
+ if (bytes_written < 0)
+ _E("write(%d) is failed. errno(%d)", fd, errno);
+
+ close(fd);
+}
+
+std::recursive_mutex& AppComBroker::GetMutex() const {
+ return mutex_;
+}
+
+} // namespace amd
--- /dev/null
+/*
+ * 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_COM_APP_COM_BROKER_HH_
+#define LIB_APP_COM_APP_COM_BROKER_HH_
+
+#include <bundle_cpp.h>
+
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include "lib/app_com/app_com_client.hh"
+#include "lib/app_com/app_com_endpoint.hh"
+#include "lib/app_com/app_com_message.hh"
+#include "lib/common/shared_queue.hh"
+
+namespace amd {
+
+class AppComBroker {
+ private:
+ AppComBroker() = default;
+ ~AppComBroker();
+
+ public:
+ static AppComBroker& GetInst();
+ void Dispose();
+
+ int Create(const std::string& endpoint, unsigned int propagate,
+ const std::string& privilege);
+ int Destroy(const std::string& endpoint);
+ int Join(const std::string& endpoint, const std::string& filter,
+ int pid, uid_t uid);
+ int Send(const std::string& endpoint,
+ std::shared_ptr<tizen_base::Bundle> envelope,
+ int sender_pid, uid_t sender_uid);
+ int Leave(const std::string& endpoint, int pid);
+ int Remove(int pid);
+ bool Exist(const std::string& endpoint);
+ const std::string& GetPrivilege(const std::string& endpoint);
+
+ private:
+ void Init();
+ void SetComm();
+ std::recursive_mutex& GetMutex() const;
+
+ private:
+ bool disposed_ = true;
+ std::thread thread_;
+ SharedQueue<AppComMessage> queue_;
+ std::map<std::string, std::unique_ptr<AppComEndpoint>> endpoints_;
+ mutable std::recursive_mutex mutex_;
+};
+
+} // namespace amd
+
+#endif // LIB_APP_COM_APP_COM_BROKER_HH_
--- /dev/null
+/*
+ * 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_com/app_com_client.hh"
+
+namespace amd {
+
+AppComClient::AppComClient(std::string filter, int pid, uid_t uid)
+ : filter_(std::move(filter)), pid_(pid), uid_(uid) {
+}
+
+AppComClient::~AppComClient() = default;
+
+const std::string& AppComClient::GetFilter() {
+ return filter_;
+}
+
+int AppComClient::GetPid() const {
+ return pid_;
+}
+
+uid_t AppComClient::GetUid() const {
+ return uid_;
+}
+
+} // namespace amd
--- /dev/null
+/*
+ * 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_COM_APP_COM_CLIENT_HH_
+#define LIB_APP_COM_APP_COM_CLIENT_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace amd {
+
+class AppComClient {
+ public:
+ AppComClient(std::string filter, int pid, uid_t uid);
+ virtual ~AppComClient();
+
+ const std::string& GetFilter();
+ int GetPid() const;
+ uid_t GetUid() const;
+
+ private:
+ std::string filter_;
+ int pid_;
+ uid_t uid_;
+};
+
+} // namespace amd
+
+#endif // LIB_APP_COM_APP_COM_CLIENT_HH_
--- /dev/null
+/*
+ * 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_com/app_com_endpoint.hh"
+
+namespace amd {
+
+AppComEndpoint::AppComEndpoint(std::string endpoint, unsigned int propagate,
+ std::string privilege)
+ : endpoint_(std::move(endpoint)),
+ propagate_(propagate),
+ privilege_(std::move(privilege)) {
+}
+
+AppComEndpoint::~AppComEndpoint() = default;
+
+void AppComEndpoint::AddClient(int pid, std::shared_ptr<AppComClient> client) {
+ auto iter = clients_.find(pid);
+ if (iter != clients_.end())
+ return;
+
+ clients_[pid] = client;
+}
+
+void AppComEndpoint::RemoveClient(int pid) {
+ auto iter = clients_.find(pid);
+ if (iter == clients_.end())
+ return;
+
+ clients_.erase(iter);
+}
+
+const std::string& AppComEndpoint::GetEndpoint() {
+ return endpoint_;
+}
+
+unsigned int AppComEndpoint::GetPropagate() const {
+ return propagate_;
+}
+
+const std::string& AppComEndpoint::GetPrivilege() {
+ return privilege_;
+}
+
+const std::map<int, std::shared_ptr<AppComClient>>&
+AppComEndpoint::GetClients() {
+ return clients_;
+}
+
+int AppComEndpoint::GetClientCount() {
+ return clients_.size();
+}
+
+} // namespace amd
--- /dev/null
+/*
+ * 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_COM_APP_COM_ENDPOINT_HH_
+#define LIB_APP_COM_APP_COM_ENDPOINT_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "lib/app_com/app_com_client.hh"
+
+namespace amd {
+
+class AppComEndpoint {
+ public:
+ AppComEndpoint(std::string endpoint, unsigned int propagate,
+ std::string privilege);
+ virtual ~AppComEndpoint();
+
+ void AddClient(int pid, std::shared_ptr<AppComClient> client);
+ void RemoveClient(int pid);
+
+ const std::string& GetEndpoint();
+ unsigned int GetPropagate() const;
+ const std::string& GetPrivilege();
+ const std::map<int, std::shared_ptr<AppComClient>>& GetClients();
+ int GetClientCount();
+
+ private:
+ std::string endpoint_;
+ unsigned int propagate_;
+ std::string privilege_;
+ std::map<int, std::shared_ptr<AppComClient>> clients_;
+};
+
+} // namespace amd
+
+#endif // LIB_APP_COM_APP_COM_ENDPOINT_HH_
--- /dev/null
+/*
+ * 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_COM_APP_COM_MESSAGE_H_
+#define LIB_APP_COM_APP_COM_MESSAGE_H_
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+
+namespace amd {
+
+class AppComMessage {
+ public:
+ AppComMessage(int pid, uid_t uid,
+ std::shared_ptr<tizen_base::Bundle> envelope)
+ : pid_(pid), uid_(uid), envelope_(std::move(envelope)) {
+ }
+
+ AppComMessage(bool done = false) : done_(done) {
+ }
+
+ virtual ~AppComMessage() = default;
+
+ int GetPid() const {
+ return pid_;
+ }
+
+ uid_t GetUid() const {
+ return uid_;
+ }
+
+ const std::shared_ptr<tizen_base::Bundle>& GetEnvelope() {
+ return envelope_;
+ }
+
+ bool Done() {
+ return done_;
+ }
+
+ private:
+ bool done_ = false;
+ int pid_;
+ uid_t uid_;
+ std::shared_ptr<tizen_base::Bundle> envelope_;
+};
+
+} // namespace amd
+
+#endif // LIB_APP_COM_APP_COM_MESSAGE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#pragma once
+
+#define AUL_DBUS_PATH "/aul/dbus_handler"
+#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
+#define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
+#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
+#define AUL_DBUS_HOMELAUNCH_SIGNAL "home_launch"
+
+#define AUL_APP_STATUS_DBUS_PATH "/Org/Tizen/Aul/AppStatus"
+#define AUL_APP_STATUS_DBUS_SIGNAL_INTERFACE "org.tizen.aul.AppStatus"
+#define STATUS_FOREGROUND "fg"
+#define STATUS_BACKGROUND "bg"
+#define AUL_APP_STATUS_DBUS_LAUNCH_REQUEST "AppLaunch"
+#define AUL_APP_STATUS_DBUS_RESUME_REQUEST "AppResume"
+#define AUL_APP_STATUS_DBUS_TERMINATE_REQUEST "AppTerminate"
+#define AUL_APP_STATUS_DBUS_STATUS_CHANGE "AppStatusChange"
+#define AUL_APP_STATUS_DBUS_GROUP "AppGroup"
+#define AUL_APP_STATUS_DBUS_TERMINATED "AppTerminated"
+
+#define ROTATION_BUS_NAME "org.tizen.system.coord"
+#define ROTATION_OBJECT_PATH "/Org/Tizen/System/Coord/Rotation"
+#define ROTATION_INTERFACE_NAME "org.tizen.system.coord.rotation"
+#define ROTATION_METHOD_NAME "Degree"
+
+#define APPFW_SUSPEND_HINT_PATH "/Org/Tizen/Appfw/SuspendHint"
+#define APPFW_SUSPEND_HINT_INTERFACE "org.tizen.appfw.SuspendHint"
+#define APPFW_SUSPEND_HINT_SIGNAL "SuspendHint"
+
+#define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
+#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
+#define RESOURCED_FREEZER_SIGNAL "FreezerState"
+
+#define RESOURCED_PROC_OBJECT "/Org/Tizen/ResourceD/Process"
+#define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
+#define RESOURCED_PROC_METHOD "ProcExclude"
+#define RESOURCED_PROC_PRELAUNCH_SIGNAL "ProcPrelaunch"
+#define RESOURCED_PROC_WATCHDOG_SIGNAL "ProcWatchdog"
+#define RESOURCED_PROC_GROUP_SIGNAL "ProcGroup"
+#define RESOURCED_SYSTEM_SERVICE_SIGNAL "SystemService"
+#define RESOURCED_ALLOWED_BG_ATTRIBUTE 0x100
+#define RESOURCED_BG_MANAGEMENT_ATTRIBUTE 0x200
+#define RESOURCED_API_VER_2_4_ATTRIBUTE 0x400
+
+#define PASS_BUS_NAME "org.tizen.system.pass"
+#define PASS_PATH_PMQOS "/Org/Tizen/System/Pass/Pmqos"
+#define PASS_INTERFACE_PMQOS "org.tizen.system.pass.pmqos"
+#define PASS_METHOD_APPLAUNCH "AppLaunch"
+
+#define SYSTEM_BUS_NAME "org.tizen.system.deviced"
+#define TEP_BUS_NAME SYSTEM_BUS_NAME
+#define TEP_OBJECT_PATH "/Org/Tizen/System/DeviceD/Tzip"
+#define TEP_INTERFACE_NAME "org.tizen.system.deviced.Tzip"
+#define TEP_MOUNT_METHOD "Mount"
+#define TEP_UNMOUNT_METHOD "Unmount"
+#define TEP_IS_MOUNTED_METHOD "IsMounted"
+
+#define WM_PROC_NAME "org.enlightenment.wm"
+#define WM_PROC_PATH "/org/enlightenment/wm"
+#define WM_PROC_INTERFACE "org.enlightenment.wm.proc"
+#define WM_PROC_METHOD "GetProcStatus"
+
+#define SD_BUS_NAME "org.freedesktop.systemd1"
+#define SD_OBJECT_PATH "/org/freedesktop/systemd1"
+#define SD_MANAGER_INTERFACE "org.freedesktop.systemd1.Manager"
+#define SD_STARTUP_FINISHED_SIGNAL "StartupFinished"
+#define SD_USER_SESSION_STARTUP_FINISHED_SIGNAL "UserSessionStartupFinished"
+#define SD_SUBSCRIBE_METHOD "Subscribe"
+#define SD_UNIT_OBJECT_PATH "/org/freedesktop/systemd1/unit/default_2etarget"
+#define SD_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+#define SD_GET_METHOD "Get"
+#define SD_SYSTEM_STATE_METHOD "SystemState"
+
+#define SYSTEM_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display"
+#define SYSTEM_INTERFACE_DISPLAY "org.tizen.system.deviced.display"
+#define SYSTEM_LOCK_STATE "lockstate"
+#define SYSTEM_UNLOCK_STATE "unlockstate"
+#define SYSTEM_LCD_OFF "lcdoff"
+#define SYSTEM_STAY_CUR_STATE "staycurstate"
+#define SYSTEM_SLEEP_MARGIN "sleepmargin"
+
+#define SYSTEM_PATH_POWEROFF "/Org/Tizen/System/DeviceD/PowerOff"
+#define SYSTEM_INTERFACE_POWEROFF "org.tizen.system.deviced.PowerOff"
+#define SYSTEM_POWEROFF_STATE_SIGNAL "ChangeState"
--- /dev/null
+/*
+ * 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_KEY_PRIVATE_HH_
+#define LIB_COMMON_KEY_PRIVATE_HH_
+
+#undef REGULAR_UID_MIN
+#define REGULAR_UID_MIN 5000
+
+#undef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+#endif // LIB_COMMON_KEY_PRIVATE_HH_
--- /dev/null
+/*
+ * 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_LOG_PRIVATE_HH_
+#define LIB_COMMON_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AMD"
+
+#undef _E
+#define _E(fmt, arg...) LOGE(fmt, ##arg)
+
+#undef _D
+#define _D(fmt, arg...) LOGD(fmt, ##arg)
+
+#undef _W
+#define _W(fmt, arg...) LOGW(fmt, ##arg)
+
+#undef _I
+#define _I(fmt, arg...) LOGI(fmt, ##arg)
+
+#endif // LIB_COMMON_LOG_PRIVATE_HH_
--- /dev/null
+/*
+ * 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_SHARED_QUEUE_HH_
+#define LIB_COMMON_SHARED_QUEUE_HH_
+
+#include <condition_variable>
+#include <thread>
+#include <mutex>
+#include <memory>
+#include <queue>
+
+namespace amd {
+
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push(item);
+ cond_var_.notify_one();
+ }
+
+ T WaitAndPop() {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ auto item = std::move(queue_.front());
+ queue_.pop();
+ return item;
+ }
+
+ bool IsEmpty() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ unsigned int Size() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::queue<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+} // namespace amd
+
+#endif // LIB_COMMON_SHARED_QUEUE_HH_
--- /dev/null
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: libamd
+Description: amd library for making plugins
+Version: @VERSION@
+Requires: bundle
+Libs: -L${libdir} -lamd
+Cflags: -I${includedir} -I${includedir}/amd
--- /dev/null
+ADD_SUBDIRECTORY(boost)
+ADD_SUBDIRECTORY(complication)
+ADD_SUBDIRECTORY(component-manager)
+ADD_SUBDIRECTORY(cooldown)
+ADD_SUBDIRECTORY(cynara-core)
+ADD_SUBDIRECTORY(extractor)
+ADD_SUBDIRECTORY(input)
+ADD_SUBDIRECTORY(job-scheduler)
+ADD_SUBDIRECTORY(launchpad)
+ADD_SUBDIRECTORY(loader-manager)
+ADD_SUBDIRECTORY(rpc-port)
+ADD_SUBDIRECTORY(rua)
+ADD_SUBDIRECTORY(screen-resolution)
+ADD_SUBDIRECTORY(share)
+ADD_SUBDIRECTORY(splash-screen)
+ADD_SUBDIRECTORY(ui-core)
+ADD_SUBDIRECTORY(watch)
+ADD_SUBDIRECTORY(watchdog)
+ADD_SUBDIRECTORY(wayland-core)
+ADD_SUBDIRECTORY(widget)
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_BOOST_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_BOOST} ${AMD_MOD_BOOST_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_BOOST} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_BOOST} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_BOOST} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_BOOST} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <amd.h>
+#include <vconf.h>
+#include <aul_cmd.h>
+#include <aul_svc_priv_key.h>
+#include <bundle_internal.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_BOOST"
+
+#define PASS_BUS_NAME "org.tizen.system.pass"
+#define PASS_PATH_PMQOS "/Org/Tizen/System/Pass/Pmqos"
+#define PASS_INTERFACE_PMQOS "org.tizen.system.pass.pmqos"
+#define PASS_METHOD_APPLAUNCH "AppLaunch"
+
+#define APP_BOOSTING_PERIOD 1500
+#define APP_BOOSTING_STOP 0
+
+#define APP_CONTROL_OPERATION_MAIN \
+ "http://tizen.org/appcontrol/operation/main"
+
+static GDBusConnection *__system_conn;
+
+static GDBusConnection *__get_system_conn(void)
+{
+ GError *err = NULL;
+
+ if (__system_conn)
+ return __system_conn;
+
+ __system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (__system_conn == NULL) {
+ _E("g_bus_get_sync() is failed: %s", err->message);
+ g_error_free(err);
+ return NULL;
+ }
+
+ return __system_conn;
+}
+
+static int __send_cpu_boost_request(int req)
+{
+ GError *err = NULL;
+ GDBusMessage *msg;
+ GDBusConnection *conn;
+ int res = 0;
+
+ conn = __get_system_conn();
+ if (conn == NULL)
+ return -1;
+
+ msg = g_dbus_message_new_method_call(PASS_BUS_NAME,
+ PASS_PATH_PMQOS,
+ PASS_INTERFACE_PMQOS,
+ PASS_METHOD_APPLAUNCH);
+ if (msg == NULL) {
+ _E("g_dbus_message_new_method_call() is failed.");
+ return -1;
+ }
+
+ g_dbus_message_set_body(msg, g_variant_new("(i)", req));
+ if (g_dbus_connection_send_message(conn,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ NULL,
+ &err) == FALSE) {
+ _E("g_dbus_connection_send_message() is failed(%s)",
+ err->message);
+ res = -1;
+ }
+
+ g_dbus_connection_flush(conn, NULL, NULL, NULL);
+ g_object_unref(msg);
+ g_clear_error(&err);
+
+ _D("send cpu boost req(%d)", req);
+
+ return res;
+}
+
+static int __on_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ __send_cpu_boost_request(APP_BOOSTING_PERIOD);
+ return 0;
+}
+
+static int __on_cancel(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ __send_cpu_boost_request(APP_BOOSTING_STOP);
+ return 0;
+}
+
+static int __on_launch(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ __send_cpu_boost_request(APP_BOOSTING_STOP);
+ return 0;
+}
+
+static int __on_relaunch_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *kb)
+{
+ int cmd = arg1;
+ const char *op;
+ int lcd_status = 0;
+
+ op = bundle_get_val(kb, AUL_SVC_K_OPERATION);
+ if ((op && !strcmp(op, APP_CONTROL_OPERATION_MAIN)) ||
+ cmd == APP_OPEN) {
+ vconf_get_int(VCONFKEY_PM_STATE, &lcd_status);
+ if (lcd_status == VCONFKEY_PM_STATE_LCDOFF)
+ _D("LCD OFF: Skip app launch boost");
+ else
+ __send_cpu_boost_request(APP_BOOSTING_PERIOD);
+ }
+
+ return 0;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("boost init");
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START,
+ __on_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
+ __on_cancel);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_LAUNCH,
+ __on_launch);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_START,
+ __on_relaunch_start);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("boost finish");
+
+ if (__system_conn) {
+ g_object_unref(__system_conn);
+ __system_conn = NULL;
+ }
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_COMPLICATION_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_COMPLICATION} ${AMD_MOD_COMPLICATION_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_COMPLICATION} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_COMPLICATION} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_COMPLICATION} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_COMPLICATION} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_sock.h>
+#include <bundle_internal.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_COMPLICATION"
+
+#define MAX_NR_OF_DESCRIPTORS 2
+#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
+
+static int __dispatch_complication_start(amd_request_h req)
+{
+ bundle *b = amd_request_get_bundle(req);
+ pid_t caller_pid = amd_request_get_pid(req);
+ uid_t target_uid = amd_request_get_target_uid(req);
+ amd_appinfo_h ai;
+ const char *appid;
+ const char *comp_type;
+ int pid;
+ bool dummy_pending = false;
+ bool dummy_bg_launch = false;
+
+ if (!b) {
+ _E("Invalid parameter");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get appid");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ ai = amd_appinfo_find(target_uid, appid);
+ if (!ai) {
+ _E("Failed to find %s:%u", appid, target_uid);
+ amd_request_send_result(req, -ENOENT);
+ return -1;
+ }
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (!comp_type) {
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ if (strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
+ _E("Target(%s) is not a service-app", appid);
+ amd_request_send_result(req, -EREJECTED);
+ return -1;
+ }
+
+ amd_request_set_request_type(req, "complication");
+ amd_request_set_cmd(req, APP_START_ASYNC);
+ pid = amd_launch_start_app(appid, req,
+ &dummy_pending, &dummy_bg_launch,
+ false);
+ if (pid < 0) {
+ _E("Failed to send launch request(%s)",
+ appid);
+ return -1;
+ }
+
+ _I("[__COMPLICATION__] appid(%s), pid(%d), caller_pid(%d)",
+ appid, pid, caller_pid);
+
+ return 0;
+}
+
+static int __complication_cynara_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ int r;
+
+ r = amd_cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
+ if (r <= AMD_CYNARA_RET_DENIED)
+ return r;
+
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
+}
+
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = COMPLICATION_UPDATE_REQUEST,
+ .callback = __dispatch_complication_start
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = COMPLICATION_UPDATE_REQUEST,
+ .checker = __complication_cynara_checker,
+ .data = NULL,
+ .priority = 10
+ },
+};
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ _D("complication init");
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register cynara checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("complication finish");
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src
+ AMD_MOD_COMPONENT_MANAGER_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src/request_handler
+ AMD_MOD_COMPONENT_MANAGER_HANDLER_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_COMPONENT_MANAGER}
+ ${AMD_MOD_COMPONENT_MANAGER_SRCS}
+ ${AMD_MOD_COMPONENT_MANAGER_HANDLER_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_COMPONENT_MANAGER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_COMPONENT_MANAGER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/request_handler)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_COMPONENT_MANAGER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_COMPONENT_MANAGER} PRIVATE
+ ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_COMPONENT_MANAGER} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_COMPONENT_MANAGER} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "component_info.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+
+ComponentInfo::LocalizedInfo::LocalizedInfo(std::string locale,
+ std::string icon,
+ std::string label)
+ : locale_(std::move(locale)),
+ icon_(std::move(icon)),
+ label_(std::move(label)) {
+}
+
+ComponentInfo::LocalizedInfo::~LocalizedInfo() = default;
+
+std::string ComponentInfo::LocalizedInfo::GetLocale() {
+ return locale_;
+}
+
+std::string ComponentInfo::LocalizedInfo::GetIcon() {
+ return icon_;
+}
+
+std::string ComponentInfo::LocalizedInfo::GetLabel() {
+ return label_;
+}
+
+ComponentInfo::ComponentInfo(uid_t uid, std::string component_id)
+ : handle_(nullptr, aul_compinfo_destroy), uid_(uid) {
+ aul_compinfo_h handle_inst = nullptr;
+ aul_compinfo_usr_create(component_id.c_str(), uid, &handle_inst);
+ handle_.reset(handle_inst);
+}
+
+ComponentInfo::ComponentInfo(aul_compinfo_h info, uid_t uid)
+ : handle_(info, aul_compinfo_destroy), uid_(uid) {
+}
+
+ComponentInfo::~ComponentInfo() = default;
+
+std::string ComponentInfo::GetAppID() {
+ const char* app_id = nullptr;
+ aul_compinfo_get_app_id(handle_.get(), &app_id);
+ if (app_id)
+ return std::string(app_id);
+
+ return std::string("");
+}
+
+std::string ComponentInfo::GetComponentID() {
+ const char* comp_id = nullptr;
+ aul_compinfo_get_comp_id(handle_.get(), &comp_id);
+ if (comp_id)
+ return std::string(comp_id);
+
+ return std::string("");
+}
+
+std::string ComponentInfo::GetType() {
+ const char* type = nullptr;
+ aul_compinfo_get_type(handle_.get(), &type);
+ if (type)
+ return std::string(type);
+
+ return std::string("");
+}
+
+std::string ComponentInfo::GetLaunchMode() {
+ const char* launch_mode = nullptr;
+ aul_compinfo_get_launch_mode(handle_.get(), &launch_mode);
+ if (launch_mode)
+ return std::string(launch_mode);
+
+ return std::string("");
+}
+
+bool ComponentInfo::IsMainComponent() {
+ bool is_main_comp = false;
+ aul_compinfo_is_main_comp(handle_.get(), &is_main_comp);
+ return is_main_comp;
+}
+
+bool ComponentInfo::IsIconDisplay() {
+ bool is_icon_display = false;
+ aul_compinfo_is_icon_display(handle_.get(), &is_icon_display);
+ return is_icon_display;
+}
+
+bool ComponentInfo::IsManagedByTaskManager() {
+ bool managed = false;
+ aul_compinfo_is_taskmanage(handle_.get(), &managed);
+ return managed;
+}
+
+std::vector<std::unique_ptr<ComponentInfo::LocalizedInfo>>
+ComponentInfo::GetLocalizedInfos() {
+ std::vector<std::unique_ptr<LocalizedInfo>> infos;
+ aul_compinfo_usr_foreach_localized_info(GetComponentID().c_str(), uid_,
+ [](aul_compinfo_localized_info_h handle, void* user_data) -> bool {
+ const char* locale;
+ aul_compinfo_localized_info_get_locale(handle, &locale);
+ const char* icon;
+ aul_compinfo_localized_info_get_icon(handle, &icon);
+ if (icon == nullptr)
+ icon = "";
+ const char* label;
+ aul_compinfo_localized_info_get_label(handle, &label);
+ if (label == nullptr)
+ label = "";
+
+ auto* infos = static_cast<std::vector<std::unique_ptr<LocalizedInfo>>*>(
+ user_data);
+ infos->emplace_back(
+ new (std::nothrow) LocalizedInfo(locale, icon, label));
+ return true;
+ }, &infos);
+ return infos;
+}
+
+tizen_base::Bundle ComponentInfo::ToBundle() {
+ tizen_base::Bundle b;
+ b.Add(AUL_K_APPID, GetAppID());
+ b.Add(AUL_K_COMPONENT_ID, GetComponentID());
+ b.Add(AUL_K_COMPONENT_TYPE, GetType());
+ b.Add(AUL_K_LAUNCH_MODE, GetLaunchMode());
+ b.Add(AUL_K_MAIN_COMP, IsMainComponent() ? "true" : "false");
+ b.Add(AUL_K_ICON_DISPLAY, IsIconDisplay() ? "true" : "false");
+ b.Add(AUL_K_TASK_MANAGE, IsManagedByTaskManager() ? "true" : "false");
+
+ std::vector<std::string> localized_info_arr;
+ std::vector<std::string> localized_info_size_arr;
+ for (auto& info : GetLocalizedInfos()) {
+ tizen_base::Bundle localized_info_b;
+ localized_info_b.Add(AUL_K_LOCALE, info->GetLocale());
+ localized_info_b.Add(AUL_K_ICON, info->GetIcon());
+ localized_info_b.Add(AUL_K_LABEL, info->GetLabel());
+
+ auto raw = localized_info_b.ToRaw();
+ localized_info_arr.emplace_back(reinterpret_cast<char*>(raw.first.get()));
+ localized_info_size_arr.push_back(std::to_string(raw.second));
+ }
+ b.Add(AUL_K_LOCALIZED_INFO, localized_info_arr);
+ b.Add(AUL_K_LOCALIZED_INFO_SIZE, localized_info_size_arr);
+ return b;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 COMPONENT_INFO_H_
+#define COMPONENT_INFO_H_
+
+#include <unistd.h>
+#include <aul_comp_info_internal.h>
+#include <bundle_cpp.h>
+
+#include <string>
+#include <memory>
+#include <vector>
+
+namespace component_manager {
+
+class ComponentInfo {
+ public:
+ class LocalizedInfo {
+ public:
+ LocalizedInfo(std::string locale, std::string icon, std::string label);
+ virtual ~LocalizedInfo();
+
+ std::string GetLocale();
+ std::string GetIcon();
+ std::string GetLabel();
+
+ private:
+ std::string locale_;
+ std::string icon_;
+ std::string label_;
+ };
+
+ public:
+ ComponentInfo(uid_t uid, std::string component_id);
+ ComponentInfo(aul_compinfo_h info, uid_t uid);
+ virtual ~ComponentInfo();
+
+ std::string GetAppID();
+ std::string GetComponentID();
+ std::string GetType();
+ std::string GetLaunchMode();
+ bool IsMainComponent();
+ bool IsIconDisplay();
+ bool IsManagedByTaskManager();
+ std::vector<std::unique_ptr<LocalizedInfo>> GetLocalizedInfos();
+
+ tizen_base::Bundle ToBundle();
+
+ private:
+ std::unique_ptr<std::remove_pointer<aul_compinfo_h>::type,
+ decltype(aul_compinfo_destroy)*> handle_;
+ uid_t uid_;
+};
+
+} // namespace component_manager
+
+#endif // COMPONENT_INFO_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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_cmd.h>
+
+#include "component_manager.h"
+#include "request_handler/component_info_get.h"
+#include "request_handler/component_info_foreach.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+using namespace component_manager::request_handler;
+
+int ComponentManager::Register() {
+ int ret = RegisterCommands();
+ if (ret< 0)
+ return ret;
+
+ ret = RegisterCynaraCheckers();
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int ComponentManager::Dispatch(std::unique_ptr<Request> req) {
+ return dispatcher_->Dispatch(std::move(req));
+}
+
+void ComponentManager::Init() {
+ dispatcher_ = std::unique_ptr<Dispatcher>(new (std::nothrow) Dispatcher());
+ dispatcher_->Register(std::shared_ptr<RequestHandler>(
+ new (std::nothrow) ComponentInfoGet()));
+ dispatcher_->Register(std::shared_ptr<RequestHandler>(
+ new (std::nothrow) ComponentInfoForeach()));
+
+ initialized_ = true;
+}
+
+int ComponentManager::RegisterCommands() {
+ static amd_request_cmd_dispatch dispatch_table[] = {
+ {
+ .cmd = COMP_INFO_GET,
+ .callback = OnDispatch
+ },
+ {
+ .cmd = COMP_INFO_FOREACH,
+ .callback = OnDispatch
+ },
+ };
+
+ int ret = amd_request_register_cmds(dispatch_table,
+ ARRAY_SIZE(dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register AMD request cmds");
+ return ret;
+ }
+
+ return 0;
+}
+
+int ComponentManager::RegisterCynaraCheckers() {
+ void* packagemanager_info = const_cast<char*>(PRIVILEGE_PACKAGEMANAGER_INFO);
+ static amd_cynara_checker cynara_checkers[] = {
+ {
+ .cmd = COMP_INFO_GET,
+ .checker = amd_cynara_simple_checker,
+ .data = packagemanager_info
+ },
+ {
+ .cmd = COMP_INFO_FOREACH,
+ .checker = amd_cynara_simple_checker,
+ .data = packagemanager_info
+ },
+ };
+
+ int ret = amd_cynara_register_checkers(cynara_checkers,
+ ARRAY_SIZE(cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register cynara checkers");
+ return ret;
+ }
+
+ return 0;
+}
+
+int ComponentManager::OnDispatch(amd_request_h request) {
+ auto req = std::unique_ptr<Request>(new (std::nothrow) Request(request));
+ auto& inst = ComponentManager::GetInst();
+ if (inst.Dispatch(std::move(req)) < 0) {
+ _E("Failed to dispatch request");
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 COMPONENT_MANAGER_H_
+#define COMPONENT_MANAGER_H_
+
+#include <amd.h>
+
+#include <string>
+#include <memory>
+
+#include "dispatcher.h"
+
+namespace component_manager {
+
+class ComponentManager {
+ private:
+ ComponentManager() = default;
+ ~ComponentManager() = default;
+
+ public:
+ ComponentManager(const ComponentManager&) = delete;
+ ComponentManager& operator = (const ComponentManager&) = delete;
+
+ static ComponentManager& GetInst() {
+ static ComponentManager inst;
+ if (!inst.initialized_)
+ inst.Init();
+ return inst;
+ }
+
+ int Register();
+ int Dispatch(std::unique_ptr<Request> req);
+
+ private:
+ void Init();
+ int RegisterCommands();
+ int RegisterCynaraCheckers();
+
+ private:
+ static int OnDispatch(amd_request_h req);
+
+ private:
+ bool initialized_ = false;
+ std::unique_ptr<Dispatcher> dispatcher_;
+};
+
+} // namespace component_manager
+
+#endif // COMPONENT_MANAGER_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "AMD_COMPONENT_MANAGER"
+
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "dispatcher.h"
+#include "pending_job.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+
+Dispatcher::Dispatcher() {
+ for (int i = 0; i < MAX_WORKER; ++i) {
+ std::string name = "compmgr+" + std::to_string(i + 1);
+ workers_.emplace_back(new (std::nothrow) Worker(name));
+ }
+}
+
+Dispatcher::~Dispatcher() = default;
+
+int Dispatcher::Dispatch(std::unique_ptr<Request> req) {
+ int cmd = req->GetCmd();
+ auto iter = map_.find(cmd);
+ if (iter == map_.end()) {
+ _W("Failed to find handler. cmd(%d)", cmd);
+ return -1;
+ }
+
+ auto handler = map_[cmd];
+ workers_[GetWorkerID()]->Send(
+ std::shared_ptr<PendingJob>(
+ new (std::nothrow) PendingJob(std::move(req), handler)));
+ return 0;
+}
+
+bool Dispatcher::Register(std::shared_ptr<RequestHandler> handler) {
+ int cmd = handler->GetCmd();
+ auto iter = map_.find(cmd);
+ if (iter != map_.end()) {
+ _W("Already exists. command[%d]", cmd);
+ return false;
+ }
+
+ map_[cmd] = std::move(handler);
+ _W("Register command[%d]", cmd);
+ return true;
+}
+
+int Dispatcher::GetWorkerID() {
+ int worker_id = 0;
+ for (int i = 1; i < MAX_WORKER; i++) {
+ if (workers_[worker_id]->GetJobCount() > workers_[i]->GetJobCount())
+ worker_id = i;
+ }
+
+ return worker_id;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 DISPATCHER_H_
+#define DISPATCHER_H_
+
+#include <map>
+#include <memory>
+
+#include "request.h"
+#include "request_handler.h"
+#include "worker.h"
+
+namespace component_manager {
+
+class Dispatcher {
+ public:
+ Dispatcher();
+ virtual ~Dispatcher();
+
+ int Dispatch(std::unique_ptr<Request> req);
+ bool Register(std::shared_ptr<RequestHandler> handler);
+
+ private:
+ int GetWorkerID();
+
+ private:
+ static const int MAX_WORKER = 2;
+
+ private:
+ std::map<int, std::shared_ptr<RequestHandler>> map_;
+ std::vector<std::unique_ptr<Worker>> workers_;
+};
+
+} // namespace component_manager
+
+#endif // DISPATCHER_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "job.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+
+Job::Job(std::string name, IJobHandler* handler) :
+ name_(std::move(name)), handler_(handler) {
+}
+
+Job::~Job() = default;
+
+Job::Job(const Job& job) {
+ name_ = job.name_;
+ handler_ = job.handler_;
+}
+
+Job& Job::operator = (const Job& job) {
+ if (this != &job) {
+ name_ = job.name_;
+ handler_ = job.handler_;
+ }
+ return *this;
+}
+
+Job::Job(Job&& job) noexcept {
+ name_ = std::move(job.name_);
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+}
+
+Job& Job::operator = (Job&& job) noexcept {
+ if (this != &job) {
+ name_ = std::move(job.name_);
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+ }
+ return *this;
+}
+
+void Job::Do() {
+ if (handler_ != nullptr)
+ handler_->OnJob();
+ _I("[__JOB__] name(%s)", name_.c_str());
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 JOB_H_
+#define JOB_H_
+
+#include <string>
+
+namespace component_manager {
+
+class Job {
+ public:
+ class IJobHandler {
+ public:
+ virtual void OnJob() = 0;
+ };
+
+ Job(std::string name, IJobHandler* handler);
+ virtual ~Job();
+ Job(const Job& job);
+ Job& operator = (const Job& b);
+ Job(Job&& job) noexcept;
+ Job& operator = (Job&& job) noexcept;
+
+ void Do();
+
+ private:
+ std::string name_;
+ IJobHandler* handler_;
+};
+
+} // namespace component_manager
+
+#endif // JOB_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "component_manager.h"
+#include "component_manager_private.h"
+
+using namespace component_manager;
+
+extern "C" EXPORT int AMD_MOD_INIT(void) {
+ _D("Component Manager Initialize");
+
+ auto& inst = ComponentManager::GetInst();
+ int ret = inst.Register();
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+extern "C" EXPORT void AMD_MOD_FINI(void) {
+ _D("Component Manager Finalize");
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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_cmd.h>
+
+#include "pending_job.h"
+
+namespace component_manager {
+
+PendingJob::PendingJob(std::unique_ptr<Request> req,
+ std::shared_ptr<RequestHandler> handler)
+ : Job(std::string(aul_cmd_convert_to_string(req->GetCmd())), this),
+ req_(std::move(req)),
+ handler_(std::move(handler)) {
+}
+
+void PendingJob::OnJob() {
+ handler_->Handle(req_);
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 PENDING_JOB_H_
+#define PENDING_JOB_H_
+
+#include <memory>
+
+#include "job.h"
+#include "request_handler.h"
+
+namespace component_manager {
+
+class PendingJob : public Job, Job::IJobHandler {
+ public:
+ PendingJob(std::unique_ptr<Request> req,
+ std::shared_ptr<RequestHandler> handler);
+
+ private:
+ void OnJob() override;
+
+ private:
+ std::unique_ptr<Request> req_;
+ std::shared_ptr<RequestHandler> handler_;
+};
+
+} // namespace component_manager
+
+#endif // PENDING_JOB_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 "request.h"
+
+namespace component_manager {
+
+Request::Request(amd_request_h req) {
+ fd_ = amd_request_remove_fd(req);
+ cmd_ = amd_request_get_cmd(req);
+ target_uid_ = amd_request_get_target_uid(req);
+ b_ = tizen_base::Bundle(amd_request_get_bundle(req));
+}
+
+Request::Request(int fd, int cmd, uid_t target_uid, tizen_base::Bundle b)
+ : fd_(fd), cmd_(cmd), target_uid_(target_uid), b_(std::move(b)) {
+}
+
+Request::~Request() {
+ if (fd_)
+ close(fd_);
+}
+
+Request::Request(const Request& req) {
+ fd_ = req.fd_;
+ cmd_ = req.cmd_;
+ target_uid_ = req.target_uid_;
+ b_ = req.b_;
+}
+
+Request& Request::operator = (const Request& req) {
+ if (this != &req) {
+ fd_ = req.fd_;
+ cmd_ = req.cmd_;
+ target_uid_ = req.target_uid_;
+ b_ = req.b_;
+ }
+ return *this;
+}
+
+Request::Request(Request&& req) noexcept {
+ fd_ = req.fd_;
+ req.fd_ = 0;
+ cmd_ = req.cmd_;
+ req.cmd_ = -1;
+ target_uid_ = req.target_uid_;
+ req.target_uid_ = 0;
+ b_ = std::move(req.b_);
+}
+
+Request& Request::operator = (Request&& req) noexcept {
+ if (this != &req) {
+ fd_ = req.fd_;
+ req.fd_ = 0;
+ cmd_ = req.cmd_;
+ req.cmd_ = -1;
+ target_uid_ = req.target_uid_;
+ req.target_uid_ = 0;
+ b_ = std::move(req.b_);
+ }
+ return *this;
+}
+
+int Request::RemoveFd() {
+ int fd = fd_;
+ fd_ = 0;
+ return fd;
+}
+
+int Request::GetFd() const {
+ return fd_;
+}
+
+int Request::GetCmd() const {
+ return cmd_;
+}
+
+uid_t Request::GetTargetUid() const {
+ return target_uid_;
+}
+
+const tizen_base::Bundle& Request::GetBundle() const {
+ return b_;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 REQUEST_H_
+#define REQUEST_H_
+
+#include <amd.h>
+#include <unistd.h>
+
+#include <bundle_cpp.h>
+
+namespace component_manager {
+
+class Request {
+ public:
+ Request(amd_request_h req);
+ Request(int fd, int cmd, uid_t target_uid, tizen_base::Bundle b);
+ ~Request();
+
+ Request(const Request& req);
+ Request& operator = (const Request& req);
+ Request(Request&& req) noexcept;
+ Request& operator = (Request&& req) noexcept;
+
+ int RemoveFd();
+ int GetFd() const;
+ int GetCmd() const;
+ uid_t GetTargetUid() const;
+ const tizen_base::Bundle& GetBundle() const;
+
+ private:
+ int fd_;
+ int cmd_;
+ uid_t target_uid_;
+ tizen_base::Bundle b_;
+};
+
+} // namespace component_manager
+
+#endif // REQUEST_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <memory>
+
+#include "request_handler.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+
+RequestHandler::RequestHandler(int cmd, std::string name)
+ : cmd_(cmd), name_(std::move(name)) {
+}
+
+RequestHandler::~RequestHandler() = default;
+
+RequestHandler::RequestHandler(const RequestHandler& handler) {
+ cmd_ = handler.cmd_;
+ name_ = handler.name_;
+}
+
+RequestHandler& RequestHandler::operator = (const RequestHandler& handler) {
+ if (this != &handler) {
+ cmd_ = handler.cmd_;
+ name_ = handler.name_;
+ }
+ return *this;
+}
+
+RequestHandler::RequestHandler(RequestHandler&& handler) noexcept {
+ cmd_ = handler.cmd_;
+ handler.cmd_ = 0;
+ name_ = std::move(handler.name_);
+}
+
+RequestHandler& RequestHandler::operator = (RequestHandler&& handler) noexcept {
+ if (this != &handler) {
+ cmd_ = handler.cmd_;
+ handler.cmd_ = 0;
+ name_ = std::move(handler.name_);
+ }
+ return *this;
+}
+
+int RequestHandler::Handle(std::unique_ptr<Request>& req) {
+ _W("Command: %s[%d]", name_.c_str(), cmd_);
+ return 0;
+}
+
+int RequestHandler::GetCmd() const {
+ return cmd_;
+}
+
+std::string RequestHandler::GetName() {
+ return name_;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 REQUEST_HANDLER_H_
+#define REQUEST_HANDLER_H_
+
+#include <string>
+#include <memory>
+
+#include "request.h"
+
+namespace component_manager {
+
+class RequestHandler {
+ public:
+ RequestHandler(int cmd, std::string name);
+ virtual ~RequestHandler();
+
+ RequestHandler(const RequestHandler& handler);
+ RequestHandler& operator = (const RequestHandler& handler);
+ RequestHandler(RequestHandler&& handler) noexcept;
+ RequestHandler& operator = (RequestHandler&& handler) noexcept;
+
+ virtual int Handle(std::unique_ptr<Request>& req);
+
+ int GetCmd() const;
+ std::string GetName();
+
+ private:
+ int cmd_;
+ std::string name_;
+};
+
+} // namespace component_manager
+
+#endif // REQUEST_HANDLER_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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_comp_info_internal.h>
+#include <aul_cmd.h>
+#include <errno.h>
+
+#ifdef _GNU_SOURCE
+#undef _GNU_SOURCE
+#endif
+#include <aul_sock.h>
+#include <amd.h>
+
+#include "component_info.h"
+#include "request_handler/component_info_foreach.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+namespace request_handler {
+
+class ComponentInfoForeachUserData {
+ public:
+ ComponentInfoForeachUserData(uid_t uid, void* user_data)
+ : uid_(uid), user_data_(user_data) { }
+
+ uid_t uid_;
+ void* user_data_;
+};
+
+ComponentInfoForeach::ComponentInfoForeach()
+ : RequestHandler(COMP_INFO_FOREACH, "COMP_INFO_FOREACH") {
+}
+
+int ComponentInfoForeach::Handle(std::unique_ptr<Request>& req) {
+ RequestHandler::Handle(req);
+
+ std::vector<std::unique_ptr<ComponentInfo>> infos;
+ ComponentInfoForeachUserData user_data(req->GetTargetUid(), &infos);
+ int ret = aul_compinfo_usr_foreach_compinfo(req->GetTargetUid(),
+ [](aul_compinfo_h handle, void* user_data) -> bool {
+ aul_compinfo_h clone = nullptr;
+ aul_compinfo_clone(handle, &clone);
+ if (clone == nullptr) {
+ _E("Failed to clone compinfo");
+ return false;
+ }
+
+ auto* data = static_cast<ComponentInfoForeachUserData*>(user_data);
+ auto* infos = static_cast<std::vector<std::unique_ptr<ComponentInfo>>*>(
+ data->user_data_);
+ infos->emplace_back(
+ new (std::nothrow) ComponentInfo(clone, data->uid_));
+ return true;
+ }, &user_data);
+ if (ret < 0) {
+ _E("Failed to retrieve component info. error(%d)", ret);
+ amd_socket_send_result(req->GetFd(), ret, false);
+ return ret;
+ }
+
+ amd_socket_send_result(req->GetFd(), infos.size(), false);
+ for (auto& info : infos) {
+ auto b = info->ToBundle();
+ bundle* b_raw = b.GetHandle();
+ ret = aul_sock_send_bundle_with_fd(req->GetFd(), APP_GET_INFO_OK, b_raw,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send bundle data. error(%d)", ret);
+ return ret;
+ }
+ }
+
+ _I("[%s][%d]", GetName().c_str(), GetCmd());
+ return 0;
+}
+
+} // namespace request_handler
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 REUQEST_HANDLER_COMPONENT_INFO_FOREACH_H_
+#define REQUEST_HANDLER_COMPONENT_INFO_FOREACH_H_
+
+#include <string>
+
+#include "request_handler.h"
+
+namespace component_manager {
+namespace request_handler {
+
+class ComponentInfoForeach : public RequestHandler {
+ public:
+ ComponentInfoForeach();
+
+ virtual int Handle(std::unique_ptr<Request>& req) override;
+};
+
+} // namespace request_handler
+} // namespace component_manager
+
+#endif // REQUEST_HANDLER_COMPONENT_INFO_FOREACH_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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_comp_info_internal.h>
+#include <aul_cmd.h>
+#include <errno.h>
+
+#ifdef _GNU_SOURCE
+#undef _GNU_SOURCE
+#endif
+#include <aul_sock.h>
+
+#include "component_info.h"
+#include "request_handler/component_info_get.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+namespace request_handler {
+
+ComponentInfoGet::ComponentInfoGet()
+ : RequestHandler(COMP_INFO_GET, "COMP_INFO_GET") {
+}
+
+int ComponentInfoGet::Handle(std::unique_ptr<Request>& req) {
+ RequestHandler::Handle(req);
+
+ auto& b = req->GetBundle();
+ std::string component_id = b.GetString(AUL_K_COMPONENT_ID);
+ if (component_id.empty()) {
+ _E("Failed to get component ID");
+ aul_sock_send_raw_with_fd(req->GetFd(), AUL_R_EINVAL, NULL, 0,
+ AUL_SOCK_ASYNC);
+ return -1;
+ }
+
+ aul_compinfo_h handle_inst;
+ int ret = aul_compinfo_usr_create(component_id.c_str(), req->GetTargetUid(),
+ &handle_inst);
+ if (ret != AUL_R_OK) {
+ _E("Failed to create component info. error(%d)", ret);
+ aul_sock_send_raw_with_fd(req->GetFd(), ret, NULL, 0, AUL_SOCK_ASYNC);
+ return ret;
+ }
+
+ ComponentInfo info(handle_inst, req->GetTargetUid());
+ auto info_b = info.ToBundle();
+ bundle* b_raw = info_b.GetHandle();
+ ret = aul_sock_send_bundle_with_fd(req->GetFd(), APP_GET_INFO_OK, b_raw,
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send bundle data. error(%d)", ret);
+ return ret;
+ }
+
+ _I("[%s][%d]", GetName().c_str(), GetCmd());
+ return 0;
+}
+
+} // namespace request_handler
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 REUQEST_HANDLER_COMPONENT_INFO_GET_H_
+#define REQUEST_HANDLER_COMPONENT_INFO_GET_H_
+
+#include <string>
+
+#include "request_handler.h"
+
+namespace component_manager {
+namespace request_handler {
+
+class ComponentInfoGet : public RequestHandler {
+ public:
+ ComponentInfoGet();
+
+ virtual int Handle(std::unique_ptr<Request>& req) override;
+};
+
+} // namespace request_handler
+} // namespace component_manager
+
+#endif // REQUEST_HANDLER_COMPONENT_INFO_GET_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 SHARED_QUEUE_H_
+#define SHARED_QUEUE_H_
+
+#include <condition_variable>
+#include <thread>
+#include <mutex>
+#include <memory>
+#include <queue>
+
+namespace component_manager {
+
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push(item);
+ cond_var_.notify_one();
+ }
+
+ T WaitAndPop() {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ auto item = std::move(queue_.front());
+ queue_.pop();
+ return item;
+ }
+
+ bool IsEmpty() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ unsigned int Size() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::queue<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+} // namespace component_manager
+
+#endif // SHARED_QUEUE_H_
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+#include "worker.h"
+#include "component_manager_private.h"
+
+namespace component_manager {
+
+Worker::Worker(std::string name) : name_(std::move(name)) {
+ thread_ = std::thread([&]{
+ SetComm();
+ Run();
+ });
+}
+
+Worker::~Worker() {
+ Quit();
+ Join();
+}
+
+bool Worker::Join() {
+ if (!thread_.joinable())
+ return false;
+
+ thread_.join();
+ return true;
+}
+
+void Worker::Send(std::shared_ptr<Job> job) {
+ queue_.Push(std::move(job));
+}
+
+void Worker::Run() {
+ do {
+ auto job = queue_.WaitAndPop();
+ job->Do();
+ } while (!done_);
+}
+
+unsigned int Worker::GetJobCount() const {
+ return queue_.Size();
+}
+
+void Worker::Quit() {
+ Send(std::shared_ptr<Job>(new (std::nothrow) Job("Quit", this)));
+}
+
+void Worker::SetComm() {
+ pid_t tid = syscall(__NR_gettid);
+ _I("[__WORKER__] Thread(%d)", tid);
+
+ std::string path = "/proc/" + std::to_string(tid) + "/comm";
+ int fd = open(path.c_str(), O_WRONLY);
+ if (fd < 0) {
+ _E("Failed to open %s. error(%d)", path.c_str(), errno);
+ return;
+ }
+
+ ssize_t bytes_written = write(fd, name_.c_str(), name_.length() + 1);
+ if (bytes_written < 0) {
+ _E("Failed to write name(%s)", name_.c_str());
+ close(fd);
+ return;
+ }
+
+ close(fd);
+}
+
+void Worker::OnJob() {
+ done_ = true;
+}
+
+} // namespace component_manager
--- /dev/null
+/*
+ * Copyright (c) 2019 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 WORKER_H_
+#define WORKER_H_
+
+#include <thread>
+#include <memory>
+#include <string>
+#include <queue>
+
+#include "shared_queue.h"
+#include "job.h"
+
+namespace component_manager {
+
+class Worker : public Job::IJobHandler {
+ public:
+ Worker(std::string name);
+ ~Worker();
+
+ void Send(std::shared_ptr<Job> job);
+ void Run();
+ unsigned int GetJobCount() const;
+
+ private:
+ bool Join();
+ void Quit();
+ void SetComm();
+ void OnJob() override;
+
+ private:
+ std::string name_;
+ std::thread thread_;
+ bool done_ = false;
+ SharedQueue<std::shared_ptr<Job>> queue_;
+};
+
+} // namespace component_manager
+
+#endif // WORKER_H_
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_COOLDOWN_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_COOLDOWN} ${AMD_MOD_COOLDOWN_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_COOLDOWN} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_COOLDOWN} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_COOLDOWN} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
+ GIO_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_COOLDOWN} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.application.manager.conf
+ DESTINATION /etc/dbus-1/system.d)
--- /dev/null
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="org.tizen.application.manager"/>
+ <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
+ </policy>
+ <policy user="app_fw">
+ <allow own="org.tizen.application.manager"/>
+ <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
+ </policy>
+ <policy user="system">
+ <allow own="org.tizen.application.manager"/>
+ <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
+ </policy>
+ <policy user="system_fw">
+ <allow own="org.tizen.application.manager"/>
+ <allow send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
+ </policy>
+ <policy context="default">
+ <deny own="org.tizen.application.manager"/>
+ <deny send_destination="org.tizen.application.manager" send_interface="org.tizen.application.manager" send_member="Cooldown"/>
+ </policy>
+</busconfig>
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_COOLDOWN"
+
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
+
+#define AMD_DBUS_INTERFACE "org.tizen.application.manager"
+#define AMD_DBUS_OBJECT_PATH "/Org/Tizen/Application/Manager"
+
+#define COOLDOWN_STATUS_RELEASE "release"
+#define COOLDOWN_STATUS_LIMIT "limit"
+
+enum cooldown_status_val {
+ COOLDOWN_RELEASE,
+ COOLDOWN_WARNING,
+ COOLDOWN_LIMIT,
+};
+
+static int cooldown_status;
+static GDBusConnection *__conn;
+static guint __registration_id;
+
+static void __cooldown_limitaction(amd_app_status_h app_status, void *data)
+{
+ amd_appinfo_h ai;
+ const char *taskmanage;
+ const char *cooldown;
+ const char *appid;
+ int app_type;
+ uid_t uid;
+
+ if (app_status == NULL)
+ return;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_WIDGET_APP || app_type == AMD_AT_WATCH_APP)
+ return;
+
+ uid = amd_app_status_get_uid(app_status);
+ appid = amd_app_status_get_appid(app_status);
+ ai = amd_appinfo_find(uid, appid);
+ if (ai == NULL)
+ return;
+
+ cooldown = amd_appinfo_get_value(ai, AMD_AIT_COOLDOWN);
+ if (cooldown && strcmp(cooldown, "true") != 0) {
+ if (app_type == AMD_AT_UI_APP) {
+ taskmanage = amd_appinfo_get_value(ai,
+ AMD_AIT_TASKMANAGE);
+ if (taskmanage && strcmp(taskmanage, "true") != 0)
+ return;
+ }
+
+ amd_app_status_terminate_apps(appid, uid);
+ }
+}
+
+static void __cooldown_release(void)
+{
+ amd_uid_state state;
+ uid_t *uids;
+ int r;
+ int i;
+
+ r = amd_login_monitor_get_uids(&uids);
+ if (r <= 0)
+ return;
+
+ for (i = 0; i < r; ++i) {
+ state = amd_login_monitor_get_uid_state(uids[i]);
+ if (state == AMD_UID_STATE_ACTIVE)
+ amd_launch_start_onboot_apps(uids[i]);
+ }
+ free(uids);
+}
+
+static int __check_cooldown_mode(amd_appinfo_h ai)
+{
+ const char *taskmanage;
+ const char *cooldown;
+ const char *comptype;
+
+ if (cooldown_status != COOLDOWN_LIMIT)
+ return 0;
+
+ cooldown = amd_appinfo_get_value(ai, AMD_AIT_COOLDOWN);
+ if (cooldown && strcmp(cooldown, "true") == 0)
+ return 0;
+
+ comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comptype == NULL) {
+ _E("Failed to get comptype");
+ return -1;
+ }
+
+ if (strcmp(comptype, APP_TYPE_WIDGET) == 0 ||
+ strcmp(comptype, APP_TYPE_WATCH) == 0)
+ return 0;
+
+ if (strcmp(comptype, APP_TYPE_UI) == 0) {
+ taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
+ if (taskmanage && strcmp(taskmanage, "false") == 0)
+ return 0;
+ }
+
+ _W("Cannot launch this application in COOLDOWN mode");
+ return -1;
+}
+
+static int __on_check_mode(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_appinfo_h info = arg3;
+
+ return __check_cooldown_mode(info);
+}
+
+static int __on_check_status(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ if (cooldown_status == COOLDOWN_LIMIT)
+ return -1;
+
+ return 0;
+}
+
+static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
+{
+ GError *err = NULL;
+ GVariant *result;
+ uid_t uid = (uid_t)-1;
+
+ result = g_dbus_connection_call_sync(connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "GetConnectionUnixUser",
+ g_variant_new("(s)", name),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &err);
+ if (result == NULL) {
+ _E("g_dbus_connection_call_sync() is failed. error(%s)",
+ err->message);
+ g_error_free(err);
+ return uid;
+ }
+
+ g_variant_get(result, "(u)", &uid);
+ g_variant_unref(result);
+
+ return uid;
+}
+
+static void __handle_method_call(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ int result = 0;
+ char *status = NULL;
+ uid_t uid;
+
+ uid = __get_caller_uid(connection,
+ g_dbus_method_invocation_get_sender(invocation));
+ if (uid == (uid_t)-1) {
+ result = -1;
+ goto end;
+ }
+
+ if (uid >= REGULAR_UID_MIN) {
+ _E("Reject request. uid(%u)", uid);
+ result = -1;
+ goto end;
+ }
+
+ if (g_strcmp0(method_name, "Cooldown") == 0) {
+ g_variant_get(parameters, "(&s)", &status);
+ _W("[__COOLDOWN__] status(%s)", status);
+ if (g_strcmp0(status, COOLDOWN_STATUS_LIMIT) == 0) {
+ cooldown_status = COOLDOWN_LIMIT;
+ amd_app_status_foreach_running_info(
+ __cooldown_limitaction,
+ NULL);
+ } else if (g_strcmp0(status, COOLDOWN_STATUS_RELEASE) == 0) {
+ cooldown_status = COOLDOWN_RELEASE;
+ __cooldown_release();
+ } else {
+ result = -1;
+ }
+ } else {
+ _E("Invalid request(%s)", method_name);
+ result = -1;
+ }
+
+end:
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(i)", result));
+}
+
+static guint __get_owner_id(GDBusConnection *connection,
+ const char *interface_name)
+{
+ GError *err = NULL;
+ guint owner_id = 0;
+ GVariant* result;
+
+ result = g_dbus_connection_call_sync(connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "RequestName",
+ g_variant_new("(su)",
+ interface_name,
+ G_BUS_NAME_OWNER_FLAGS_NONE),
+ G_VARIANT_TYPE("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &err);
+ if (err) {
+ _E("g_dbus_connection_call_sync() is failed. error(%s)",
+ err->message);
+ g_error_free(err);
+ return 0;
+ }
+
+ if (result == NULL) {
+ _E("Failed to get RequestName");
+ return 0;
+ }
+
+ g_variant_get(result, "(u)", &owner_id);
+ if (owner_id == 0) {
+ _E("Acquiring the own name is failed");
+ g_variant_unref(result);
+ return 0;
+ }
+
+ _D("Acquiring the own name : %u", owner_id);
+ g_variant_unref(result);
+
+ return owner_id;
+}
+
+static int __init_request_handler(void *user_data)
+{
+ static const char introspection_xml[] =
+ "<node>"
+ " <interface name='org.tizen.application.manager'>"
+ " <method name='Cooldown'>"
+ " <arg type='s' name='status' direction='in'/>"
+ " <arg type='i' name='ret' direction='out'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+ static const GDBusInterfaceVTable interface_vtable = {
+ __handle_method_call,
+ NULL,
+ NULL
+ };
+ GDBusNodeInfo *introspection_data;
+ GError *err = NULL;
+ guint owner_id;
+
+ __conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!__conn) {
+ _E("g_bus_get_sync() is failed. error(%s)",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ introspection_data = g_dbus_node_info_new_for_xml(introspection_xml,
+ &err);
+ if (!introspection_data) {
+ _E("g_dbus_node_info_new_for_xml() is failed. error(%s)",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ __registration_id = g_dbus_connection_register_object(
+ __conn,
+ AMD_DBUS_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ NULL,
+ NULL,
+ &err);
+ g_dbus_node_info_unref(introspection_data);
+ if (__registration_id == 0) {
+ _E("g_dbus_connection_register_object() is failed. error(%s)",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ owner_id = __get_owner_id(__conn, AMD_DBUS_INTERFACE);
+ _I("registration_id(%u), owner_id(%u)", __registration_id, owner_id);
+
+ return 0;
+}
+
+static void __fini_request_handler(void)
+{
+ if (__registration_id > 0) {
+ g_dbus_connection_unregister_object(__conn, __registration_id);
+ __registration_id = 0;
+ }
+
+ if (__conn) {
+ g_object_unref(__conn);
+ __conn = NULL;
+ }
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("cooldown init");
+ amd_signal_add_ready_cb(__init_request_handler, NULL);
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
+ __on_check_mode);
+ amd_noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
+ __on_check_status);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("cooldown fini");
+ __fini_request_handler();
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_CYNARA_CORE_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_CYNARA_CORE} ${AMD_MOD_CYNARA_CORE_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_CYNARA_CORE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_CYNARA_CORE} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_CYNARA_CORE} PUBLIC
+ AUL_DEPS
+ CERT_SVC_VCORE_DEPS
+ CYNARA_CLIENT_ASYNC_DEPS
+ CYNARA_CREDS_SOCKET_DEPS
+ CYNARA_SESSION_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ SECURITY_MANAGER_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_CYNARA_CORE} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <malloc.h>
+#include <stdlib.h>
+#include <cynara-client-async.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <glib.h>
+#include <glib-unix.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <aul_svc_priv_key.h>
+#include <aul.h>
+#include <amd.h>
+#include <security-manager.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_CYNARA_CORE"
+
+#define MAX_LOCAL_BUFSZ 128
+
+static cynara_async *r_cynara;
+static int cynara_fd = -1;
+static guint cynara_fd_id;
+static GHashTable *__checker_table;
+static GList *__sub_checkers;
+
+struct caller_info {
+ GHashTable *id_table;
+
+ char *user;
+ char *client;
+ char *session;
+ char *appid;
+ uid_t uid;
+ bool offline;
+
+ amd_cynara_response_cb callback;
+ void *user_data;
+};
+
+typedef struct _cynara_sub_checker {
+ char *name;
+ amd_cynara_sub_checker_func checker;
+} cynara_sub_checker;
+
+static int __check_privilege_offline(const char *appid, const char *privilege,
+ uid_t uid);
+
+static gboolean __cancel_func(gpointer key, gpointer value, gpointer user_data)
+{
+ int r;
+
+ r = cynara_async_cancel_request(r_cynara, GPOINTER_TO_UINT(key));
+ if (r != CYNARA_API_SUCCESS)
+ _E("cynara_async_cancel_request failed.");
+
+ return TRUE;
+}
+
+static void __destroy_caller_info(struct caller_info *info)
+{
+ if (info == NULL)
+ return;
+
+ if (info->appid)
+ free(info->appid);
+
+ if (info->client)
+ free(info->client);
+
+ if (info->session)
+ free(info->session);
+
+ if (info->user)
+ free(info->user);
+
+ if (info->id_table) {
+ g_hash_table_foreach_remove(info->id_table, __cancel_func, NULL);
+ g_hash_table_destroy(info->id_table);
+ }
+
+ free(info);
+}
+
+static int __get_caller_info_from_cynara(int sockfd, struct caller_info *info)
+{
+ pid_t pid;
+ int r;
+ char buf[MAX_LOCAL_BUFSZ];
+
+ if (info == NULL)
+ return -1;
+
+ r = cynara_creds_socket_get_pid(sockfd, &pid);
+ if (r != CYNARA_API_SUCCESS) {
+ cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+ _E("cynara_creds_socket_get_pid failed: %s", buf);
+ return -1;
+ }
+
+ info->session = cynara_session_from_pid(pid);
+ if (info->session == NULL) {
+ _E("cynara_session_from_pid failed.");
+ return -1;
+ }
+
+ r = cynara_creds_socket_get_user(sockfd, USER_METHOD_DEFAULT,
+ &(info->user));
+ if (r != CYNARA_API_SUCCESS) {
+ cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+ _E("cynara_cred_socket_get_user failed.");
+ return -1;
+ }
+
+ r = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_DEFAULT,
+ &(info->client));
+ if (r != CYNARA_API_SUCCESS) {
+ cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+ _E("cynara_creds_socket_get_client failed.");
+ return -1;
+ }
+
+ info->offline = false;
+
+ return 0;
+}
+
+static void __resp_cb(cynara_check_id id, cynara_async_call_cause cause,
+ int resp, void *data)
+{
+ enum amd_cynara_result res;
+ struct caller_info *info = (struct caller_info *)data;
+ char *privilege;
+
+ _D("check id %u, cause %d, resp %d", id, cause, resp);
+
+ privilege = g_hash_table_lookup(info->id_table,
+ GUINT_TO_POINTER(id));
+ if (privilege == NULL) {
+ _W("Cynara: resp: %u not exist in id_table", id);
+ return;
+ }
+ _I("privilege(%s)", privilege);
+
+ g_hash_table_remove(info->id_table, GUINT_TO_POINTER(id));
+
+ switch (cause) {
+ case CYNARA_CALL_CAUSE_ANSWER:
+ if (resp == CYNARA_API_ACCESS_ALLOWED) {
+ if (g_hash_table_size(info->id_table) > 0)
+ return;
+ res = AMD_CYNARA_RET_ALLOWED;
+ } else {
+ _E("cynara denied (%s|%s|%s|%d)",
+ info->client, info->session,
+ info->user, id);
+ res = AMD_CYNARA_RET_DENIED;
+ }
+ break;
+ case CYNARA_CALL_CAUSE_CANCEL:
+ _D("Cynara: resp: resp %d canceled", id);
+ return;
+ case CYNARA_CALL_CAUSE_FINISH:
+ case CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE:
+ default:
+ _E("Cynara: resp: not answer");
+ res = AMD_CYNARA_RET_ERROR;
+ break;
+ }
+
+ if (info->callback)
+ info->callback(res, info->user_data);
+
+ __destroy_caller_info(info);
+}
+
+static enum amd_cynara_result __check_server(struct caller_info *info,
+ const char *privilege)
+{
+ int r;
+ cynara_check_id id;
+
+ r = cynara_async_create_request(r_cynara, info->client, info->session,
+ info->user, privilege,
+ &id, __resp_cb, info);
+ if (r != CYNARA_API_SUCCESS) {
+ _E("cynara_async_create_request error : %d", r);
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ g_hash_table_insert(info->id_table, GUINT_TO_POINTER(id),
+ strdup(privilege));
+
+ return AMD_CYNARA_RET_UNKNOWN;
+}
+
+static enum amd_cynara_result __check_cache(struct caller_info *info,
+ const char *privilege)
+{
+ int ret;
+
+ ret = cynara_async_check_cache(r_cynara, info->client, info->session,
+ info->user, privilege);
+ switch (ret) {
+ case CYNARA_API_ACCESS_ALLOWED:
+ ret = AMD_CYNARA_RET_ALLOWED;
+ break;
+ case CYNARA_API_ACCESS_DENIED:
+ ret = AMD_CYNARA_RET_DENIED;
+ break;
+ case CYNARA_API_CACHE_MISS:
+ ret = AMD_CYNARA_RET_UNKNOWN;
+ break;
+ default:
+ _E("cynara cache error %d (%s|%s|%s)", ret,
+ info->client, info->session, info->user);
+ ret = AMD_CYNARA_RET_UNKNOWN;
+ break;
+ }
+
+ return ret;
+}
+
+static int __cynara_simple_checker(amd_cynara_caller_info_h info, amd_request_h req, void *data)
+{
+ int ret;
+ const char *privilege = data;
+
+ if (info->offline) {
+ ret = __check_privilege_offline(info->appid, privilege,
+ info->uid);
+ } else {
+ ret = __check_cache(info, privilege);
+ }
+ if (ret != AMD_CYNARA_RET_UNKNOWN) {
+ if (ret == AMD_CYNARA_RET_DENIED) {
+ _E("cynara denied (%s|%s|%s|%s)", privilege,
+ info->client, info->session, info->user);
+ }
+ return ret;
+ }
+
+ return __check_server(info, privilege);
+}
+
+static int __check_privilege_by_checker(amd_request_h req, amd_cynara_caller_info_h info)
+{
+ int ret;
+ amd_cynara_checker *checker;
+
+ checker = g_hash_table_lookup(__checker_table,
+ GINT_TO_POINTER(amd_request_get_cmd(req)));
+ if (checker && checker->checker) {
+ ret = checker->checker(info, req, checker->data);
+ return ret;
+ }
+
+ return 0;
+}
+
+static bool __has_checker(amd_request_h req)
+{
+ amd_cynara_checker *checker;
+
+ checker = g_hash_table_lookup(__checker_table,
+ GINT_TO_POINTER(amd_request_get_cmd(req)));
+ if (checker)
+ return true;
+
+ return false;
+}
+
+static int __verify_caller_process(amd_request_h req)
+{
+ amd_app_status_h app_status;
+ const char *appid;
+ pid_t pid;
+ uid_t uid;
+ char attr[512] = { 0, };
+ int r;
+
+ uid = amd_request_get_uid(req);
+ if (uid < REGULAR_UID_MIN)
+ return 0;
+
+ pid = amd_request_get_pid(req);
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (app_status) {
+ appid = amd_app_status_get_appid(app_status);
+ if (amd_appinfo_is_platform_app(appid, uid))
+ return 0;
+ } else {
+ r = amd_proc_get_attr(pid, attr, sizeof(attr));
+ if (r != 0) {
+ _E("Failed to get attr. pid(%d)", pid);
+ return -1;
+ }
+
+ if (!strcmp(attr, "User"))
+ return 0;
+ }
+
+ _E("Reject request. caller(%d)", pid);
+
+ return -1;
+}
+
+static bool __is_indirect_request(amd_request_h req)
+{
+ const char *req_type;
+
+ req_type = amd_request_get_request_type(req);
+ if (req_type && !strcmp(req_type, "indirect-request"))
+ return true;
+
+ return false;
+}
+
+static int __check_org_caller(bundle *b,
+ const char *org_caller_appid, uid_t org_caller_uid)
+{
+ amd_appinfo_h appinfo;
+ const char *org_caller_pkgid;
+ const char *pkgid;
+
+ appinfo = amd_appinfo_find(org_caller_uid, org_caller_appid);
+ if (!appinfo) {
+ _E("Failed to find appinfo(%s:%u)",
+ org_caller_appid, org_caller_uid);
+ return -1;
+ }
+
+ pkgid = amd_appinfo_get_value(appinfo, AMD_AIT_PKGID);
+ if (!pkgid) {
+ _E("Critical error!");
+ return -1;
+ }
+
+ org_caller_pkgid = bundle_get_val(b, AUL_K_ORG_CALLER_PKGID);
+ if (!org_caller_pkgid) {
+ _E("Failed to get pkgid");
+ return -1;
+ }
+
+ if (strcmp(pkgid, org_caller_pkgid) != 0) {
+ _E("%s is not equal to %s", org_caller_pkgid, pkgid);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __get_org_caller_info_from_bundle(bundle *b,
+ struct caller_info *info)
+{
+ int r;
+ const char *str;
+
+ str = bundle_get_val(b, AUL_K_ORG_CALLER_APPID);
+ if (!str) {
+ _E("Failed to get org caller appid");
+ return -1;
+ }
+
+ info->appid = strdup(str);
+ if (!info->appid) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ str = bundle_get_val(b, AUL_K_ORG_CALLER_UID);
+ if (!str) {
+ _E("Failed to get org caller uid");
+ return -1;
+ }
+
+ info->uid = strtoul(str, NULL, 10);
+
+ r = __check_org_caller(b, info->appid, info->uid);
+ if (r < 0)
+ return -1;
+
+ info->offline = true;
+ _D("Orginal caller(%s:%u)", info->appid, info->uid);
+
+ return 0;
+}
+
+static struct caller_info *__create_caller_info(amd_request_h req,
+ amd_cynara_response_cb callback)
+{
+ int r;
+ struct caller_info *info;
+ bundle *b;
+
+ info = calloc(1, sizeof(*info));
+ if (info == NULL) {
+ _E("insufficient memory");
+ return NULL;
+ }
+
+ if (__is_indirect_request(req)) {
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ __destroy_caller_info(info);
+ return NULL;
+ }
+
+ r = __get_org_caller_info_from_bundle(b, info);
+ if (r < 0) {
+ _E("Failed to get org caller info");
+ __destroy_caller_info(info);
+ return NULL;
+ }
+ } else {
+ r = __get_caller_info_from_cynara(amd_request_get_fd(req),
+ info);
+ if (r < 0) {
+ _E("Failed to get caller info");
+ __destroy_caller_info(info);
+ return NULL;
+ }
+ }
+
+ info->callback = callback;
+ info->user_data = req;
+
+ info->id_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, free);
+
+ return info;
+}
+
+static int __cynara_check_privilege(amd_request_h req, amd_cynara_response_cb callback)
+{
+ int r;
+ struct caller_info *info;
+
+ if (!__has_checker(req)) {
+ _D("No proper checker. Skip checking privileges (cmd = %d)",
+ amd_request_get_cmd(req));
+ return AMD_CYNARA_RET_ALLOWED;
+ }
+
+ if (__is_indirect_request(req)) {
+ r = __verify_caller_process(req);
+ if (r != 0)
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ info = __create_caller_info(req, callback);
+ if (info == NULL)
+ return -1;
+
+ r = __check_privilege_by_checker(req, info);
+
+ if (r != AMD_CYNARA_RET_UNKNOWN)
+ __destroy_caller_info(info);
+
+ return r;
+}
+
+static int __check_privilege_offline(const char *appid, const char *privilege,
+ uid_t uid)
+{
+ int priv_ret;
+ int ret;
+
+ ret = security_manager_app_has_privilege(appid, privilege,
+ uid, &priv_ret);
+ if (ret < 0) {
+ _E("failed to check privilege (%d)", ret);
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ if (priv_ret != 1)
+ return AMD_CYNARA_RET_DENIED;
+
+ return AMD_CYNARA_RET_ALLOWED;
+}
+
+static int __cynara_check_privilege_offline(amd_request_h req,
+ const char *appid, const char *privilege)
+{
+ return __check_privilege_offline(appid, privilege,
+ amd_request_get_target_uid(req));
+}
+
+static gboolean __proc_cb(gint fd, GIOCondition cond, gpointer data)
+{
+ int ret;
+
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ cynara_fd_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ ret = cynara_async_process(r_cynara);
+ if (ret != CYNARA_API_SUCCESS)
+ _E("process error %d", ret);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void __status_cb(int old_fd, int new_fd, cynara_async_status status,
+ void *data)
+{
+ if (old_fd != -1) {
+ if (cynara_fd_id) {
+ g_source_remove(cynara_fd_id);
+ cynara_fd_id = 0;
+ }
+ cynara_fd = -1;
+ }
+
+ if (new_fd != -1) {
+ GIOCondition cond;
+
+ cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ if (status == CYNARA_STATUS_FOR_RW)
+ cond |= G_IO_OUT;
+
+ cynara_fd_id = g_unix_fd_add(new_fd, cond, __proc_cb, data);
+ cynara_fd = new_fd;
+ }
+}
+
+static int __cynara_register_checkers(const amd_cynara_checker *checkers, int cnt)
+{
+ int i;
+ amd_cynara_checker *c;
+
+ if (cnt <= 0 || !__checker_table || !checkers)
+ return -1;
+
+ for (i = 0; i < cnt; i++) {
+ c = g_hash_table_lookup(__checker_table,
+ GINT_TO_POINTER(checkers[i].cmd));
+ if (c) {
+ if (checkers[i].priority <= c->priority)
+ continue;
+
+ g_hash_table_remove(__checker_table,
+ GINT_TO_POINTER(checkers[i].cmd));
+ }
+
+ g_hash_table_insert(__checker_table,
+ GINT_TO_POINTER(checkers[i].cmd),
+ (gpointer)(&checkers[i]));
+ }
+
+ return 0;
+}
+
+static const char *__cynara_caller_info_get_client(amd_cynara_caller_info_h info)
+{
+ if (!info)
+ return NULL;
+
+ return info->client;
+}
+
+static int __cynara_sub_checker_add(const char *name, amd_cynara_sub_checker_func func)
+{
+ cynara_sub_checker *c;
+
+ if (!name || !func)
+ return -1;
+
+ c = calloc(1, sizeof(cynara_sub_checker));
+ if (!c)
+ return -1;
+
+ c->name = strdup(name);
+ c->checker = func;
+
+ if (!(c->name)) {
+ free(c);
+ return -1;
+ }
+
+ __sub_checkers = g_list_append(__sub_checkers, c);
+
+ return 0;
+}
+
+static int __cynara_sub_checker_check(const char *name, amd_cynara_caller_info_h info, amd_request_h req)
+{
+ GList *i = __sub_checkers;
+ cynara_sub_checker *c;
+ int ret;
+
+ if (!name || !info || !req)
+ return AMD_CYNARA_RET_ERROR;
+
+ while (i) {
+ c = i->data;
+ if (!strcmp(name, c->name)) {
+ ret = c->checker(info, req);
+ if (ret != AMD_CYNARA_RET_CONTINUE)
+ return ret;
+ }
+
+ i = g_list_next(i);
+ }
+
+ return AMD_CYNARA_RET_CONTINUE;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int ret;
+
+ _D("Cynara-core init");
+ ret = cynara_async_initialize(&r_cynara, NULL, __status_cb, NULL);
+ if (ret != CYNARA_API_SUCCESS) {
+ _E("cynara initialize failed. %d", ret);
+ return ret;
+ }
+
+ __checker_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, NULL);
+
+ amd_cynara_ops ops = {
+ .register_checkers = __cynara_register_checkers,
+ .sub_checker_add = __cynara_sub_checker_add,
+ .sub_checker_check = __cynara_sub_checker_check,
+ .check_async = __cynara_check_privilege,
+ .check = __cynara_simple_checker,
+ .check_offline = __cynara_check_privilege_offline
+ };
+
+ amd_cynara_caller_info_ops ci_ops = {
+ .get_client = __cynara_caller_info_get_client
+ };
+
+ return amd_cynara_register_ops(ops, ci_ops);
+}
+
+static void __free_sub_checker(gpointer data)
+{
+ cynara_sub_checker *c = data;
+
+ free(c->name);
+ free(c);
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("Cynara-core fini");
+ if (r_cynara == NULL)
+ return;
+
+ if (cynara_fd_id) {
+ g_source_remove(cynara_fd_id);
+ cynara_fd_id = 0;
+ }
+
+ cynara_async_finish(r_cynara);
+ r_cynara = NULL;
+ cynara_fd = -1;
+
+ if (__checker_table) {
+ g_hash_table_destroy(__checker_table);
+ __checker_table = NULL;
+ }
+
+ if (__sub_checkers) {
+ g_list_free_full(__sub_checkers, __free_sub_checker);
+ __sub_checkers = NULL;
+ }
+}
+
+
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_EXTRACTOR_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_EXTRACTOR} ${AMD_MOD_EXTRACTOR_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_EXTRACTOR} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_EXTRACTOR} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_EXTRACTOR} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ LIBTZPLATFORM_CONFIG_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_EXTRACTOR} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <aul.h>
+#include <bundle_internal.h>
+#include <tzplatform_config.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_EXTRACTOR"
+
+#define PATH_APP_ROOT tzplatform_getenv(TZ_USER_APP)
+#define PATH_GLOBAL_APP_RO_ROOT tzplatform_getenv(TZ_SYS_RO_APP)
+#define PATH_GLOBAL_APP_RW_ROOT tzplatform_getenv(TZ_SYS_RW_APP)
+
+typedef char **(_extractor_mountable)(const amd_appinfo_h ai);
+
+static GHashTable *mount_point_hash;
+
+static char **__extractor_mountable_get_tep_paths(const amd_appinfo_h ai)
+{
+ char tep_path[PATH_MAX];
+ char **mnt_path;
+ const char *tep_name;
+ const char *root_path;
+
+ if (ai == NULL)
+ return NULL;
+
+ tep_name = amd_appinfo_get_value(ai, AMD_AIT_TEP);
+ if (tep_name == NULL)
+ return NULL;
+
+ mnt_path = (char **)malloc(sizeof(char *) * 2);
+ if (mnt_path == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ mnt_path[1] = strdup(tep_name);
+ if (mnt_path[1] == NULL) {
+ _E("Out of memory");
+ free(mnt_path);
+ return NULL;
+ }
+
+ root_path = amd_appinfo_get_value(ai, AMD_AIT_ROOT_PATH);
+ snprintf(tep_path, PATH_MAX, "%s/tep/mount", root_path);
+ mnt_path[0] = strdup(tep_path);
+ if (mnt_path[0] == NULL) {
+ _E("Out of memory");
+ free(mnt_path[1]);
+ free(mnt_path);
+ return NULL;
+ }
+
+ return mnt_path;
+}
+
+static char **__extractor_mountable_get_tpk_paths(const amd_appinfo_h ai)
+{
+ char mount_point[PATH_MAX];
+ char **mnt_path;
+ const char *tpk;
+ const char *root_path;
+
+ if (ai == NULL)
+ return NULL;
+
+ tpk = amd_appinfo_get_value(ai, AMD_AIT_MOUNTABLE_PKG);
+ if (tpk == NULL)
+ return NULL;
+
+ mnt_path = (char **)malloc(sizeof(char *) * 2);
+ if (mnt_path == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ mnt_path[1] = strdup(tpk);
+ if (mnt_path[1] == NULL) {
+ _E("Out of memory");
+ free(mnt_path);
+ return NULL;
+ }
+ root_path = amd_appinfo_get_value(ai, AMD_AIT_ROOT_PATH);
+ snprintf(mount_point, PATH_MAX, "%s/.pkg", root_path);
+ mnt_path[0] = strdup(mount_point);
+ if (mnt_path[0] == NULL) {
+ free(mnt_path[1]);
+ free(mnt_path);
+ return NULL;
+ }
+
+ return mnt_path;
+}
+
+static void __free_path(char **path, int cnt)
+{
+ int i;
+
+ if (path == NULL)
+ return;
+
+ for (i = 0; i < cnt; i++) {
+ if (path[i])
+ free(path[i]);
+ }
+ free(path);
+}
+
+static void __free_set(gpointer data)
+{
+ g_hash_table_destroy((GHashTable *)data);
+}
+
+static void __prepare_map(void)
+{
+ if (mount_point_hash == NULL) {
+ mount_point_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, free, __free_set);
+ }
+}
+
+static void __put_mount_path(const amd_appinfo_h ai, const char *str)
+{
+ const char *appid;
+ GHashTable *set;
+
+ __prepare_map();
+ set = g_hash_table_lookup(mount_point_hash, str);
+ if (set == NULL) {
+ set = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, NULL);
+ if (set == NULL)
+ return;
+ g_hash_table_insert(mount_point_hash, strdup(str), set);
+ }
+
+ appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+ g_hash_table_insert(set, strdup(appid), NULL);
+}
+
+static bool __is_unmountable(const char *appid, const char *key)
+{
+ GHashTable *set;
+
+ if (amd_app_status_get_process_cnt(appid) > 1)
+ return false;
+
+ __prepare_map();
+ set = g_hash_table_lookup(mount_point_hash, key);
+
+ if (set == NULL)
+ return false;
+
+ g_hash_table_remove(set, appid);
+ if (g_hash_table_size(set) > 0)
+ return false;
+
+ return true;
+}
+
+static void __extractor_mount(const amd_appinfo_h ai, bundle *kb,
+ _extractor_mountable mountable)
+{
+ int ret;
+ const char **array = NULL;
+ int len = 0;
+ const char *default_array[1] = { NULL };
+ char **new_array = NULL;
+ int i;
+ bool dup = false;
+ const char *pkgid = NULL;
+ char **mnt_path;
+
+ mnt_path = mountable(ai);
+ if (mnt_path == NULL)
+ return;
+
+ if (!mnt_path[0] || !mnt_path[1]) {
+ __free_path(mnt_path, 2);
+ return;
+ }
+
+ array = bundle_get_str_array(kb, AUL_K_TEP_PATH, &len);
+ if (array == NULL) {
+ default_array[0] = mnt_path[0];
+ bundle_add_str_array(kb, AUL_K_TEP_PATH,
+ default_array, 1);
+ } else {
+ for (i = 0; i < len; i++) {
+ if (strcmp(mnt_path[0], array[i]) == 0) {
+ dup = true;
+ break;
+ }
+ }
+
+ if (!dup) {
+ new_array = calloc(len + 1, sizeof(char *));
+ if (new_array == NULL) {
+ _E("out of memory");
+ __free_path(mnt_path, 2);
+ return;
+ }
+
+ for (i = 0; i < len; i++) {
+ new_array[i] = strdup(array[i]);
+ if (new_array[i] == NULL) {
+ _E("Out of memory");
+ __free_path(new_array, i);
+ return;
+ }
+ }
+ new_array[len] = strdup(mnt_path[0]);
+ if (new_array[len] == NULL) {
+ _E("Out of memory");
+ __free_path(new_array, len);
+ return;
+ }
+ bundle_del(kb, AUL_K_TEP_PATH);
+ bundle_add_str_array(kb, AUL_K_TEP_PATH,
+ (const char **)new_array, len + 1);
+ __free_path(new_array, len + 1);
+ }
+ }
+
+ __put_mount_path(ai, mnt_path[0]);
+ ret = aul_is_tep_mount_dbus_done(mnt_path[0]);
+ if (ret != 1) {
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ ret = amd_signal_send_tep_mount(mnt_path, pkgid);
+ if (ret < 0) {
+ _E("dbus error %d", ret);
+ } else {
+ _D("Mount request was sent %s %s",
+ mnt_path[0], mnt_path[1]);
+ }
+ }
+
+ __free_path(mnt_path, 2);
+}
+
+static void __extractor_unmount(int pid, _extractor_mountable mountable)
+{
+ const char *appid;
+ amd_appinfo_h ai;
+ int ret;
+ char **mnt_path;
+ amd_app_status_h app_status;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL)
+ return;
+
+ uid = amd_app_status_get_uid(app_status);
+ appid = amd_app_status_get_appid(app_status);
+ if (appid == NULL)
+ return;
+
+ ai = amd_appinfo_find(uid, appid);
+ if (ai == NULL)
+ return;
+
+ mnt_path = mountable(ai);
+ if (mnt_path == NULL)
+ return;
+
+ if (!__is_unmountable(appid, mnt_path[0]))
+ return;
+
+ g_hash_table_remove(mount_point_hash, mnt_path[0]);
+ ret = amd_signal_send_tep_unmount(mnt_path[0]);
+ if (ret < 0)
+ _E("Failed to send unmount: %s", mnt_path[0]);
+ else
+ _D("Unmount request was sent %s", mnt_path[0]);
+
+ __free_path(mnt_path, 2);
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+ int pid;
+
+ pid = amd_app_status_get_pid(app_status);
+ __extractor_unmount(pid, __extractor_mountable_get_tep_paths);
+ __extractor_unmount(pid, __extractor_mountable_get_tpk_paths);
+
+ return 0;
+}
+
+static int __on_launch_prepared(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ const amd_appinfo_h info = arg3;
+
+ __extractor_mount(info, data, __extractor_mountable_get_tep_paths);
+ __extractor_mount(info, data, __extractor_mountable_get_tpk_paths);
+
+ return 0;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("extractor init");
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
+ __on_launch_prepared);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("extractor fini");
+}
+
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_INPUT_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_INPUT} ${AMD_MOD_INPUT_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_INPUT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_INPUT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_INPUT} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_INPUT} PUBLIC
+ AUL_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ TIZEN_EXTENSION_CLIENT_DEPS
+ WAYLAND_CLIENT_DEPS
+ WAYLAND_TBM_CLIENT_DEPS
+ XKBCOMMON_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_INPUT} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/conf/amd_input.conf DESTINATION
+ ${AMD_MODULES_DIR}/conf)
--- /dev/null
+[Setting]
+# Input lock timeout interval: 1 sec
+InputLockTimeout=1000
--- /dev/null
+/*
+ * Copyright (c) 2018 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_INPUT_CONFIG_H__
+#define __AMD_INPUT_CONFIG_H__
+
+int _input_config_init(void);
+
+void _input_config_fini(void);
+
+unsigned int _input_config_get_timeout_interval(void);
+
+#endif /* __AMD_INPUT_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "AMD_INPUT"
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdbool.h>
+#include <malloc.h>
+#include <sys/mman.h>
+
+#include <glib.h>
+#include <wayland-client.h>
+#include <tizen-extension-client-protocol.h>
+#include <xkbcommon/xkbcommon.h>
+#include <aul.h>
+#include <amd.h>
+
+#include "amd_input_config.h"
+#include "amd_input_private.h"
+
+static bool locked;
+static bool init_done;
+static guint timer;
+static unsigned int timeout_val;
+static int latest_pid;
+static struct tizen_keyrouter *keyrouter;
+static struct tizen_input_device_manager *input_devmgr;
+static struct wl_display *display;
+static struct wl_seat *seat;
+static guint sid;
+
+struct xkb_context *g_ctx;
+struct xkb_keymap *g_keymap;
+struct wl_keyboard *keyboard;
+static uint32_t keyrouter_id;
+static uint32_t input_devmgr_id;
+static uint32_t seat_id;
+
+typedef struct _keycode_map {
+ xkb_keysym_t keysym;
+ xkb_keycode_t *keycodes;
+ int nkeycodes;
+} keycode_map;
+
+static int __input_lock(void);
+static int __input_unlock(void);
+
+#define TIZEN_FEATURE_BLOCK_INPUT \
+ (!(amd_config_get_tizen_profile() & \
+ (AMD_TIZEN_PROFILE_TV | AMD_TIZEN_PROFILE_IVI)))
+
+static void __keyboard_keymap(void *data, struct wl_keyboard *keyboard,
+ uint32_t format, int fd, uint32_t size)
+{
+ char *map = NULL;
+
+ LOGD("format=%d, fd=%d, size=%d", format, fd, size);
+ if (!g_ctx) {
+ LOGE("This client failed to make xkb context");
+ close(fd);
+ return;
+ }
+
+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
+ LOGE("Invaild format: %d", format);
+ close(fd);
+ return;
+ }
+
+ map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+ if (map == MAP_FAILED) {
+ LOGE("Failed to mmap from fd(%d) size(%d)", fd, size);
+ close(fd);
+ return;
+ }
+
+ if (g_keymap)
+ xkb_map_unref(g_keymap);
+
+ g_keymap = xkb_map_new_from_string(g_ctx, map,
+ XKB_KEYMAP_FORMAT_TEXT_V1, 0);
+ munmap(map, size);
+ if (!g_keymap)
+ LOGE("Failed to get keymap from fd(%d)", fd);
+ close(fd);
+}
+
+static void __keyboard_enter(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys)
+{
+ LOGD("serial=%d", serial);
+}
+
+static void __keyboard_leave(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface)
+{
+ LOGD("serial=%d", serial);
+}
+
+static void __keyboard_key(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w)
+{
+ LOGD("serial=%d, time=%d, key=%d, state_w=%d",
+ serial, time, key, state_w);
+}
+
+static void __keyboard_modifiers(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
+ uint32_t mods_locked, uint32_t group)
+{
+ LOGD("serial=%d, mods_depressed=%d, mods_latched=%d mods_locked=%d, " \
+ "group=%d", serial, mods_depressed, mods_latched,
+ mods_locked, group);
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ .keymap = __keyboard_keymap,
+ .enter = __keyboard_enter,
+ .leave = __keyboard_leave,
+ .key = __keyboard_key,
+ .modifiers = __keyboard_modifiers
+};
+
+static gboolean __timeout_handler(void *data)
+{
+ timer = 0;
+ __input_unlock();
+ return FALSE;
+}
+
+static void __find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key,
+ void *data)
+{
+ keycode_map *found_keycodes = (keycode_map *)data;
+ xkb_keysym_t keysym = found_keycodes->keysym;
+ int nsyms = 0;
+ const xkb_keysym_t *syms_out = NULL;
+ xkb_keycode_t *keycodes;
+
+ nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
+ if (nsyms && syms_out && *syms_out == keysym) {
+ found_keycodes->nkeycodes++;
+ keycodes = realloc(found_keycodes->keycodes,
+ sizeof(int) * found_keycodes->nkeycodes);
+ if (keycodes == NULL) {
+ LOGE("Failed to reallocate the keycodes");
+ found_keycodes->nkeycodes--;
+ return;
+ }
+ found_keycodes->keycodes = keycodes;
+ found_keycodes->keycodes[found_keycodes->nkeycodes - 1] = key;
+ }
+}
+
+static int __xkb_keycode_from_keysym(struct xkb_keymap *keymap,
+ xkb_keysym_t keysym, xkb_keycode_t **keycodes)
+{
+ keycode_map found_keycodes = {0,};
+
+ found_keycodes.keysym = keysym;
+ xkb_keymap_key_for_each(g_keymap, __find_keycode, &found_keycodes);
+ *keycodes = found_keycodes.keycodes;
+
+ return found_keycodes.nkeycodes;
+}
+
+static void __keygrab_request(struct tizen_keyrouter *tizen_keyrouter,
+ struct wl_surface *surface, uint32_t key, uint32_t mode)
+{
+ tizen_keyrouter_set_keygrab(tizen_keyrouter, surface, key, mode);
+ LOGD("request set_keygrab (key:%d, mode:%d)!", key, mode);
+}
+
+static void __keyungrab_request(struct tizen_keyrouter *tizen_keyrouter,
+ struct wl_surface *surface, uint32_t key)
+{
+ tizen_keyrouter_unset_keygrab(tizen_keyrouter, surface, key);
+ LOGD("request unset_keygrab (key:%d)!", key);
+}
+
+static void __do_keygrab(const char *keyname, uint32_t mode)
+{
+ xkb_keysym_t keysym = 0x0;
+ int nkeycodes = 0;
+ xkb_keycode_t *keycodes = NULL;
+ int i;
+
+ keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
+ nkeycodes = __xkb_keycode_from_keysym(g_keymap, keysym, &keycodes);
+
+ for (i = 0; i < nkeycodes; i++) {
+ LOGD("%s's keycode is %d (nkeycode: %d)",
+ keyname, keycodes[i], nkeycodes);
+ __keygrab_request(keyrouter, NULL, keycodes[i], mode);
+ }
+ free(keycodes);
+ keycodes = NULL;
+}
+
+static void __do_keyungrab(const char *keyname)
+{
+ xkb_keysym_t keysym = 0x0;
+ int nkeycodes = 0;
+ xkb_keycode_t *keycodes = NULL;
+ int i;
+
+ keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
+ nkeycodes = __xkb_keycode_from_keysym(g_keymap, keysym, &keycodes);
+
+ for (i = 0; i < nkeycodes; i++) {
+ LOGD("%s's keycode is %d (nkeycode: %d)\n",
+ keyname, keycodes[i], nkeycodes);
+ __keyungrab_request(keyrouter, NULL, keycodes[i]);
+ }
+ free(keycodes);
+ keycodes = NULL;
+}
+
+static int __xkb_init(void)
+{
+ if (!g_ctx) {
+ g_ctx = xkb_context_new(0);
+ if (!g_ctx) {
+ LOGE("Failed to get xkb_context");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void __xkb_fini(void)
+{
+ if (g_ctx) {
+ xkb_context_unref(g_ctx);
+ g_ctx = NULL;
+ }
+}
+
+static void __input_device_info(void *data,
+ struct tizen_input_device *tizen_input_device,
+ const char *name, uint32_t class, uint32_t subclass,
+ struct wl_array *axes)
+{
+ LOGD("device info - name: %s, class: %d, subclass: %d",
+ name, class, subclass);
+}
+
+static void __input_device_event_device(void *data,
+ struct tizen_input_device *tizen_input_device,
+ unsigned int serial, const char *name, uint32_t time)
+{
+ LOGD("event device - name: %s, time: %d", name, time);
+}
+
+static void __input_device_axis(void *data,
+ struct tizen_input_device *tizen_input_device,
+ uint32_t axis_type, wl_fixed_t value)
+{
+ LOGD("axis - axis_type: %d, value: %lf",
+ axis_type, wl_fixed_to_double(value));
+}
+
+static const struct tizen_input_device_listener input_device_listener = {
+ __input_device_info,
+ __input_device_event_device,
+ __input_device_axis,
+};
+
+static void __cb_device_add(void *data,
+ struct tizen_input_device_manager *tizen_input_device_manager,
+ uint32_t serial, const char *name,
+ struct tizen_input_device *device, struct wl_seat *seat)
+{
+ LOGD("%s device is added!", name);
+ tizen_input_device_add_listener(device, &input_device_listener, NULL);
+}
+
+static void __cb_device_remove(void *data,
+ struct tizen_input_device_manager *tizen_input_device_manager,
+ uint32_t serial, const char *name,
+ struct tizen_input_device *device, struct wl_seat *seat)
+{
+ LOGD("%s device is removed!", name);
+ tizen_input_device_release(device);
+}
+
+static void __cb_error(void *data,
+ struct tizen_input_device_manager *tizen_input_device_manager,
+ uint32_t errorcode)
+{
+ LOGE("error: %d", errorcode);
+}
+
+static void __cb_block_expired(void *data,
+ struct tizen_input_device_manager *tizen_input_device_manager)
+{
+ LOGD("block expired");
+}
+
+static struct tizen_input_device_manager_listener input_devmgr_listener = {
+ __cb_device_add,
+ __cb_device_remove,
+ __cb_error,
+ __cb_block_expired
+};
+
+static int __on_lock(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+ int status;
+ int caller_pid = arg2;
+ amd_app_status_h caller_app_status;
+ int caller_app_type;
+
+ if (TIZEN_FEATURE_BLOCK_INPUT) {
+ caller_app_status = amd_app_status_find_by_pid(caller_pid);
+ if (!caller_app_status)
+ return 0;
+
+ caller_app_type = amd_app_status_get_app_type(
+ caller_app_status);
+ if (caller_app_type == AMD_AT_SERVICE_APP)
+ return 0;
+
+ status = amd_app_status_get_status(app_status);
+ if (status != STATUS_VISIBLE && !arg1)
+ __input_lock();
+ }
+
+ return 0;
+}
+
+static int __on_unlock(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ int status = arg1;
+ int pid = amd_app_status_get_pid(app_status);
+
+ if (TIZEN_FEATURE_BLOCK_INPUT) {
+ if (latest_pid == pid && status == STATUS_VISIBLE)
+ __input_unlock();
+ }
+
+ return 0;
+}
+
+static int __on_launch_complete(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comptype;
+
+ comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comptype && !strcmp(comptype, APP_TYPE_UI))
+ latest_pid = arg1;
+
+ return 0;
+}
+
+static int __on_registry_handler(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+ struct wl_registry *registry = (struct wl_registry *)arg3;
+
+ if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER)) {
+ if (!input_devmgr) {
+ input_devmgr_id = id;
+ input_devmgr = wl_registry_bind(registry, id,
+ &tizen_input_device_manager_interface,
+ 2);
+ LOGD("input_devmgr(%p)", input_devmgr);
+ if (tizen_input_device_manager_add_listener(input_devmgr,
+ &input_devmgr_listener, NULL) < 0) {
+ LOGE("Failed to add listener");
+ }
+ }
+ } else if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER)) {
+ if (!keyrouter) {
+ keyrouter_id = id;
+ keyrouter = wl_registry_bind(registry, id,
+ &tizen_keyrouter_interface, 1);
+ LOGD("keyrouter(%p)", keyrouter);
+ }
+ } else if (!strcmp(msg, AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT)) {
+ if (!seat) {
+ seat_id = id;
+ seat = wl_registry_bind(registry, id,
+ &wl_seat_interface, 1);
+ if (!seat)
+ return -1;
+
+ LOGD("seat(%p)", seat);
+ keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_add_listener(keyboard, &keyboard_listener,
+ NULL);
+ LOGD("keyboard(%p)", keyboard);
+ }
+ }
+
+ return 0;
+}
+
+static int __on_registry_remover(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+
+ if (id == keyrouter_id && keyrouter) {
+ tizen_keyrouter_destroy(keyrouter);
+ keyrouter = NULL;
+ keyrouter_id = 0;
+ LOGW("tizen keyrouter is destroyed");
+ }
+
+ if (id == input_devmgr_id && input_devmgr) {
+ tizen_input_device_manager_destroy(input_devmgr);
+ input_devmgr = NULL;
+ input_devmgr_id = 0;
+ LOGW("tizen input device manager is destroyed");
+ }
+
+ if (id == seat_id && seat) {
+ if (keyboard) {
+ wl_keyboard_destroy(keyboard);
+ keyboard = NULL;
+ }
+
+ wl_seat_destroy(seat);
+ seat = NULL;
+ seat_id = 0;
+ LOGW("wl seat is destroyed");
+ }
+
+ return 0;
+}
+
+static int __input_init(void)
+{
+ if (!display) {
+ display = amd_wayland_get_display();
+ if (!display) {
+ LOGD("Failed to connect to wayland compositor");
+ return -1;
+ }
+ }
+
+ if (__xkb_init() < 0)
+ return -1;
+
+ LOGD("Connected to wayland compositor!");
+
+ if (input_devmgr == NULL) {
+ LOGE("input_devmgr is null");
+ return -1;
+ }
+
+ if (keyrouter == NULL) {
+ LOGE("keyrouter is null");
+ return -1;
+ }
+
+ if (seat == NULL) {
+ LOGE("seat is null");
+ return -1;
+ }
+
+ if (keyboard == NULL) {
+ LOGE("keyboard is null");
+ return -1;
+ }
+
+ wl_display_flush(display);
+ wl_display_roundtrip(display);
+
+ if (g_keymap == NULL) {
+ LOGE("g_keymap is null");
+ return -1;
+ }
+
+ init_done = true;
+
+ return 0;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ LOGD("input init");
+
+ _input_config_init();
+ timeout_val = _input_config_get_timeout_interval();
+
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER,
+ __on_registry_handler);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_KEYROUTER,
+ __on_registry_handler);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_WL_SEAT,
+ __on_registry_handler);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
+ __on_registry_remover);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_START,
+ __on_unlock);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_FAIL,
+ __on_unlock);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_END,
+ __on_lock);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ __on_launch_complete);
+ __xkb_init();
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ __xkb_fini();
+ if (sid > 0) {
+ g_source_remove(sid);
+ sid = 0;
+ }
+ _input_config_fini();
+}
+
+static int __input_lock(void)
+{
+ if (locked)
+ __input_unlock();
+
+ if (!init_done && __input_init() < 0)
+ return -1;
+
+ LOGD("call tizen_input_device_manager_block_events");
+ tizen_input_device_manager_block_events(input_devmgr, 0,
+ TIZEN_INPUT_DEVICE_MANAGER_CLAS_TOUCHSCREEN |
+ TIZEN_INPUT_DEVICE_MANAGER_CLAS_MOUSE, timeout_val);
+ timer = g_timeout_add(timeout_val, __timeout_handler, NULL);
+ __do_keygrab("XF86Back", TIZEN_KEYROUTER_MODE_EXCLUSIVE);
+ wl_display_roundtrip(display);
+
+ locked = true;
+
+ return 0;
+}
+
+static int __input_unlock(void)
+{
+ if (!locked)
+ return 0;
+
+ if (!init_done && __input_init() < 0)
+ return -1;
+
+ LOGD("call tizen_input_device_manager_unblock_events");
+ tizen_input_device_manager_unblock_events(input_devmgr, 0);
+ __do_keyungrab("XF86Back");
+ wl_display_roundtrip(display);
+
+ locked = false;
+ if (timer > 0) {
+ g_source_remove(timer);
+ timer = 0;
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iniparser.h>
+
+#include "amd_input_config.h"
+#include "amd_input_private.h"
+
+#define CONFIG_PATH "/usr/share/amd/conf/amd_input.conf"
+#define CONFIG_SECTION_NAME "Setting"
+#define CONFIG_KEY_LOCK_TIMEOUT "InputLockTimeout"
+
+struct input_config_s {
+ unsigned int interval;
+};
+
+static struct input_config_s __config;
+
+static int __input_config_get_int(dictionary *d,
+ const char *section, const char *key)
+{
+ char buf[512];
+
+ snprintf(buf, sizeof(buf), "%s:%s", section, key);
+
+ return iniparser_getint(d, buf, -1);
+}
+
+static int __input_config_load(const char *path)
+{
+ dictionary *d;
+ int r;
+
+ r = access(path, R_OK);
+ if (r != 0) {
+ _E("Failed to access %s. errno(%d)", path, errno);
+ return -1;
+ }
+
+ d = iniparser_load(path);
+ if (!d) {
+ _E("Failed to load %s by iniparser", path);
+ return -1;
+ }
+
+ r = __input_config_get_int(d, CONFIG_SECTION_NAME,
+ CONFIG_KEY_LOCK_TIMEOUT);
+ if (r > 0) {
+ __config.interval = r;
+ _W("Interval: %u", __config.interval);
+ }
+
+ iniparser_freedict(d);
+
+ return 0;
+}
+
+unsigned int _input_config_get_timeout_interval(void)
+{
+ return __config.interval;
+}
+
+int _input_config_init(void)
+{
+ _D("Input config init");
+
+ __config.interval = 1000; /* 1 sec */
+
+ if (__input_config_load(CONFIG_PATH) < 0)
+ _W("Failed to load input config");
+
+ return 0;
+}
+
+void _input_config_fini(void)
+{
+ _D("Input config fini");
+ __config.interval = 0;
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_JOB_SCHEDULER_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_JOB_SCHEDULER} ${AMD_MOD_JOB_SCHEDULER_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_JOB_SCHEDULER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_JOB_SCHEDULER} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_JOB_SCHEDULER} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_JOB_SCHEDULER} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_job_scheduler.h>
+#include <bundle_internal.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_JOB_SCHEDULER"
+
+struct job_s {
+ char *id;
+ pid_t pid;
+ guint timer;
+};
+
+static GHashTable *__job_table;
+
+static int __remove_job(const char *id, pid_t pid);
+
+static void __destroy_job(gpointer data)
+{
+ struct job_s *job = (struct job_s *)data;
+
+ if (job == NULL)
+ return;
+
+ if (job->timer)
+ g_source_remove(job->timer);
+
+ if (job->id)
+ free(job->id);
+
+ free(job);
+}
+
+static gboolean __job_timeout_handler(gpointer data)
+{
+ struct job_s *job = (struct job_s *)data;
+
+ _D("job_id(%s), pid(%d)", job->id, job->pid);
+ job->timer = 0;
+ __remove_job(job->id, job->pid);
+
+ return G_SOURCE_REMOVE;
+}
+
+static struct job_s *__create_job(const char *id, pid_t pid)
+{
+ struct job_s *job;
+
+ job = malloc(sizeof(struct job_s));
+ if (job == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ job->id = strdup(id);
+ if (job->id == NULL) {
+ _E("Out of memory");
+ free(job);
+ return NULL;
+ }
+
+ job->timer = g_timeout_add(5000, __job_timeout_handler, job);
+ if (job->timer == 0) {
+ _E("Failed to add timer");
+ free(job->id);
+ free(job);
+ return NULL;
+ }
+
+ job->pid = pid;
+
+ return job;
+}
+
+static struct job_s *__find_job(GList *list, const char *id)
+{
+ struct job_s *job;
+ GList *iter;
+
+ iter = list;
+ while (iter) {
+ job = (struct job_s *)iter->data;
+ if (strcmp(job->id, id) == 0)
+ return job;
+
+ iter = iter->next;
+ }
+
+ return NULL;
+}
+
+static int __add_job(const char *id, pid_t pid)
+{
+ struct job_s *job;
+ GList *list;
+
+ list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
+ if (list) {
+ job = __find_job(list, id);
+ if (job) {
+ if (job->timer)
+ g_source_remove(job->timer);
+
+ job->timer = g_timeout_add(5000, __job_timeout_handler,
+ job);
+ if (job->timer == 0)
+ return -1;
+ } else {
+ job = __create_job(id, pid);
+ if (job == NULL)
+ return -1;
+
+ list = g_list_append(list, job);
+ g_hash_table_replace(__job_table, GINT_TO_POINTER(pid),
+ list);
+ }
+ } else {
+ job = __create_job(id, pid);
+ if (job == NULL)
+ return -1;
+
+ list = g_list_append(list, job);
+ g_hash_table_insert(__job_table, GINT_TO_POINTER(pid), list);
+ }
+ amd_suspend_remove_timer(pid);
+
+ return 0;
+}
+
+static int __remove_job(const char *id, pid_t pid)
+{
+ struct job_s *job;
+ GList *list;
+ amd_app_status_h app_status;
+ int status;
+
+ list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
+ if (list == NULL)
+ return -1;
+
+ job = __find_job(list, id);
+ if (job == NULL)
+ return -1;
+
+ list = g_list_remove(list, job);
+ if (list == NULL) {
+ g_hash_table_remove(__job_table, GINT_TO_POINTER(pid));
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status) {
+ status = amd_app_status_get_status(app_status);
+ if (status != STATUS_DYING)
+ amd_suspend_add_timer(pid);
+ }
+ } else {
+ g_hash_table_replace(__job_table, GINT_TO_POINTER(pid), list);
+ }
+
+ __destroy_job(job);
+
+ return 0;
+}
+
+static int __remove_all_jobs(pid_t pid)
+{
+ GList *list;
+
+ list = (GList *)g_hash_table_lookup(__job_table, GINT_TO_POINTER(pid));
+ if (list == NULL)
+ return -1;
+
+ g_hash_table_remove(__job_table, GINT_TO_POINTER(pid));
+ g_list_free_full(list, __destroy_job);
+
+ return 0;
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ pid_t pid = amd_app_status_get_pid(app_status);
+
+ __remove_all_jobs(pid);
+
+ return 0;
+}
+
+static int __dispatch_job_status_update(amd_request_h req)
+{
+ bundle *b = amd_request_get_bundle(req);
+ pid_t pid = amd_request_get_pid(req);
+ const char *job_id;
+ const char *job_status_str;
+ aul_job_status_e job_status;
+ int r;
+
+ if (b == NULL) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ job_id = bundle_get_val(b, AUL_K_JOB_ID);
+ if (job_id == NULL) {
+ _E("Failed to get job - pid(%d)", pid);
+ return -1;
+ }
+
+ job_status_str = bundle_get_val(b, AUL_K_JOB_STATUS);
+ if (job_status_str == NULL) {
+ _E("Failed to get job(%s) status", job_id);
+ return -1;
+ }
+
+ if (!isdigit(*job_status_str)) {
+ _E("Invalid job(%s) status(%s)", job_id, job_status_str);
+ return -1;
+ }
+
+ job_status = strtoul(job_status_str, NULL, 10);
+ switch (job_status) {
+ case JOB_STATUS_START:
+ r = __add_job(job_id, pid);
+ if (r < 0) {
+ _E("Failed to add job(%s)", job_id);
+ return -1;
+ }
+ break;
+ case JOB_STATUS_STOPPED:
+ case JOB_STATUS_FINISHED:
+ r = __remove_job(job_id, pid);
+ if (r < 0) {
+ _W("Failed to remove job(%s)", job_id);
+ return -1;
+ }
+ break;
+ default:
+ _W("Unknown job status(%u)", job_status);
+ break;
+ }
+
+ _D("job_id(%s), job_status(%u), pid(%d)", job_id, job_status, pid);
+
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = JOB_STATUS_UPDATE,
+ .callback = __dispatch_job_status_update
+ },
+};
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ _D("job scheduler init");
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ __job_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (__job_table == NULL) {
+ _E("Failed to create job table");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+
+ return 0;
+}
+
+static gboolean __foreach_remove_cb(gpointer key, gpointer value,
+ gpointer data)
+{
+ pid_t pid = GPOINTER_TO_INT(key);
+ GList *list = (GList *)value;
+
+ _D("pid(%d)", pid);
+ g_list_free_full(list, __destroy_job);
+
+ return TRUE;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("job scheduler finish");
+
+ if (__job_table) {
+ g_hash_table_foreach_remove(__job_table, __foreach_remove_cb,
+ NULL);
+ g_hash_table_destroy(__job_table);
+ }
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_LAUNCHPAD_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_LAUNCHPAD} ${AMD_MOD_LAUNCHPAD_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_LAUNCHPAD} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_LAUNCHPAD} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_LAUNCHPAD} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_LAUNCHPAD} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ LIBSMACK_DEPS
+ LIBSYSTEMD_DEPS
+ LIBTZPLATFORM_CONFIG_DEPS
+ SECURITY_MANAGER_DEPS
+ TANCHOR_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_LAUNCHPAD} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2018 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 __LAUNCHER_INFO_H__
+#define __LAUNCHER_INFO_H__
+
+#include <glib.h>
+
+typedef struct launcher_info_s *launcher_info_h;
+
+GList *_launcher_info_load(const char *path);
+void _launcher_info_unload(GList *info);
+launcher_info_h _launcher_info_find(GList *info_list, const char *app_type);
+const char *_launcher_info_get_exe(launcher_info_h launcher_info);
+GList *_launcher_info_get_extra_args(launcher_info_h launcher_info);
+
+#endif /* __LAUNCHER_INFO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_LAUNCHPAD"
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+#include <amd_mod_common.h>
+
+#include "launcher_info.h"
+#include "launchpad_private.h"
+
+#define FREE_AND_NULL(x) do { \
+ if (x) { \
+ free(x); \
+ x = NULL; \
+ } \
+} while (0)
+
+#define TAG_LAUNCHER "[LAUNCHER]"
+#define TAG_NAME "NAME"
+#define TAG_EXE "EXE"
+#define TAG_APP_TYPE "APP_TYPE"
+#define TAG_EXTRA_ARG "EXTRA_ARG"
+
+struct launcher_info_s {
+ char *name;
+ char *exe;
+ GList *app_types;
+ GList *extra_args;
+};
+
+static struct launcher_info_s *__create_launcher_info(void)
+{
+ struct launcher_info_s *info;
+
+ info = calloc(1, sizeof(struct launcher_info_s));
+ if (info == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ return info;
+}
+
+static void __destroy_launcher_info(gpointer data)
+{
+ struct launcher_info_s *info = (struct launcher_info_s *)data;
+
+ if (info == NULL)
+ return;
+
+ if (info->extra_args)
+ g_list_free_full(info->extra_args, free);
+ if (info->app_types)
+ g_list_free_full(info->app_types, free);
+ if (info->exe)
+ free(info->exe);
+ if (info->name)
+ free(info->name);
+ free(info);
+}
+
+static void __parse_app_types(struct launcher_info_s *info, char *line)
+{
+ char *token;
+ char *saveptr = NULL;
+
+ token = strtok_r(line, " |\t\r\n", &saveptr);
+ while (token) {
+ info->app_types = g_list_append(info->app_types, strdup(token));
+ token = strtok_r(NULL, " |\t\r\n", &saveptr);
+ }
+}
+
+static GList *__parse_file(GList *list, const char *path)
+{
+ FILE *fp;
+ char buf[LINE_MAX];
+ char *tok1 = NULL;
+ char *tok2 = NULL;
+ struct launcher_info_s *info = NULL;
+
+ fp = fopen(path, "rt");
+ if (fp == NULL)
+ return list;
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ FREE_AND_NULL(tok1);
+ FREE_AND_NULL(tok2);
+ sscanf(buf, "%ms %ms", &tok1, &tok2);
+ if (tok1 && strcasecmp(TAG_LAUNCHER, tok1) == 0) {
+ if (info) {
+ _D("name: %s, exe: %s", info->name, info->exe);
+ list = g_list_append(list, info);
+ }
+
+ info = __create_launcher_info();
+ if (info == NULL)
+ break;
+
+ continue;
+ }
+
+ if (!tok1 || !tok2)
+ continue;
+ if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
+ continue;
+ if (info == NULL)
+ continue;
+
+ if (strcasecmp(TAG_NAME, tok1) == 0) {
+ info->name = strdup(tok2);
+ if (info->name == NULL) {
+ _E("Out of memory");
+ __destroy_launcher_info(info);
+ info = NULL;
+ break;
+ }
+ } else if (strcasecmp(TAG_EXE, tok1) == 0) {
+ info->exe = strdup(tok2);
+ if (info->exe == NULL) {
+ _E("Out of memory");
+ __destroy_launcher_info(info);
+ info = NULL;
+ break;
+ }
+ if (access(info->exe, F_OK | X_OK) != 0) {
+ _E("Failed to access %s", info->exe);
+ __destroy_launcher_info(info);
+ info = NULL;
+ }
+ } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
+ __parse_app_types(info, &buf[strlen(tok1)]);
+ if (info->app_types == NULL) {
+ _E("app_types is NULL");
+ __destroy_launcher_info(info);
+ info = NULL;
+ break;
+ }
+ } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) {
+ info->extra_args = g_list_append(info->extra_args,
+ strdup(tok2));
+ }
+ }
+ fclose(fp);
+
+ if (info) {
+ _D("name: %s, exe: %s", info->name, info->exe);
+ list = g_list_append(list, info);
+ }
+
+ if (tok1)
+ free(tok1);
+ if (tok2)
+ free(tok2);
+
+ return list;
+}
+
+GList *_launcher_info_load(const char *path)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ GList *list = NULL;
+ char buf[PATH_MAX];
+ char *ext;
+
+ if (path == NULL)
+ return NULL;
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return NULL;
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (dentry->d_name[0] == '.')
+ continue;
+
+ ext = strrchr(dentry->d_name, '.');
+ if (ext && strcmp(ext, ".launcher") == 0) {
+ snprintf(buf, sizeof(buf), "%s/%s",
+ path, dentry->d_name);
+ list = __parse_file(list, buf);
+ }
+ }
+ closedir(dp);
+
+ return list;
+}
+
+void _launcher_info_unload(GList *info)
+{
+ if (info == NULL)
+ return;
+
+ g_list_free_full(info, __destroy_launcher_info);
+}
+
+static int __comp_str(gconstpointer a, gconstpointer b)
+{
+ if (a == NULL || b == NULL)
+ return -1;
+
+ return strcmp(a, b);
+}
+
+static int __comp_app_type(gconstpointer a, gconstpointer b)
+{
+ struct launcher_info_s *info = (struct launcher_info_s *)a;
+
+ if (info == NULL || info->app_types == NULL || b == NULL)
+ return -1;
+
+ if (g_list_find_custom(info->app_types, b, __comp_str))
+ return 0;
+
+ return -1;
+}
+
+launcher_info_h _launcher_info_find(GList *info_list, const char *app_type)
+{
+ GList *list;
+
+ if (info_list == NULL || app_type == NULL)
+ return NULL;
+
+ list = g_list_find_custom(info_list, app_type, __comp_app_type);
+ if (list == NULL)
+ return NULL;
+
+ return (launcher_info_h)list->data;
+}
+
+const char *_launcher_info_get_exe(launcher_info_h info)
+{
+ if (info == NULL)
+ return NULL;
+
+ return info->exe;
+}
+
+GList *_launcher_info_get_extra_args(launcher_info_h info)
+{
+ if (info == NULL)
+ return NULL;
+
+ return info->extra_args;
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/signalfd.h>
+#include <sys/stat.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/smack.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <systemd/sd-journal.h>
+#include <amd.h>
+#include <bundle_internal.h>
+#include <security-manager.h>
+#include <tzplatform_config.h>
+#include <trust-anchor.h>
+#include <amd_mod_common.h>
+
+#include "launcher_info.h"
+#include "launchpad_private.h"
+
+#define AUL_K_EXEC "__AUL_EXEC__"
+#define AUL_K_APPID "__AUL_APPID__"
+#define AUL_K_STARTTIME "__AUL_STARTTIME__"
+#define AUL_K_HWACC "__AUL_HWACC__"
+#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__"
+#define AUL_K_PKGID "__AUL_PKGID_"
+#define AUL_K_PID "__AUL_PID__"
+#define AUL_K_ROOT_PATH "__AUL_ROOT_PATH__"
+#define AUL_K_API_VERSION "__AUL_API_VERSION__"
+#define AUL_K_APP_TYPE "__AUL_APP_TYPE__"
+#define AUL_K_IS_GLOBAL "__AUL_IS_GLOBAL__"
+
+#define FORMAT_DBUS_ADDRESS \
+ "kernel:path=/sys/fs/kdbus/%u-user/bus;unix:path=/run/user/%u/bus"
+#define AUL_DBUS_PATH "/aul/dbus_handler"
+#define AUL_DBUS_INTERFACE "org.tizen.aul.signal"
+#define AUL_DBUS_APP_LAUNCH_SIGNAL "app_launch"
+#define AUL_DBUS_APP_DEAD_SIGNAL "app_dead"
+
+#define ARG_PATH 0
+#define PATH_DEV_NULL "/dev/null"
+#define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
+#define APP_STARTUP_SIGNAL 89
+#define CONNECT_RETRY_COUNT 3
+#define CONNECT_RETRY_TIME (100 * 1000)
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+typedef struct _app_pkt_t {
+ int cmd;
+ int len;
+ int opt;
+ unsigned char data[1];
+} app_pkt_t;
+
+struct launch_arg {
+ const char *appid;
+ const char *app_path;
+ const char *pkgid;
+ const char *app_type;
+ const char *is_global;
+ bundle *b;
+};
+
+struct env_map {
+ const char *key;
+ const char *name;
+};
+
+struct app_arg {
+ int argc;
+ char **argv;
+};
+
+static struct env_map env_maps[] = {
+ { AUL_K_STARTTIME, "APP_START_TIME" },
+ { AUL_K_HWACC, "HWACC" },
+ { AUL_K_TASKMANAGE, "TASKMANAGE" },
+ { AUL_K_APPID, "AUL_APPID" },
+ { AUL_K_PKGID, "AUL_PKGID" },
+ { AUL_K_APP_TYPE, "RUNTIME_TYPE" },
+ { AUL_K_API_VERSION, "TIZEN_API_VERSION" },
+ { NULL, NULL },
+};
+
+static sigset_t old_mask;
+static guint sigchld_sid;
+static GDBusConnection *conn;
+static GList *launcher_info_list;
+
+static int __unlink_socket_path(int pid, uid_t uid);
+
+static int __send_signal(const char *path, const char *interface,
+ const char *signal, GVariant *param)
+{
+ GError *err = NULL;
+
+ if (!conn) {
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!conn) {
+ LOGE("Failed to get system bus - %s", err->message);
+ g_error_free(err);
+ return -1;
+ }
+ }
+
+ if (!g_dbus_connection_emit_signal(conn, NULL, path, interface,
+ signal, param, &err)) {
+ LOGE("Failed to emit signal(%s) - %s", signal, err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ if (!g_dbus_connection_flush_sync(conn, NULL, &err)) {
+ LOGE("Failed to flush connection - %s", err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __send_app_launch_signal(int pid, const char *appid)
+{
+ GVariant *param;
+ int r;
+
+ param = g_variant_new("(us)", pid, appid);
+ if (!param) {
+ LOGE("Out of memory");
+ return;
+ }
+
+ r = __send_signal(AUL_DBUS_PATH, AUL_DBUS_INTERFACE,
+ AUL_DBUS_APP_LAUNCH_SIGNAL, param);
+ if (r < 0)
+ return;
+
+ LOGD("Send app launch signal - pid(%d), appid(%s)", pid, appid);
+}
+
+static void __send_app_dead_signal(int pid)
+{
+ GVariant *param;
+ int r;
+
+ param = g_variant_new("(u)", pid);
+ if (!param) {
+ LOGE("Out of memory");
+ return;
+ }
+
+ r = __send_signal(AUL_DBUS_PATH, AUL_DBUS_INTERFACE,
+ AUL_DBUS_APP_DEAD_SIGNAL, param);
+ if (r < 0)
+ return;
+
+ LOGD("Send app dead signal - pid(%d)", pid);
+}
+
+static void __init_signal(void)
+{
+ int i;
+
+ for (i = 0; i < _NSIG; ++i) {
+ switch (i) {
+ case SIGQUIT:
+ case SIGILL:
+ case SIGABRT:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGPIPE:
+ break;
+ default:
+ signal(i, SIG_DFL);
+ break;
+ }
+ }
+}
+
+static void __finish_signal(void)
+{
+ int i;
+
+ for (i = 0; i < _NSIG; ++i)
+ signal(i, SIG_DFL);
+}
+
+static int __unblock_sigchld(void)
+{
+ if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0) {
+ LOGE("Failed to change blocked signal");
+ return -1;
+ }
+
+ LOGD("Unblock SIGCHLD");
+ return 0;
+}
+
+static void __process_sigchld(struct signalfd_siginfo *siginfo)
+{
+ int status;
+ pid_t child_pid;
+ pid_t child_pgid;
+
+ child_pgid = getpgid(siginfo->ssi_pid);
+ LOGD("pid(%d), pgid(%d), signo(%d), status(%d)",
+ siginfo->ssi_pid, child_pgid, siginfo->ssi_signo,
+ siginfo->ssi_status);
+
+ while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
+ if (child_pid == child_pgid)
+ killpg(child_pgid, SIGKILL);
+
+ __send_app_dead_signal(child_pid);
+ __unlink_socket_path(child_pid, siginfo->ssi_uid);
+ }
+}
+
+static gboolean __handle_sigchld(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ struct signalfd_siginfo siginfo;
+ ssize_t s;
+ int fd = g_io_channel_unix_get_fd(io);
+ amd_app_status_h app_status;
+ const char *appid;
+
+ do {
+ s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
+ if (s == 0)
+ break;
+
+ if (s != sizeof(struct signalfd_siginfo))
+ break;
+
+ __process_sigchld(&siginfo);
+ app_status = amd_app_status_find_by_pid(siginfo.ssi_pid);
+ if (app_status) {
+ appid = amd_app_status_get_appid(app_status);
+ security_manager_cleanup_app(appid, siginfo.ssi_uid, siginfo.ssi_pid);
+ }
+ } while (s > 0);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void __destroy_func(gpointer data)
+{
+ GIOChannel *io = (GIOChannel *)data;
+ gint fd;
+
+ if (!io)
+ return;
+
+ fd = g_io_channel_unix_get_fd(io);
+ if (fd > 0)
+ close(fd);
+
+ g_io_channel_unref(io);
+}
+
+static int __init_sigchld_fd(void)
+{
+ int fd;
+ sigset_t mask;
+ GIOChannel *io;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+
+ if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+ LOGE("Failed to change blocked signals");
+
+ fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
+ if (fd < 0) {
+ LOGE("Failed to create signalfd for SIGCHLD");
+ return -1;
+ }
+
+ io = g_io_channel_unix_new(fd);
+ if (!io) {
+ LOGE("Failed to create g io channel");
+ close(fd);
+ return 0;
+ }
+
+ sigchld_sid = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, G_IO_IN,
+ __handle_sigchld, io, __destroy_func);
+ if (sigchld_sid == 0) {
+ LOGE("Failed to add sigchld fd wacher");
+ g_io_channel_unref(io);
+ close(fd);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __set_user_group(void)
+{
+ uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+ gid_t gid = tzplatform_getgid(TZ_SYS_DEFAULT_USER);
+ const char *user;
+ int r;
+
+ user = tzplatform_getenv(TZ_SYS_DEFAULT_USER);
+ if (!user) {
+ LOGE("Failed to get env - TZ_SYS_DEFAULT_USER");
+ return;
+ }
+
+ r = initgroups(user, gid);
+ if (r != 0)
+ LOGE("Failed to initialize the supplementary group access list");
+
+ r = setregid(gid, gid);
+ if (r != 0)
+ LOGE("Failed to set real and effective group id");
+
+ r = setreuid(uid, uid);
+ if (r != 0)
+ LOGE("Failed to set real and effective user id");
+
+ tzplatform_set_user(uid);
+}
+
+static void __unlink_dir(const char *path)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ struct stat statbuf;
+ char buf[PATH_MAX];
+ int r;
+
+ dp = opendir(path);
+ if (!dp)
+ return;
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (!strcmp(dentry->d_name, ".") ||
+ !strcmp(dentry->d_name, ".."))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
+ r = stat(buf, &statbuf);
+ if (r == 0) {
+ if (S_ISDIR(statbuf.st_mode))
+ __unlink_dir(buf);
+ else
+ unlink(buf);
+ }
+ }
+
+ rmdir(path);
+ closedir(dp);
+}
+
+static int __unlink_socket_path(int pid, uid_t uid)
+{
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "/run/aul/apps/%d/%d", uid, pid);
+ if (access(path, F_OK) == 0)
+ __unlink_dir(path);
+
+ if (access(path, F_OK) == 0)
+ return -1;
+
+ return 0;
+}
+
+static void __redirect_stdio(const char *ident)
+{
+ int fd;
+
+ /* stdin */
+ fd = open(PATH_DEV_NULL, O_RDONLY | O_NOCTTY);
+ if (fd < 0) {
+ LOGW("Failed to open /dev/null - err(%d)", errno);
+ return;
+ }
+ if (dup2(fd, STDIN_FILENO) < 0) {
+ LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
+ fd, STDIN_FILENO);
+ }
+ close(fd);
+
+ /* stdout */
+ fd = sd_journal_stream_fd(ident, LOG_INFO, false);
+ if (fd < 0) {
+ LOGW("Failed to connect journal socket - err(%d)", errno);
+ fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
+ if (fd < 0) {
+ LOGW("Failed to open /dev/null - err(%d)", errno);
+ return;
+ }
+ }
+ if (dup2(fd, STDOUT_FILENO) < 0) {
+ LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
+ fd, STDOUT_FILENO);
+ }
+ close(fd);
+
+ /* stderr */
+ fd = sd_journal_stream_fd(ident, LOG_INFO, false);
+ if (fd < 0) {
+ LOGW("Failed to connect journal socket - err(%d)", errno);
+ fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
+ if (fd < 0) {
+ LOGW("Failed to open /dev/null - err(%d)", errno);
+ return;
+ }
+ }
+
+ if (dup2(fd, STDERR_FILENO) < 0) {
+ LOGW("Failed to duplicate fd - oldfd(%d), newfd(%d)",
+ fd, STDERR_FILENO);
+ }
+ close(fd);
+}
+
+static void __set_env(bundle *b)
+{
+ const char *val;
+ char buf[PATH_MAX];
+ int i;
+
+ for (i = 0; env_maps[i].key; ++i) {
+ val = bundle_get_val(b, env_maps[i].key);
+ if (val)
+ setenv(env_maps[i].name, val, 1);
+ }
+
+ val = bundle_get_val(b, AUL_K_ROOT_PATH);
+ if (val) {
+ setenv("AUL_ROOT_PATH", val, 1);
+ /* for backward compatibility */
+ snprintf(buf, sizeof(buf), "%s/lib/", val);
+ setenv("LD_LIBRARY_PATH", buf, 1);
+ }
+
+ val = tzplatform_getenv(TZ_USER_HOME);
+ if (val)
+ setenv("HOME", val, 1);
+
+ val = tzplatform_getenv(TZ_SYS_DEFAULT_USER);
+ if (val) {
+ setenv("LOGNAME", val, 1);
+ setenv("USER", val, 1);
+ }
+
+ snprintf(buf, sizeof(buf), "%d", getpid());
+ setenv("AUL_PID", buf, 1);
+
+ snprintf(buf, sizeof(buf), "/run/user/%d", getuid());
+ setenv("XDG_RUNTIME_DIR", buf, 1);
+
+ snprintf(buf, sizeof(buf), FORMAT_DBUS_ADDRESS, getuid(), getuid());
+ setenv("DBUS_SESSION_BUS_ADDRESS", buf, 1);
+}
+
+static int __send_cmd_to_amd(int cmd)
+{
+ struct sockaddr_un addr = {0,};
+ int retry = CONNECT_RETRY_COUNT;
+ app_pkt_t pkt = {0,};
+ int fd;
+ int ret;
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ /* support above version 2.6.27*/
+ if (fd < 0) {
+ if (errno == EINVAL) {
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ LOGE("second chance - socket create error");
+ return -1;
+ }
+ } else {
+ LOGE("socket error");
+ return -1;
+ }
+ }
+
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", PATH_AMD_SOCK);
+ while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ if (errno != ETIMEDOUT || retry <= 0) {
+ LOGE("Failed to connect error(%d)", errno);
+ close(fd);
+ return -1;
+ }
+
+ usleep(CONNECT_RETRY_TIME);
+ --retry;
+ LOGD("re-connect to %s (%d)", addr.sun_path, retry);
+ }
+
+ pkt.cmd = cmd;
+ ret = send(fd, &pkt, sizeof(app_pkt_t), MSG_NOSIGNAL);
+ if (ret <= 0) {
+ LOGE("Failed to send cmd(%d), errno(%d)", cmd, errno);
+ close(fd);
+ return -ECOMM;
+ }
+ close(fd);
+
+ return 0;
+}
+
+static int __prepare_exec(struct launch_arg *arg)
+{
+ char *name;
+ int r;
+
+ /* Set new session ID & new process group ID*/
+ /* In linux, child can set new session ID without check permission */
+ setsid();
+
+ LOGW("trust_anchor_launch ++");
+ if (arg->is_global && !strcmp(arg->is_global, "true"))
+ r = trust_anchor_launch(arg->pkgid, GLOBAL_USER);
+ else
+ r = trust_anchor_launch(arg->pkgid, getuid());
+ LOGW("trust_anchor_launch --");
+ if (r != TRUST_ANCHOR_ERROR_NONE &&
+ r != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
+ LOGE("trust_anchor_launch() is failed. %d", r);
+ return -1;
+ }
+
+ /* Set privileges */
+ LOGW("security_manager_prepare_app ++");
+ r = security_manager_prepare_app(arg->appid);
+ LOGW("security_manager_prepare_app --");
+ if (r != SECURITY_MANAGER_SUCCESS) {
+ LOGE("Failed to set privileges");
+ return -1;
+ }
+
+ __send_cmd_to_amd(APP_STARTUP_SIGNAL);
+
+ name = basename(arg->app_path);
+ if (!name) {
+ LOGE("Failed to parse name");
+ return -1;
+ }
+
+ __redirect_stdio(name);
+ prctl(PR_SET_NAME, name);
+ __set_env(arg->b);
+
+ return 0;
+}
+
+static void __close_all_fds(void)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ int fd;
+ int max_fd = sysconf(_SC_OPEN_MAX);
+
+ dp = opendir("/proc/self/fd");
+ if (!dp) {
+ for (fd = 3; fd < max_fd; ++fd)
+ close(fd);
+ return;
+ }
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (!isdigit(dentry->d_name[0]))
+ continue;
+
+ fd = atoi(dentry->d_name);
+ if (fd < 3 || fd >= max_fd)
+ continue;
+
+ if (fd == dirfd(dp))
+ continue;
+
+ close(fd);
+ }
+ closedir(dp);
+}
+
+static int __create_launcher_argv(int *argc, char ***argv, const char *app_type)
+{
+ int launcher_argc;
+ char **launcher_argv;
+ launcher_info_h launcher_info;
+ const char *exe;
+ const char *extra_arg;
+ GList *extra_args;
+ GList *iter;
+ int i;
+
+ launcher_info = _launcher_info_find(launcher_info_list, app_type);
+ if (launcher_info == NULL)
+ return 0;
+
+ exe = _launcher_info_get_exe(launcher_info);
+ if (exe == NULL) {
+ LOGE("Failed to get launcher exe");
+ return -1;
+ }
+
+ extra_args = _launcher_info_get_extra_args(launcher_info);
+ launcher_argc = g_list_length(extra_args) + 1;
+ launcher_argv = (char **)calloc(launcher_argc, sizeof(char *));
+ if (launcher_argv == NULL) {
+ LOGE("Out of memory");
+ return -1;
+ }
+
+ i = ARG_PATH;
+ launcher_argv[i++] = strdup(exe);
+
+ iter = g_list_first(extra_args);
+ while (iter) {
+ extra_arg = (const char *)iter->data;
+ if (extra_arg)
+ launcher_argv[i++] = strdup(extra_arg);
+
+ iter = g_list_next(iter);
+ }
+
+ *argc = launcher_argc;
+ *argv = launcher_argv;
+
+ return 0;
+}
+
+static void __destroy_launcher_argv(int argc, char **argv)
+{
+ int i;
+
+ if (argv == NULL)
+ return;
+
+ for (i = 0; i < argc; i++)
+ free(argv[i]);
+ free(argv);
+}
+
+static int __create_app_argv(int *argc, char ***argv, const char *app_path,
+ bundle *b, const char *app_type)
+{
+ int new_argc;
+ char **new_argv;
+ struct app_arg launcher_arg = { 0, };
+ struct app_arg arg = { 0, };
+ int i;
+ int r;
+ int c;
+
+ r = __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv,
+ app_type);
+ if (r < 0) {
+ LOGE("Failed to create launcher argv");
+ return -1;
+ }
+
+ arg.argc = bundle_export_to_argv(b, &arg.argv);
+ if (arg.argc <= 0) {
+ LOGE("Failed to export bundle");
+ __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
+ return -1;
+ }
+
+ arg.argv[ARG_PATH] = strdup(app_path);
+ if (arg.argv[ARG_PATH] == NULL) {
+ LOGE("Failed to duplicate app path");
+ bundle_free_exported_argv(arg.argc, &arg.argv);
+ __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
+ return -1;
+ }
+
+ new_argc = launcher_arg.argc + arg.argc;
+ if (new_argc == arg.argc) {
+ *argc = arg.argc;
+ *argv = arg.argv;
+ return 0;
+ }
+
+ new_argv = (char **)calloc(new_argc + 1, sizeof(char *));
+ if (new_argv == NULL) {
+ LOGE("Out of memory");
+ free(arg.argv[ARG_PATH]);
+ bundle_free_exported_argv(arg.argc, &arg.argv);
+ __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
+ return -1;
+ }
+
+ c = ARG_PATH;
+ for (i = 0; i < launcher_arg.argc; i++)
+ new_argv[c++] = launcher_arg.argv[i];
+ for (i = 0; i < arg.argc; i++)
+ new_argv[c++] = arg.argv[i];
+
+ *argc = new_argc;
+ *argv = new_argv;
+
+ return 0;
+}
+
+static int __exec_app_process(struct launch_arg *arg)
+{
+ int app_argc;
+ char **app_argv = NULL;
+ int i;
+ int r;
+
+ __unblock_sigchld();
+ __finish_signal();
+ __set_user_group();
+
+ LOGD("appid(%s), pid(%d), uid(%d)", arg->appid, getpid(), getuid());
+
+ r = __unlink_socket_path(getpid(), getuid());
+ if (r < 0) {
+ LOGE("Failed to delete socket path");
+ return r;
+ }
+
+ r = __prepare_exec(arg);
+ if (r < 0) {
+ LOGE("Failed to prepare exec");
+ return r;
+ }
+
+ r = __create_app_argv(&app_argc, &app_argv, arg->app_path, arg->b,
+ arg->app_type);
+ if (r < 0) {
+ LOGE("Failed to create app arg");
+ return r;
+ }
+
+ for (i = 0; i < app_argc; ++i)
+ LOGD("input argument %d: %s##", i, app_argv[i]);
+
+ __close_all_fds();
+
+ r = execv(app_argv[ARG_PATH], app_argv);
+ if (r < 0) {
+ fprintf(stderr, "Failed to execute %s - err(%d)",
+ app_argv[ARG_PATH], errno);
+ }
+
+ return r;
+}
+
+static int __launcher(bundle *b, uid_t uid, void *user_data)
+{
+ struct launch_arg arg;
+ int pid;
+ int r;
+ uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+ if (!b) {
+ LOGE("Invalid parameter");
+ return -1;
+ }
+
+ if (uid != default_uid) {
+ LOGE("uid(%u) is not default uid(%u)", uid, default_uid);
+ return -1;
+ }
+
+ arg.appid = bundle_get_val(b, AUL_K_APPID);
+ arg.app_path = bundle_get_val(b, AUL_K_EXEC);
+ arg.pkgid = bundle_get_val(b, AUL_K_PKGID);
+ arg.app_type = bundle_get_val(b, AUL_K_APP_TYPE);
+ arg.is_global = bundle_get_val(b, AUL_K_IS_GLOBAL);
+ arg.b = b;
+
+ pid = fork();
+ if (pid == 0) {
+ r = __exec_app_process(&arg);
+ exit(r);
+ } else if (pid > 0) {
+ LOGD("==> real launch pid: %d(%s)", pid, arg.app_path);
+ __send_app_launch_signal(pid, arg.appid);
+ } else {
+ LOGE("Failed to fork process");
+ }
+
+ return pid;
+}
+
+static gboolean __send_startup_finished(gpointer data)
+{
+ uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+ amd_noti_send(AMD_NOTI_MSG_LOGIN_MONITOR_STARTUP_FINISHED,
+ (int)uid, 0, NULL, NULL);
+ return G_SOURCE_REMOVE;
+}
+
+static void __create_user_directories(void)
+{
+ char buf[PATH_MAX];
+ int pid;
+
+ pid = fork();
+ if (pid == 0) {
+ __unblock_sigchld();
+ __finish_signal();
+ __set_user_group();
+
+ snprintf(buf, sizeof(buf), "/run/aul/apps/%u", getuid());
+ if (mkdir(buf, 0700) < 0)
+ LOGW("Failed to create %s", buf);
+ if (smack_setlabel(buf, "User", SMACK_LABEL_ACCESS))
+ LOGW("Failed to change smack");
+
+ snprintf(buf, sizeof(buf), "/run/aul/dbspace/%u", getuid());
+ if (mkdir(buf, 0701) < 0)
+ LOGW("Failed to create %s", buf);
+ if (smack_setlabel(buf, "User::Home", SMACK_LABEL_ACCESS))
+ LOGW("Failed to change smack");
+
+ exit(EXIT_SUCCESS);
+ }
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ LOGD("launchpad init");
+
+ r = amd_launchpad_set_launcher(__launcher, NULL);
+ if (r < 0)
+ return -1;
+
+ r = __init_sigchld_fd();
+ if (r < 0)
+ return -1;
+
+ __init_signal();
+ __create_user_directories();
+ launcher_info_list = _launcher_info_load("/usr/share/aul");
+ g_idle_add(__send_startup_finished, NULL);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ LOGD("launchpad fini");
+
+ if (launcher_info_list) {
+ _launcher_info_unload(launcher_info_list);
+ launcher_info_list = NULL;
+ }
+
+ if (conn) {
+ g_object_unref(conn);
+ conn = NULL;
+ }
+
+ if (sigchld_sid > 0) {
+ g_source_remove(sigchld_sid);
+ sigchld_sid = 0;
+ }
+
+ amd_launchpad_set_launcher(NULL, NULL);
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src
+ AMD_MOD_LOADER_MANAGER_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_LOADER_MANAGER} ${AMD_MOD_LOADER_MANAGER_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_LOADER_MANAGER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_LOADER_MANAGER} PRIVATE
+ ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_LOADER_MANAGER} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_LOADER_MANAGER} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <amd.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <bundle_internal.h>
+#include <glib.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_LOADER_MANAGER"
+
+#define METADATA_KEY_APP_DEFINED_LOADER \
+ "http://tizen.org/metadata/app-defined-loader"
+
+static GHashTable *__loader_table;
+
+static void __loader_table_update(const char *loader_name, int loader_id)
+{
+ if (g_hash_table_contains(__loader_table, loader_name)) {
+ g_hash_table_replace(__loader_table, strdup(loader_name),
+ GINT_TO_POINTER(loader_id));
+ } else {
+ g_hash_table_insert(__loader_table, strdup(loader_name),
+ GINT_TO_POINTER(loader_id));
+ }
+}
+
+static bool __loader_table_lookup(const char *loader_name, int *loader_id)
+{
+ gpointer found;
+
+ if (!g_hash_table_contains(__loader_table, loader_name)) {
+ _W("loader_id(%s) doesn't exist", loader_name);
+ *loader_id = -1;
+ return false;
+ }
+
+ found = g_hash_table_lookup(__loader_table, loader_name);
+ *loader_id = GPOINTER_TO_INT(found);
+ return true;
+}
+
+static int __metadata_foreach_cb(const char *value, void *user_data)
+{
+ int *loader_id = (int *)user_data;
+
+ if (!value)
+ return 0;
+
+ if (__loader_table_lookup(value, loader_id))
+ return -1;
+
+ return 0;
+}
+
+static int __get_loader_id(const char *app_id, uid_t uid)
+{
+ amd_app_property_h app_property;
+ int loader_id = -1;
+
+ app_property = amd_app_property_find(uid);
+ if (!app_property)
+ return -1;
+
+ amd_app_property_metadata_foreach(app_property, app_id,
+ METADATA_KEY_APP_DEFINED_LOADER,
+ __metadata_foreach_cb,
+ (void *)&loader_id);
+
+ return loader_id;
+}
+
+static int __on_launch_prepare_end(const char *msg,
+ int arg1, int arg2, void *arg3, bundle *data)
+{
+ amd_appinfo_h ai = arg3;
+ uid_t target_uid = (uid_t)arg2;
+ const char *app_id;
+ const char *loader_id_str;
+ int req_loader_id;
+ int loader_id;
+
+ if (bundle_get_type(data, AUL_K_SDK) != BUNDLE_TYPE_NONE)
+ return AMD_NOTI_CONTINUE;
+
+ if (bundle_get_type(data, AUL_K_APP_DEFINED_LOADER) != BUNDLE_TYPE_NONE)
+ return AMD_NOTI_CONTINUE;
+
+ loader_id_str = bundle_get_val(data, AUL_K_LOADER_ID);
+ if (!loader_id_str)
+ return AMD_NOTI_CONTINUE;
+
+ req_loader_id = atoi(loader_id_str);
+
+ app_id = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+ if (!app_id) {
+ _E("Failed to get appid");
+ return AMD_NOTI_STOP;
+ }
+
+ loader_id = __get_loader_id(app_id, target_uid);
+ if (loader_id < 0)
+ return AMD_NOTI_CONTINUE;
+
+ if (req_loader_id != loader_id) {
+ _W("Not matched. %d:%d", req_loader_id, loader_id);
+ bundle_del(data, AUL_K_LOADER_ID);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ _W("app_id(%s), loader_id(%d)", app_id, loader_id);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __dispatch_app_prepare_app_defined_loader(amd_request_h req)
+{
+ const char *loader_name;
+ bundle *b;
+ int ret;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ loader_name = bundle_get_val(b, AUL_K_LOADER_NAME);
+ if (!loader_name) {
+ _E("Failed to get loader name");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ ret = amd_socket_send_cmd_to_launchpad(amd_request_get_target_uid(req),
+ PAD_CMD_PREPARE_APP_DEFINED_LOADER,
+ b);
+ amd_request_send_result(req, ret);
+ if (ret < 0) {
+ _E("Failed to prepare loader process. error(%d)", ret);
+ return ret;
+ }
+
+ __loader_table_update(loader_name, ret);
+ _I("loader_name(%s), result(%d)", loader_name, ret);
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_PREPARE_APP_DEFINED_LOADER,
+ .callback = __dispatch_app_prepare_app_defined_loader
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_PREPARE_APP_DEFINED_LOADER,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+};
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int ret;
+
+ _W("AMD_LOADER_MANAGER_INIT");
+
+ ret = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register dispatch table");
+ return -1;
+ }
+
+ ret = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register cynara checkers");
+ return -1;
+ }
+
+ ret = amd_app_property_metadata_add_filter(
+ METADATA_KEY_APP_DEFINED_LOADER,
+ NULL);
+ if (ret < 0) {
+ _E("Failed to add metadata filter");
+ return -1;
+ }
+
+ __loader_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, NULL);
+ if (!__loader_table) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
+ __on_launch_prepare_end);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _W("AMD_LOADER_MANAGER_FINI");
+
+ if (__loader_table)
+ g_hash_table_destroy(__loader_table);
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_RPC_PORT_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_RPC_PORT} ${AMD_MOD_RPC_PORT_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_RPC_PORT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_RPC_PORT} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_RPC_PORT} PUBLIC
+ AUL_DEPS
+ CERT_SVC_VCORE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_RPC_PORT} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <sys/socket.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_rpc_port.h>
+#include <aul_svc.h>
+#include <aul_sock.h>
+#include <bundle_internal.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_RPC_PORT"
+
+#define MAX_NR_OF_DESCRIPTORS 2
+#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
+#define KEY_PRIVILEGE_CHECK_BYPASS \
+ "http://tizen.org/rpc-port/privilege-check-bypass"
+
+struct metadata_info_s {
+ const char *port_name;
+ bool exist;
+};
+
+static GHashTable *__pid_table;
+
+static void __rpc_unref(int pid)
+{
+ gpointer value;
+ int count;
+ amd_app_status_h app_status;
+ int status;
+
+ value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
+ if (!value) {
+ _E("Critical error");
+ return;
+ }
+
+ count = GPOINTER_TO_INT(value);
+ count--;
+ if (count == 0) {
+ g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
+ amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status) {
+ status = amd_app_status_get_status(app_status);
+ if (status != STATUS_DYING)
+ amd_suspend_add_timer(pid);
+ }
+ } else {
+ g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
+ GINT_TO_POINTER(count));
+ }
+}
+
+static void __rpc_ref(int pid)
+{
+ gpointer value;
+ int count;
+
+ value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
+ if (value) {
+ count = GPOINTER_TO_INT(value);
+ count++;
+ g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
+ GINT_TO_POINTER(count));
+ } else {
+ count = 1;
+ g_hash_table_insert(__pid_table, GINT_TO_POINTER(pid),
+ GINT_TO_POINTER(count));
+ amd_suspend_remove_timer(pid);
+ amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
+ }
+}
+
+static void __set_real_appid(uid_t uid, bundle *kb)
+{
+ const char *alias_appid;
+ const char *appid;
+ const char *alias_info;
+ amd_app_property_h app_property;
+
+ alias_appid = bundle_get_val(kb, AUL_K_APPID);
+ if (alias_appid == NULL)
+ return;
+
+ alias_info = bundle_get_val(kb, AUL_SVC_K_ALIAS_INFO);
+ if (alias_info && strcmp(alias_info, "disable") == 0)
+ return;
+
+ app_property = amd_app_property_find(uid);
+ if (app_property == NULL)
+ return;
+
+ appid = amd_app_property_get_real_appid(app_property, alias_appid);
+ if (appid == NULL)
+ return;
+
+ _D("alias_appid(%s), appid(%s)", alias_appid, appid);
+ bundle_del(kb, AUL_K_ORG_APPID);
+ bundle_add(kb, AUL_K_ORG_APPID, alias_appid);
+ bundle_del(kb, AUL_K_APPID);
+ bundle_add(kb, AUL_K_APPID, appid);
+}
+
+static int __dispatch_rpc_port_prepare_stub(amd_request_h req)
+{
+ bundle *b = amd_request_get_bundle(req);
+ pid_t caller_pid = amd_request_get_pid(req);
+ uid_t target_uid = amd_request_get_target_uid(req);
+ amd_appinfo_h ai;
+ const char *appid;
+ const char *port_name;
+ int pid;
+ bool dummy_pending = false;
+ bool dummy_bg_launch = false;
+
+ if (!b) {
+ _E("Invalid parameter");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ __set_real_appid(target_uid, b);
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get appid");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ port_name = bundle_get_val(b, AUL_K_RPC_PORT);
+ if (!port_name) {
+ _E("Failed to get port name");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ ai = amd_appinfo_find(target_uid, appid);
+ if (!ai) {
+ _E("Failed to find %s:%u", appid, target_uid);
+ amd_request_send_result(req, -ENOENT);
+ return -1;
+ }
+
+ amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req, b);
+
+ amd_request_set_request_type(req, "rpc-port");
+ amd_request_set_cmd(req, APP_START_ASYNC);
+ pid = amd_launch_start_app(appid, req,
+ &dummy_pending, &dummy_bg_launch,
+ false);
+ if (pid < 0) {
+ _E("Failed to send launch request(%s:%s)",
+ appid, port_name);
+ amd_noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, pid, 0, NULL, NULL);
+ return -1;
+ }
+ amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END,
+ pid, dummy_bg_launch, req, b);
+
+ __rpc_ref(pid);
+
+ _I("[__RPC_PORT__] appid(%s), pid(%d), port_name(%s), caller_pid(%d)",
+ appid, pid, port_name, caller_pid);
+
+ return 0;
+}
+
+static int __pass_fds(int fd, const int (*fds)[2])
+{
+ struct msghdr msg = { 0, };
+ struct cmsghdr *cmsg;
+ union {
+ /*
+ * ancillary data buffer, wrapped in a union in order to ensure
+ * it is suitably aligned
+ */
+ char buf[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)];
+ struct cmsghdr align;
+ } u;
+ int *fdptr;
+ char iobuf[1];
+ struct iovec io = {
+ .iov_base = iobuf,
+ .iov_len = sizeof(iobuf)
+ };
+ int r;
+
+ msg.msg_iov = &io;
+ msg.msg_iovlen = 1;
+ msg.msg_control = u.buf;
+ msg.msg_controllen = sizeof(u.buf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg) {
+ _E("Failed to get the first cmsghdr");
+ return -EINVAL;
+ }
+
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int) * MAX_NR_OF_DESCRIPTORS);
+
+ /* Initialize the payload: */
+ fdptr = (int *)CMSG_DATA(cmsg);
+ memcpy(fdptr, *fds, sizeof(int) * MAX_NR_OF_DESCRIPTORS);
+
+ r = sendmsg(fd, &msg, 0);
+ if (r < 0) {
+ _E("Failed to send message. errno(%d)", errno);
+ return r;
+ }
+
+ _D("[__RPC_PORT__] sendmsg result(%d)", r);
+
+ return r;
+}
+
+static int __dispatch_rpc_port_create_socket_pair(amd_request_h req)
+{
+ int fds[2] = { 0, };
+ int r;
+
+ r = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
+ if (r != 0) {
+ _E("Failed to create socket pair. err = %d", r);
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ if (fds[0] == -1) {
+ _E("Failed to open socket");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ _I("[__RPC_PORT__] A Pair of sockets: %d:%d", fds[0], fds[1]);
+
+ r = __pass_fds(amd_request_get_fd(req), &fds);
+ if (r < 0) {
+ _E("Failed to pass file descriptors");
+ amd_request_send_result(req, r);
+ }
+
+ close(fds[0]);
+ close(fds[1]);
+
+ return 0;
+}
+
+static int __dispatch_rpc_port_notify_rpc_finished(amd_request_h req)
+{
+ pid_t pid = amd_request_get_pid(req);
+
+ if (pid <= 0) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ __rpc_unref(pid);
+ _I("[__RPC_PORT__] pid(%d)", pid);
+
+ return 0;
+}
+
+static int __foreach_metadata_cb(const char *value, void *user_data)
+{
+ struct metadata_info_s *info = (struct metadata_info_s *)user_data;
+ char *str;
+ char *token;
+ char *saveptr = NULL;
+
+ str = strdup(value);
+ if (!str) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ token = strtok_r(str, "|", &saveptr);
+ while (token) {
+ if (!strcmp(token, info->port_name)) {
+ info->exist = true;
+ free(str);
+ return -1; /* To break metadata iteration */
+ }
+ token = strtok_r(NULL, "|", &saveptr);
+ }
+
+ free(str);
+
+ return 0;
+}
+
+static int __verify_privilege_check_bypass(amd_request_h req)
+{
+ int r;
+ bundle *b;
+ const char *appid;
+ struct metadata_info_s info = { 0, };
+ amd_app_property_h app_property;
+ uid_t uid = amd_request_get_target_uid(req);
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Invalid request");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get appid");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ info.port_name = bundle_get_val(b, AUL_K_RPC_PORT);
+ if (!info.port_name) {
+ _E("Failed to get port name");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ app_property = amd_app_property_find(uid);
+ if (app_property) {
+ r = amd_app_property_metadata_foreach(app_property,
+ appid, KEY_PRIVILEGE_CHECK_BYPASS,
+ __foreach_metadata_cb, &info);
+ if (r != 0) {
+ _E("Failed to retrieve metadata");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ if (info.exist && amd_appinfo_is_platform_app(appid, uid)) {
+ SECURE_LOGD("Bypass privilege check");
+ return AMD_CYNARA_RET_ALLOWED;
+ }
+ }
+
+ return AMD_CYNARA_RET_UNKNOWN;
+}
+
+static int __prepare_stub_cynara_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ int r;
+
+ r = __verify_privilege_check_bypass(req);
+ if (r != AMD_CYNARA_RET_UNKNOWN)
+ return r;
+
+ r = amd_cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
+ if (r <= AMD_CYNARA_RET_DENIED)
+ return r;
+
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
+}
+
+static int __create_socket_pair_cynara_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ int r;
+
+ r = __verify_privilege_check_bypass(req);
+ if (r != AMD_CYNARA_RET_UNKNOWN)
+ return r;
+
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ int pid = arg1;
+
+ if (g_hash_table_contains(__pid_table, GINT_TO_POINTER(pid)))
+ g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
+
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = RPC_PORT_PREPARE_STUB,
+ .callback = __dispatch_rpc_port_prepare_stub
+ },
+ {
+ .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
+ .callback = __dispatch_rpc_port_create_socket_pair
+ },
+ {
+ .cmd = RPC_PORT_NOTIFY_RPC_FINISHED,
+ .callback = __dispatch_rpc_port_notify_rpc_finished
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = RPC_PORT_PREPARE_STUB,
+ .checker = __prepare_stub_cynara_checker,
+ .data = NULL,
+ .priority = 10
+ },
+ {
+ .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
+ .checker = __create_socket_pair_cynara_checker,
+ .data = NULL,
+ .priority = 10
+ },
+};
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ _D("rpc port init");
+
+ r = amd_app_property_metadata_add_filter(KEY_PRIVILEGE_CHECK_BYPASS,
+ NULL);
+ if (r < 0) {
+ _E("Failed to add metadata filter");
+ return -1;
+ }
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register cynara checkers");
+ return -1;
+ }
+
+ __pid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (!__pid_table) {
+ _E("Failed to create pid table");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("rpc port finish");
+
+ if (__pid_table)
+ g_hash_table_destroy(__pid_table);
+
+ amd_app_property_metadata_remove_filter(KEY_PRIVILEGE_CHECK_BYPASS,
+ NULL);
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_RUA_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_RUA} ${AMD_MOD_RUA_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_RUA} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_RUA} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_RUA} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_RUA} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ RUA_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_RUA} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+/**
+ * @brief Called when the image file is created.
+ *
+ * @param[in] image The image file
+ * @param[in] user_data The user data passed from the callback registration function
+ */
+typedef void (*rua_image_monitor_event_cb)(const char *image, void *user_data);
+
+/**
+ * @brief Clears all image files.
+ */
+void _rua_image_monitor_clear_all(void);
+
+/**
+ * @brief Clears the image file.
+ *
+ * @param[in] image The image file
+ */
+void _rua_image_monitor_clear(const char *image);
+
+/**
+ * @brief Sets the event callback function.
+ *
+ * @param[in] callback The callback function to be called when the image file is created
+ * @param[in] user_data The user data to be ppased to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_image_monitor_set_event_cb(rua_image_monitor_event_cb callback,
+ void *user_data);
+
+/**
+ * @brief Initializes the image monitor.
+ *
+ * return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_image_monitor_init(void);
+
+/**
+ * @brief Finalizes the image monitor.
+ */
+void _rua_image_monitor_fini(void);
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <bundle.h>
+
+/**
+ * @brief Intializes the RUA information.
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_info_init(void);
+
+/**
+ * @brief Finalizes the RUA information.
+ */
+void _rua_info_fini(void);
+
+/**
+ * @brief Adds a RUA information.
+ *
+ * @param[in] kb The bundle object
+ * @param[in] pid The process ID
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_info_add(bundle *kb, pid_t pid);
+
+/**
+ * @brief Removes the RUA information.
+ *
+ * @param[in] kb The bundle object
+ * @param[in] uid The user ID
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_info_remove(bundle *kb, uid_t uid);
+
+/**
+ * @brief Updates the image path of the RUA information.
+ *
+ * @param[in] image The image path
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ */
+int _rua_info_update_image(const char *image);
+
+/**
+ * @brief Gets the image path of the instance.
+ *
+ * @param[in] instance_id The ID of the instance
+ *
+ * @return @c the image path on success,
+ * otherwise a nullptr
+ */
+const char *_rua_info_get_image(const char *instance_id);
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+/**
+ * @brief Gets the ID of the instance.
+ *
+ * @return @c an instance ID on success,
+ * otherwise a nullptr
+ */
+const char *_rua_launch_context_get_id(void);
+
+/**
+ * @brief Gets the name of the instance.
+ *
+ * @return @c a instance name on success,
+ * otherwise a nullptr
+ */
+const char *_rua_launch_context_get_name(void);
+
+/**
+ * @brief Gets the icon path.
+ *
+ * @return @c an icon path on success,
+ * otherwise a nullptr
+ */
+const char *_rua_launch_context_get_icon(void);
+
+/**
+ * @brief Gets the URI.
+ *
+ * @return @c URI on success,
+ * otherwise a nullptr
+ */
+const char *_rua_launch_context_get_uri(void);
+
+/**
+ * @brief Releases the launch context.
+ */
+void _rua_launch_context_free(void);
+
+/**
+ * @brief Initialize the launch context.
+ *
+ * @return @c 0 on succes,
+ * otherwise a negative error value
+ */
+int _rua_launch_context_init(void);
+
+/**
+ * @brief Finalize the launch context.
+ */
+void _rua_launch_context_fini(void);
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_RUA"
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+/**
+ * @brief Initializes RUA request.
+ *
+ * @return @c 0 on succes,
+ * otherwise a negative error value
+ */
+int _rua_request_init(void);
+
+/**
+ * @brief Finalizes RUA request.
+ */
+void _rua_request_fini(void);
--- /dev/null
+/*
+ * Copyright (c) 2017 - 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <rua_internal.h>
+#include <rua_stat_internal.h>
+#include <dlog.h>
+
+#include <amd.h>
+
+#include "amd_rua_request.h"
+#include "amd_rua_info.h"
+#include "amd_rua_launch_context.h"
+#include "amd_rua_image_monitor.h"
+#include "amd_rua_private.h"
+
+#define AUL_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+#define RUA_TIMEOUT 1500
+
+typedef struct _rua_data_t {
+ pid_t pid;
+ uid_t uid;
+ char *stat_tag;
+ char *stat_caller;
+ char *app_id;
+ char *app_path;
+ char *comp_id;
+ char *instance_id;
+ char *instance_name;
+ char *icon;
+ char *uri;
+ bool is_group_mode;
+ char *arg;
+} rua_data_t;
+
+typedef int (*rua_data_add_cb)(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status);
+typedef void (*rua_data_remove_cb)(rua_data_t *rua);
+
+typedef struct _rua_data_vft {
+ rua_data_add_cb ctor;
+ rua_data_remove_cb dtor;
+} rua_data_vft;
+
+struct rua_context_s {
+ GList *user_list;
+};
+
+static struct rua_context_s *__get_context(void)
+{
+ static struct rua_context_s context;
+
+ return &context;
+}
+
+static bool __is_group_mode(bundle *kb, uid_t uid)
+{
+ const char *str;
+ const char *mode;
+ const char *appid;
+ amd_appinfo_h ai;
+
+ if (kb == NULL)
+ return false;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (appid == NULL)
+ return false;
+
+ ai = amd_appinfo_find(uid, appid);
+ mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
+ if (mode != NULL && strcmp(mode, "caller") == 0) {
+ str = bundle_get_val(kb, AUL_SVC_K_LAUNCH_MODE);
+ if (str != NULL && strcmp(str, "group") == 0)
+ return true;
+ } else if (mode != NULL && strcmp(mode, "group") == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static void __rua_data_remove_comp_id(rua_data_t *rua)
+{
+ if (!rua || !rua->comp_id)
+ return;
+
+ free(rua->comp_id);
+ rua->comp_id = NULL;
+}
+
+static void __rua_data_remove_arg(rua_data_t *rua)
+{
+ if (!rua || !rua->arg)
+ return;
+
+ free(rua->arg);
+ rua->arg = NULL;
+}
+
+static void __rua_data_remove_uri(rua_data_t *rua)
+{
+ if (!rua || !rua->uri)
+ return;
+
+ free(rua->uri);
+ rua->uri = NULL;
+}
+
+static void __rua_data_remove_icon(rua_data_t *rua)
+{
+ if (!rua || !rua->icon)
+ return;
+
+ free(rua->icon);
+ rua->icon = NULL;
+}
+
+static void __rua_data_remove_instance_name(rua_data_t *rua)
+{
+ if (!rua || !rua->instance_name)
+ return;
+
+ free(rua->instance_name);
+ rua->instance_name = NULL;
+}
+
+static void __rua_data_remove_instance_id(rua_data_t *rua)
+{
+ if (!rua || !rua->instance_id)
+ return;
+
+ free(rua->instance_id);
+ rua->instance_id = NULL;
+}
+
+static void __rua_data_remove_app_path(rua_data_t *rua)
+{
+ if (!rua || !rua->app_path)
+ return;
+
+ free(rua->app_path);
+ rua->app_path = NULL;
+}
+
+static void __rua_data_remove_app_id(rua_data_t *rua)
+{
+ if (!rua || !rua->app_id)
+ return;
+
+ free(rua->app_id);
+ rua->app_id = NULL;
+}
+
+static void __rua_data_remove_stat_caller(rua_data_t *rua)
+{
+ if (!rua || !rua->stat_caller)
+ return;
+
+ free(rua->stat_caller);
+ rua->stat_caller = NULL;
+}
+
+static void __rua_data_remove_stat_tag(rua_data_t *rua)
+{
+ if (!rua || !rua->stat_tag)
+ return;
+
+ free(rua->stat_tag);
+ rua->stat_tag = NULL;
+}
+
+static int __rua_data_add_comp_id(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ amd_app_type_e app_type;
+ const char *comp_id;
+ bundle *kb;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type != AMD_AT_COMPONENT_BASED_APP)
+ return 0;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Failed to get bundle");
+ return -1;
+ }
+
+ comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ if (!comp_id) {
+ _E("Failed to get component ID");
+ return -1;
+ }
+
+ rua->comp_id = strdup(comp_id);
+ if (!rua->comp_id) {
+ _E("Failed to duplicate component ID");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_arg(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ if (amd_request_get_len(req) <= 0)
+ return 0;
+
+ rua->arg = calloc(amd_request_get_len(req) + 1, sizeof(char));
+ if (!rua->arg) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ memcpy(rua->arg, amd_request_get_raw(req), amd_request_get_len(req));
+
+ return 0;
+}
+
+static int __rua_data_add_group_mode(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ uid_t uid = amd_request_get_target_uid(req);
+
+ rua->is_group_mode = __is_group_mode(kb, uid);
+
+ return 0;
+}
+
+static int __rua_data_add_uri(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *uri = _rua_launch_context_get_uri();
+
+ if (uri == NULL)
+ return 0;
+
+ rua->uri = strdup(uri);
+ if (!rua->uri) {
+ _E("Failed to duplicate uri");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_icon(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *icon = _rua_launch_context_get_icon();
+
+ if (icon == NULL)
+ return 0;
+
+ rua->icon = strdup(icon);
+ if (!rua->icon) {
+ _E("Failed to duplicate icon");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_instance_name(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *instance_name = _rua_launch_context_get_name();
+
+ if (instance_name == NULL)
+ return 0;
+
+ rua->instance_name = strdup(instance_name);
+ if (!rua->instance_name) {
+ _E("Failed to duplicate instance name");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_instance_id(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *inst_id = _rua_launch_context_get_id();
+ amd_appinfo_h ai;
+ const char *app_id;
+ const char *multiple;
+ uid_t uid;
+
+ if (!inst_id) {
+ uid = amd_app_status_get_uid(app_status);
+ app_id = amd_app_status_get_appid(app_status);
+ ai = amd_appinfo_find(uid, app_id);
+ if (!ai) {
+ _E("Failed to find appinfo");
+ return -1;
+ }
+
+ multiple = amd_appinfo_get_value(ai, AMD_AIT_MULTI);
+ if (multiple && !strcmp(multiple, "true"))
+ inst_id = amd_app_status_get_instance_id(app_status);
+ }
+
+ if (inst_id) {
+ rua->instance_id = strdup(inst_id);
+ if (!rua->instance_id) {
+ _E("Failed to duplicate instance ID");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_app_path(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *app_path;
+
+ app_path = amd_app_status_get_app_path(app_status);
+ if (!app_path) {
+ _E("Failed to get application path");
+ return -1;
+ }
+
+ rua->app_path = strdup(app_path);
+ if (!rua->app_path) {
+ _E("Failed to duplicate application path");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_app_id(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *app_id;
+
+ app_id = amd_app_status_get_appid(app_status);
+ if (!app_id) {
+ _E("Failed to get application ID");
+ return -1;
+ }
+
+ rua->app_id = strdup(app_id);
+ if (!rua->app_id) {
+ _E("Failed to duplicate application ID");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_stat_caller(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *stat_caller;
+ bundle *kb;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Failed to get bundle");
+ return -1;
+ }
+
+ stat_caller = bundle_get_val(kb, AUL_SVC_K_RUA_STAT_CALLER);
+ if (!stat_caller)
+ return 0;
+
+ rua->stat_caller = strdup(stat_caller);
+ if (!rua->stat_caller) {
+ _E("Failed to duplicate stat caller");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_stat_tag(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ const char *stat_tag;
+ bundle *kb;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Failed to get bundle");
+ return -1;
+ }
+
+ stat_tag = bundle_get_val(kb, AUL_SVC_K_RUA_STAT_TAG);
+ if (!stat_tag)
+ return 0;
+
+ rua->stat_tag = strdup(stat_tag);
+ if (!rua->stat_tag) {
+ _E("Failed to duplicate stat tag");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __rua_data_add_uid(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ rua->uid = amd_request_get_target_uid(req);
+
+ return 0;
+}
+
+static int __rua_data_add_pid(rua_data_t *rua, amd_request_h req,
+ amd_app_status_h app_status)
+{
+ rua->pid = amd_app_status_get_pid(app_status);
+
+ return 0;
+}
+
+static rua_data_vft __rua_data_table[] = {
+ { __rua_data_add_pid, NULL },
+ { __rua_data_add_uid, NULL },
+ { __rua_data_add_stat_tag, __rua_data_remove_stat_tag },
+ { __rua_data_add_stat_caller, __rua_data_remove_stat_caller },
+ { __rua_data_add_app_id, __rua_data_remove_app_id },
+ { __rua_data_add_app_path, __rua_data_remove_app_path },
+ { __rua_data_add_instance_id, __rua_data_remove_instance_id },
+ { __rua_data_add_instance_name, __rua_data_remove_instance_name },
+ { __rua_data_add_icon, __rua_data_remove_icon },
+ { __rua_data_add_uri, __rua_data_remove_uri },
+ { __rua_data_add_group_mode, NULL },
+ { __rua_data_add_arg, __rua_data_remove_arg },
+ { __rua_data_add_comp_id, __rua_data_remove_comp_id },
+};
+
+static void __destroy_rua_data(void *data)
+{
+ rua_data_t *rua = data;
+ int i;
+
+ if (!rua)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(__rua_data_table); ++i) {
+ if (__rua_data_table[i].dtor)
+ __rua_data_table[i].dtor(rua);
+ }
+
+ free(rua);
+}
+
+static rua_data_t *__create_rua_data(amd_request_h req, pid_t pid)
+{
+ amd_app_status_h app_status;
+ rua_data_t *rua;
+ int ret;
+ int i;
+
+ if (!req) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return NULL;
+ }
+
+ rua = calloc(1, sizeof(rua_data_t));
+ if (!rua) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(__rua_data_table); ++i) {
+ if (__rua_data_table[i].ctor) {
+ ret = __rua_data_table[i].ctor(rua, req, app_status);
+ if (ret < 0) {
+ __destroy_rua_data(rua);
+ return NULL;
+ }
+ }
+ }
+
+ return rua;
+}
+
+static const char *__get_instance_id(pid_t pid)
+{
+ amd_app_status_h app_status;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (!app_status)
+ return NULL;
+
+ return amd_app_status_get_instance_id(app_status);
+}
+
+static gboolean __add_history_handler(gpointer user_data)
+{
+ rua_data_t *rua = (rua_data_t *)user_data;
+ struct rua_rec rec = { 0, };
+ const char *image;
+ const char *instance_id;
+ int ret;
+
+ if (!rua)
+ return G_SOURCE_REMOVE;
+
+ if (!rua->is_group_mode) {
+ rec.pkg_name = rua->app_id;
+ rec.app_path = rua->app_path;
+ rec.arg = rua->arg;
+ rec.launch_time = time(NULL);
+ rec.instance_id = rua->instance_id;
+ rec.instance_name = rua->instance_name;
+ rec.icon = rua->icon;
+ rec.uri = rua->uri;
+
+ instance_id = rua->instance_id;
+ if (!instance_id)
+ instance_id = __get_instance_id(rua->pid);
+
+ image = _rua_info_get_image(instance_id);
+ if (image)
+ rec.image = (char *)image;
+
+ ret = rua_usr_db_add_history(&rec, rua->uid);
+ if (ret < 0)
+ _W("Failed to add rua history");
+
+ SECURE_LOGD("RUA history added. app_id(%s) app_path(%s)",
+ rec.pkg_name, rec.app_path);
+ }
+
+ if (rua->stat_caller && rua->stat_tag) {
+ ret = rua_stat_usr_db_update(rua->stat_caller, rua->stat_tag,
+ rua->uid);
+ if (ret < 0)
+ _W("Failed to update rua stat");
+
+ SECURE_LOGD("RUA stat updated. caller(%s), tag(%s)",
+ rua->stat_caller, rua->stat_tag);
+ }
+
+ __destroy_rua_data(rua);
+
+ return G_SOURCE_REMOVE;
+}
+
+static bool __user_exist(uid_t uid)
+{
+ struct rua_context_s *context = __get_context();
+ GList *iter;
+ uid_t u;
+
+ iter = context->user_list;
+ while (iter) {
+ u = GPOINTER_TO_UINT(iter->data);
+ if (u == uid)
+ return true;
+
+ iter = g_list_next(iter);
+ }
+
+ return false;
+}
+
+static void __user_add(uid_t uid)
+{
+ struct rua_context_s *context = __get_context();
+
+ context->user_list = g_list_append(context->user_list,
+ GUINT_TO_POINTER(uid));
+}
+
+static void __user_remove(uid_t uid)
+{
+ struct rua_context_s *context = __get_context();
+
+ context->user_list = g_list_remove(context->user_list,
+ GUINT_TO_POINTER(uid));
+}
+
+static int __reply_foreach_cb(const char *key, void *user_data)
+{
+ if (key && !strcmp(key, "rua") && user_data) {
+ g_timeout_add(RUA_TIMEOUT, __add_history_handler, user_data);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int __on_request_user_init(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+
+ _I("user(%u)", uid);
+
+ if (__user_exist(uid))
+ return AMD_NOTI_CONTINUE;
+
+ rua_usr_db_delete_history(NULL, uid);
+ __user_add(uid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_login_monitor_user_logout(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+
+ _I("user(%u)", uid);
+
+ __user_remove(uid);
+ _rua_info_remove(NULL, uid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_status(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ const char *instance_id;
+ const char *comp_id = NULL;
+ const char *pkg_name = NULL;
+ uid_t target_uid;
+ int ret;
+ amd_app_status_h status = arg3;
+ amd_comp_status_h comp_status;
+ amd_app_type_e app_type = amd_app_status_get_app_type(status);
+
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ instance_id = amd_app_status_get_instance_id(status);
+ comp_status = amd_comp_status_find_by_instance_id(instance_id);
+ if (comp_status == NULL) {
+ _E("Fail to get comp status (%s)", instance_id);
+ return AMD_NOTI_CONTINUE;
+ }
+ comp_id = amd_comp_status_get_comp_id(comp_status);
+ }
+
+ pkg_name = amd_app_status_get_pkgid(status);
+ target_uid = amd_app_status_get_uid(status);
+ ret = rua_usr_db_update_history(pkg_name, comp_id, time(NULL), target_uid);
+ if (ret < 0)
+ _W("Failed to update rua history");
+ SECURE_LOGI("[__RUA_INFO__] Updated. pkg_name(%s), comp_id(%s)",
+ pkg_name, comp_id);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_app_start_pend(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ pid_t pid = (pid_t)arg1;
+ bool bg_launch = (bool)arg2;
+ amd_request_h req = (amd_request_h)arg3;
+ amd_request_reply_h reply = (amd_request_reply_h)data;
+ rua_data_t *rua = NULL;
+ bundle *kb;
+ int ret;
+
+ if (!bg_launch) {
+ kb = amd_request_get_bundle(req);
+ ret = amd_noti_send(AMD_NOTI_MSG_RUA_SAVE_CRITICAL, 0, 0,
+ req, kb);
+ if (ret == 0) {
+ rua = __create_rua_data(req, pid);
+ if (rua && !rua->is_group_mode)
+ _rua_info_add(kb, pid);
+ }
+ }
+
+ _rua_launch_context_free();
+ if (rua) {
+ amd_request_reply_add_extra(reply, "rua",
+ rua, __destroy_rua_data);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_app_start_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ pid_t pid = (pid_t)arg1;
+ bool bg_launch = (bool)arg2;
+ amd_request_h req = (amd_request_h)arg3;
+ bundle *kb = data;
+ rua_data_t *rua = NULL;
+ amd_app_status_h app_status;
+ int ret;
+
+ if (pid > 0 && !bg_launch) {
+ ret = amd_noti_send(AMD_NOTI_MSG_RUA_SAVE_CRITICAL, 0, 0,
+ req, kb);
+ if (ret == 0) {
+ rua = __create_rua_data(req, pid);
+ if (!rua) {
+ _rua_launch_context_free();
+ return AMD_NOTI_STOP;
+ }
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status != NULL) {
+ if (amd_app_status_is_running(app_status))
+ __add_history_handler(rua);
+ } else {
+ g_timeout_add(RUA_TIMEOUT,
+ __add_history_handler, rua);
+ }
+ }
+ }
+
+ _rua_launch_context_free();
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static void __rua_image_monitor_event_cb(const char *image, void *user_data)
+{
+ _rua_info_update_image(image);
+}
+
+static int __on_launch_app_startup_signal_end(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ int pid = arg1;
+
+ amd_request_reply_foreach_extra(pid, __reply_foreach_cb);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int ret;
+
+ _D("RUA Initialize");
+
+ ret = _rua_launch_context_init();
+ if (ret < 0)
+ return ret;
+
+ ret = _rua_request_init();
+ if (ret < 0)
+ return ret;
+
+ ret = _rua_info_init();
+ if (ret < 0)
+ return ret;
+
+ _rua_image_monitor_set_event_cb(__rua_image_monitor_event_cb, NULL);
+
+ ret = _rua_image_monitor_init();
+ if (ret < 0)
+ return ret;
+
+ amd_noti_listen(AMD_NOTI_MSG_REQUEST_USER_INIT,
+ __on_request_user_init);
+ amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
+ __on_login_monitor_user_logout);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_PEND,
+ __on_launch_app_start_pend);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_END,
+ __on_launch_app_start_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_STARTUP_SIGNAL_END,
+ __on_launch_app_startup_signal_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
+ __on_launch_status);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("RUA Finalize");
+
+ _rua_image_monitor_fini();
+ _rua_info_fini();
+ _rua_request_fini();
+ _rua_launch_context_fini();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <amd.h>
+
+#include "amd_rua_image_monitor.h"
+#include "amd_rua_private.h"
+
+#define PATH_RUN "/run"
+#define FILE_E_IMG ".e-img"
+#define PATH_RUN_E_IMG PATH_RUN "/" FILE_E_IMG
+
+struct rua_image_monitor_s {
+ amd_inotify_watch_info_h directory_create;
+ amd_inotify_watch_info_h image_create;
+ amd_inotify_watch_info_h image_close_write;
+ rua_image_monitor_event_cb callback;
+ void *user_data;
+};
+
+static struct rua_image_monitor_s *__get_monitor(void)
+{
+ static struct rua_image_monitor_s inst;
+
+ return &inst;
+}
+
+void _rua_image_monitor_clear_all(void)
+{
+ DIR *dp;
+ struct dirent *dentry = NULL;
+ char buf[PATH_MAX];
+ struct stat statbuf;
+ int r;
+
+ dp = opendir(PATH_RUN_E_IMG);
+ if (dp == NULL)
+ return;
+
+ while ((dentry = readdir(dp))) {
+ if (!strcmp(dentry->d_name, ".") ||
+ !strcmp(dentry->d_name, ".."))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/%s",
+ PATH_RUN_E_IMG, dentry->d_name);
+ r = stat(buf, &statbuf);
+ if (r == 0) {
+ if (S_ISREG(statbuf.st_mode))
+ unlink(buf);
+ }
+ }
+
+ closedir(dp);
+}
+
+void _rua_image_monitor_clear(const char *image)
+{
+ if (!image)
+ return;
+
+ unlink(image);
+}
+
+static void __foreach_images(void)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+ DIR *dp;
+ struct dirent *dentry;
+ char buf[PATH_MAX];
+ struct stat statbuf;
+ int r;
+
+ if (!monitor->callback)
+ return;
+
+ dp = opendir(PATH_RUN_E_IMG);
+ if (dp == NULL)
+ return;
+
+ while ((dentry = readdir(dp))) {
+ if (!strcmp(dentry->d_name, ".") ||
+ !strcmp(dentry->d_name, ".."))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/%s",
+ PATH_RUN_E_IMG, dentry->d_name);
+ r = stat(buf, &statbuf);
+ if (r == 0) {
+ if (S_ISREG(statbuf.st_mode))
+ monitor->callback(buf, monitor->user_data);
+ }
+ }
+ closedir(dp);
+}
+
+static bool __on_image_create(const char *event_name, void *user_data)
+{
+ if (event_name)
+ _D("%s created", event_name);
+
+ return true;
+}
+
+static bool __on_image_close_write(const char *event_name,
+ void *user_data)
+{
+ struct rua_image_monitor_s *monitor = user_data;
+ char path[PATH_MAX];
+
+ if (event_name) {
+ snprintf(path, sizeof(path), "%s/%s",
+ PATH_RUN_E_IMG, event_name);
+ if (monitor->callback)
+ monitor->callback(path, monitor->user_data);
+
+ _D("%s opened for writing was closed ", event_name);
+ }
+
+ return true;
+}
+
+static void __fini_rua_image_monitor(void)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+
+ if (monitor->image_close_write) {
+ amd_inotify_rm_watch(monitor->image_close_write);
+ monitor->image_close_write = NULL;
+ }
+
+ if (monitor->image_create) {
+ amd_inotify_rm_watch(monitor->image_create);
+ monitor->image_create = NULL;
+ }
+}
+
+static int __init_rua_image_monitor(void)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+
+ monitor->image_create = amd_inotify_add_watch(PATH_RUN_E_IMG,
+ IN_CREATE, __on_image_create, monitor);
+ if (!monitor->image_create)
+ _W("Failed to add inotify watch %s", PATH_RUN_E_IMG);
+
+ monitor->image_close_write = amd_inotify_add_watch(PATH_RUN_E_IMG,
+ IN_CLOSE_WRITE, __on_image_close_write, monitor);
+ if (!monitor->image_close_write) {
+ _E("Failed to add inotify watch %s", PATH_RUN_E_IMG);
+ return -1;
+ }
+
+ __foreach_images();
+
+ return 0;
+}
+
+static bool __on_directory_create(const char *event_name, void *user_data)
+{
+ struct rua_image_monitor_s *monitor = user_data;
+
+ if (!event_name) {
+ _E("Invalid parameter");
+ return true;
+ }
+
+ if (!strcmp(event_name, FILE_E_IMG)) {
+ __init_rua_image_monitor();
+ monitor->directory_create = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+int _rua_image_monitor_set_event_cb(rua_image_monitor_event_cb callback,
+ void *user_data)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+
+ if (!callback) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ monitor->callback = callback;
+ monitor->user_data = user_data;
+
+ return 0;
+}
+
+int _rua_image_monitor_init(void)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+ int ret;
+
+ _D("RUA Image Monitor Initialize");
+
+ ret = access(PATH_RUN_E_IMG, F_OK);
+ if (ret < 0) {
+ _W("Failed to access %s", PATH_RUN_E_IMG);
+ monitor->directory_create = amd_inotify_add_watch(PATH_RUN,
+ IN_CREATE, __on_directory_create, monitor);
+ if (!monitor->directory_create) {
+ _E("Failed to add inotify watch %s", PATH_RUN);
+ return -1;
+ }
+
+ return 0;
+ }
+
+ ret = __init_rua_image_monitor();
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void _rua_image_monitor_fini(void)
+{
+ struct rua_image_monitor_s *monitor = __get_monitor();
+
+ _D("RUA Image Monitor Finalize");
+
+ __fini_rua_image_monitor();
+
+ if (monitor->directory_create) {
+ amd_inotify_rm_watch(monitor->directory_create);
+ monitor->directory_create = NULL;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <rua_internal.h>
+#include <rua_stat_internal.h>
+#include <amd.h>
+
+#include "amd_rua_info.h"
+#include "amd_rua_image_monitor.h"
+#include "amd_rua_private.h"
+
+struct rua_info_s {
+ char *key;
+ pid_t pid;
+ uid_t uid;
+ char *app_id;
+ char *app_path;
+ char *instance_id;
+ char *image_path;
+ char *temp_path;
+ char *comp_id;
+ GList *wid_list;
+};
+
+struct rua_info_context_s {
+ GHashTable *table;
+};
+
+typedef bool (*rua_info_foreach_remove_cb)(struct rua_info_s *info,
+ void *user_data);
+
+static struct rua_info_context_s *__get_context(void)
+{
+ static struct rua_info_context_s inst;
+
+ return &inst;
+}
+
+static void __destroy_rua_info(gpointer data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)data;
+
+ if (info == NULL)
+ return;
+
+ if (info->wid_list)
+ g_list_free(info->wid_list);
+
+ if (info->temp_path) {
+ _rua_image_monitor_clear(info->temp_path);
+ free(info->temp_path);
+ }
+
+ if (info->image_path) {
+ _rua_image_monitor_clear(info->image_path);
+ free(info->image_path);
+ }
+
+ if (info->comp_id)
+ free(info->comp_id);
+
+ if (info->instance_id)
+ free(info->instance_id);
+
+ if (info->app_path)
+ free(info->app_path);
+
+ if (info->app_id)
+ free(info->app_id);
+
+ if (info->key)
+ free(info->key);
+
+ free(info);
+}
+
+static struct rua_info_s *__create_rua_info(const char *key,
+ const char *app_id, const char *app_path,
+ const char *instance_id, const char *comp_id,
+ pid_t pid, uid_t uid)
+{
+ struct rua_info_s *info;
+
+ info = calloc(1, sizeof(struct rua_info_s));
+ if (info == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->key = strdup(key);
+ if (!info->key) {
+ _E("Failed to duplicate key");
+ __destroy_rua_info(info);
+ return NULL;
+ }
+
+ info->app_id = strdup(app_id);
+ if (!info->app_id) {
+ _E("Failed to duplicate application ID");
+ __destroy_rua_info(info);
+ return NULL;
+ }
+
+ info->app_path = strdup(app_path);
+ if (!info->app_path) {
+ _E("Failed to duplicate application path");
+ __destroy_rua_info(info);
+ return NULL;
+ }
+
+ if (instance_id) {
+ info->instance_id = strdup(instance_id);
+ if (!info->instance_id) {
+ _E("Failed to duplicate instance ID");
+ __destroy_rua_info(info);
+ return NULL;
+ }
+ }
+
+ if (comp_id) {
+ info->comp_id = strdup(comp_id);
+ if (!info->comp_id) {
+ _E("Failed to duplicate component ID");
+ __destroy_rua_info(info);
+ return NULL;
+ }
+ }
+
+ info->pid = pid;
+ info->uid = uid;
+
+ return info;
+}
+
+static gint __compare_wid(gconstpointer a, gconstpointer b)
+{
+ int wid1 = GPOINTER_TO_INT(a);
+ int wid2 = GPOINTER_TO_INT(b);
+
+ if (wid1 == wid2)
+ return 0;
+
+ return -1;
+}
+
+static struct rua_info_s *__rua_info_find_by_wid(int wid)
+{
+ struct rua_info_context_s *context = __get_context();
+ struct rua_info_s *info;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ GList *found;
+
+ g_hash_table_iter_init(&iter, context->table);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ info = (struct rua_info_s *)value;
+ if (!info || !info->wid_list)
+ continue;
+
+ found = g_list_find_custom(info->wid_list, GINT_TO_POINTER(wid),
+ __compare_wid);
+ if (found)
+ return info;
+ }
+
+ return NULL;
+}
+
+static struct rua_info_s *__rua_info_find_by_instance_id(const char *id)
+{
+ struct rua_info_context_s *context = __get_context();
+ struct rua_info_s *info;
+
+ info = (struct rua_info_s *)g_hash_table_lookup(context->table, id);
+ if (info)
+ return info;
+
+ return NULL;
+}
+
+static struct rua_info_s *__rua_info_find(int pid)
+{
+ struct rua_info_context_s *context = __get_context();
+ struct rua_info_s *info;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ g_hash_table_iter_init(&iter, context->table);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ info = (struct rua_info_s *)value;
+ if (!info)
+ continue;
+
+ if (info->pid == pid)
+ return info;
+ }
+
+ return NULL;
+}
+
+static bool __has_taskmanage(amd_app_status_h app_status, bundle *kb, uid_t uid)
+{
+ amd_app_type_e app_type;
+ amd_compinfo_h ci;
+ amd_appinfo_h ai;
+ const char *taskmanage;
+ const char *comp_id;
+ const char *app_id;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ if (!comp_id) {
+ _E("Failed to get component ID");
+ return false;
+ }
+
+ ci = amd_compinfo_find(uid, comp_id);
+ if (!ci) {
+ _E("Failed to find compinfo");
+ return false;
+ }
+
+ taskmanage = amd_compinfo_get_value(ci,
+ AMD_COMPINFO_TYPE_TASKMANAGE);
+ } else {
+ app_id = amd_app_status_get_appid(app_status);
+ if (!app_id) {
+ _E("Failed to get application ID");
+ return false;
+ }
+
+ ai = amd_appinfo_find(uid, app_id);
+ if (!ai) {
+ _E("Failed to find appinfo");
+ return false;
+ }
+
+ taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
+ }
+
+ if (taskmanage && !strcmp(taskmanage, "true"))
+ return true;
+
+ return false;
+}
+
+static bool __can_have_window(amd_app_status_h app_status,
+ const char *instance_id)
+{
+ amd_comp_status_h comp_status;
+ amd_comp_type_e comp_type;
+ amd_app_type_e app_type;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_UI_APP)
+ return true;
+
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ comp_status = amd_comp_status_find_by_instance_id(instance_id);
+ if (!comp_status) {
+ _W("Failed to find comp status");
+ return false;
+ }
+
+ comp_type = amd_comp_status_get_comp_type(comp_status);
+ if (comp_type == AMD_CT_FRAME_COMP)
+ return true;
+ }
+
+ return false;
+}
+
+static gboolean __foreach_remove_by_rua_info(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)value;
+ struct rua_info_s *new_info = (struct rua_info_s *)user_data;
+
+ if (info->uid == new_info->uid &&
+ !strcmp(info->app_id, new_info->app_id)) {
+ if (info->instance_id && new_info->instance_id &&
+ !strcmp(info->instance_id, new_info->instance_id))
+ return TRUE;
+ else if (!info->instance_id && !new_info->instance_id)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean __foreach_remove_by_uid(gpointer key, gpointer value,
+ gpointer data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)value;
+ uid_t uid = GPOINTER_TO_UINT(data);
+
+ if (info->uid == uid)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean __foreach_remove_by_app_id(gpointer key, gpointer value,
+ gpointer data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)value;
+ const char *app_id = (const char *)data;
+
+ if (!strcmp(info->app_id, app_id))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean __foreach_remove_by_app_path(gpointer key, gpointer value,
+ gpointer data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)value;
+ const char *app_path = (const char *)data;
+
+ if (!strcmp(info->app_path, app_path))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean __foreach_remove_by_instance_id(gpointer key, gpointer value,
+ gpointer data)
+{
+ struct rua_info_s *info = (struct rua_info_s *)value;
+ const char *instance_id = (const char *)data;
+
+ if (info->instance_id && !strcmp(info->instance_id, instance_id))
+ return TRUE;
+
+ return FALSE;
+}
+
+int _rua_info_add(bundle *kb, pid_t pid)
+{
+ struct rua_info_context_s *context = __get_context();
+ struct rua_info_s *info;
+ amd_app_status_h app_status;
+ amd_app_type_e app_type;
+ const char *instance_id;
+ const char *app_path;
+ const char *comp_id;
+ const char *app_id;
+ const char *key;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return -1;
+ }
+
+ instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ if (instance_id)
+ key = instance_id;
+ else
+ key = amd_app_status_get_instance_id(app_status);
+
+ if (!key) {
+ _E("key is nullptr");
+ return -1;
+ }
+
+ if (!__can_have_window(app_status, instance_id)) {
+ _D("The instance cannot have a window");
+ return 0;
+ }
+
+ uid = amd_app_status_get_uid(app_status);
+ if (!__has_taskmanage(app_status, kb, uid)) {
+ _W("The instance isn't managed by taskmanager");
+ return 0;
+ }
+
+ app_path = amd_app_status_get_app_path(app_status);
+ app_id = amd_app_status_get_appid(app_status);
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_COMPONENT_BASED_APP)
+ comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ else
+ comp_id = NULL;
+
+ info = __create_rua_info(key, app_id, app_path, instance_id, comp_id,
+ pid, uid);
+ if (!info)
+ return -1;
+
+ g_hash_table_foreach_remove(context->table,
+ __foreach_remove_by_rua_info, info);
+
+ if (g_hash_table_contains(context->table, key))
+ g_hash_table_replace(context->table, info->key, info);
+ else
+ g_hash_table_insert(context->table, info->key, info);
+
+ return 0;
+}
+
+int _rua_info_remove(bundle *kb, uid_t uid)
+{
+ struct rua_info_context_s *context = __get_context();
+ const char *instance_id = NULL;
+ const char *app_path = NULL;
+ const char *app_id = NULL;
+
+ if (kb) {
+ app_id = bundle_get_val(kb, AUL_K_RUA_PKGNAME);
+ app_path = bundle_get_val(kb, AUL_K_RUA_APPPATH);
+ instance_id = bundle_get_val(kb, AUL_K_RUA_INSTANCE_ID);
+ }
+
+ if (app_id) {
+ g_hash_table_foreach_remove(context->table,
+ __foreach_remove_by_app_id,
+ (void *)app_id);
+ } else if (app_path) {
+ g_hash_table_foreach_remove(context->table,
+ __foreach_remove_by_app_path,
+ (void *)app_path);
+ } else if (instance_id) {
+ g_hash_table_foreach_remove(context->table,
+ __foreach_remove_by_instance_id,
+ (void *)instance_id);
+ } else {
+ g_hash_table_foreach_remove(context->table,
+ __foreach_remove_by_uid,
+ GUINT_TO_POINTER(uid));
+ _rua_image_monitor_clear_all();
+ }
+
+ return 0;
+}
+
+int _rua_info_update_image(const char *image)
+{
+ struct rua_info_s *info;
+ char *file;
+ int pid = -1;
+ int wid = 0;
+ int num = -1;
+ int ret;
+
+ file = basename(image);
+ if (!file) {
+ _E("Failed to get basename. image(%s)", image);
+ return -1;
+ }
+
+ ret = sscanf(file, "win_%d_%d-%d.png", &pid, &wid, &num);
+ if (ret != 3) {
+ _E("Failed to parse image file");
+ return -1;
+ }
+
+ info = __rua_info_find_by_wid(wid);
+ if (!info) {
+ _W("Unknown wid(%d)", wid);
+ info = __rua_info_find(pid);
+ }
+
+ if (!info) {
+ _E("Failed to find rua info. %s will be deleted", image);
+ _rua_image_monitor_clear(image);
+ return -1;
+ }
+
+ if (info->image_path) {
+ if (!strcmp(info->image_path, image))
+ return 0;
+
+ if (info->temp_path && strcmp(info->temp_path, image) != 0) {
+ _rua_image_monitor_clear(info->temp_path);
+ free(info->temp_path);
+ }
+
+ info->temp_path = info->image_path;
+ }
+
+ ret = rua_usr_db_update_image(info->app_id, info->comp_id,
+ info->instance_id, image, info->uid);
+ if (ret < 0) {
+ SECURE_LOGW("Failed to update image path(%s). instance(%s)",
+ image, info->instance_id);
+ }
+
+ info->image_path = strdup(image);
+ if (!info->image_path) {
+ _E("Failed to duplicate image path(%s)", image);
+ return -1;
+ }
+ SECURE_LOGI("[__RUA_INFO__] Updated. instance(%s), update(%s)",
+ info->instance_id, info->image_path);
+
+ return 0;
+}
+
+const char *_rua_info_get_image(const char *instance_id)
+{
+ struct rua_info_s *info;
+
+ if (!instance_id)
+ return NULL;
+
+ info = __rua_info_find_by_instance_id(instance_id);
+ if (!info)
+ return NULL;
+
+ return info->image_path;
+}
+
+static int __on_app_group_window_set(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ int wid = arg2;
+ const char *instance_id = (const char *)instance_id;
+ amd_app_status_h app_status;
+ amd_comp_status_h comp_status;
+ const char *leader_id;
+ struct rua_info_s *info;
+
+ if (instance_id) {
+ comp_status = amd_comp_status_find_by_instance_id(instance_id);
+ if (!comp_status) {
+ _W("Failed to find comp status");
+ return AMD_NOTI_STOP;
+ }
+
+ leader_id = amd_comp_status_get_leader_id(comp_status);
+ } else {
+ app_status = amd_app_status_find_by_pid(pid);
+ if (!app_status) {
+ _W("Failed to find app status. pid(%d)", pid);
+ return AMD_NOTI_STOP;
+ }
+
+ instance_id = amd_app_status_get_instance_id(app_status);
+ leader_id = amd_app_status_get_leader_id(app_status);
+ }
+
+ if (leader_id)
+ instance_id = leader_id;
+
+ info = __rua_info_find_by_instance_id(instance_id);
+ if (!info)
+ info = __rua_info_find(pid);
+
+ if (!info) {
+ SECURE_LOGW("Failed to find rua info. instance(%s)",
+ instance_id);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ info->wid_list = g_list_append(info->wid_list, GINT_TO_POINTER(wid));
+ SECURE_LOGI("[__RUA_INFO__] instance(%s), wid(%d)", instance_id, wid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_app_group_destroy_app_group_context(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ int wid = arg2;
+ struct rua_info_s *info;
+
+ info = __rua_info_find_by_wid(wid);
+ if (!info)
+ return AMD_NOTI_CONTINUE;
+
+ info->wid_list = g_list_remove(info->wid_list, GINT_TO_POINTER(wid));
+
+ return AMD_NOTI_CONTINUE;
+}
+
+int _rua_info_init(void)
+{
+ struct rua_info_context_s *context = __get_context();
+
+ _D("RUA Info Initialize");
+
+ context->table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, __destroy_rua_info);
+ if (!context->table) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET,
+ __on_app_group_window_set);
+ amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT,
+ __on_app_group_destroy_app_group_context);
+
+ return 0;
+}
+
+void _rua_info_fini(void)
+{
+ struct rua_info_context_s *context = __get_context();
+
+ _D("RUA Info Finalize");
+
+ if (context->table) {
+ g_hash_table_destroy(context->table);
+ context->table = NULL;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <rua_internal.h>
+#include <rua_stat_internal.h>
+#include <aul.h>
+#include <amd.h>
+
+#include "amd_rua_launch_context.h"
+#include "amd_rua_private.h"
+
+#define MULTI_INSTANCE_SHORTCUT "multi-instance-shortcut"
+#define QUERY_KEY_ID "id="
+#define QUERY_KEY_ICON "icon="
+#define QUERY_KEY_NAME "name="
+#define AUL_SVC_K_URI "__APP_SVC_URI__"
+#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+
+struct rua_launch_context_s {
+ char *id;
+ char *name;
+ char *icon;
+ char *uri;
+};
+
+static struct rua_launch_context_s *__get_launch_context(void)
+{
+ static struct rua_launch_context_s context;
+
+ return &context;
+}
+
+const char *_rua_launch_context_get_id(void)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+
+ return info->id;
+}
+
+const char *_rua_launch_context_get_name(void)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+
+ return info->name;
+}
+
+const char *_rua_launch_context_get_icon(void)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+
+ return info->icon;
+}
+
+const char *_rua_launch_context_get_uri(void)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+
+ return info->uri;
+}
+
+void _rua_launch_context_free(void)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+
+ if (info->uri) {
+ free(info->uri);
+ info->uri = NULL;
+ }
+
+ if (info->id) {
+ free(info->id);
+ info->id = NULL;
+ }
+
+ if (info->icon) {
+ free(info->icon);
+ info->icon = NULL;
+ }
+
+ if (info->name) {
+ free(info->name);
+ info->name = NULL;
+ }
+}
+
+static char *__get_value_from_query(const char *src, const char *key)
+{
+ int src_len = strlen(src);
+ int key_len = strlen(key);
+
+ if (src_len > key_len) {
+ if (strncmp(src, key, key_len) == 0)
+ return g_uri_unescape_string(src + key_len, NULL);
+ }
+
+ return NULL;
+}
+
+static int __set_launch_context(bundle *kb)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+ const char *uri;
+ gchar *scheme;
+ gchar *query;
+ char *token;
+ char *saveptr = NULL;
+ char *dup_uri;
+
+ uri = bundle_get_val(kb, AUL_SVC_K_URI);
+ if (uri == NULL)
+ return -1;
+
+ scheme = g_uri_parse_scheme(uri);
+ if (scheme == NULL)
+ return -1;
+
+ if (strcmp(scheme, MULTI_INSTANCE_SHORTCUT) != 0) {
+ g_free(scheme);
+ return -1;
+ }
+ g_free(scheme);
+
+ dup_uri = strdup(uri);
+ if (dup_uri == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+
+ info->uri = strdup(uri);
+ if (info->uri == NULL) {
+ _E("Out of memory");
+ free(dup_uri);
+ return -1;
+ }
+
+ query = index(dup_uri, '?');
+ if (query == NULL) {
+ _rua_launch_context_free();
+ free(dup_uri);
+ return -1;
+ }
+
+ token = strtok_r(query + 1, "&", &saveptr);
+ while (token != NULL) {
+ if (info->id == NULL) {
+ info->id = __get_value_from_query(token,
+ QUERY_KEY_ID);
+ }
+
+ if (info->icon == NULL) {
+ info->icon = __get_value_from_query(token,
+ QUERY_KEY_ICON);
+ }
+
+ if (info->name == NULL) {
+ info->name = __get_value_from_query(token,
+ QUERY_KEY_NAME);
+ }
+
+ token = strtok_r(NULL, "&", &saveptr);
+ }
+ free(dup_uri);
+
+ if (info->id == NULL || info->icon == NULL || info->name == NULL) {
+ _W("Failed to get instance info");
+ _rua_launch_context_free();
+ return -1;
+ }
+
+ return 0;
+}
+
+int _rua_launch_context_set(bundle *kb)
+{
+ struct rua_launch_context_s *info = __get_launch_context();
+ const char *instance_id;
+ int ret;
+
+ ret = __set_launch_context(kb);
+ if (ret == 0) {
+ bundle_del(kb, AUL_K_INSTANCE_ID);
+ bundle_add(kb, AUL_K_INSTANCE_ID, info->id);
+ bundle_del(kb, AUL_K_NEW_INSTANCE);
+ bundle_add(kb, AUL_K_NEW_INSTANCE, "true");
+ bundle_del(kb, AUL_K_MULTI_INSTANCE_SHORTCUT);
+ bundle_add(kb, AUL_K_MULTI_INSTANCE_SHORTCUT, "true");
+ _D("Multiple instance launch - id(%s), name(%s), icon(%s)",
+ info->id, info->name, info->icon);
+ return 0;
+ }
+
+ instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ if (!instance_id)
+ return 0;
+
+ info->id = strdup(instance_id);
+ if (!info->id) {
+ _W("Out of memory");
+ return -1;
+ }
+
+ _D("Multiple instance launch - id(%s)", info->id);
+
+ return 0;
+}
+
+static int __on_launch_app_start_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_request_h req = (amd_request_h)arg3;
+ bundle *kb = data;
+ const char *launch_mode;
+ uid_t uid;
+
+ launch_mode = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
+ if (launch_mode && strcmp(launch_mode, "single")) {
+ uid = amd_request_get_target_uid(req);
+ if (!amd_launch_mode_is_group_mode(kb, uid))
+ bundle_del(kb, AUL_K_INSTANCE_ID);
+ }
+
+ _rua_launch_context_free();
+ _rua_launch_context_set(data);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+int _rua_launch_context_init(void)
+{
+ _D("RUA Launch Context Initialize");
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_START,
+ __on_launch_app_start_start);
+
+ return 0;
+}
+
+void _rua_launch_context_fini(void)
+{
+ _D("RUA Launch Context Finalize");
+
+ _rua_launch_context_free();
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <rua_internal.h>
+#include <rua_stat_internal.h>
+#include <aul.h>
+#include <amd.h>
+
+#include "amd_rua_request.h"
+#include "amd_rua_info.h"
+#include "amd_rua_private.h"
+
+static int __dispatch_update_rua_stat(amd_request_h req)
+{
+ char *caller = NULL;
+ char *tag = NULL;
+ bundle *kb;
+ uid_t uid;
+ int ret;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Invalid request");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_SVC_K_RUA_STAT_CALLER, &caller);
+ bundle_get_str(kb, AUL_SVC_K_RUA_STAT_TAG, &tag);
+
+ uid = amd_request_get_target_uid(req);
+ ret = rua_stat_usr_db_update(caller, tag, uid);
+ amd_request_send_result(req, ret);
+ _D("rua_stat_usr_db_update - uid(%d), result(%d)", uid, ret);
+
+ return 0;
+}
+
+static int __dispatch_add_history(amd_request_h req)
+{
+ struct rua_rec rec = {0,};
+ char *time_str = NULL;
+ bundle *kb;
+ uid_t uid;
+ int ret;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Invalid request");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_RUA_PKGNAME, &rec.pkg_name);
+ bundle_get_str(kb, AUL_K_RUA_APPPATH, &rec.app_path);
+ bundle_get_str(kb, AUL_K_RUA_ARG, &rec.arg);
+ bundle_get_str(kb, AUL_K_RUA_TIME, &time_str);
+ if (time_str != NULL)
+ rec.launch_time = atoi(time_str);
+ else
+ rec.launch_time = (int)time(NULL);
+ bundle_get_str(kb, AUL_K_RUA_INSTANCE_ID, &rec.instance_id);
+ bundle_get_str(kb, AUL_K_RUA_INSTANCE_NAME, &rec.instance_name);
+ bundle_get_str(kb, AUL_K_RUA_ICON, &rec.icon);
+ bundle_get_str(kb, AUL_K_RUA_URI, &rec.uri);
+
+ uid = amd_request_get_target_uid(req);
+ ret = rua_usr_db_add_history(&rec, uid);
+ amd_request_send_result(req, ret);
+ LOGD("rua_usr_db_add_history - uid(%d), result(%d)", uid, ret);
+
+ return 0;
+}
+
+static int __dispatch_remove_history(amd_request_h req)
+{
+ bundle *kb;
+ uid_t uid;
+ int ret;
+
+ kb = amd_request_get_bundle(req);
+ if (!kb) {
+ _E("Invalid request");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ uid = amd_request_get_target_uid(req);
+ ret = rua_usr_db_delete_history(kb, uid);
+ amd_request_send_result(req, ret);
+
+ _rua_info_remove(kb, uid);
+ LOGD("rua_usr_db_delete_history - uid(%d), result(%d)", uid, ret);
+
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_UPDATE_RUA_STAT,
+ .callback = __dispatch_update_rua_stat
+ },
+ {
+ .cmd = APP_ADD_HISTORY,
+ .callback = __dispatch_add_history
+ },
+ {
+ .cmd = APP_REMOVE_HISTORY,
+ .callback = __dispatch_remove_history
+ },
+
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_UPDATE_RUA_STAT,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+ {
+ .cmd = APP_ADD_HISTORY,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+ {
+ .cmd = APP_REMOVE_HISTORY,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+};
+
+int _rua_request_init(void)
+{
+ int ret;
+
+ _D("RUA Request Initialize");
+
+ ret = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (ret < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ ret = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (ret < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _rua_request_fini(void)
+{
+ _D("RUA Request Finalize");
+
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src
+ AMD_MOD_SCREEN_RESOLUTION_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_SCREEN_RESOLUTION}
+ ${AMD_MOD_SCREEN_RESOLUTION_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_SCREEN_RESOLUTION} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_SCREEN_RESOLUTION} PRIVATE
+ ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_SCREEN_RESOLUTION} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ TIZEN_EXTENSION_CLIENT_DEPS
+ TIZEN_LAUNCH_CLIENT_DEPS
+ WAYLAND_CLIENT_DEPS
+ WAYLAND_TBM_CLIENT_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_SCREEN_RESOLUTION} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/conf/amd_screen_resolution.conf
+ DESTINATION ${AMD_MODULES_DIR}/conf)
--- /dev/null
+[Screen Resolution]
+responsive
+4k_only
+2k_only
+1k_only
+4k
+2k
+1k
+max
+
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <amd.h>
+#include <amd_mod_common.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <bundle_internal.h>
+#include <tizen-extension-client-protocol.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tzplatform_config.h>
+#include <tizen-launch-client-protocol.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_SCREEN_RESOLUTION"
+
+struct wayland_context_s {
+ struct wl_display *display;
+ struct tizen_launch_appinfo *launch_appinfo;
+ uint32_t launch_appinfo_id;
+};
+
+static struct wayland_context_s __context;
+
+static int __launch_appinfo_register_appid(const char *appid)
+{
+ if (!__context.display) {
+ __context.display = amd_wayland_get_display();
+ if (!__context.display) {
+ LOGW("Failed to get wayland display");
+ return -1;
+ }
+ }
+
+ if (!__context.launch_appinfo) {
+ LOGW("Failed to bind tizen launch appinfo");
+ return -1;
+ }
+
+ tizen_launch_appinfo_register_appid(__context.launch_appinfo,
+ appid);
+ wl_display_flush(__context.display);
+ LOGI("Register appid: %s", appid);
+
+ return 0;
+}
+
+static int __launch_appinfo_deregister_appid(const char *appid)
+{
+ if (!__context.display) {
+ __context.display = amd_wayland_get_display();
+ if (!__context.display) {
+ LOGW("Failed to get wayland display");
+ return -1;
+ }
+ }
+
+ if (!__context.launch_appinfo) {
+ LOGW("Failed to bind tizen launch appinfo");
+ return -1;
+ }
+
+ tizen_launch_appinfo_deregister_appid(__context.launch_appinfo, appid);
+ wl_display_flush(__context.display);
+ LOGI("Deregister appid: %s", appid);
+
+ return 0;
+}
+
+static int __launch_appinfo_launch_app(const char *appid, int pid)
+{
+ if (!appid || pid < 0) {
+ LOGE("Invalid parameter");
+ return -1;
+ }
+
+ if (!__context.display) {
+ __context.display = amd_wayland_get_display();
+ if (!__context.display) {
+ LOGW("Failed to get wayland display");
+ return -1;
+ }
+ }
+
+ if (!__context.launch_appinfo) {
+ LOGW("Failed to bind tizen launch appinfo");
+ return -1;
+ }
+
+ tizen_launch_appinfo_set_pid(__context.launch_appinfo,
+ appid, (uint32_t)pid);
+ tizen_launch_appinfo_ready_metadata(__context.launch_appinfo,
+ appid, (uint32_t)pid);
+ wl_display_flush(__context.display);
+ LOGI("Launch app. %s:%d", appid, pid);
+
+ return 0;
+}
+
+static int __on_wayland_listener_tizen_launch_appinfo(const char *msg,
+ int arg1, int arg2, void *arg3, bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+ struct wl_registry *registry = (struct wl_registry *)arg3;
+
+ if (!__context.launch_appinfo) {
+ __context.launch_appinfo_id = id;
+ __context.launch_appinfo = wl_registry_bind(registry, id,
+ &tizen_launch_appinfo_interface, 1);
+ LOGI("tizen_launch_appinfo(%p), id(%u)",
+ __context.launch_appinfo, id);
+ }
+
+ if (!__context.display)
+ __context.display = amd_wayland_get_display();
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_wayland_listener_remove(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+
+ if (id == __context.launch_appinfo_id && __context.launch_appinfo) {
+ tizen_launch_appinfo_destroy(__context.launch_appinfo);
+ __context.launch_appinfo = NULL;
+ __context.launch_appinfo_id = 0;
+ LOGW("tizen_launch_appinfo is destroyed");
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+static int __on_launch_prepare_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comp_type;
+ const char *appid;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
+ appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+ LOGI("prepare start appid: %s", appid);
+ __launch_appinfo_register_appid(appid);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ bool new_process = (bool)arg2;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comp_type;
+ const char *appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+
+ if (!new_process)
+ return AMD_NOTI_CONTINUE;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && strcmp(comp_type, APP_TYPE_SERVICE) != 0) {
+ LOGI("complete start app end pid: %d", pid);
+ __launch_appinfo_launch_app(appid, pid);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_main_app_dead(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+ const char *appid = amd_app_status_get_appid(app_status);
+ int app_type = amd_app_status_get_app_type(app_status);
+
+ if (app_type != AMD_AT_SERVICE_APP)
+ __launch_appinfo_deregister_appid(appid);
+
+ LOGI("main app dead: %s", appid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ LOGD("screen resolution init");
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_APPINFO,
+ __on_wayland_listener_tizen_launch_appinfo);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
+ __on_wayland_listener_remove);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_START,
+ __on_launch_prepare_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ __on_launch_complete_start);
+ amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
+ __on_main_app_dead);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ LOGD("screen resolution fini");
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_SHARE_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_SHARE} ${AMD_MOD_SHARE_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_SHARE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_SHARE} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_SHARE} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ LIBTZPLATFORM_CONFIG_DEPS
+ SECURITY_MANAGER_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_SHARE} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2016 - 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <linux/limits.h>
+
+#include <glib.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_svc.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <tzplatform_config.h>
+#include <security-manager.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_SHARE"
+
+#define LEGACY_APP_PATH "/opt/usr/apps/"
+#define AUL_SVC_K_URI "__APP_SVC_URI__"
+#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
+
+typedef struct _shared_info_t {
+ char *owner_appid;
+ private_sharing_req *handle;
+} shared_info_t;
+
+struct shared_info_main_s {
+ char *appid;
+ uid_t uid;
+ shared_info_t *shared_info;
+};
+
+typedef struct shared_info_main_s *shared_info_h;
+
+static shared_info_h __cur_shared_info;
+static int __temporary_permission_destroy(shared_info_h handle);
+
+static int __can_share(const char *path, const char *pkgid, uid_t uid)
+{
+ struct stat path_stat;
+ char buf[PATH_MAX];
+
+ if (stat(path, &path_stat) != 0) {
+ _E("failed to stat file to share (%s, %d)", path, errno);
+ return -1;
+ }
+
+ if (!S_ISREG(path_stat.st_mode)) {
+ _E("file is not a regular file (%s)", path);
+ return -1;
+ }
+
+ tzplatform_set_user(uid);
+ snprintf(buf, sizeof(buf), "%s/%s/data/",
+ tzplatform_getenv(TZ_USER_APP), pkgid);
+ tzplatform_reset_user();
+
+ if (strncmp(path, buf, strlen(buf)) != 0) {
+ SECURE_LOGD("file is not in app's data directory (%s)", path);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __get_owner_pid(int caller_pid, bundle *kb)
+{
+ char *org_caller = NULL;
+ const char *appid;
+ int org_caller_pid;
+ amd_app_status_h app_status;
+ int ret;
+
+ ret = bundle_get_str(kb, AUL_K_ORG_CALLER_PID, &org_caller);
+ if (ret != BUNDLE_ERROR_NONE)
+ return caller_pid;
+
+ org_caller_pid = atoi(org_caller);
+ app_status = amd_app_status_find_by_pid(caller_pid);
+ appid = amd_app_status_get_appid(app_status);
+ if (appid && (strcmp(APP_SELECTOR, appid) == 0 ||
+ strcmp(SHARE_PANEL, appid) == 0))
+ caller_pid = org_caller_pid;
+
+ return caller_pid;
+}
+
+static const char *__get_owner_appid(int caller_pid, bundle *kb)
+{
+ const char *owner_appid;
+ int owner_pid = -1;
+ amd_app_status_h app_status;
+
+ owner_pid = __get_owner_pid(caller_pid, kb);
+ owner_pid = getpgid(owner_pid); /* for webapp */
+ app_status = amd_app_status_find_by_pid(owner_pid);
+ owner_appid = amd_app_status_get_appid(app_status);
+
+ return owner_appid;
+}
+
+static shared_info_h __new_shared_info_handle(const char *appid, uid_t uid,
+ const char *owner_appid)
+{
+ shared_info_h h;
+ int ret;
+
+ h = malloc(sizeof(struct shared_info_main_s));
+ if (h == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ h->shared_info = malloc(sizeof(shared_info_t));
+ if (h->shared_info == NULL) {
+ _E("Out of memory");
+ free(h);
+ return NULL;
+ }
+
+ ret = security_manager_private_sharing_req_new(&h->shared_info->handle);
+ if (ret != SECURITY_MANAGER_SUCCESS) {
+ _E("Failed to create private sharing request handle");
+ free(h->shared_info);
+ free(h);
+ return NULL;
+ }
+
+ h->shared_info->owner_appid = strdup(owner_appid);
+ if (h->shared_info->owner_appid == NULL) {
+ _E("Out of memory");
+ security_manager_private_sharing_req_free(
+ h->shared_info->handle);
+ free(h->shared_info);
+ free(h);
+ return NULL;
+ }
+
+ h->appid = strdup(appid);
+ if (h->appid == NULL) {
+ _E("Out of memory");
+ free(h->shared_info->owner_appid);
+ security_manager_private_sharing_req_free(
+ h->shared_info->handle);
+ free(h->shared_info);
+ free(h);
+ return NULL;
+ }
+ h->uid = uid;
+
+ return h;
+}
+
+static char *__convert_legacy_path(const char *path, uid_t uid)
+{
+ char buf[PATH_MAX];
+ int len = strlen(LEGACY_APP_PATH);
+
+ if (strncmp(LEGACY_APP_PATH, path, len) == 0) {
+ tzplatform_set_user(uid);
+ snprintf(buf, sizeof(buf), "%s/%s",
+ tzplatform_getenv(TZ_USER_APP), &path[len]);
+ tzplatform_reset_user();
+
+ return strdup(buf);
+ }
+
+ return strdup(path);
+}
+
+static GList *__add_valid_uri(GList *paths, int caller_pid, const char *appid,
+ const char *owner_appid, bundle *kb, uid_t uid)
+{
+ char *path = NULL;
+ const char *pkgid;
+ amd_appinfo_h ai;
+ int ret;
+
+ ret = bundle_get_str(kb, AUL_SVC_K_URI, &path);
+ if (ret != BUNDLE_ERROR_NONE)
+ return paths;
+
+ if (!path) {
+ _D("path was null");
+ return paths;
+ }
+
+ if (strncmp(path, "file://", 7) == 0) {
+ path = &path[7];
+ } else {
+ _E("file wasn't started with file://");
+ return paths;
+ }
+
+ ai = amd_appinfo_find(uid, owner_appid);
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+
+ path = __convert_legacy_path(path, uid);
+ if (__can_share(path, pkgid, uid) != 0) {
+ _E("__can_share() returned an error");
+ free(path);
+ return paths;
+ }
+ paths = g_list_append(paths, path);
+
+ return paths;
+}
+
+static GList *__add_valid_key_for_data_selected(GList *paths, int caller_pid,
+ const char *appid, const char *owner_appid, bundle *kb,
+ uid_t uid)
+{
+ int i;
+ int len = 0;
+ const char **path_array = NULL;
+ char *path_str;
+ int type = bundle_get_type(kb, AUL_SVC_DATA_SELECTED);
+ const char *pkgid = NULL;
+ amd_appinfo_h ai = NULL;
+
+ if (type != BUNDLE_TYPE_STR_ARRAY)
+ return paths;
+
+ path_array = bundle_get_str_array(kb, AUL_SVC_DATA_SELECTED, &len);
+ if (!path_array || len <= 0) {
+ _E("path_array was null");
+ return paths;
+ }
+
+ ai = amd_appinfo_find(uid, owner_appid);
+ if (ai == NULL) {
+ _E("appinfo is NULL");
+ return paths;
+ }
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ if (pkgid == NULL) {
+ _E("pkgid was null");
+ return paths;
+ }
+
+ for (i = 0; i < len; i++) {
+ path_str = __convert_legacy_path(path_array[i], uid);
+ if (__can_share(path_str, pkgid, uid) == 0)
+ paths = g_list_append(paths, path_str);
+ else
+ free(path_str);
+ }
+
+ return paths;
+}
+
+static GList *__add_valid_key_for_data_path(GList *paths, int caller_pid,
+ const char *appid, const char *owner_appid, bundle *kb,
+ uid_t uid)
+{
+ int type = bundle_get_type(kb, AUL_SVC_DATA_PATH);
+ char *path = NULL;
+ const char **path_array = NULL;
+ int len;
+ int i;
+ const char *pkgid = NULL;
+ amd_appinfo_h ai = NULL;
+ char *path_str;
+
+ switch (type) {
+ case BUNDLE_TYPE_STR:
+ bundle_get_str(kb, AUL_SVC_DATA_PATH, &path);
+ if (!path) {
+ _E("path was null");
+ break;
+ }
+
+ ai = amd_appinfo_find(uid, owner_appid);
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ if (pkgid == NULL) {
+ _E("pkgid was null");
+ break;
+ }
+
+ path = __convert_legacy_path(path, uid);
+ if (__can_share(path, pkgid, uid) != 0) {
+ _E("__can_share() returned an error");
+ free(path);
+ break;
+ }
+
+ paths = g_list_append(paths, path);
+ break;
+ case BUNDLE_TYPE_STR_ARRAY:
+ path_array = bundle_get_str_array(kb, AUL_SVC_DATA_PATH, &len);
+ if (!path_array || len <= 0) {
+ _E("path_array was null");
+ break;
+ }
+
+ ai = amd_appinfo_find(uid, owner_appid);
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ if (pkgid == NULL) {
+ _E("pkgid was null");
+ break;
+ }
+
+ for (i = 0; i < len; i++) {
+ path_str = __convert_legacy_path(path_array[i], uid);
+ if (__can_share(path_str, pkgid, uid) == 0)
+ paths = g_list_append(paths, path_str);
+ else
+ free(path_str);
+ }
+
+ break;
+ }
+
+ return paths;
+}
+
+static char **__convert_list_to_array(GList *list)
+{
+ int len;
+ int i = 0;
+ char **array;
+
+ if (list == NULL)
+ return NULL;
+
+ len = g_list_length(list);
+ if (len == 0)
+ return NULL;
+
+ array = (char **)g_malloc0(sizeof(char *) * (len + 1));
+ if (array == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ while (list) {
+ array[i] = g_strdup(list->data);
+ if (array[i] == NULL) {
+ _E("Out of memory");
+ g_strfreev(array);
+ return NULL;
+ }
+
+ list = g_list_next(list);
+ i++;
+ }
+ array[len] = NULL;
+
+ return array;
+}
+
+static int __destroy_status(amd_app_status_h status)
+{
+ GList *list;
+ GList *i;
+ shared_info_t *shared_info;
+
+ if (!status)
+ return -1;
+
+ list = amd_app_status_get_extra(status, "share");
+ if (!list)
+ return -1;
+
+ i = list;
+ while (i) {
+ shared_info = (shared_info_t *)i->data;
+ if (shared_info) {
+ if (shared_info->owner_appid)
+ free(shared_info->owner_appid);
+ free(shared_info);
+ }
+ i = g_list_next(i);
+ }
+
+ g_list_free(list);
+ amd_app_status_remove_extra(status, "share");
+
+ return 0;
+}
+
+static shared_info_h __temporary_permission_create(int caller_pid, const char *appid,
+ bundle *kb, uid_t uid)
+{
+ char **path_array = NULL;
+ int len;
+ const char *owner_appid = NULL;
+ GList *paths = NULL;
+ shared_info_h h = NULL;
+ int r;
+
+ owner_appid = __get_owner_appid(caller_pid, kb);
+ paths = __add_valid_key_for_data_path(paths, caller_pid, appid,
+ owner_appid, kb, uid);
+ paths = __add_valid_key_for_data_selected(paths, caller_pid, appid,
+ owner_appid, kb, uid);
+ paths = __add_valid_uri(paths, caller_pid, appid, owner_appid, kb, uid);
+ if (!paths || !owner_appid)
+ goto clear;
+
+ _D("grant permission %s : %s", owner_appid, appid);
+
+ h = __new_shared_info_handle(appid, uid, owner_appid);
+ if (h == NULL)
+ goto clear;
+
+ len = g_list_length(paths);
+ path_array = __convert_list_to_array(paths);
+ if (path_array == NULL)
+ goto clear;
+
+ r = security_manager_private_sharing_req_set_owner_appid(
+ h->shared_info->handle, owner_appid);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ _E("Failed to set owner appid(%s) %d", owner_appid, r);
+
+ r = security_manager_private_sharing_req_set_target_appid(
+ h->shared_info->handle, appid);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ _E("Failed to set target appid(%s) %d", appid, r);
+
+ r = security_manager_private_sharing_req_add_paths(
+ h->shared_info->handle, (const char **)path_array, len);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ _E("Failed to add paths %d", r);
+
+ _D("security_manager_private_sharing_apply ++");
+ r = security_manager_private_sharing_apply(h->shared_info->handle);
+ _D("security_manager_private_sharing_apply --");
+ if (r != SECURITY_MANAGER_SUCCESS) {
+ _E("Failed to apply private sharing %d", r);
+ __temporary_permission_destroy(h);
+ h = NULL;
+ }
+
+clear:
+ if (paths)
+ g_list_free_full(paths, free);
+
+ if (path_array)
+ g_strfreev(path_array);
+
+ return h;
+}
+
+static int __temporary_permission_apply(int pid, uid_t uid, shared_info_h handle)
+{
+ amd_app_status_h status;
+ GList *list;
+
+ if (handle == NULL)
+ return -1;
+
+ status = amd_app_status_find_by_pid(pid);
+ if (status == NULL)
+ return -1;
+
+ list = amd_app_status_get_extra(status, "share");
+ list = g_list_append(list, handle->shared_info);
+ amd_app_status_set_extra(status, "share", list);
+ handle->shared_info = NULL;
+
+ return 0;
+}
+
+static int __temporary_permission_destroy(shared_info_h handle)
+{
+ int r;
+
+ if (handle == NULL)
+ return -1;
+
+ if (handle->shared_info) { /* back out */
+ _D("revoke permission %s : %s",
+ handle->shared_info->owner_appid,
+ handle->appid);
+ r = security_manager_private_sharing_drop(
+ handle->shared_info->handle);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ _E("revoke error %d", r);
+
+ security_manager_private_sharing_req_free(
+ handle->shared_info->handle);
+ free(handle->shared_info->owner_appid);
+ }
+
+ free(handle->appid);
+ free(handle);
+
+ return 0;
+}
+
+static int __temporary_permission_drop(int pid, uid_t uid)
+{
+ int r;
+ shared_info_t *sit;
+ amd_app_status_h app_status;
+ GList *list;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL)
+ return -1;
+
+ list = amd_app_status_get_extra(app_status, "share");
+ if (!list) {
+ _D("list was null");
+ return -1;
+ }
+
+ while (list) {
+ sit = (shared_info_t *)list->data;
+ _D("revoke permission %s : %d", sit->owner_appid, pid);
+ r = security_manager_private_sharing_drop(sit->handle);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ _E("revoke error %d", r);
+ security_manager_private_sharing_req_free(sit->handle);
+ list = g_list_next(list);
+ }
+
+ return __destroy_status(app_status);
+}
+
+static int __temporary_permission_drop_with_owner(const char *owner_appid,
+ int pid, uid_t uid)
+{
+ shared_info_t *shared_info;
+ amd_app_status_h app_status;
+ GList *list;
+ GList *iter;
+ int ret;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL)
+ return -1;
+
+ list = amd_app_status_get_extra(app_status, "share");
+ if (!list) {
+ _D("list was null");
+ return -1;
+ }
+
+ iter = list;
+ while (iter) {
+ shared_info = (shared_info_t *)iter->data;
+ iter = g_list_next(iter);
+ if (!strcmp(shared_info->owner_appid, owner_appid)) {
+ list = g_list_remove(list, shared_info);
+ _D("Revoke permission %s : %d",
+ shared_info->owner_appid, pid);
+ ret = security_manager_private_sharing_drop(shared_info->handle);
+ if (ret != SECURITY_MANAGER_SUCCESS)
+ _E("Revoke error %d", ret);
+
+ security_manager_private_sharing_req_free(shared_info->handle);
+ free(shared_info->owner_appid);
+ free(shared_info);
+ }
+ }
+
+ if (list)
+ amd_app_status_set_extra(app_status, "share", list);
+ else
+ amd_app_status_remove_extra(app_status, "share");
+
+ return 0;
+}
+
+static int __on_app_result_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ char *appid = arg3;
+ int pid = arg1;
+ uid_t uid = arg2;
+
+ if (appid) {
+ __cur_shared_info = __temporary_permission_create(pid, appid, data, uid);
+ if (__cur_shared_info == NULL)
+ _D("No sharable path : %d %s", pid, appid);
+ }
+
+ return 0;
+}
+
+static int __on_app_result_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = arg2;
+ int res = GPOINTER_TO_INT(arg3);
+ int ret;
+
+ if (__cur_shared_info) {
+ if (res >= 0) {
+ ret = __temporary_permission_apply(pid, uid, __cur_shared_info);
+ if (ret != 0) {
+ _D("Couldn't apply temporary permission: %d",
+ ret);
+ }
+ }
+ __temporary_permission_destroy(__cur_shared_info);
+ __cur_shared_info = NULL;
+ }
+
+ return 0;
+}
+
+static int __on_launch_prepare_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int caller_pid = arg1;
+ uid_t target_uid = arg2;
+ const char *appid;
+ amd_appinfo_h ai = arg3;
+ amd_app_status_h status;
+ const char *caller_appid;
+
+ appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+ status = amd_app_status_find_by_pid(caller_pid);
+ caller_appid = amd_app_status_get_appid(status);
+
+ if (caller_appid) {
+ __cur_shared_info = __temporary_permission_create(caller_pid,
+ appid, data, target_uid);
+ if (__cur_shared_info == NULL)
+ _W("No sharable path: %d %s", caller_pid, appid);
+ }
+
+ return 0;
+}
+
+static int __on_launch_complete_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t target_uid = arg2;
+ int ret;
+
+ if (__cur_shared_info) {
+ ret = __temporary_permission_apply(pid, target_uid,
+ __cur_shared_info);
+ if (ret < 0)
+ _D("Couldn't apply temporary permission: %d", ret);
+
+ __temporary_permission_destroy(__cur_shared_info);
+ __cur_shared_info = NULL;
+ }
+
+ return 0;
+}
+
+static int __on_launch_cancel(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ if (__cur_shared_info) {
+ __temporary_permission_destroy(__cur_shared_info);
+ __cur_shared_info = NULL;
+ }
+
+ return 0;
+}
+
+static int __on_app_status_destroy(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h status = arg3;
+
+ __destroy_status(status);
+
+ return 0;
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = arg2;
+
+ __temporary_permission_drop(pid, uid);
+
+ return 0;
+}
+
+static int __dispatch_set_private_sharing(amd_request_h req)
+{
+ uid_t target_uid = amd_request_get_target_uid(req);
+ int caller_pid = amd_request_get_pid(req);
+ int callee_pid;
+ bundle *data = amd_request_get_bundle(req);
+ const char *callee_appid;
+ const char *caller_appid;
+ amd_app_status_h caller_app_status;
+ amd_app_status_h callee_app_status;
+ int ret;
+
+ if (data == NULL)
+ return -1;
+
+ caller_app_status = amd_app_status_find_by_pid(caller_pid);
+ caller_appid = amd_app_status_get_appid(caller_app_status);
+ callee_appid = bundle_get_val(data, AUL_K_CALLEE_APPID);
+ shared_info_h info = __temporary_permission_create(caller_pid,
+ callee_appid, data, target_uid);
+ if (info == NULL) {
+ _W("No sharable path: %d %s", caller_pid, caller_appid);
+ return -1;
+ }
+
+ callee_app_status = amd_app_status_find_by_appid(callee_appid, target_uid);
+ callee_pid = amd_app_status_get_pid(callee_app_status);
+ ret = __temporary_permission_apply(callee_pid, target_uid, info);
+ if (ret != 0) {
+ _E("Couldn't apply temporary permission: %d",
+ ret);
+ }
+ __temporary_permission_destroy(info);
+ _I("caller(%s), callee(%s), result(%d)",
+ caller_appid, callee_appid, ret);
+
+ return ret;
+}
+
+static int __dispatch_unset_private_sharing(amd_request_h req)
+{
+ const char *callee_appid;
+ const char *caller_appid;
+ int callee_pid;
+ amd_app_status_h callee_app_status;
+ amd_app_status_h caller_app_status;
+ int caller_pid = amd_request_get_pid(req);
+ uid_t target_uid = amd_request_get_target_uid(req);
+ bundle *data = amd_request_get_bundle(req);
+
+ caller_app_status = amd_app_status_find_by_pid(caller_pid);
+ caller_appid = amd_app_status_get_appid(caller_app_status);
+ callee_appid = bundle_get_val(data, AUL_K_CALLEE_APPID);
+ callee_app_status = amd_app_status_find_by_appid(callee_appid, target_uid);
+ callee_pid = amd_app_status_get_pid(callee_app_status);
+
+ __temporary_permission_drop_with_owner(caller_appid, callee_pid, target_uid);
+
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = SET_PRIVATE_SHARING,
+ .callback = __dispatch_set_private_sharing
+ },
+ {
+ .cmd = UNSET_PRIVATE_SHARING,
+ .callback = __dispatch_unset_private_sharing
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = SET_PRIVATE_SHARING,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_DATASHARING,
+ .priority = 10
+ },
+};
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ _D("share init");
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register cynara checkers");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_RESULT_START,
+ __on_app_result_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_RESULT_END,
+ __on_app_result_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_END,
+ __on_launch_prepare_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
+ __on_launch_complete_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
+ __on_launch_cancel);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_RELAUNCH_CANCEL,
+ __on_launch_cancel);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_DESTROY,
+ __on_app_status_destroy);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("share finish");
+}
+
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_SPLASH_SCREEN_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_SPLASH_SCREEN} ${AMD_MOD_SPLASH_SCREEN_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_SPLASH_SCREEN} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_SPLASH_SCREEN} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_SPLASH_SCREEN} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ SENSOR_DEPS
+ TIZEN_EXTENSION_CLIENT_DEPS
+ TIZEN_LAUNCH_CLIENT_DEPS
+ WAYLAND_CLIENT_DEPS
+ WAYLAND_TBM_CLIENT_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_SPLASH_SCREEN} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdbool.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <glib.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_svc.h>
+#include <aul_svc_priv_key.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tizen-launch-client-protocol.h>
+#include <vconf.h>
+#include <sensor_internal.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_SPLASH_SCREEN"
+
+#define APP_CONTROL_OPERATION_MAIN "http://tizen.org/appcontrol/operation/main"
+#define K_FAKE_EFFECT "__FAKE_EFFECT__"
+#define SPLASH_SCREEN_INFO_PATH "/usr/share/aul"
+#define TAG_SPLASH_IMAGE "[SplashImage]"
+#define TAG_NAME "Name"
+#define TAG_FILE "File"
+#define TAG_TYPE "Type"
+#define TAG_ORIENTATION "Orientation"
+#define TAG_INDICATOR_DISPLAY "Indicator-display"
+#define TAG_COLOR_DEPTH "Color-depth"
+#define TIMEOUT_INTERVAL 10000 /* 10 sec */
+#define CUSTOM_EFFECT_CALLEE "_CUSTOM_EFFECT_CALLEE_"
+
+#define TIZEN_FEATURE_CHARGER_STATUS \
+ (amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_WEARABLE))
+#define TIZEN_FEATURE_AUTO_ROTATION \
+ (!(amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_TV)))
+
+#define FREE_AND_NULL(x) \
+ do { \
+ if (x) { \
+ free(x); \
+ x = NULL; \
+ } \
+ } while (0)
+
+struct splash_image_s {
+ struct tizen_launch_splash *image;
+ char *appid;
+ char *src;
+ int type;
+ int rotation;
+ int indicator;
+ int color_depth;
+ int pid;
+ bool custom_effect;
+ char *effect_type;
+ char *theme_type;
+ guint timer;
+};
+
+struct rotation_s {
+ sensor_t sensor;
+ int handle;
+ int angle;
+ int auto_rotate;
+ int charger_status;
+ bool initialized;
+ guint timer;
+};
+
+struct image_info_s {
+ char *name;
+ char *file;
+ char *type;
+ char *orientation;
+ char *indicator_display;
+ char *color_depth;
+};
+
+typedef struct splash_image_s *splash_image_h;
+static struct wl_display *display;
+static struct tizen_launch_effect *tz_launch_effect;
+static int splash_screen_initialized;
+static struct rotation_s rotation;
+static GList *default_image_list;
+static splash_image_h splash_image;
+static splash_image_h cur_splash_image;
+static uint32_t tz_launch_effect_id;
+
+static int __init_splash_screen(void);
+static int __init_rotation(void);
+
+static splash_image_h __splash_screen_get_image(int pid)
+{
+ if (splash_image == NULL)
+ return NULL;
+
+ if (splash_image->pid == pid)
+ return splash_image;
+
+ return NULL;
+}
+
+static void __set_splash_image(splash_image_h si)
+{
+ splash_image = si;
+}
+
+static void __splash_screen_destroy_image(splash_image_h si)
+{
+ if (si == NULL)
+ return;
+
+ if (si->timer)
+ g_source_remove(si->timer);
+ if (si->theme_type)
+ free(si->theme_type);
+ if (si->effect_type)
+ free(si->effect_type);
+ if (si->appid)
+ free(si->appid);
+ if (si->src)
+ free(si->src);
+ if (si->image) {
+ tizen_launch_splash_destroy(si->image);
+ wl_display_flush(display);
+ }
+ free(si);
+ __set_splash_image(NULL);
+}
+
+static gboolean __timeout_handler(gpointer data)
+{
+ splash_image_h si = (splash_image_h)data;
+ amd_app_status_h app_status;
+
+ if (si == NULL)
+ return FALSE;
+
+ app_status = amd_app_status_find_by_pid(si->pid);
+ if (app_status) {
+ if (amd_app_status_is_starting(app_status) == false) {
+ _W("% is not starting", si->pid);
+ return TRUE;
+ }
+ }
+
+ si->timer = 0;
+ __splash_screen_destroy_image(si);
+
+ return FALSE;
+}
+
+static int __app_can_launch_splash_image(amd_appinfo_h ai, bundle *kb)
+{
+ const char *comp_type;
+ const char *fake_effect;
+ int display;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type == NULL || strcmp(comp_type, APP_TYPE_UI) != 0) {
+ _D("component_type: %s", comp_type);
+ return -1;
+ }
+
+ fake_effect = bundle_get_val(kb, K_FAKE_EFFECT);
+ if (fake_effect && !strcmp(fake_effect, "OFF"))
+ return -1;
+
+ amd_appinfo_get_int_value(ai, AMD_AIT_SPLASH_SCREEN_DISPLAY, &display);
+ if (!(display & APP_ENABLEMENT_MASK_ACTIVE))
+ return -1;
+
+ return 0;
+}
+
+static struct appinfo_splash_image *__get_splash_image_info(
+ amd_appinfo_h ai, bundle *kb, int cmd)
+{
+ amd_appinfo_h caller_ai;
+ amd_appinfo_splash_image_h image;
+ const char *operation;
+ const char *uid_str;
+ const char *caller_appid;
+ const char *comp_type;
+ uid_t uid = 0;
+ bool landscape;
+
+ if ((rotation.angle == 90 || rotation.angle == 270)
+ && rotation.auto_rotate == true)
+ landscape = true;
+ else
+ landscape = false;
+
+ operation = bundle_get_val(kb, AUL_SVC_K_OPERATION);
+ if (cmd == APP_OPEN || (operation &&
+ (!strcmp(operation, APP_CONTROL_OPERATION_MAIN) ||
+ !strcmp(operation, AUL_SVC_OPERATION_DEFAULT)))) {
+ image = amd_appinfo_find_splash_image(ai, "launch-effect",
+ landscape);
+ if (image)
+ return image;
+ }
+
+ if (operation) {
+ image = amd_appinfo_find_splash_image(ai, operation, landscape);
+ if (image)
+ return image;
+ }
+
+ caller_appid = bundle_get_val(kb, AUL_K_CALLER_APPID);
+ if (caller_appid == NULL)
+ return NULL;
+
+ uid_str = bundle_get_val(kb, AUL_K_TARGET_UID);
+ if (uid_str == NULL)
+ return NULL;
+
+ if (isdigit(*uid_str))
+ uid = atol(uid_str);
+ caller_ai = amd_appinfo_find(uid, caller_appid);
+ if (caller_ai == NULL)
+ return NULL;
+
+ comp_type = amd_appinfo_get_value(caller_ai, AMD_AIT_COMPTYPE);
+ if (comp_type == NULL)
+ return NULL;
+
+ if (!strcmp(comp_type, APP_TYPE_WATCH) ||
+ !strcmp(comp_type, APP_TYPE_WIDGET)) {
+ return amd_appinfo_find_splash_image(ai, "launch-effect",
+ landscape);
+ }
+
+ return NULL;
+}
+
+static struct image_info_s *__get_default_image_info(bundle *kb)
+{
+ struct image_info_s *info = NULL;
+ const char *orientation = "portrait";
+ const char *str;
+ GList *list;
+
+ if (default_image_list == NULL)
+ return NULL;
+
+ if ((rotation.angle == 90 || rotation.angle == 270) &&
+ rotation.auto_rotate == true)
+ orientation = "landscape";
+
+ str = bundle_get_val(kb, AUL_SVC_K_SPLASH_SCREEN);
+ if (str == NULL)
+ str = "default";
+
+ list = default_image_list;
+ while (list) {
+ info = (struct image_info_s *)list->data;
+ if (info && strcmp(str, info->name) == 0) {
+ if (!strcasecmp(info->orientation, orientation))
+ return info;
+ }
+
+ list = g_list_next(list);
+ }
+
+ return NULL;
+}
+
+static splash_image_h __splash_screen_create_image(amd_appinfo_h ai,
+ bundle *kb, int cmd, bool is_subapp, bool custom_effect)
+{
+ amd_appinfo_splash_image_h image_info;
+ struct splash_image_s *si;
+ struct image_info_s *info;
+ const char *appid;
+ const char *src = NULL;
+ const char *type;
+ int file_type = 0;
+ int indicator = 1;
+ int color_depth = 24; /* default */
+
+ if (!splash_screen_initialized) {
+ if (__init_splash_screen() < 0)
+ return NULL;
+ }
+
+ if (__app_can_launch_splash_image(ai, kb) < 0)
+ return NULL;
+
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ if (rotation.charger_status) {
+ if (!rotation.initialized && __init_rotation() < 0)
+ _W("Failed to initialize rotation");
+ }
+ } else {
+ if (!rotation.initialized && __init_rotation() < 0)
+ _W("Failed to initialize rotation");
+ }
+ _D("angle: %d", rotation.angle);
+
+ image_info = __get_splash_image_info(ai, kb, cmd);
+ if (image_info) {
+ src = amd_appinfo_splash_image_get_source(image_info);
+ if (access(src, F_OK) != 0)
+ return NULL;
+ type = amd_appinfo_splash_image_get_type(image_info);
+ if (type && strcasecmp(type, "edj") == 0)
+ file_type = 1;
+ indicator = amd_appinfo_splash_image_get_indicator_display(
+ image_info);;
+ color_depth = amd_appinfo_splash_image_get_color_depth(
+ image_info);
+ } else {
+ info = __get_default_image_info(kb);
+ if (info == NULL)
+ return NULL;
+ src = info->file;
+ if (access(src, F_OK) != 0)
+ return NULL;
+ if (strcasecmp(info->type, "edj") == 0)
+ file_type = 1;
+ if (strcmp(info->indicator_display, "false") == 0)
+ indicator = 0;
+ if (strcmp(info->color_depth, "32") == 0)
+ color_depth = 32;
+ }
+
+ si = (struct splash_image_s *)calloc(1, sizeof(struct splash_image_s));
+ if (si == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ si->image = tizen_launch_effect_create_splash_img(
+ tz_launch_effect);
+ if (si->image == NULL) {
+ _E("Failed to get launch image");
+ free(si);
+ return NULL;
+ }
+ wl_display_flush(display);
+
+ si->src = strdup(src);
+ if (si->src == NULL) {
+ _E("out of memory");
+ __splash_screen_destroy_image(si);
+ return NULL;
+ }
+
+ if (is_subapp)
+ si->effect_type = strdup("depth-in");
+ else
+ si->effect_type = strdup("launch");
+ if (si->effect_type == NULL) {
+ _E("Out of memory");
+ __splash_screen_destroy_image(si);
+ return NULL;
+ }
+
+ si->theme_type = strdup("default");
+ if (si->theme_type == NULL) {
+ _E("Out of memory");
+ __splash_screen_destroy_image(si);
+ return NULL;
+ }
+
+ appid = amd_appinfo_get_value(ai, AMD_AIT_NAME);
+ si->appid = strdup(appid);
+ if (si->appid == NULL) {
+ _E("out of memory");
+ __splash_screen_destroy_image(si);
+ return NULL;
+ }
+
+ si->type = file_type;
+ si->rotation = rotation.angle;
+ si->indicator = indicator;
+ si->color_depth = color_depth;
+ si->custom_effect = custom_effect;
+
+ si->timer = g_timeout_add(TIMEOUT_INTERVAL, __timeout_handler, si);
+ __set_splash_image(si);
+
+ return si;
+}
+
+static void __set_options(struct wl_array *options, const char *app_id)
+{
+ bundle *b;
+ bundle_raw *raw = NULL;
+ int len = 0;
+ int ret;
+ size_t size;
+ void *data;
+
+ b = bundle_create();
+ if (!b) {
+ _E("Out of memory");
+ return;
+ }
+
+ bundle_add(b, AUL_K_APPID, app_id);
+ ret = bundle_encode(b, &raw, &len);
+ bundle_free(b);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Failed to encode bundle. error(%d)", ret);
+ return;
+ }
+
+ size = strlen((const char *)raw) + 1;
+ data = wl_array_add(options, size);
+ memcpy(data, raw, size);
+ free(raw);
+}
+
+static void __set_extra_config(struct wl_array *extra_config,
+ const char *app_id)
+{
+ int len;
+ void *data;
+
+ len = strlen(CUSTOM_EFFECT_CALLEE) + 1;
+ data = wl_array_add(extra_config, len);
+ memcpy(data, CUSTOM_EFFECT_CALLEE, len);
+
+ len = strlen(app_id) + 1;
+ data = wl_array_add(extra_config, len);
+ memcpy(data, app_id, len);
+}
+
+static void __splash_screen_send_image(splash_image_h si)
+{
+ struct wl_array options;
+ struct wl_array extra_config;
+
+ if (si == NULL || si->image == NULL)
+ return;
+
+ wl_array_init(&options);
+ __set_options(&options, si->appid);
+
+ wl_array_init(&extra_config);
+ __set_extra_config(&extra_config, si->appid);
+
+ _D("src(%s), type(%d), color-depth(%d), rotation(%d), " \
+ "indicator(%d), effect_type(%s)",
+ si->src, si->type, si->color_depth, si->rotation,
+ si->indicator, si->effect_type);
+ tizen_launch_splash_launch_v2(si->image, si->src, si->type,
+ si->color_depth, si->rotation, si->indicator,
+ si->effect_type, si->theme_type, &options,
+ si->custom_effect ? &extra_config : NULL);
+ wl_display_flush(display);
+
+ wl_array_release(&extra_config);
+ wl_array_release(&options);
+}
+
+static void __splash_screen_send_pid(splash_image_h si, int pid)
+{
+ if (si == NULL)
+ return;
+
+ _D("pid(%d)", pid);
+ si->pid = pid;
+ tizen_launch_splash_owner(si->image, pid);
+ wl_display_flush(display);
+}
+
+static void __splash_screen_set_effect_type(int pid, const char *appid, bool is_subapp)
+{
+ struct wl_array options;
+ bundle *b;
+ bundle_raw *raw_data = NULL;
+ int len = 0;
+ int ret;
+ size_t size;
+ void *data;
+ const char *effect_type;
+
+ if (!splash_screen_initialized)
+ return;
+
+ wl_array_init(&options);
+
+ if (is_subapp)
+ effect_type = "depth-in";
+ else
+ effect_type = "launch";
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ bundle_add(b, AUL_K_APPID, appid);
+ ret = bundle_encode(b, &raw_data, &len);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Failed to encode bundle");
+ bundle_free(b);
+ return;
+ }
+ bundle_free(b);
+
+ size = strlen((const char *)raw_data);
+ data = wl_array_add(&options, size + 1);
+ memcpy(data, raw_data, size + 1);
+ free(raw_data);
+
+ _D("effect_type(%s), pid(%d)", effect_type, pid);
+ tizen_launch_effect_type_set(tz_launch_effect, effect_type,
+ pid, &options);
+ wl_display_flush(display);
+
+ wl_array_release(&options);
+}
+
+static int __init_splash_screen(void)
+{
+ if (!display) {
+ display = amd_wayland_get_display();
+ if (!display) {
+ _E("Failed to get display");
+ return -1;
+ }
+ }
+
+ if (!tz_launch_effect) {
+ _E("Failed to bind tizen launch screen");
+ return -1;
+ }
+
+ splash_screen_initialized = 1;
+
+ return 0;
+}
+
+static void __rotation_changed_cb(sensor_t sensor, unsigned int event_type,
+ sensor_data_t *data, void *user_data)
+{
+ int event;
+
+ if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
+ return;
+
+ event = (int)data->values[0];
+ switch (event) {
+ case AUTO_ROTATION_DEGREE_0:
+ rotation.angle = 0;
+ break;
+ case AUTO_ROTATION_DEGREE_90:
+ rotation.angle = 90;
+ break;
+ case AUTO_ROTATION_DEGREE_180:
+ rotation.angle = 180;
+ break;
+ case AUTO_ROTATION_DEGREE_270:
+ rotation.angle = 270;
+ break;
+ default:
+ break;
+ }
+
+ _D("angle: %d", rotation.angle);
+}
+
+static void __auto_rotate_screen_cb(keynode_t *key, void *data)
+{
+ rotation.auto_rotate = vconf_keynode_get_bool(key);
+ if (!rotation.auto_rotate) {
+ _D("auto_rotate: %d, angle: %d",
+ rotation.auto_rotate, rotation.angle);
+ }
+}
+
+static void __fini_rotation(void)
+{
+ if (!rotation.initialized)
+ return;
+
+ if (!TIZEN_FEATURE_AUTO_ROTATION)
+ return;
+
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+ __auto_rotate_screen_cb);
+ sensord_unregister_event(rotation.handle,
+ AUTO_ROTATION_CHANGE_STATE_EVENT);
+ sensord_disconnect(rotation.handle);
+ rotation.angle = 0;
+
+ rotation.initialized = false;
+}
+
+static int __init_rotation(void)
+{
+ int ret;
+ bool r;
+
+ if (!TIZEN_FEATURE_AUTO_ROTATION) {
+ rotation.initialized = true;
+ return 0;
+ }
+
+ if (!rotation.sensor) {
+ rotation.sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
+ if (!rotation.sensor) {
+ _E("Failed to get sensor. errno(%d)", errno);
+ return -1;
+ }
+ }
+
+ rotation.angle = 0;
+ rotation.handle = sensord_connect(rotation.sensor);
+ if (rotation.handle < 0) {
+ _W("Failed to connect sensord");
+ return -1;
+ }
+
+ r = sensord_register_event(rotation.handle,
+ AUTO_ROTATION_CHANGE_STATE_EVENT,
+ SENSOR_INTERVAL_NORMAL,
+ 0,
+ __rotation_changed_cb,
+ NULL);
+ if (!r) {
+ _W("Failed to register event");
+ sensord_disconnect(rotation.handle);
+ return -1;
+ }
+
+ r = sensord_start(rotation.handle, 0);
+ if (!r) {
+ _W("Failed to start sensord");
+ sensord_unregister_event(rotation.handle,
+ AUTO_ROTATION_CHANGE_STATE_EVENT);
+ sensord_disconnect(rotation.handle);
+ return -1;
+ }
+
+ ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+ &rotation.auto_rotate);
+ if (ret != VCONF_OK)
+ rotation.auto_rotate = false;
+
+ ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+ __auto_rotate_screen_cb, NULL);
+ if (ret != 0) {
+ _W("Failed to register callback for %s",
+ VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL);
+ }
+ rotation.initialized = true;
+
+ return 0;
+}
+
+static void __destroy_image_info(struct image_info_s *info)
+{
+ if (info == NULL)
+ return;
+
+ if (info->color_depth)
+ free(info->color_depth);
+ if (info->indicator_display)
+ free(info->indicator_display);
+ if (info->type)
+ free(info->type);
+ if (info->orientation)
+ free(info->orientation);
+ if (info->file)
+ free(info->file);
+ if (info->name)
+ free(info->name);
+ free(info);
+}
+
+struct image_info_s *__create_image_info(void)
+{
+ struct image_info_s *info;
+
+ info = (struct image_info_s *)calloc(1, sizeof(struct image_info_s));
+ if (info == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ return info;
+}
+
+static int __validate_image_info(struct image_info_s *info)
+{
+ if (!info || !info->name || !info->file || !info->orientation)
+ return -1;
+
+ if (!info->type) {
+ if (strstr(info->file, "edj"))
+ info->type = strdup("edj");
+ else
+ info->type = strdup("img");
+ if (info->type == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ if (!info->indicator_display) {
+ info->indicator_display = strdup("true");
+ if (info->indicator_display == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ if (!info->color_depth) {
+ info->color_depth = strdup("24");
+ if (info->color_depth == NULL) {
+ _E("Out of memory");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void __parse_file(const char *file)
+{
+ FILE *fp;
+ char buf[LINE_MAX];
+ char *tok1 = NULL;
+ char *tok2 = NULL;
+ struct image_info_s *info = NULL;
+
+ fp = fopen(file, "rt");
+ if (fp == NULL)
+ return;
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ FREE_AND_NULL(tok1);
+ FREE_AND_NULL(tok2);
+ sscanf(buf, "%ms %ms", &tok1, &tok2);
+
+ if (tok1 && strcasecmp(TAG_SPLASH_IMAGE, tok1) == 0) {
+ if (info) {
+ if (__validate_image_info(info) < 0) {
+ __destroy_image_info(info);
+ } else {
+ default_image_list = g_list_append(
+ default_image_list,
+ info);
+ }
+ }
+ info = __create_image_info();
+ continue;
+ }
+
+ if (!tok1 || !tok2 || !info)
+ continue;
+
+ if (strcasecmp(TAG_NAME, tok1) == 0)
+ info->name = strdup(tok2);
+ else if (strcasecmp(TAG_FILE, tok1) == 0)
+ info->file = strdup(tok2);
+ else if (strcasecmp(TAG_TYPE, tok1) == 0)
+ info->type = strdup(tok2);
+ else if (strcasecmp(TAG_ORIENTATION, tok1) == 0)
+ info->orientation = strdup(tok2);
+ else if (strcasecmp(TAG_INDICATOR_DISPLAY, tok1) == 0)
+ info->indicator_display = strdup(tok2);
+ else if (strcasecmp(TAG_COLOR_DEPTH, tok1) == 0)
+ info->color_depth = strdup(tok2);
+ }
+
+ if (info) {
+ if (__validate_image_info(info) < 0) {
+ __destroy_image_info(info);
+ } else {
+ default_image_list = g_list_append(default_image_list,
+ info);
+ }
+ }
+
+ if (tok1)
+ free(tok1);
+ if (tok2)
+ free(tok2);
+
+ fclose(fp);
+}
+
+static int __load_splash_screen_info(const char *path)
+{
+ DIR *dp;
+ struct dirent *entry = NULL;
+ char *ext;
+ char buf[PATH_MAX];
+
+ dp = opendir(path);
+ if (dp == NULL)
+ return -1;
+
+ while ((entry = readdir(dp)) != NULL) {
+ if (entry->d_name[0] == '.')
+ continue;
+
+ ext = strrchr(entry->d_name, '.');
+ if (ext && !strcmp(ext, ".conf")) {
+ snprintf(buf, sizeof(buf), "%s/%s",
+ path, entry->d_name);
+ __parse_file(buf);
+ }
+ }
+
+ closedir(dp);
+
+ return 0;
+}
+
+static int __on_launch_start(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ int cmd = arg1;
+ bundle *kb = data;
+ amd_launch_context_h h = arg3;
+
+ cur_splash_image = NULL;
+ if (bundle_get_val(kb, AUL_K_MULTI_INSTANCE_SHORTCUT)) {
+ _W("Multiple instance shortcut");
+ return 0;
+ }
+
+ if (amd_launch_context_is_bg_launch(h)) {
+ _W("Background launch");
+ return 0;
+ }
+
+ cur_splash_image = __splash_screen_create_image(
+ amd_launch_context_get_appinfo(h), kb, cmd,
+ amd_launch_context_is_subapp(h),
+ amd_launch_context_is_custom_effect(h));
+ __splash_screen_send_image(cur_splash_image);
+
+ return 0;
+}
+
+static int __on_launch_end(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_launch_context_h h = arg3;
+ amd_appinfo_h ai = amd_launch_context_get_appinfo(h);
+ const char *comp_type;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (cur_splash_image) {
+ __splash_screen_send_pid(cur_splash_image,
+ amd_launch_context_get_pid(h));
+ } else if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ __splash_screen_set_effect_type(amd_launch_context_get_pid(h),
+ amd_launch_context_get_appid(h),
+ amd_launch_context_is_subapp(h));
+ }
+
+ return 0;
+}
+
+static int __on_launch_cancel(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ if (cur_splash_image) {
+ __splash_screen_destroy_image(cur_splash_image);
+ cur_splash_image = NULL;
+ }
+
+ return 0;
+}
+
+static int __on_cleanup(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ int pid = arg1;
+ splash_image_h si;
+
+ si = __splash_screen_get_image(pid);
+ if (si)
+ __splash_screen_destroy_image(si);
+
+ return 0;
+}
+
+static int __on_wl_listener(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+ struct wl_registry *registry = (struct wl_registry *)arg3;
+
+ if (!tz_launch_effect) {
+ tz_launch_effect_id = id;
+ tz_launch_effect = wl_registry_bind(registry, id,
+ &tizen_launch_effect_interface, 1);
+ _D("tz_launch_effect(%p)", tz_launch_effect);
+ }
+
+ return 0;
+}
+
+static int __on_wl_listener_remove(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+
+ if (id == tz_launch_effect_id && tz_launch_effect) {
+ tizen_launch_effect_destroy(tz_launch_effect);
+ tz_launch_effect = NULL;
+ tz_launch_effect_id = 0;
+ splash_screen_initialized = 0;
+ _W("tizen launch effect is destroyed");
+ }
+
+ return 0;
+}
+
+static void __charger_status_changed_cb(keynode_t *keynode, void *user_data)
+{
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ rotation.charger_status = vconf_keynode_get_int(keynode);
+ if (rotation.charger_status) {
+ if (__init_rotation() < 0)
+ _W("Failed to initialize rotation");
+ } else {
+ __fini_rotation();
+ }
+ _D("charger status(%d)", rotation.charger_status);
+ }
+}
+
+static gboolean __rotation_init_handler(gpointer data)
+{
+ int r;
+
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ r = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ &rotation.charger_status);
+ if (r < 0) {
+ _W("Failed to get charger status");
+ return G_SOURCE_CONTINUE;
+ }
+
+ r = vconf_notify_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ __charger_status_changed_cb, NULL);
+ if (r < 0) {
+ _W("Failed to register vconf cb");
+ return G_SOURCE_CONTINUE;
+ }
+
+ if (rotation.charger_status) {
+ if (__init_rotation() < 0)
+ _W("Failed to initialize rotation");
+ }
+ } else {
+ if (__init_rotation() < 0)
+ _W("Failed to initialize rotation");
+ }
+
+ rotation.timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("splash screen init");
+
+ __load_splash_screen_info(SPLASH_SCREEN_INFO_PATH);
+
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_LAUNCH_EFFECT,
+ __on_wl_listener);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
+ __on_wl_listener_remove);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_START,
+ __on_launch_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
+ __on_launch_cancel);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_DO_STARTING_APP_END,
+ __on_launch_end);
+ amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
+ __on_cleanup);
+
+ rotation.timer = g_timeout_add(500, __rotation_init_handler, NULL);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("splash screen finish");
+
+ if (rotation.timer)
+ g_source_remove(rotation.timer);
+
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ __charger_status_changed_cb);
+
+ __fini_rotation();
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_UI_CORE_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_UI_CORE} ${AMD_MOD_UI_CORE_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_UI_CORE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_UI_CORE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_UI_CORE} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_UI_CORE} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ TIZEN_EXTENSION_CLIENT_DEPS
+ WAYLAND_CLIENT_DEPS
+ WAYLAND_TBM_CLIENT_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_UI_CORE} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+int _screen_connector_add_app_screen(int pid, unsigned int surf,
+ const char *instance_id, uid_t uid);
+int _screen_connector_init(void);
+void _screen_connector_fini(void);
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2019 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <glib.h>
+
+typedef struct app_group_s *app_group_h;
+
+typedef GList *app_group_node_h;
+
+typedef void (*app_group_foreach_context_cb)(const char *id, pid_t pid,
+ int wid, bool fg, void *user_data);
+
+app_group_h _app_group_find(const char *id);
+
+const char *_app_group_get_leader_id_by_window(int window);
+
+const char *_app_group_get_id(pid_t pid);
+
+void _app_group_get_group_pids(app_group_h group, int *cnt, pid_t **pids);
+
+void _app_group_get_leader_pids(int *cnt, pid_t **pids);
+
+pid_t _app_group_get_leader_pid(app_group_h h);
+
+void _app_group_get_idle_pids(int *cnt, pid_t **pids);
+
+char **_app_group_get_leader_ids(int *cnt);
+
+int _app_group_get_count(app_group_h group);
+
+int _app_group_foreach_context(app_group_h group,
+ app_group_foreach_context_cb callback,
+ void *user_data);
+
+int _app_group_get_idle_count(void);
+
+int _app_group_foreach_idle_context(app_group_foreach_context_cb callback,
+ void *user_data);
+
+int _app_group_init(void);
+
+void _app_group_fini(void);
+
+app_group_node_h _app_group_node_find(const char *id);
+
+int _app_group_node_get_window(app_group_node_h node);
+
+void _app_group_node_lower(app_group_node_h node, bool *exit);
+
+void _app_group_node_clear_top(app_group_node_h node, uid_t uid);
+
+bool _app_group_node_get_fg_flag(app_group_node_h node);
+
+int _app_group_node_set_window(app_group_node_h node, int wid);
+
+app_group_node_h _app_group_node_find_by_wid(int wid);
+
+app_group_node_h _app_group_node_add_node(app_group_node_h node);
+
+int _app_group_node_remove_node(app_group_node_h node);
+
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "AMD_APP_GROUP"
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+int _app_group_request_init(void);
+
+void _app_group_request_fini(void);
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+int _app_group_wayland_lower_window(int wid);
+
+int _app_group_wayland_attach_window(int parent_wid, int child_wid);
+
+int _app_group_wayland_detach_window(int child_wid);
+
+int _app_group_wayland_activate_below(int wid, int below_wid);
+
+int _app_group_wayland_activate_above(int wid, int above_wid);
+
+int _app_group_wayland_init(void);
+
+void _app_group_wayland_fini(void);
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+#include <unistd.h>
+
+pid_t _status_get_effective_pid(pid_t pid);
--- /dev/null
+/*
+ * Copyright (c) 2016 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+#include <ctype.h>
+#include <bundle_internal.h>
+#include <dlog.h>
+#include <aul.h>
+#include <aul_sock.h>
+#include <aul_screen_connector.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#include "amd_screen_connector.h"
+#include "app_group.h"
+#include "status.h"
+
+#define SUSPEND_INTERVAL 5 /* sec */
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_SCREEN_CONNECTOR"
+
+struct app_screen_s {
+ char *appid;
+ char *instance_id;
+ int pid;
+ uid_t uid;
+ unsigned int surf;
+ int screen_type;
+ int caller_pid;
+ GList *viewer_list;
+};
+
+struct viewer_info_s {
+ int pid;
+ int screen_type;
+ bool priv;
+ unsigned int ref;
+ aul_screen_status_e status;
+ GList *watch_list;
+};
+
+struct user_info_s {
+ uid_t uid;
+ struct app_screen_s *last_focused_app_screen;
+ GList *screen_viewer_list;
+ GList *app_screen_list;
+};
+
+static GHashTable *user_table;
+
+static struct app_screen_s *__create_app_screen(int pid, uid_t uid,
+ const char *appid, unsigned int surf, const char *instance_id,
+ int screen_type, int caller_pid)
+{
+ struct app_screen_s *app_screen;
+
+ app_screen = calloc(1, sizeof(struct app_screen_s));
+ if (app_screen == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ app_screen->appid = strdup(appid);
+ if (app_screen->appid == NULL) {
+ _E("out of memory");
+ free(app_screen);
+ return NULL;
+ }
+
+ app_screen->instance_id = strdup(instance_id);
+ if (app_screen->instance_id == NULL) {
+ _E("out of memory");
+ free(app_screen->appid);
+ free(app_screen);
+ return NULL;
+ }
+
+ app_screen->pid = pid;
+ app_screen->uid = uid;
+ app_screen->surf = surf;
+ app_screen->screen_type = screen_type;
+ app_screen->caller_pid = caller_pid;
+
+ return app_screen;
+}
+
+static void __destroy_app_screen(gpointer data)
+{
+ struct app_screen_s *app_screen = (struct app_screen_s *)data;
+ struct viewer_info_s *viewer_info;
+ GList *iter;
+
+ if (app_screen == NULL)
+ return;
+
+ if (app_screen->viewer_list) {
+ iter = app_screen->viewer_list;
+ while (iter) {
+ viewer_info = (struct viewer_info_s *)iter->data;
+ viewer_info->watch_list = g_list_remove(
+ viewer_info->watch_list, app_screen);
+ iter = g_list_next(iter);
+ }
+ g_list_free(app_screen->viewer_list);
+ }
+
+ if (app_screen->instance_id)
+ free(app_screen->instance_id);
+ if (app_screen->appid)
+ free(app_screen->appid);
+ free(app_screen);
+}
+
+static gint __compare_instance_id(gconstpointer a, gconstpointer b)
+{
+ struct app_screen_s *app_screen = (struct app_screen_s *)a;
+ const char *instance_id = (const char *)b;
+
+ if (app_screen == NULL || instance_id == NULL)
+ return -1;
+
+ if (!strcmp(app_screen->instance_id, instance_id))
+ return 0;
+
+ return -1;
+}
+
+static void __destroy_viewer_info(struct viewer_info_s *viewer_info)
+{
+ struct app_screen_s *app_screen;
+ GList *iter;
+
+ if (viewer_info == NULL)
+ return;
+
+ if (viewer_info->watch_list) {
+ iter = viewer_info->watch_list;
+ while (iter) {
+ app_screen = (struct app_screen_s *)iter->data;
+ app_screen->viewer_list = g_list_remove(
+ app_screen->viewer_list, viewer_info);
+ iter = g_list_next(iter);
+ }
+ g_list_free(viewer_info->watch_list);
+ }
+
+ free(viewer_info);
+}
+
+static struct viewer_info_s *__create_viewer_info(int pid, int screen_type,
+ bool priv, unsigned int ref)
+{
+ struct viewer_info_s *viewer_info;
+
+ viewer_info = calloc(1, sizeof(struct viewer_info_s));
+ if (viewer_info == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ viewer_info->pid = pid;
+ viewer_info->screen_type = screen_type;
+ viewer_info->priv = priv;
+ viewer_info->ref = ref;
+
+ return viewer_info;
+}
+
+static void __destroy_user_info(gpointer data)
+{
+ struct user_info_s *user_info = (struct user_info_s *)data;
+
+ if (user_info == NULL)
+ return;
+
+ if (user_info->app_screen_list) {
+ g_list_free_full(user_info->app_screen_list,
+ __destroy_app_screen);
+ }
+ if (user_info->screen_viewer_list)
+ g_list_free_full(user_info->screen_viewer_list, free);
+ free(user_info);
+}
+
+static struct user_info_s *__create_user_info(uid_t uid)
+{
+ struct user_info_s *user_info;
+
+ user_info = malloc(sizeof(struct user_info_s));
+ if (user_info == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ user_info->uid = uid;
+ user_info->screen_viewer_list = NULL;
+ user_info->app_screen_list = NULL;
+ user_info->last_focused_app_screen = NULL;
+
+ return user_info;
+}
+
+static bundle *__create_bundle(struct app_screen_s *app_screen,
+ const char *event)
+{
+ bundle *b;
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ bundle_add_str(b, "__AUL_SC_EVENT__", event);
+ bundle_add_str(b, "__AUL_SC_APPID__", app_screen->appid);
+ bundle_add_byte(b, "__AUL_SC_PID__", &app_screen->pid, sizeof(int));
+ bundle_add_byte(b, "__AUL_SC_SURFACE__",
+ &app_screen->surf, sizeof(unsigned int));
+ bundle_add_str(b, "__AUL_SC_INSTANCE_ID__", app_screen->instance_id);
+
+ return b;
+}
+
+static void __send_app_screen_event(struct viewer_info_s *viewer_info,
+ struct app_screen_s *app_screen, const char *event)
+{
+ bundle *b;
+ char endpoint[128];
+
+ b = __create_bundle(app_screen, event);
+ if (b == NULL) {
+ _E("out of memory");
+ return;
+ }
+
+ snprintf(endpoint, sizeof(endpoint), "app_screen_event:%u:%d",
+ viewer_info->ref, viewer_info->pid);
+ amd_app_com_send(endpoint, app_screen->pid, b, app_screen->uid);
+ bundle_free(b);
+}
+
+static void __send_app_screen_added(gpointer data, gpointer user_data)
+{
+ struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
+ struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
+
+ if (viewer_info->pid == app_screen->pid)
+ return;
+ if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
+ return;
+ if (!(viewer_info->screen_type & app_screen->screen_type))
+ return;
+ __send_app_screen_event(viewer_info, app_screen, "add_screen");
+}
+
+static void __send_app_screen_removed(gpointer data, gpointer user_data)
+{
+ struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
+ struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
+
+ if (viewer_info->pid == app_screen->pid)
+ return;
+ if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
+ return;
+ if (!(viewer_info->screen_type & app_screen->screen_type))
+ return;
+ __send_app_screen_event(viewer_info, app_screen, "remove_screen");
+}
+
+static void __send_app_screen_updated(gpointer data, gpointer user_data)
+{
+ struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
+ struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
+
+ if (viewer_info->pid == app_screen->pid)
+ return;
+ if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
+ return;
+ if (!(viewer_info->screen_type & app_screen->screen_type))
+ return;
+ __send_app_screen_event(viewer_info, app_screen, "update_screen");
+}
+
+static void __send_app_screen_focused(gpointer data, gpointer user_data)
+{
+ struct viewer_info_s *viewer_info = (struct viewer_info_s *)data;
+ struct app_screen_s *app_screen = (struct app_screen_s *)user_data;
+
+ if (viewer_info->pid == app_screen->pid)
+ return;
+ if (viewer_info->priv && viewer_info->pid != app_screen->caller_pid)
+ return;
+ if (!(viewer_info->screen_type & app_screen->screen_type))
+ return;
+ __send_app_screen_event(viewer_info, app_screen, "focus_screen");
+}
+
+static gint __compare_app_screen_instance_id(gconstpointer a, gconstpointer b)
+{
+ struct app_screen_s *app_screen = (struct app_screen_s *)a;
+ const char *instance_id = (const char *)b;
+
+ if (strcmp(app_screen->instance_id, instance_id) == 0)
+ return 0;
+
+ return -1;
+}
+
+static unsigned int __screen_connector_get_surface_id(const char *instance_id,
+ uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ GList *found;
+
+ if (instance_id == NULL)
+ return 0;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return 0;
+
+ found = g_list_find_custom(user_info->app_screen_list,
+ instance_id, __compare_app_screen_instance_id);
+ if (found) {
+ app_screen = (struct app_screen_s *)found->data;
+ return app_screen->surf;
+ }
+
+ return 0;
+}
+
+static int __get_screen_type(int app_type)
+{
+ switch (app_type) {
+ case AMD_AT_UI_APP:
+ return AUL_SCREEN_TYPE_UI;
+ case AMD_AT_WIDGET_APP:
+ return AUL_SCREEN_TYPE_WIDGET;
+ case AMD_AT_WATCH_APP:
+ return AUL_SCREEN_TYPE_WATCH;
+ default:
+ return -1;
+ }
+}
+
+static app_group_h __find_app_group_by_pid(pid_t pid)
+{
+ const char *id;
+
+ id = _app_group_get_id(pid);
+
+ return _app_group_find(id);
+}
+
+static app_group_node_h __find_app_group_node_by_pid(pid_t pid)
+{
+ const char *id;
+
+ id = _app_group_get_id(pid);
+
+ return _app_group_node_find(id);
+}
+
+static int __get_pid_by_surf(int pid, unsigned int surf)
+{
+ pid_t *pids = NULL;
+ int cnt = 0;
+ int i;
+ unsigned int wid;
+ app_group_h app_group;
+ app_group_node_h node;
+
+
+ app_group = __find_app_group_by_pid(pid);
+ _app_group_get_group_pids(app_group, &cnt, &pids);
+ for (i = 0; i < cnt; ++i) {
+ node = __find_app_group_node_by_pid(pids[i]);
+ wid = (unsigned int)_app_group_node_get_window(node);
+ if (wid == surf) {
+ _D("pid(%d), surf(%u)", pids[i], surf);
+ pid = pids[i];
+ }
+ }
+ free(pids);
+
+ return pid;
+}
+
+static gboolean __suspend_timer(gpointer data)
+{
+ int pid = GPOINTER_TO_INT(data);
+ int ret;
+
+ if (pid < 1)
+ return FALSE;
+
+ ret = amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
+ _D("pid(%d), result(%d)", pid, ret);
+
+ return FALSE;
+}
+
+static gint __compare_app_screen_surf(gconstpointer a, gconstpointer b)
+{
+ struct app_screen_s *app_screen = (struct app_screen_s *)a;
+ unsigned int surf = GPOINTER_TO_UINT(b);
+
+ if (app_screen->surf == surf)
+ return 0;
+
+ return -1;
+}
+
+static const char *__screen_connector_get_appid_by_surface_id(unsigned int surf,
+ uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return NULL;
+
+ found = g_list_find_custom(user_info->app_screen_list,
+ GUINT_TO_POINTER(surf), __compare_app_screen_surf);
+ if (found) {
+ app_screen = (struct app_screen_s *)found->data;
+ return app_screen->appid;
+ }
+
+ return NULL;
+}
+
+static const char *__screen_connector_get_instance_id_by_surface_id(
+ unsigned int surf, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return NULL;
+
+ found = g_list_find_custom(user_info->app_screen_list,
+ GUINT_TO_POINTER(surf), __compare_app_screen_surf);
+ if (found) {
+ app_screen = (struct app_screen_s *)found->data;
+ return app_screen->instance_id;
+ }
+
+ return NULL;
+}
+
+/* TODO: The provider_appid should be provider_instance_id. */
+static int __send_viewer_visibility_to_provider(const char *provider_appid,
+ aul_screen_status_e status, int viewer_pid, uid_t viewer_uid)
+{
+ bundle *b;
+
+ b = bundle_create();
+ if (b == NULL) {
+ _E("out of memory");
+ return -1;
+ }
+
+ bundle_add_byte(b, "__AUL_SC_VIEWER_STATUS__",
+ &status, sizeof(aul_screen_status_e));
+ amd_app_com_send(provider_appid, viewer_pid, b, viewer_uid);
+ bundle_free(b);
+ _D("send viewer status to %s(%d)", provider_appid, status);
+
+ return 0;
+}
+
+static gint __compare_viewer_pid(gconstpointer a, gconstpointer b)
+{
+ struct viewer_info_s *viewer_info = (struct viewer_info_s *)a;
+ int pid = GPOINTER_TO_INT(b);
+
+ if (viewer_info->pid == pid)
+ return 0;
+
+ return -1;
+}
+
+static int __screen_connector_update_screen_viewer_status(int pid, int status,
+ unsigned int surf, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ struct viewer_info_s *viewer_info;
+ bool send_pause = true;
+ GList *found;
+ GList *iter;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ found = g_list_find_custom(user_info->screen_viewer_list,
+ GINT_TO_POINTER(pid), __compare_viewer_pid);
+ if (found == NULL)
+ return -1;
+
+ viewer_info = (struct viewer_info_s *)found->data;
+ if (status != AUL_SCREEN_STATUS_PRE_RESUME)
+ viewer_info->status = status;
+ else
+ _W("pre resume status will not be stored as a viewer status");
+
+ found = g_list_find_custom(user_info->app_screen_list,
+ GUINT_TO_POINTER(surf), __compare_app_screen_surf);
+ if (found == NULL)
+ return -1;
+
+ app_screen = (struct app_screen_s *)found->data;
+ found = g_list_find(app_screen->viewer_list, viewer_info);
+ if (!found) {
+ app_screen->viewer_list = g_list_append(app_screen->viewer_list,
+ viewer_info);
+ }
+
+ found = g_list_find(viewer_info->watch_list, app_screen);
+ if (!found) {
+ viewer_info->watch_list = g_list_append(viewer_info->watch_list,
+ app_screen);
+ }
+
+ if (status == AUL_SCREEN_STATUS_PAUSE) {
+ iter = app_screen->viewer_list;
+ while (iter) {
+ viewer_info = (struct viewer_info_s *)iter->data;
+ if (viewer_info->status != AUL_SCREEN_STATUS_PAUSE) {
+ /*
+ * Every veiwer must be paused to send
+ * viewer pause event to provider
+ */
+ send_pause = false;
+ _W("Skip pause : viewer pid(%d), status(%d)",
+ viewer_info->pid, viewer_info->status);
+ break;
+ }
+ iter = g_list_next(iter);
+ }
+ if (send_pause) {
+ __send_viewer_visibility_to_provider(app_screen->appid,
+ status, pid, uid);
+ }
+ } else if (status == AUL_SCREEN_STATUS_RESUME ||
+ status == AUL_SCREEN_STATUS_PRE_RESUME) {
+ __send_viewer_visibility_to_provider(app_screen->appid, status,
+ pid, uid);
+ } else {
+ _W("Unknown status(%d)", status);
+ }
+
+ return 0;
+}
+
+static int __screen_connector_send_update_request(const char *appid,
+ const char *instance_id, uid_t uid)
+{
+ amd_app_status_h app_status;
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ int dummy = 0;
+ int pid;
+ int ret;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ if (instance_id) {
+ app_status = amd_app_status_find_by_instance_id(appid,
+ instance_id, uid);
+ } else {
+ app_status = amd_app_status_find_by_appid(appid, uid);
+ }
+ if (app_status == NULL)
+ return -1;
+ if (amd_app_status_get_status(app_status) == STATUS_DYING)
+ return -1;
+ if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
+ return -1;
+ if (amd_app_status_is_home_app(app_status))
+ return -1;
+ if (instance_id == NULL) {
+ instance_id = amd_app_status_get_instance_id(app_status);
+ if (instance_id == NULL)
+ return -1;
+ }
+
+ found = g_list_find_custom(user_info->app_screen_list, instance_id,
+ __compare_instance_id);
+ if (found == NULL)
+ return -1;
+
+ app_screen = (struct app_screen_s *)found->data;
+ pid = __get_pid_by_surf(app_screen->pid, app_screen->surf);
+ ret = amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
+ if (ret < 0)
+ return -1;
+
+ ret = aul_sock_send_raw(pid, uid, APP_UPDATE_REQUESTED,
+ (unsigned char *)&dummy, 0, AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("Failed to send the update request");
+ amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
+ return -1;
+ }
+ g_timeout_add_seconds(SUSPEND_INTERVAL, __suspend_timer,
+ GINT_TO_POINTER(pid));
+ _D("pid(%d), uid(%d)", pid, uid);
+
+ return 0;
+}
+
+int _screen_connector_add_app_screen(int pid, unsigned int surf,
+ const char *instance_id, uid_t uid)
+{
+ amd_app_status_h app_status;
+ app_group_h app_group;
+ const char *appid;
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ int caller_pid;
+ int leader_pid;
+ int app_type;
+ int screen_type;
+ int effective_pid;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ effective_pid = _status_get_effective_pid(pid);
+ if (effective_pid < 0)
+ return -1;
+
+ if (instance_id)
+ app_group = _app_group_find(instance_id);
+ else
+ app_group = __find_app_group_by_pid(effective_pid);
+ leader_pid = _app_group_get_leader_pid(app_group);
+ if (leader_pid > 0)
+ pid = leader_pid;
+ else
+ pid = effective_pid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL) {
+ _W("Failed to find app status info - pid(%d), uid(%d)",
+ pid, uid);
+ return -1;
+ }
+
+ if (amd_app_status_is_home_app(app_status))
+ return 0;
+
+ appid = amd_app_status_get_appid(app_status);
+ if (instance_id == NULL)
+ instance_id = amd_app_status_get_instance_id(app_status);
+
+ found = g_list_find_custom(user_info->app_screen_list, instance_id,
+ __compare_instance_id);
+ if (found) {
+ app_screen = (struct app_screen_s *)found->data;
+ if (app_screen->surf == surf) {
+ _D("Already exists");
+ return 0;
+ }
+
+ app_screen->surf = surf;
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_updated, app_screen);
+ _W("surf is changed to %u", surf);
+ return 0;
+ }
+
+ caller_pid = amd_app_status_get_first_caller_pid(app_status);
+ app_type = amd_app_status_get_app_type(app_status);
+ screen_type = __get_screen_type(app_type);
+ app_screen = __create_app_screen(pid, uid, appid, surf, instance_id,
+ screen_type, caller_pid);
+ if (app_screen == NULL)
+ return -1;
+
+ user_info->app_screen_list = g_list_append(user_info->app_screen_list,
+ app_screen);
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_added, app_screen);
+ _D("pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
+
+ return 0;
+}
+
+static int __screen_connector_remove_app_screen(int pid,
+ const char *instance_id, uid_t uid)
+{
+ app_group_h app_group;
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ amd_app_status_h app_status;
+ int leader_pid;
+ int effective_pid;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ effective_pid = _status_get_effective_pid(pid);
+ if (effective_pid < 0)
+ return -1;
+
+ if (instance_id)
+ app_group = _app_group_find(instance_id);
+ else
+ app_group = __find_app_group_by_pid(effective_pid);
+ leader_pid = _app_group_get_leader_pid(app_group);
+ if (leader_pid > 0)
+ pid = leader_pid;
+ else
+ pid = effective_pid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL) {
+ _W("Failed to find app status info - pid(%d), uid(%d)",
+ pid, uid);
+ return -1;
+ }
+
+ if (amd_app_status_is_home_app(app_status))
+ return 0;
+
+ if (instance_id == NULL)
+ instance_id = amd_app_status_get_instance_id(app_status);
+
+ found = g_list_find_custom(user_info->app_screen_list, instance_id,
+ __compare_instance_id);
+ if (found == NULL)
+ return -1;
+
+ app_screen = (struct app_screen_s *)found->data;
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_removed, app_screen);
+ user_info->app_screen_list = g_list_remove(user_info->app_screen_list,
+ app_screen);
+ __destroy_app_screen(app_screen);
+ if (user_info->last_focused_app_screen == app_screen)
+ user_info->last_focused_app_screen = NULL;
+
+ _D("pid(%d), instance_id(%s)", pid, instance_id);
+
+ return 0;
+}
+
+static gint __compare_viewers(gconstpointer a, gconstpointer b)
+{
+ struct viewer_info_s *viewer_a = (struct viewer_info_s *)a;
+ struct viewer_info_s *viewer_b = (struct viewer_info_s *)b;
+
+ if (viewer_a->pid == viewer_b->pid &&
+ viewer_a->screen_type == viewer_b->screen_type &&
+ viewer_a->priv == viewer_b->priv &&
+ viewer_a->ref == viewer_b->ref)
+ return 0;
+
+ return -1;
+}
+
+static int __screen_connector_update_app_screen(int pid, unsigned int surf,
+ uid_t uid)
+{
+ amd_app_status_h app_status;
+ app_group_h app_group;
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ const char *appid;
+ const char *instance_id;
+ int leader_pid;
+ int effective_pid;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ effective_pid = _status_get_effective_pid(pid);
+ if (effective_pid < 0)
+ return -1;
+
+ app_group = __find_app_group_by_pid(effective_pid);
+ leader_pid = _app_group_get_leader_pid(app_group);
+ if (leader_pid > 0)
+ pid = leader_pid;
+ else
+ pid = effective_pid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL) {
+ _W("Failed to find app status info - pid(%d), uid(%d)",
+ pid, uid);
+ return -1;
+ }
+
+ if (amd_app_status_is_home_app(app_status))
+ return 0;
+
+ appid = amd_app_status_get_appid(app_status);
+ instance_id = amd_app_status_get_instance_id(app_status);
+
+ found = g_list_find_custom(user_info->app_screen_list, instance_id,
+ __compare_instance_id);
+ if (found == NULL)
+ return -1;
+
+ app_screen = (struct app_screen_s *)found->data;
+ if (app_screen->surf == surf)
+ return 0;
+
+ app_screen->surf = surf;
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_updated, app_screen);
+ _D("pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
+
+ return 0;
+}
+
+static int __screen_connector_focus_app_screen(int pid, unsigned int surf,
+ uid_t uid)
+{
+ amd_app_status_h app_status;
+ app_group_h app_group;
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ const char *appid;
+ const char *instance_id;
+ int leader_pid;
+ int effective_pid;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ effective_pid = _status_get_effective_pid(pid);
+ if (effective_pid < 0)
+ return -1;
+
+ app_group = __find_app_group_by_pid(effective_pid);
+ leader_pid = _app_group_get_leader_pid(app_group);
+ if (leader_pid > 0)
+ pid = leader_pid;
+ else
+ pid = effective_pid;
+
+ app_status = amd_app_status_find_by_pid(pid);
+ if (app_status == NULL) {
+ _W("Failed to find app status info - pid(%d), uid(%d)",
+ pid, uid);
+ return -1;
+ }
+
+ if (amd_app_status_is_home_app(app_status))
+ return 0;
+
+ appid = amd_app_status_get_appid(app_status);
+ instance_id = amd_app_status_get_instance_id(app_status);
+
+ found = g_list_find_custom(user_info->app_screen_list, instance_id,
+ __compare_instance_id);
+ if (found == NULL)
+ return -1;
+
+ app_screen = (struct app_screen_s *)found->data;
+
+ user_info->last_focused_app_screen = app_screen;
+
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_focused, app_screen);
+ _D("focus pid(%d), appid(%s), surf(%d), uid(%d)", pid, appid, surf, uid);
+
+ return 0;
+}
+
+static int __screen_connector_remove_app_screen_v2(int pid, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct app_screen_s *app_screen;
+ GList *iter;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ iter = g_list_first(user_info->app_screen_list);
+ while (iter) {
+ app_screen = (struct app_screen_s *)iter->data;
+ iter = g_list_next(iter);
+ if (app_screen && app_screen->pid == pid) {
+ _D("pid(%d), surf(%d)", pid, app_screen->surf);
+ g_list_foreach(user_info->screen_viewer_list,
+ __send_app_screen_removed, app_screen);
+ user_info->app_screen_list = g_list_remove(
+ user_info->app_screen_list,
+ app_screen);
+ __destroy_app_screen(app_screen);
+ if (user_info->last_focused_app_screen == app_screen)
+ user_info->last_focused_app_screen = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static void __foreach_app_screen_list(gpointer data, gpointer user_data)
+{
+ __send_app_screen_added(user_data, data);
+}
+
+static int __screen_connector_add_screen_viewer(int pid, int screen_type,
+ bool priv, unsigned int ref, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct viewer_info_s *viewer_info;
+ GList *list;
+
+ pid = _status_get_effective_pid(pid);
+ if (pid < 0)
+ return -1;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL) {
+ _W("user info is empty");
+ return -1;
+ }
+
+ viewer_info = __create_viewer_info(pid, screen_type, priv, ref);
+ if (viewer_info == NULL)
+ return -1;
+
+ list = g_list_find_custom(user_info->screen_viewer_list, viewer_info,
+ __compare_viewers);
+ if (list) {
+ _D("Already exists");
+ __destroy_viewer_info(viewer_info);
+ return 0;
+ }
+
+ user_info->screen_viewer_list = g_list_append(
+ user_info->screen_viewer_list, viewer_info);
+
+ g_list_foreach(user_info->app_screen_list,
+ __foreach_app_screen_list, viewer_info);
+ _D("pid(%d), screen_type(%d), private(%d), ref(%u), uid(%d)",
+ pid, screen_type, priv, ref, uid);
+
+ return 0;
+}
+
+static int __screen_connector_remove_screen_viewer(int pid, int screen_type,
+ bool priv, unsigned int ref, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct viewer_info_s *viewer_info;
+ GList *iter;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL) {
+ _W("user info is empty");
+ return -1;
+ }
+
+ pid = _status_get_effective_pid(pid);
+ if (pid < 0)
+ return -1;
+
+ iter = g_list_first(user_info->screen_viewer_list);
+ while (iter) {
+ viewer_info = (struct viewer_info_s *)iter->data;
+ iter = g_list_next(iter);
+ if (viewer_info->pid == pid &&
+ viewer_info->screen_type == screen_type &&
+ viewer_info->priv == priv &&
+ viewer_info->ref == ref) {
+ user_info->screen_viewer_list = g_list_remove(
+ user_info->screen_viewer_list,
+ viewer_info);
+ __destroy_viewer_info(viewer_info);
+ }
+ }
+
+ _D("pid(%d), screen_type(%d), private(%d), ref(%u) uid(%d)",
+ pid, screen_type, priv, ref, uid);
+
+ return 0;
+}
+
+static int __screen_connector_remove_screen_viewer_v2(int pid, uid_t uid)
+{
+ struct user_info_s *user_info;
+ struct viewer_info_s *viewer_info;
+ GList *iter;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL) {
+ _W("user info is empty");
+ return -1;
+ }
+
+ iter = g_list_first(user_info->screen_viewer_list);
+ while (iter) {
+ viewer_info = (struct viewer_info_s *)iter->data;
+ iter = g_list_next(iter);
+ if (viewer_info->pid == pid) {
+ user_info->screen_viewer_list = g_list_remove(
+ user_info->screen_viewer_list,
+ viewer_info);
+ __destroy_viewer_info(viewer_info);
+ }
+ }
+
+ return 0;
+}
+
+static int __screen_connector_usr_init(uid_t uid)
+{
+ struct user_info_s *user_info;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info) {
+ _E("Already exists");
+ return 0;
+ }
+
+ user_info = __create_user_info(uid);
+ if (user_info == NULL)
+ return -1;
+
+ g_hash_table_insert(user_table, GUINT_TO_POINTER(uid), user_info);
+
+ return 0;
+}
+
+static void __screen_connector_usr_fini(uid_t uid)
+{
+ g_hash_table_remove(user_table, GUINT_TO_POINTER(uid));
+}
+
+static int __dispatch_add_app_screen(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *instance_id;
+ const char *value;
+ unsigned int surf;
+ int ret;
+
+ if (b == NULL)
+ return -1;
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ value = bundle_get_val(b, AUL_K_WID);
+ if (value == NULL)
+ return -1;
+
+ surf = atol(value);
+ ret = _screen_connector_add_app_screen(pid, surf,
+ instance_id, uid);
+ _D("pid(%d), surf(%d), instance_id(%s), result(%d)",
+ pid, surf, instance_id, ret);
+
+ return 0;
+}
+
+static int __dispatch_remove_app_screen(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *instance_id;
+ int ret;
+
+ if (b == NULL)
+ return -1;
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ ret = __screen_connector_remove_app_screen(pid,
+ instance_id, uid);
+ _D("pid(%d), instance_id(%s), result(%d)",
+ pid, instance_id, ret);
+
+ return 0;
+}
+
+static int __dispatch_app_update_requested(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int caller_pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *appid;
+ const char *instance_id;
+ int ret;
+
+ if (b == NULL)
+ return -1;
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (appid == NULL)
+ return -1;
+
+ instance_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ ret = __screen_connector_send_update_request(appid, instance_id, uid);
+ _D("appid(%s), instance_id(%s), caller_pid(%d), result(%d)",
+ appid, instance_id, caller_pid, ret);
+
+ return 0;
+}
+
+static int __dispatch_add_screen_viewer(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *value;
+ bool priv;
+ int screen_type;
+ unsigned int ref;
+ int ret;
+
+ if (b == NULL)
+ return -1;
+
+ value = bundle_get_val(b, AUL_K_SCREEN_TYPE);
+ if (value == NULL)
+ return -1;
+ screen_type = atoi(value);
+
+ value = bundle_get_val(b, AUL_K_VIEWER_REF);
+ if (value == NULL)
+ return -1;
+ ref = atol(value);
+
+ value = bundle_get_val(b, AUL_K_PRIVATE);
+ if (value && strcmp(value, "true") == 0)
+ priv = true;
+ else
+ priv = false;
+
+ ret = __screen_connector_add_screen_viewer(pid, screen_type,
+ priv, ref, uid);
+ _D("pid(%d), screen_type(%d), private(%d), result(%d)",
+ pid, screen_type, priv, ret);
+
+ return 0;
+}
+
+static int __dispatch_remove_screen_viewer(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *value;
+ bool priv;
+ int screen_type;
+ unsigned int ref;
+ int ret;
+
+ if (b == NULL)
+ return -1;
+
+ value = bundle_get_val(b, AUL_K_SCREEN_TYPE);
+ if (value == NULL)
+ return -1;
+ screen_type = atoi(value);
+
+ value = bundle_get_val(b, AUL_K_VIEWER_REF);
+ if (value == NULL)
+ return -1;
+ ref = atol(value);
+
+ value = bundle_get_val(b, AUL_K_PRIVATE);
+ if (value && strcmp(value, "true") == 0)
+ priv = true;
+ else
+ priv = false;
+
+ ret = __screen_connector_remove_screen_viewer(pid, screen_type,
+ priv, ref, uid);
+ _D("pid(%d), screen_type(%d), private(%d), result(%d)",
+ pid, screen_type, priv, ret);
+
+ return 0;
+}
+
+static int __screen_connector_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ bundle *b = amd_request_get_bundle(req);
+ const char *type_str;
+ int type;
+
+ if (b == NULL) {
+ _E("Empty bundle data !!");
+ return -1;
+ }
+
+ type_str = bundle_get_val(b, AUL_K_SCREEN_TYPE);
+ if (type_str == NULL) {
+ _E("Cannot get screen type !!");
+ return -1;
+ }
+
+ type = atoi(type_str);
+ if (type & AUL_SCREEN_TYPE_UI)
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_PLATFORM);
+
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_WIDGET_VIEWER);
+}
+
+static int __dispatch_app_get_appid_by_surface_id(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ bundle *b = amd_request_get_bundle(req);
+ unsigned int *surf = NULL;
+ const char *appid;
+ size_t size;
+ bundle *ret_b;
+
+ if (b == NULL) {
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ bundle_get_byte(b, "__AUL_SC_SURFACE__", (void **)&surf, &size);
+ if (surf == NULL) {
+ _E("Failed to get surface");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = __screen_connector_get_appid_by_surface_id(*surf, uid);
+ if (appid == NULL) {
+ _E("Failed to get appid");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ ret_b = bundle_create();
+ if (ret_b == NULL) {
+ _E("Out of memory");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ bundle_add_str(ret_b, AUL_K_APPID, appid);
+ aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
+ amd_request_get_cmd(req), ret_b, AUL_SOCK_NOREPLY);
+ bundle_free(ret_b);
+
+ return 0;
+}
+
+static int __dispatch_app_get_instance_id_by_surface_id(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ bundle *b = amd_request_get_bundle(req);
+ unsigned int *surf = NULL;
+ const char *instance_id;
+ size_t size;
+ bundle *ret_b;
+
+ if (b == NULL) {
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ bundle_get_byte(b, "__AUL_SC_SURFACE__", (void **)&surf, &size);
+ if (surf == NULL) {
+ _E("Failed to get surface");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ instance_id = __screen_connector_get_instance_id_by_surface_id(*surf,
+ uid);
+ if (instance_id == NULL) {
+ _E("Failed to get instance_id");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ ret_b = bundle_create();
+ if (ret_b == NULL) {
+ _E("Out of memory");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ bundle_add_str(ret_b, AUL_K_INSTANCE_ID, instance_id);
+ aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
+ amd_request_get_cmd(req), ret_b, AUL_SOCK_NOREPLY);
+ bundle_free(ret_b);
+
+ return 0;
+}
+
+static int __dispatch_trigger_focused_force(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ struct user_info_s *user_info;
+ struct viewer_info_s *viewer_info;
+ GList *found;
+
+ user_info = g_hash_table_lookup(user_table, GUINT_TO_POINTER(uid));
+ if (user_info == NULL)
+ return -1;
+
+ if (user_info->last_focused_app_screen == NULL) {
+ _E("requested bad focused screen");
+ return -1;
+ }
+
+ found = g_list_find_custom(user_info->screen_viewer_list,
+ GINT_TO_POINTER(pid), __compare_viewer_pid);
+ if (found == NULL)
+ return -1;
+
+ viewer_info = (struct viewer_info_s *)found->data;
+
+ __send_app_screen_event(viewer_info,
+ user_info->last_focused_app_screen, "focus_screen");
+
+ return 0;
+}
+
+static int __dispatch_update_screen_viewer_status(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ int pid = amd_request_get_pid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *val;
+ aul_screen_status_e status;
+ unsigned int surf;
+ int r;
+
+ if (b == NULL) {
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ val = bundle_get_val(b, "__AUL_SC_VIEWER_STATUS__");
+ if (val == NULL || !isdigit(*val)) {
+ _E("Failed to get viewer status");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ status = atoi(val);
+
+ val = bundle_get_val(b, AUL_K_WID);
+ if (val == NULL || !isdigit(*val)) {
+ _E("Failed to get surface id");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ surf = strtoul(val, NULL, 10);
+
+ r = __screen_connector_update_screen_viewer_status(pid, status,
+ surf, uid);
+ amd_request_send_result(req, r);
+
+ return 0;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = ADD_APP_SCREEN,
+ .callback = __dispatch_add_app_screen
+ },
+ {
+ .cmd = REMOVE_APP_SCREEN,
+ .callback = __dispatch_remove_app_screen
+ },
+ {
+ .cmd = APP_UPDATE_REQUESTED,
+ .callback = __dispatch_app_update_requested
+ },
+ {
+ .cmd = ADD_SCREEN_VIEWER,
+ .callback = __dispatch_add_screen_viewer
+ },
+ {
+ .cmd = REMOVE_SCREEN_VIEWER,
+ .callback = __dispatch_remove_screen_viewer
+ },
+ {
+ .cmd = APP_GET_APPID_BY_SURFACE_ID,
+ .callback = __dispatch_app_get_appid_by_surface_id
+ },
+ {
+ .cmd = APP_GET_INSTANCE_ID_BY_SURFACE_ID,
+ .callback = __dispatch_app_get_instance_id_by_surface_id
+ },
+ {
+ .cmd = UPDATE_SCREEN_VIEWER_STATUS,
+ .callback = __dispatch_update_screen_viewer_status
+ },
+ {
+ .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
+ .callback = __dispatch_trigger_focused_force
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = ADD_SCREEN_VIEWER,
+ .checker = __screen_connector_checker,
+ .data = NULL
+ },
+ {
+ .cmd = REMOVE_SCREEN_VIEWER,
+ .checker = __screen_connector_checker,
+ .data = NULL
+ },
+ {
+ .cmd = APP_UPDATE_REQUESTED,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM
+ },
+ {
+ .cmd = TRIGGER_APP_SCREEN_FOCUSED_FORCE,
+ .checker = __screen_connector_checker,
+ .data = NULL
+ }
+};
+
+static int __on_launch_status(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = arg2;
+ app_group_node_h node = __find_app_group_node_by_pid(pid);
+ unsigned int surf = _app_group_node_get_window(node);
+
+ __screen_connector_update_app_screen(pid, surf, uid);
+ amd_noti_send(AMD_NOTI_MSG_SCREEN_CONNECTOR_APP_SCREEN_UPDATE,
+ pid, (int)surf, NULL, NULL);
+ return 0;
+}
+
+static int __on_focus_status(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data) {
+ int pid = arg1;
+ uid_t uid = arg2;
+ app_group_node_h node = __find_app_group_node_by_pid(pid);
+ unsigned int surf = _app_group_node_get_window(node);
+
+ __screen_connector_focus_app_screen(pid, surf, uid);
+
+ return 0;
+}
+
+static int __on_app_status_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h h = arg3;
+
+ if (amd_app_status_get_status(h) == STATUS_DYING) {
+ __screen_connector_remove_app_screen_v2(
+ amd_app_status_get_pid(h),
+ amd_app_status_get_uid(h));
+ }
+
+ return 0;
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = arg2;
+
+ __screen_connector_remove_app_screen_v2(pid, uid);
+ __screen_connector_remove_screen_viewer_v2(pid, uid);
+
+ return 0;
+}
+
+static int __on_login(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = arg1;
+ int status = arg2;
+
+ if (status & (AMD_UID_STATE_OPENING | AMD_UID_STATE_ONLINE |
+ AMD_UID_STATE_ACTIVE))
+ __screen_connector_usr_init(uid);
+
+ return 0;
+}
+
+static int __on_logout(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = arg1;
+ int status = arg2;
+
+ if (status & (AMD_UID_STATE_CLOSING | AMD_UID_STATE_OFFLINE))
+ __screen_connector_usr_fini(uid);
+
+ return 0;
+}
+
+static int __on_widget_app_restart(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = (uid_t)arg2;
+
+ __screen_connector_remove_app_screen_v2(pid, uid);
+
+ return 0;
+}
+
+static int __on_widget_running_info(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ unsigned int *surf = GINT_TO_POINTER(arg1);
+ uid_t uid = (uid_t)arg2;
+ const char *instance_id = (const char *)arg3;
+
+ *surf = __screen_connector_get_surface_id(instance_id, uid);
+
+ return 0;
+}
+
+int _screen_connector_init(void)
+{
+ int r;
+
+ _D("screen connector init");
+
+ user_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __destroy_user_info);
+ if (user_table == NULL) {
+ _E("Failed to create user table");
+ return -1;
+ }
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
+ __on_launch_status);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
+ __on_launch_status);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FOCUS,
+ __on_focus_status);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
+ __on_app_status_end);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGIN,
+ __on_login);
+ amd_noti_listen(AMD_NOTI_MSG_LOGIN_MONITOR_LOGOUT,
+ __on_logout);
+ amd_noti_listen(AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART,
+ __on_widget_app_restart);
+ amd_noti_listen(AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND,
+ __on_widget_running_info);
+
+ return 0;
+}
+
+void _screen_connector_fini(void)
+{
+ _D("screen connector fini");
+
+ if (user_table)
+ g_hash_table_destroy(user_table);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <glib.h>
+#include <dlog.h>
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+#include <aul_sock.h>
+#include <system_info.h>
+#include <aul_comp_types.h>
+#include <amd.h>
+
+#include "amd_screen_connector.h"
+#include "app_group.h"
+#include "app_group_wayland.h"
+#include "app_group_request.h"
+#include "app_group_private.h"
+
+#define APP_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__"
+#define STATUS_FOREGROUND "fg"
+#define STATUS_BACKGROUND "bg"
+#define TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP \
+ (!(amd_config_get_tizen_profile() & (AMD_TIZEN_PROFILE_TV)))
+
+#ifndef AUL_K_ORG_CALLER_INSTANCE_ID
+#define AUL_K_ORG_CALLER_INSTANCE_ID "__AUL_ORG_CALLER_INSTANCE_ID__"
+#endif
+
+#ifndef AUL_K_CALLER_INSTANCE_ID
+#define AUL_K_CALLER_INHSTANCE_ID "__AUL_CALLER_INSTANCE_ID__"
+#endif
+
+typedef enum {
+ APP_GROUP_LAUNCH_MODE_SINGLE = 0,
+ APP_GROUP_LAUNCH_MODE_GROUP,
+ APP_GROUP_LAUNCH_MODE_CALLER,
+} app_group_launch_mode_e;
+
+struct app_group_context_s {
+ char *id;
+ char *caller_id;
+ pid_t pid;
+ pid_t caller_pid;
+ int wid;
+ int status;
+ app_group_launch_mode_e launch_mode;
+ bool fg;
+ bool group_sig;
+ bool can_be_leader;
+ bool reroute;
+ bool can_shift;
+ bool recycle;
+};
+
+struct launch_context_s {
+ app_group_launch_mode_e mode;
+ bool can_attach;
+ pid_t leader_pid;
+ const char *leader_id;
+ bool new_instance;
+};
+
+struct app_group_s {
+ char *leader_id;
+ pid_t leader_pid;
+ GList *list;
+};
+
+static GList *__app_group_list;
+static GList *__recycle_bin;
+static struct launch_context_s __launch_context;
+
+static void __prepare_to_suspend(int pid, uid_t uid);
+
+static void __destroy_app_group_context(gpointer data)
+{
+ struct app_group_context_s *ctx = (struct app_group_context_s *)data;
+
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_DESTROY_APP_GROUP_CONTEXT,
+ ctx->pid, ctx->wid, ctx->id, NULL);
+
+ if (ctx->caller_id)
+ free(ctx->caller_id);
+ if (ctx->id)
+ free(ctx->id);
+ free(ctx);
+}
+
+static struct app_group_context_s *__create_app_group_context(
+ pid_t pid, const char *id,
+ pid_t caller_pid, const char *caller_id,
+ app_group_launch_mode_e launch_mode,
+ bool can_shift, bool recycle)
+{
+ struct app_group_context_s *ctx;
+
+ ctx = calloc(1, sizeof(struct app_group_context_s));
+ if (!ctx) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ ctx->id = strdup(id);
+ if (!ctx->id) {
+ _E("Failed to duplicate ID(%s)", id);
+ free(ctx);
+ return NULL;
+ }
+
+ ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
+ if (!ctx->caller_id) {
+ _E("Failed to duplicate caller ID(%s)", caller_id);
+ __destroy_app_group_context(ctx);
+ return NULL;
+ }
+
+ ctx->pid = pid;
+ ctx->caller_pid = caller_pid;
+ ctx->wid = 0;
+ ctx->fg = false;
+ ctx->can_be_leader = false;
+ ctx->reroute = false;
+ ctx->launch_mode = launch_mode;
+ ctx->can_shift = can_shift;
+ ctx->recycle = recycle;
+
+ return ctx;
+}
+
+static void __destroy_app_group(gpointer data)
+{
+ struct app_group_s *group = (struct app_group_s *)data;
+
+ if (group->list)
+ g_list_free_full(group->list, __destroy_app_group_context);
+ if (group->leader_id)
+ free(group->leader_id);
+ free(group);
+}
+
+static struct app_group_s *__create_app_group(const char *leader_id,
+ pid_t leader_pid)
+{
+ struct app_group_s *group;
+
+ group = calloc(1, sizeof(struct app_group_s));
+ if (!group) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ group->leader_id = strdup(leader_id);
+ if (!group->leader_id) {
+ _E("Failed to duplicate leader ID");
+ free(group);
+ return NULL;
+ }
+
+ group->leader_pid = leader_pid;
+
+ return group;
+}
+
+static gint __compare_context_id(gconstpointer a, gconstpointer b)
+{
+ struct app_group_context_s *ctx = (struct app_group_context_s *)a;
+ const char *id = (const char *)b;
+
+ return strcmp(ctx->id, id);
+}
+
+static gint __compare_group_id(gconstpointer a, gconstpointer b)
+{
+ app_group_h group = (app_group_h)a;
+ const char *id = (const char *)b;
+
+ return strcmp(group->leader_id, id);
+}
+
+const char *_app_group_get_id(pid_t pid)
+{
+ amd_app_status_h app_status;
+ int app_type;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return NULL;
+ }
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ _E("The type of the application(%d) is component-based", pid);
+ return NULL;
+ }
+
+ return amd_app_status_get_instance_id(app_status);
+}
+
+static pid_t __get_caller_pid(bundle *kb)
+{
+ const char *pid_str;
+
+ pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+ if (!pid_str) {
+ pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
+ if (!pid_str)
+ return -1;
+ }
+
+ return atoi(pid_str);
+}
+
+static const char *__get_caller_id(bundle *kb)
+{
+ const char *id;
+
+ id = bundle_get_val(kb, AUL_K_ORG_CALLER_INSTANCE_ID);
+ if (!id)
+ id = bundle_get_val(kb, AUL_K_CALLER_INSTANCE_ID);
+
+ return id;
+}
+
+app_group_node_h _app_group_node_find(const char *id)
+{
+ app_group_h group;
+ app_group_node_h node;
+ GList *iter;
+
+ if (!id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ node = g_list_find_custom(group->list, id,
+ __compare_context_id);
+ if (node)
+ return node;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+app_group_h _app_group_find(const char *id)
+{
+ app_group_h group;
+ app_group_node_h node;
+ GList *iter;
+
+ if (!id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ node = g_list_find_custom(group->list, id,
+ __compare_context_id);
+ if (node)
+ return group;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+pid_t _app_group_get_leader_pid(app_group_h h)
+{
+ if (!h)
+ return -1;
+
+ return h->leader_pid;
+}
+
+static struct app_group_context_s *__detach_context_from_recycle_bin(
+ const char *id)
+{
+ struct app_group_context_s *ctx;
+ GList *found;
+
+ if (!id)
+ return NULL;
+
+ found = g_list_find_custom(__recycle_bin, id, __compare_context_id);
+ if (!found)
+ return NULL;
+
+ ctx = (struct app_group_context_s *)found->data;
+ __recycle_bin = g_list_delete_link(__recycle_bin, found);
+
+ return ctx;
+}
+
+int _app_group_node_get_window(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return 0;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (ctx)
+ return ctx->wid;
+
+ return 0;
+}
+
+const char *_app_group_node_get_id(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return NULL;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (ctx)
+ return ctx->id;
+
+ return NULL;
+}
+
+int _app_group_node_set_window(app_group_node_h node, int wid)
+{
+ struct app_group_context_s *ctx;
+ int prev_wid = 0;
+ int next_wid = 0;
+ int caller_wid;
+ app_group_node_h caller_node;
+ amd_comp_status_h comp = NULL;
+
+ if (!node) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return -1;
+
+ ctx->wid = wid;
+ comp = amd_comp_status_find_by_instance_id(ctx->id);
+ if (comp)
+ amd_comp_status_set_window(comp, wid);
+
+ prev_wid = _app_group_node_get_window(g_list_previous(node));
+ if (prev_wid != 0)
+ _app_group_wayland_attach_window(prev_wid, wid);
+
+ if (ctx->can_shift && ctx->caller_id) {
+ caller_node = _app_group_node_find(ctx->caller_id);
+ caller_wid = _app_group_node_get_window(caller_node);
+ if (caller_wid != 0)
+ _app_group_wayland_attach_window(caller_wid, wid);
+ }
+
+ next_wid = _app_group_node_get_window(g_list_next(node));
+ if (next_wid != 0)
+ _app_group_wayland_attach_window(wid, next_wid);
+
+ return 0;
+}
+
+static gint __compare_window_id(gconstpointer a, gconstpointer b)
+{
+ struct app_group_context_s *ctx = (struct app_group_context_s *)a;
+ int wid = GPOINTER_TO_INT(b);
+
+ if (ctx->wid == wid)
+ return 0;
+
+ return -1;
+}
+
+app_group_node_h _app_group_node_find_by_wid(int wid)
+{
+ app_group_h group;
+ app_group_node_h node;
+ GList *iter;
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ node = g_list_find_custom(group->list,
+ GINT_TO_POINTER(wid),
+ __compare_window_id);
+ if (node)
+ return node;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+app_group_node_h _app_group_node_add_node(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+ struct app_group_context_s *new_ctx;
+ app_group_h group;
+
+ if (!node)
+ return NULL;
+
+ ctx = (struct app_group_context_s *)node->data;
+ group = _app_group_find(ctx->id);
+ new_ctx = __create_app_group_context(ctx->pid, ctx->id, ctx->caller_pid,
+ ctx->caller_id, ctx->launch_mode, ctx->can_shift, true);
+ if (!new_ctx) {
+ _E("Failed to create app group context. %s:%d",
+ ctx->id, ctx->pid);
+ return NULL;
+ }
+
+ new_ctx->group_sig = ctx->group_sig;
+ new_ctx->reroute = true;
+ new_ctx->can_be_leader = ctx->can_be_leader;
+
+ group = _app_group_find(ctx->id);
+ group->list = g_list_append(group->list, new_ctx);
+
+ return g_list_last(group->list);
+}
+
+int _app_group_node_remove_node(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+
+ if (!node)
+ return -EINVAL;
+
+ ctx = (struct app_group_context_s *)node->data;
+ group = _app_group_find(ctx->id);
+ group->list = g_list_remove(group->list, ctx);
+ __destroy_app_group_context(ctx);
+
+ return 0;
+}
+
+static bool __app_group_node_is_leader(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+
+ if (!node)
+ return false;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx) {
+ _E("App group context is nullptr");
+ return false;
+ }
+
+ group = _app_group_find(ctx->id);
+ if (group && g_list_first(group->list) == node)
+ return true;
+
+ return false;
+}
+
+static app_group_node_h __app_group_node_find_second_leader(const char *id)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+ GList *node;
+
+ group = _app_group_find(id);
+ if (!group)
+ return NULL;
+
+ node = g_list_next(group->list);
+ if (node) {
+ ctx = (struct app_group_context_s *)node->data;
+ if (ctx && ctx->can_be_leader) {
+ _W("Sencond leader. leader_id(%s), id(%s)",
+ id, ctx->id);
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
+static void __app_group_remove(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+
+ if (!node)
+ return;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx) {
+ _E("App group context is nullptr");
+ return;
+ }
+
+ group = _app_group_find(ctx->id);
+ if (!group) {
+ _E("Failed to find app group. %s", ctx->id);
+ return;
+ }
+
+ group->list = g_list_delete_link(group->list, node);
+ __destroy_app_group_context(ctx);
+
+ if (g_list_length(group->list) == 0) {
+ __app_group_list = g_list_remove(__app_group_list, group);
+ __destroy_app_group(group);
+ }
+}
+
+static pid_t __app_group_node_get_pid(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return -1;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return -1;
+
+ return ctx->pid;
+}
+
+static void __app_group_node_remove(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+ char id[512];
+
+ if (!node)
+ return;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return;
+
+ snprintf(id, sizeof(id), "%s", ctx->id);
+
+ __app_group_remove(node);
+ ctx = __detach_context_from_recycle_bin(id);
+ if (ctx)
+ free(ctx);
+}
+
+static struct app_group_context_s *__detach_context_from_app_group(
+ const char *id)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+ GList *found;
+
+ group = _app_group_find(id);
+ if (!group)
+ return NULL;
+
+ found = g_list_find_custom(group->list, id, __compare_context_id);
+ if (!found)
+ return NULL;
+
+ ctx = (struct app_group_context_s *)found->data;
+ group->list = g_list_delete_link(group->list, found);
+
+ if (g_list_length(group->list) == 0) {
+ __app_group_list = g_list_remove(__app_group_list, group);
+ __destroy_app_group(group);
+ }
+
+ return ctx;
+}
+
+void _app_group_node_clear_top(app_group_node_h node, uid_t uid)
+{
+ const char *id;
+ int wid;
+ pid_t pid;
+ GList *iter;
+ GList *curr;
+
+ if (!node)
+ return;
+
+ iter = g_list_last(node);
+ while (iter && iter != node) {
+ curr = iter;
+ iter = g_list_previous(iter);
+ wid = _app_group_node_get_window(curr);
+ _app_group_wayland_detach_window(wid);
+ pid = __app_group_node_get_pid(curr);
+ aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
+ id = _app_group_node_get_id(curr);
+ amd_launch_term_sub_inst(pid, id, uid);
+ __app_group_node_remove(curr);
+ }
+}
+
+static void __app_group_node_remove_leader(const char *id)
+{
+ struct app_group_context_s *ctx;
+ app_group_node_h node;
+ app_group_h group;
+ GList *found;
+
+ found = g_list_find_custom(__app_group_list, id, __compare_group_id);
+ if (!found)
+ return;
+
+ group = (app_group_h)found->data;
+ if (!group)
+ return;
+
+ if (!g_list_next(group->list))
+ return;
+
+ node = group->list;
+ group->list = NULL;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (ctx)
+ __destroy_app_group_context(ctx);
+
+ node = g_list_delete_link(node, node);
+ ctx = (struct app_group_context_s *)node->data;
+
+ __app_group_list = g_list_remove(__app_group_list, group);
+ __destroy_app_group(group);
+
+ group = __create_app_group(ctx->id, ctx->pid);
+ if (group) {
+ group->list = node;
+ __app_group_list = g_list_append(__app_group_list, group);
+ }
+}
+
+static const char *__app_group_node_get_next_caller_id(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return NULL;
+
+ node = g_list_next(node);
+ if (!node)
+ return NULL;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return NULL;
+
+ return ctx->caller_id;
+}
+
+static bool __app_group_node_can_reroute(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return false;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return false;
+
+ return ctx->reroute;
+}
+
+static void __app_group_node_reroute(app_group_node_h node)
+{
+ int prev_wid;
+ int next_wid;
+
+ prev_wid = _app_group_node_get_window(g_list_previous(node));
+ if (!prev_wid)
+ return;
+
+ next_wid = _app_group_node_get_window(g_list_next(node));
+ if (!next_wid)
+ return;
+
+ _D("Reroute");
+ _app_group_wayland_attach_window(prev_wid, next_wid);
+}
+
+static bool __app_group_node_is_sub(app_group_node_h node)
+{
+ if (!node)
+ return false;
+
+ if (g_list_previous(node))
+ return true;
+
+ return false;
+}
+
+static void __app_group_node_remove_full(app_group_node_h node, uid_t uid)
+{
+ struct app_group_context_s *ctx;
+ const char *caller_id;
+
+ if (!node)
+ return;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx) {
+ _E("App group context is nullptr");
+ return;
+ }
+
+ if (__app_group_node_is_leader(node)) {
+ _W("App group leader. %s:%d", ctx->id, ctx->pid);
+ if (!__app_group_node_find_second_leader(ctx->id)) {
+ _app_group_node_clear_top(node, uid);
+ __app_group_node_remove(node);
+ } else {
+ __app_group_node_remove_leader(ctx->id);
+ }
+ } else if (__app_group_node_is_sub(node)) {
+ _W("App group Sub. %s:%d", ctx->id, ctx->pid);
+ caller_id = __app_group_node_get_next_caller_id(node);
+ if (__app_group_node_can_reroute(node) ||
+ (caller_id && strcmp(caller_id, ctx->id) != 0)) {
+ _W("App group reroute");
+ __app_group_node_reroute(node);
+ } else {
+ _W("App group clear top");
+ _app_group_node_clear_top(node, uid);
+ }
+ __app_group_node_remove(node);
+ }
+}
+
+static void __app_group_remove_full(pid_t pid, uid_t uid)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+ app_group_node_h node;
+ GList *iter;
+ GList *iter_node;
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ iter = g_list_next(iter);
+ iter_node = g_list_last(group->list);
+ while (iter_node) {
+ ctx = (struct app_group_context_s *)iter_node->data;
+ node = iter_node;
+ iter_node = g_list_previous(iter_node);
+ if (ctx && ctx->pid == pid)
+ __app_group_node_remove_full(node, uid);
+ }
+ }
+}
+
+static int __app_group_get_nth(app_group_h group, int wid)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ iter = group->list;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx->wid == wid)
+ return g_list_position(group->list, iter);
+
+ iter = g_list_next(iter);
+ }
+
+ return -1;
+}
+
+static struct app_group_context_s *__app_group_add(
+ pid_t leader_pid, const char *leader_id,
+ pid_t pid, const char *id,
+ pid_t caller_pid, const char *caller_id,
+ app_group_launch_mode_e launch_mode,
+ bool can_shift, bool recycle,
+ int before_wid)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+ app_group_node_h node;
+ GList *found;
+ int pos = -1;
+
+ if (!id || !leader_id) {
+ _E("Invalid parameter");
+ return NULL;
+ }
+
+ ctx = __detach_context_from_recycle_bin(id);
+ if (!ctx) {
+ ctx = __create_app_group_context(pid, id, caller_pid, caller_id,
+ launch_mode, can_shift, recycle);
+ if (!ctx) {
+ _E("Failed to create app group context. %s:%d",
+ id, pid);
+ return NULL;
+ }
+
+ if (leader_pid == pid || ctx->recycle)
+ ctx->group_sig = true;
+ else
+ ctx->group_sig = false;
+ }
+
+ found = g_list_find_custom(__app_group_list, leader_id,
+ __compare_group_id);
+ if (!found) {
+ group = __create_app_group(leader_id, leader_pid);
+ if (!group) {
+ _E("Failed to create app group. %s:%d",
+ leader_id, leader_pid);
+ __destroy_app_group_context(ctx);
+ return NULL;
+ }
+
+ __app_group_list = g_list_append(__app_group_list,
+ group);
+ found = g_list_last(__app_group_list);
+ }
+
+ group = (app_group_h)found->data;
+
+ node = g_list_find_custom(group->list, id, __compare_context_id);
+ if (node) {
+ _E("Already exists. %s:%d", id, pid);
+ __destroy_app_group_context(ctx);
+ return NULL;
+ }
+
+ if (before_wid > 0)
+ pos = __app_group_get_nth(group, before_wid);
+
+ if (pos != -1)
+ group->list = g_list_insert(group->list, ctx, pos);
+ else
+ group->list = g_list_append(group->list, ctx);
+
+ SECURE_LOGD("[__APP_GROUP__] leader(%s:%d), length(%d)",
+ leader_id, leader_pid, g_list_length(group->list));
+
+ if (ctx->wid != 0) {
+ node = _app_group_node_find_by_wid(ctx->wid);
+ _app_group_node_set_window(node, ctx->wid);
+ }
+
+ return ctx;
+}
+
+static void __set_hint(struct app_group_context_s *ctx, bundle *b)
+{
+ const char *str;
+
+ if (!ctx || !b)
+ return;
+
+ str = bundle_get_val(b, AUL_SVC_K_CAN_BE_LEADER);
+ if (str && !strcmp(str, "true"))
+ ctx->can_be_leader = true;
+ str = bundle_get_val(b, AUL_SVC_K_REROUTE);
+ if (str && !strcmp(str, "true"))
+ ctx->reroute = true;
+}
+
+static void __app_group_start(pid_t leader_pid, const char *leader_id,
+ pid_t pid, const char *id, bundle *b, bool can_attach,
+ app_group_launch_mode_e launch_mode)
+{
+ bool can_shift = false;
+ bool recycle = false;
+ const char *str;
+ const char *caller_id;
+ pid_t caller_pid;
+ struct app_group_context_s *ctx;
+ int before_wid = 0;
+
+ _D("app_group_start");
+
+ caller_pid = __get_caller_pid(b);
+ caller_id = __get_caller_id(b);
+ if (!caller_id)
+ caller_id = _app_group_get_id(caller_pid);
+
+ str = bundle_get_val(b, AUL_SVC_K_SHIFT_WINDOW);
+ if (str && !strcmp(str, "true"))
+ can_shift = true;
+
+ str = bundle_get_val(b, AUL_SVC_K_RECYCLE);
+ if (str && !strcmp(str, "true"))
+ recycle = true;
+
+ str = bundle_get_val(b, AUL_K_INSERT_BEFORE_WINDOW);
+ if (str && isdigit(str[0]))
+ before_wid = atoi(str);
+
+ if (can_attach) {
+ ctx = __app_group_add(leader_pid, leader_id, pid, id,
+ caller_pid, caller_id, launch_mode,
+ false, recycle, before_wid);
+ } else {
+ ctx = __app_group_add(pid, id, pid, id,
+ caller_pid, caller_id, launch_mode,
+ can_shift, false, before_wid);
+ }
+ __set_hint(ctx, b);
+}
+
+static void __app_group_context_do_recycle(struct app_group_context_s *ctx)
+{
+ amd_app_status_h app_status;
+ const char *appid;
+ const char *pkgid;
+ const char *comp_type;
+ amd_appinfo_h ai;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_pid(ctx->pid);
+ uid = amd_app_status_get_uid(app_status);
+
+ if (ctx->fg) {
+ appid = amd_app_status_get_appid(app_status);
+ ai = amd_appinfo_find(uid, appid);
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+
+ _D("Send BG signal %s:%s", appid, comp_type);
+ aul_send_app_status_change_signal(ctx->pid, appid, pkgid,
+ STATUS_BACKGROUND, comp_type);
+ amd_app_status_find_service_apps(app_status, STATUS_BG,
+ __prepare_to_suspend, true);
+ ctx->fg = false;
+ }
+
+ __recycle_bin = g_list_append(__recycle_bin, ctx);
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_DO_RECYCLE_END,
+ ctx->pid, uid, NULL, NULL);
+}
+
+void _app_group_node_lower(app_group_node_h node, bool *exit)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node || !exit)
+ return;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (__app_group_node_is_sub(node)) {
+ if (ctx->recycle && ctx->reroute) {
+ __app_group_node_reroute(node);
+ if (ctx->wid != 0)
+ _app_group_wayland_detach_window(ctx->wid);
+
+ ctx = __detach_context_from_app_group(ctx->id);
+ __app_group_context_do_recycle(ctx);
+ *exit = false;
+ } else {
+ *exit = true;
+ }
+ return;
+ }
+
+ *exit = false;
+ if (ctx->can_shift) {
+ _app_group_wayland_detach_window(ctx->wid);
+ ctx->can_shift = false;
+ _app_group_wayland_lower_window(ctx->wid);
+ }
+}
+
+static void __app_group_restart(const char *id, bundle *b)
+{
+ struct app_group_context_s *ctx;
+ app_group_node_h node;
+ const char *shift_window;
+ int caller_wid;
+ const char *caller_id;
+ app_group_node_h caller_node;
+
+ if (!id || !b) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ node = _app_group_node_find(id);
+ if (!node)
+ return;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return;
+
+ ctx->caller_pid = __get_caller_pid(b);
+
+ if (ctx->caller_id) {
+ free(ctx->caller_id);
+ ctx->caller_id = NULL;
+ }
+
+ caller_id = __get_caller_id(b);
+ if (!caller_id)
+ caller_id = _app_group_get_id(ctx->caller_pid);
+
+ ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
+
+ if (ctx->can_shift) {
+ if (ctx->wid != 0)
+ _app_group_wayland_detach_window(ctx->wid);
+ ctx->can_shift = false;
+ }
+
+ shift_window = bundle_get_val(b, AUL_SVC_K_SHIFT_WINDOW);
+ if (shift_window && !strcmp(shift_window, "true")) {
+ ctx->can_shift = true;
+ if (ctx->wid != 0) {
+ caller_node = _app_group_node_find(ctx->caller_id);
+ caller_wid = _app_group_node_get_window(caller_node);
+ if (caller_wid != 0) {
+ _app_group_wayland_attach_window(caller_wid,
+ ctx->wid);
+ } else {
+ _E("Invalid caller window id");
+ }
+ }
+ }
+}
+
+static void __app_group_restart_recycle_bin(const char *leader_id,
+ const char *id, bundle *b, bool can_attach)
+{
+ struct app_group_context_s *ctx;
+ app_group_h group;
+ app_group_node_h node;
+ app_group_node_h caller_node;
+ const char *caller_id;
+ gint caller_pos;
+ GList *found;
+
+ if (!id)
+ return;
+
+ ctx = __detach_context_from_recycle_bin(id);
+ if (!ctx)
+ return;
+
+ ctx->caller_pid = __get_caller_pid(b);
+
+ if (ctx->caller_id) {
+ free(ctx->caller_id);
+ ctx->caller_id = NULL;
+ }
+
+ caller_id = __get_caller_id(b);
+ if (!caller_id)
+ caller_id = _app_group_get_id(ctx->caller_pid);
+
+ ctx->caller_id = strdup(caller_id ? caller_id : "NULL");
+ ctx->group_sig = true;
+
+ caller_node = _app_group_node_find(ctx->caller_id);
+ if (!caller_node) {
+ __app_group_context_do_recycle(ctx);
+ return;
+ }
+
+ if (can_attach) {
+ found = g_list_find_custom(__app_group_list, leader_id,
+ __compare_group_id);
+ if (!found) {
+ __app_group_context_do_recycle(ctx);
+ return;
+ }
+
+ group = (app_group_h)found->data;
+ } else {
+ found = g_list_find_custom(__app_group_list, id,
+ __compare_group_id);
+ if (!found) {
+ group = __create_app_group(ctx->id, ctx->pid);
+ if (!group) {
+ _E("Failed to create app group. %s:%d",
+ ctx->id, ctx->pid);
+ __app_group_context_do_recycle(ctx);
+ return;
+ }
+
+ __app_group_list = g_list_append(__app_group_list,
+ group);
+ found = g_list_last(__app_group_list);
+ }
+
+ group = (app_group_h)found->data;
+ }
+
+ caller_pos = g_list_position(group->list, caller_node);
+ group->list = g_list_insert(group->list, ctx, caller_pos + 1);
+ SECURE_LOGD("[__APP_GROUP__] leader(%s:%d), length(%d)",
+ group->leader_id,
+ group->leader_pid,
+ g_list_length(group->list));
+
+ if (ctx->wid != 0) {
+ node = _app_group_node_find(id);
+ _app_group_node_set_window(node, ctx->wid);
+ }
+}
+
+static void __prepare_to_wake(int pid, uid_t uid)
+{
+ int ret;
+ int dummy = 0;
+
+ ret = aul_sock_send_raw(pid, uid, APP_SUSPEND, (unsigned char *)&dummy,
+ sizeof(int), AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("Failed to send suspend signal. pid(%d), result(%d)",
+ pid, ret);
+ }
+
+ _D("[__APP_SUSPEND__] pid: %d, uid: %d", pid, uid);
+}
+
+static void __prepare_to_suspend(int pid, uid_t uid)
+{
+ int ret;
+ int dummy = 0;
+
+ ret = aul_sock_send_raw(pid, uid, APP_WAKE, (unsigned char *)&dummy,
+ sizeof(int), AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("Failed to send wake signal. pid(%d), result(%d)",
+ pid, ret);
+ }
+
+ _D("[__APP_WAKE__] pid: %d, uid: %d", pid, uid);
+}
+
+static void __app_group_send_status(pid_t pid, bool flag, bool force, bool self)
+{
+ amd_app_status_h app_status;
+ amd_appinfo_h ai;
+ const char *appid;
+ const char *pkgid;
+ bool bg_allowed;
+ bool excluded;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return;
+ }
+
+ appid = amd_app_status_get_appid(app_status);
+ uid = amd_app_status_get_uid(app_status);
+
+ ai = amd_appinfo_find(uid, appid);
+ if (!ai) {
+ _E("Failed to find appinfo. %s:%d", appid, uid);
+ return;
+ }
+
+ pkgid = amd_appinfo_get_value(ai, AMD_AIT_PKGID);
+ bg_allowed = amd_suspend_is_allowed_background(ai);
+ excluded = amd_suspend_is_excluded(pid);
+
+ _D("Send %s signal %s", flag ? "FG" : "BG", appid);
+ aul_send_app_status_change_signal(pid, appid, pkgid,
+ flag ? STATUS_FOREGROUND : STATUS_BACKGROUND,
+ APP_TYPE_UI);
+ if (!excluded && !bg_allowed) {
+ amd_app_status_find_service_apps(app_status,
+ flag ? STATUS_VISIBLE : STATUS_BG,
+ flag ? __prepare_to_wake : __prepare_to_suspend,
+ flag ? false : true);
+ if (!flag && force && self) {
+ __prepare_to_suspend(pid, uid);
+ amd_suspend_add_timer(pid);
+ }
+ }
+}
+
+static void __app_group_set_flag(app_group_h group, pid_t pid, bool flag,
+ bool force)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ if (!group)
+ return;
+
+ iter = group->list;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx && (ctx->fg != flag || force)) {
+ __app_group_send_status(ctx->pid, flag, force,
+ ctx->pid == pid);
+ ctx->fg = flag;
+ }
+ iter = g_list_next(iter);
+ }
+}
+
+static bool __app_group_is_visible(app_group_h group)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ if (!group)
+ return false;
+
+ iter = group->list;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx && ctx->status == STATUS_VISIBLE)
+ return true;
+
+ iter = g_list_next(iter);
+ }
+
+ return false;
+}
+
+static bool __app_group_can_attach_window(bundle *b, const char *appid,
+ app_group_launch_mode_e *launch_mode, uid_t uid)
+{
+ const char *str;
+ const char *mode = NULL;
+ const char *comp_type;
+ const char *comp_id;
+ const char *type;
+ amd_appinfo_h ai;
+ amd_compinfo_h ci;
+
+ ai = amd_appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
+ } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
+ comp_id = bundle_get_val(b, AUL_K_COMPONENT_ID);
+ if (!comp_id)
+ return false;
+
+ ci = amd_compinfo_find(uid, comp_id);
+ if (!ci)
+ return false;
+
+ type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
+ if (!type || strcmp(type, "frame") != 0)
+ return false;
+
+ mode = amd_compinfo_get_value(ci,
+ AMD_COMPINFO_TYPE_LAUNCH_MODE);
+ }
+
+ if (mode && !strcmp(mode, "caller"))
+ *launch_mode = APP_GROUP_LAUNCH_MODE_CALLER;
+ else if (mode && !strcmp(mode, "group"))
+ *launch_mode = APP_GROUP_LAUNCH_MODE_GROUP;
+ else
+ *launch_mode = APP_GROUP_LAUNCH_MODE_SINGLE;
+
+ switch (*launch_mode) {
+ case APP_GROUP_LAUNCH_MODE_CALLER:
+ _D("Launch mode is caller");
+ str = bundle_get_val(b, APP_SVC_K_LAUNCH_MODE);
+ if (str && !strcmp(str, "group"))
+ return true;
+ break;
+ case APP_GROUP_LAUNCH_MODE_GROUP:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+static bool __app_group_can_be_leader(bundle *b)
+{
+ const char *str;
+
+ str = bundle_get_val(b, AUL_SVC_K_CAN_BE_LEADER);
+ if (str && !strcmp(str, "true"))
+ return true;
+
+ return false;
+}
+
+static void __app_group_context_remove_from_recycle_bin(pid_t pid)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ iter = __recycle_bin;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ iter = g_list_next(iter);
+ if (ctx && ctx->pid == pid) {
+ __recycle_bin = g_list_remove(__recycle_bin, ctx);
+ __destroy_app_group_context(ctx);
+ }
+ }
+}
+
+static bool __app_group_is_group_mode(bundle *kb, uid_t uid)
+{
+ const char *str;
+ const char *mode = NULL;
+ const char *appid;
+ const char *comp_type;
+ const char *comp_id;
+ const char *type;
+ amd_appinfo_h ai;
+ amd_compinfo_h ci;
+
+ if (!kb)
+ return false;
+
+ appid = bundle_get_val(kb, AUL_K_APPID);
+ if (!appid)
+ return false;
+
+ ai = amd_appinfo_find(uid, appid);
+ if (!ai)
+ return false;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ mode = amd_appinfo_get_value(ai, AMD_AIT_LAUNCH_MODE);
+ } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
+ comp_id = bundle_get_val(kb, AUL_K_COMPONENT_ID);
+ if (!comp_id)
+ return false;
+
+ ci = amd_compinfo_find(uid, comp_id);
+ if (!ci)
+ return false;
+
+ type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
+ if (!type || strcmp(type, "frame") != 0)
+ return false;
+
+ mode = amd_compinfo_get_value(ci,
+ AMD_COMPINFO_TYPE_LAUNCH_MODE);
+ }
+
+ if (mode && !strcmp(mode, "caller")) {
+ str = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
+ if (str && !strcmp(str, "group"))
+ return true;
+ } else if (mode && !strcmp(mode, "group")) {
+ return true;
+ }
+
+ return false;
+}
+
+void _app_group_get_leader_pids(int *cnt, pid_t **pids)
+{
+ app_group_h group;
+ GList *iter;
+ pid_t *leader_pids;
+ int size;
+ int idx = 0;
+
+
+ size = g_list_length(__app_group_list);
+ if (size > 0) {
+ leader_pids = (pid_t *)calloc(size, sizeof(pid_t));
+ if (!leader_pids) {
+ _E("Out of memory");
+ return;
+ }
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ if (group)
+ leader_pids[idx++] = group->leader_pid;
+
+ iter = g_list_next(iter);
+ }
+
+ *cnt = size;
+ *pids = leader_pids;
+ }
+}
+
+char **_app_group_get_leader_ids(int *cnt)
+{
+ app_group_h group;
+ GList *iter;
+ char **leader_ids;
+ int idx = 0;
+ int size;
+
+ size = g_list_length(__app_group_list);
+ if (size == 0)
+ return NULL;
+
+ leader_ids = (char **)calloc(size + 1, sizeof(char *));
+ if (!leader_ids) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ if (group && group->leader_id)
+ leader_ids[idx++] = strdup(group->leader_id);
+
+ iter = g_list_next(iter);
+ }
+
+ *cnt = size;
+
+ return leader_ids;
+}
+
+int _app_group_get_count(app_group_h group)
+{
+ if (!group)
+ return -1;
+
+ return g_list_length(group->list);
+}
+
+int _app_group_foreach_context(app_group_h group,
+ app_group_foreach_context_cb callback,
+ void *user_data)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ if (!group)
+ return -1;
+
+ iter = group->list;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx) {
+ callback(ctx->id, ctx->pid, ctx->wid, ctx->fg,
+ user_data);
+ }
+ iter = g_list_next(iter);
+ }
+
+ return 0;
+}
+
+void _app_group_get_group_pids(app_group_h group, int *cnt, pid_t **pids)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+ int size;
+ pid_t *group_pids;
+ int idx = 0;
+
+ if (!group)
+ return;
+
+ size = g_list_length(group->list);
+ if (size == 0)
+ return;
+
+ group_pids = calloc(size, sizeof(pid_t));
+ if (!group_pids) {
+ _E("Out of memory");
+ return;
+ }
+
+ iter = group->list;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx)
+ group_pids[idx++] = ctx->pid;
+ iter = g_list_next(iter);
+ }
+
+ *cnt = size;
+ *pids = group_pids;
+}
+
+static void __app_group_context_set_status(struct app_group_context_s *ctx,
+ struct app_group_context_s *last_ctx,
+ pid_t leader_pid, pid_t pid,
+ int status, bool force)
+{
+ amd_app_status_h app_status;
+ const char *pkgid;
+ app_group_h group;
+
+ if (status > 0)
+ ctx->status = status;
+
+ if ((last_ctx && last_ctx->wid != 0) ||
+ status == STATUS_VISIBLE ||
+ force == true) {
+ group = _app_group_find(ctx->id);
+ if (__app_group_is_visible(group)) {
+ __app_group_set_flag(group, pid, true, force);
+ if (!ctx->group_sig && leader_pid != pid) {
+ app_status = amd_app_status_find_by_pid(pid);
+ pkgid = amd_app_status_get_pkgid(app_status);
+ _D("Send group signal %d", pid);
+ aul_send_app_group_signal(leader_pid, pid,
+ pkgid);
+ ctx->group_sig = true;
+ }
+ } else {
+ __app_group_set_flag(group, pid, false, force);
+ }
+ }
+}
+
+static int __app_group_node_set_status(app_group_node_h node, int status,
+ bool force)
+{
+ struct app_group_context_s *ctx;
+ struct app_group_context_s *last_ctx = NULL;
+ struct app_group_context_s *first_ctx = NULL;
+ pid_t leader_pid = -1;
+ pid_t pid;
+
+ if (!node)
+ return -1;
+
+ ctx = (struct app_group_context_s *)node->data;
+ pid = ctx->pid;
+
+ node = g_list_last(node);
+ if (node)
+ last_ctx = (struct app_group_context_s *)node->data;
+
+ node = g_list_first(node);
+ if (node) {
+ first_ctx = (struct app_group_context_s *)node->data;
+ leader_pid = first_ctx->pid;
+ }
+
+ __app_group_context_set_status(ctx, last_ctx, leader_pid, pid,
+ status, force);
+
+ return 0;
+}
+
+bool _app_group_node_get_fg_flag(app_group_node_h node)
+{
+ struct app_group_context_s *ctx;
+
+ if (!node)
+ return false;
+
+ ctx = (struct app_group_context_s *)node->data;
+ if (!ctx)
+ return false;
+
+ return ctx->fg;
+}
+
+static int __app_group_can_start(const char *appid, bundle *b,
+ bool *can_attach, pid_t *leader_pid,
+ app_group_launch_mode_e *mode, uid_t uid)
+{
+ pid_t caller_pid;
+ const char *caller_id;
+ const char *leader_id = NULL;
+ pid_t caller_wid;
+ app_group_node_h node;
+ app_group_h group;
+ int ret = 0;
+
+ if (__app_group_can_attach_window(b, appid, mode, uid)) {
+ *can_attach = true;
+ caller_pid = __get_caller_pid(b);
+ caller_id = __get_caller_id(b);
+ if (!caller_id) {
+ caller_id = _app_group_get_id(caller_pid);
+ if (!caller_id) {
+ _E("Failed to get caller id. %d", caller_pid);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ group = _app_group_find(caller_id);
+ *leader_pid = _app_group_get_leader_pid(group);
+ if (*leader_pid != -1) {
+ leader_id = group->leader_id;
+ node = _app_group_node_find(caller_id);
+ caller_wid = _app_group_node_get_window(node);
+ if (caller_wid == 0) {
+ _W("Caller(%d) window isn't ready",
+ caller_pid);
+ if (__app_group_can_be_leader(b))
+ *can_attach = false;
+ else
+ *can_attach = true;
+ }
+ } else {
+ _E("Cannot find leader pid");
+ if (__app_group_can_be_leader(b)) {
+ *can_attach = false;
+ } else {
+ ret = -1;
+ goto end;
+ }
+ }
+ }
+
+end:
+ __launch_context.can_attach = *can_attach;
+ __launch_context.mode = *mode;
+ __launch_context.leader_pid = *leader_pid;
+ __launch_context.leader_id = leader_id;
+
+ _W("[__APP_GROUP__] can_attach(%d), mode(%d), leader(%s:%d)",
+ __launch_context.can_attach,
+ __launch_context.mode,
+ __launch_context.leader_id ? __launch_context.leader_id : "null",
+ __launch_context.leader_pid);
+
+ return ret;
+}
+
+static int __app_group_find_pid_from_recycle_bin(const char *appid)
+{
+ struct app_group_context_s *ctx;
+ amd_app_status_h app_status;
+ const char *appid_from_bin;
+ GList *iter;
+
+ if (!appid)
+ return -1;
+
+ iter = __recycle_bin;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx) {
+ app_status = amd_app_status_find_by_pid(ctx->pid);
+ appid_from_bin = amd_app_status_get_appid(app_status);
+ if (appid_from_bin && !strcmp(appid_from_bin, appid))
+ return ctx->pid;
+ }
+
+ iter = g_list_next(iter);
+ }
+
+ return -1;
+}
+
+void _app_group_get_idle_pids(int *cnt, pid_t **pids)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+ pid_t *idle_pids;
+ int size;
+ int idx = 0;
+
+ size = g_list_length(__recycle_bin);
+ if (size <= 0)
+ return;
+
+ idle_pids = calloc(size, sizeof(pid_t));
+ if (!idle_pids) {
+ _E("Out of memory");
+ return;
+ }
+
+ iter = __recycle_bin;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx)
+ idle_pids[idx++] = ctx->pid;
+ iter = g_list_next(iter);
+ }
+
+ *cnt = size;
+ *pids = idle_pids;
+}
+
+int _app_group_get_idle_count(void)
+{
+ return g_list_length(__recycle_bin);
+}
+
+int _app_group_foreach_idle_context(app_group_foreach_context_cb callback,
+ void *user_data)
+{
+ struct app_group_context_s *ctx;
+ GList *iter;
+
+ iter = __recycle_bin;
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ if (ctx) {
+ callback(ctx->id, ctx->pid, ctx->wid, ctx->fg,
+ user_data);
+ }
+ iter = g_list_next(iter);
+ }
+
+ return 0;
+}
+
+static int __on_app_status_update_status_end(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ bool force = (bool)arg1;
+ bool update_group_info = (bool)arg2;
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ app_group_node_h node;
+ pid_t pid;
+ int status;
+ int app_type;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type != AMD_AT_UI_APP)
+ return AMD_NOTI_CONTINUE;
+
+ status = amd_app_status_get_status(app_status);
+ if (update_group_info && status != STATUS_DYING) {
+ pid = amd_app_status_get_pid(app_status);
+ node = _app_group_node_find(_app_group_get_id(pid));
+ __app_group_node_set_status(node, status, force);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_term_app_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ app_group_node_h node;
+ app_group_h group;
+ const char *id;
+ pid_t pid = (pid_t)arg1;
+ amd_request_h req = (amd_request_h)arg3;
+ struct app_group_context_s *ctx;
+ amd_app_status_h app_status;
+ GList *iter;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status)
+ return AMD_NOTI_CONTINUE;
+
+ if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
+ return AMD_NOTI_CONTINUE;
+
+ id = _app_group_get_id(pid);
+ node = _app_group_node_find(id);
+ if (__app_group_node_is_leader(node)) {
+ group = _app_group_find(id);
+ if (!group || !group->list)
+ return AMD_NOTI_CONTINUE;
+
+ uid = amd_request_get_target_uid(req);
+ iter = g_list_last(group->list);
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ node = iter;
+ iter = g_list_previous(iter);
+ if (ctx) {
+ if (ctx->pid != group->leader_pid) {
+ amd_launch_term_sub_inst(ctx->pid,
+ ctx->id, uid);
+ }
+ __app_group_node_remove(node);
+ }
+ }
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_term_bgapp_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ struct app_group_context_s *ctx;
+ amd_app_status_h app_status;
+ app_group_node_h node;
+ app_group_h group;
+ pid_t pid = (pid_t)arg1;
+ amd_request_h req = (amd_request_h)arg3;
+ const char *id;
+ GList *iter;
+ int status;
+ uid_t uid;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status)
+ return AMD_NOTI_CONTINUE;
+
+ if (amd_app_status_get_app_type(app_status) != AMD_AT_UI_APP)
+ return AMD_NOTI_CONTINUE;
+
+ id = _app_group_get_id(pid);
+ node = _app_group_node_find(id);
+ if (__app_group_node_is_leader(node)) {
+ group = _app_group_find(id);
+ if (!group || !group->list)
+ return AMD_NOTI_CONTINUE;
+
+ ctx = (struct app_group_context_s *)g_list_last(group->list);
+ if (!ctx)
+ return AMD_NOTI_CONTINUE;
+
+ app_status = amd_app_status_find_by_pid(ctx->pid);
+ status = amd_app_status_get_status(app_status);
+ if (status != STATUS_BG)
+ return AMD_NOTI_CONTINUE;
+
+ uid = amd_request_get_target_uid(req);
+ iter = g_list_last(group->list);
+ while (iter) {
+ ctx = (struct app_group_context_s *)iter->data;
+ node = iter;
+ iter = g_list_previous(iter);
+ if (ctx) {
+ if (ctx->pid != group->leader_pid) {
+ amd_launch_term_sub_inst(ctx->pid,
+ ctx->id, uid);
+ }
+ __app_group_node_remove(node);
+ }
+ }
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __app_group_prepare(int status, uid_t uid, amd_launch_context_h h,
+ bundle *kb)
+{
+ app_group_launch_mode_e launch_mode = APP_GROUP_LAUNCH_MODE_SINGLE;
+ bool can_attach = false;
+ pid_t leader_pid = -1;
+ const char *appid;
+ pid_t pid;
+ int ret;
+
+ appid = amd_launch_context_get_appid(h);
+ pid = amd_launch_context_get_pid(h);
+ if (pid <= 0 || status == STATUS_DYING) {
+ ret = __app_group_can_start(appid, kb, &can_attach,
+ &leader_pid, &launch_mode, uid);
+ if (ret != 0) {
+ _E("Can't make group info");
+ return -1;
+ }
+
+ if (can_attach && leader_pid == -1) {
+ _E("Can't launch singleton app in the same group");
+ return -1;
+ }
+ }
+
+ if (pid == -1 && can_attach) {
+ pid = __app_group_find_pid_from_recycle_bin(appid);
+ amd_launch_context_set_pid(h, pid);
+ }
+
+ return 0;
+}
+
+static int __on_launch_prepare_ui_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int status = arg1;
+ uid_t uid = (uid_t)arg2;
+ amd_launch_context_h h = (amd_launch_context_h)arg3;
+ bundle *kb = data;
+ int ret;
+
+ if (__app_group_is_group_mode(kb, uid)) {
+ amd_launch_context_set_pid(h, -1);
+ amd_launch_context_set_subapp(h, true);
+ amd_launch_context_set_app_status(h, NULL);
+ } else {
+ if (amd_launch_context_is_new_instance(h))
+ amd_launch_context_set_subapp(h, true);
+ else
+ amd_launch_context_set_subapp(h, false);
+ }
+
+ ret = __app_group_prepare(status, uid, h, data);
+ if (ret < 0)
+ return AMD_NOTI_STOP;
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_prepare_component_based_start(const char *msg,
+ int arg1, int arg2, void *arg3, bundle *data)
+{
+ int status = arg1;
+ uid_t uid = (uid_t)arg2;
+ amd_launch_context_h h = (amd_launch_context_h)arg3;
+ bundle *kb = data;
+ amd_comp_status_h comp_status = NULL;
+ const char *id;
+ int ret;
+
+ id = amd_launch_context_get_instance_id(h);
+ if (status != COMP_STATUS_DESTROYED) {
+ comp_status = amd_comp_status_find_by_instance_id(id);
+ if (comp_status)
+ status = amd_comp_status_get_status(comp_status);
+ else
+ status = COMP_STATUS_DESTROYED;
+ }
+
+ if (__app_group_is_group_mode(kb, uid)) {
+ amd_launch_context_set_subapp(h, true);
+ amd_launch_context_set_comp_status(h, NULL);
+ __launch_context.new_instance = true;
+ } else {
+ if (!comp_status || status == COMP_STATUS_DESTROYED) {
+ __launch_context.new_instance = true;
+ } else {
+ __launch_context.new_instance =
+ amd_launch_context_is_new_instance(h);
+ }
+ }
+
+ ret = __app_group_prepare(status, uid, h, data);
+ if (ret < 0)
+ return AMD_NOTI_STOP;
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static void __terminate_unmanageable_app(amd_app_status_h app_status)
+{
+ app_group_h group;
+ amd_app_status_h leader_status;
+ amd_appinfo_h ai;
+ const char *taskmanage;
+ const char *appid;
+ bool bg_allowed;
+ bool excluded;
+ GList *iter;
+ uid_t uid;
+
+ if (!amd_app_status_is_home_app(app_status))
+ return;
+
+ iter = __app_group_list;
+ while (iter) {
+ group = (app_group_h)iter->data;
+ iter = g_list_next(iter);
+ if (!group)
+ continue;
+
+ leader_status = amd_app_status_find_by_pid(group->leader_pid);
+ if (!leader_status)
+ continue;
+
+ if (amd_app_status_is_home_app(leader_status))
+ continue;
+
+ if (amd_app_status_get_status(leader_status) != STATUS_BG)
+ continue;
+
+ appid = amd_app_status_get_appid(leader_status);
+ uid = amd_app_status_get_uid(leader_status);
+
+ ai = amd_appinfo_find(uid, appid);
+ taskmanage = amd_appinfo_get_value(ai, AMD_AIT_TASKMANAGE);
+ bg_allowed = amd_suspend_is_allowed_background(ai);
+ excluded = amd_suspend_is_excluded(group->leader_pid);
+ if (taskmanage && !strcmp(taskmanage, "false") &&
+ !bg_allowed && !excluded) {
+ SECURE_LOGW("Terminate leader app(%s:%d)",
+ appid, group->leader_pid);
+ aul_send_app_terminate_request_signal(group->leader_pid,
+ NULL, NULL, NULL);
+ amd_launch_term_sub_inst(group->leader_pid,
+ group->leader_id, uid);
+ }
+ }
+}
+
+static int __on_launch_status_fg(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+
+ if (TIZEN_FEATURE_TERMINATE_UNMANAGEABLE_APP)
+ __terminate_unmanageable_app(app_status);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static gint __compare_app_status_for_sorting(gconstpointer p1, gconstpointer p2)
+{
+ amd_app_status_h app_status1 = (amd_app_status_h)p1;
+ amd_app_status_h app_status2 = (amd_app_status_h)p2;
+ int app_group_cnt1;
+ int app_group_cnt2;
+ int *app_group_pids1;
+ int *app_group_pids2;
+ int fg_cnt1;
+ int fg_cnt2;
+ int timestamp1;
+ int timestamp2;
+ const char *id1;
+ const char *id2;
+ app_group_h app_group1;
+ app_group_h app_group2;
+
+ if (amd_app_status_get_app_type(app_status1) != AMD_AT_UI_APP ||
+ amd_app_status_get_app_type(app_status2) != AMD_AT_UI_APP)
+ return 0;
+
+ timestamp1 = amd_app_status_get_timestamp(app_status1);
+ timestamp2 = amd_app_status_get_timestamp(app_status2);
+ if (timestamp1 > timestamp2)
+ return 1;
+ else if (timestamp1 < timestamp2)
+ return -1;
+
+ id1 = amd_app_status_get_leader_id(app_status1);
+ app_group1 = _app_group_find(id1);
+ _app_group_get_group_pids(app_group1, &app_group_cnt1,
+ &app_group_pids1);
+ id2 = amd_app_status_get_leader_id(app_status2);
+ app_group2 = _app_group_find(id2);
+ _app_group_get_group_pids(app_group2, &app_group_cnt2,
+ &app_group_pids2);
+ free(app_group_pids1);
+ free(app_group_pids2);
+
+ if (app_group_cnt1 < app_group_cnt2)
+ return 1;
+ else if (app_group_cnt1 > app_group_cnt2)
+ return -1;
+
+ fg_cnt1 = amd_app_status_get_fg_cnt(app_status1);
+ fg_cnt2 = amd_app_status_get_fg_cnt(app_status2);
+ if (fg_cnt1 > fg_cnt2)
+ return 1;
+ else if (fg_cnt1 < fg_cnt2)
+ return -1;
+
+ return 0;
+}
+
+static int __on_app_status_term_bg_apps(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_term_bg_apps(__compare_app_status_for_sorting);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_comp_status_notify_exit(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg2;
+ const char *id = (const char *)arg3;
+ app_group_node_h node;
+
+ node = _app_group_node_find(id);
+ if (!node)
+ return AMD_NOTI_CONTINUE;
+
+ __app_group_node_remove_full(node, uid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_comp_status_update_status_end(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ bool update_group_info = (bool)arg2;
+ amd_comp_status_h comp_status = (amd_comp_status_h)arg3;
+ app_group_node_h node;
+ const char *id;
+ int status;
+
+ status = amd_comp_status_get_status(comp_status);
+ if (update_group_info && status != COMP_STATUS_DESTROYED) {
+ id = amd_comp_status_get_instance_id(comp_status);
+ node = _app_group_node_find(id);
+
+ if (status == COMP_STATUS_RESUMED)
+ status = STATUS_VISIBLE;
+ else
+ status = STATUS_BG;
+
+ __app_group_node_set_status(node, status, false);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_app_status_app_register_pid(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ pid_t pid = (pid_t)arg1;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comp_type;
+ const char *id;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ id = _app_group_get_id(pid);
+ __app_group_start(pid, id, pid, id, data, false,
+ APP_GROUP_LAUNCH_MODE_SINGLE);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ bool new_process = (bool)arg2;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comp_type;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI))
+ __launch_context.new_instance = new_process;
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_launch_complete_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ pid_t pid = (pid_t)arg1;
+ uid_t uid = (uid_t)arg2;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ amd_appinfo_h ci;
+ const char *comp_type;
+ const char *comp_id;
+ const char *type;
+ const char *id = NULL;
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comp_type && !strcmp(comp_type, APP_TYPE_UI)) {
+ id = _app_group_get_id(pid);
+ } else if (comp_type && !strcmp(comp_type, APP_TYPE_COMPONENT_BASED)) {
+ comp_id = bundle_get_val(data, AUL_K_COMPONENT_ID);
+ if (!comp_id)
+ return AMD_NOTI_CONTINUE;
+
+ ci = amd_compinfo_find(uid, comp_id);
+ if (!ci)
+ return AMD_NOTI_CONTINUE;
+
+ type = amd_compinfo_get_value(ci, AMD_COMPINFO_TYPE_TYPE);
+ if (!type || strcmp(type, "frame") != 0)
+ return AMD_NOTI_CONTINUE;
+
+ id = bundle_get_val(data, AUL_K_INSTANCE_ID);
+ } else {
+ return AMD_NOTI_CONTINUE;
+ }
+
+ if (!id) {
+ _E("Failed to get id. pid(%d)", pid);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ if (__launch_context.new_instance) {
+ __app_group_start(__launch_context.leader_pid,
+ __launch_context.leader_id,
+ pid, id, data,
+ __launch_context.can_attach,
+ __launch_context.mode);
+ SECURE_LOGI("Add app group %s:%d", id, pid);
+ } else {
+ __app_group_restart(id, data);
+ __app_group_restart_recycle_bin(__launch_context.leader_id, id,
+ data, __launch_context.can_attach);
+ SECURE_LOGI("Restart app group %s:%d", id, pid);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_app_status_add(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ int app_type;
+
+ if (__launch_context.leader_id == NULL)
+ return AMD_NOTI_CONTINUE;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_UI_APP) {
+ amd_app_status_set_leader_id(app_status,
+ __launch_context.leader_id);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_comp_status_add(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int ret;
+ amd_comp_status_h comp_status = (amd_comp_status_h)arg3;
+ amd_comp_type_e comp_type;
+
+ if (__launch_context.leader_id == NULL)
+ return AMD_NOTI_CONTINUE;
+
+ comp_type = amd_comp_status_get_comp_type(comp_status);
+ if (comp_type == AMD_CT_FRAME_COMP) {
+ ret = amd_comp_status_set_leader_id(comp_status,
+ __launch_context.leader_id);
+ if (ret < 0) {
+ _E("Fail to set leader id (%s)",
+ __launch_context.leader_id);
+ }
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ pid_t pid;
+ uid_t uid;
+
+ if (!app_status)
+ return AMD_NOTI_STOP;
+
+ pid = amd_app_status_get_pid(app_status);
+ uid = amd_app_status_get_uid(app_status);
+
+ __app_group_remove_full(pid, uid);
+ __app_group_context_remove_from_recycle_bin(pid);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static bool __is_running_instance(bundle *kb, uid_t uid)
+{
+ amd_app_status_h app_status;
+ amd_comp_status_h comp_status;
+ const char *instance_id;
+ const char *app_id;
+ int status;
+
+ app_id = bundle_get_val(kb, AUL_K_APPID);
+ instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ app_status = amd_app_status_find_by_instance_id(app_id,
+ instance_id, uid);
+ if (app_status) {
+ if (amd_app_status_get_status(app_status) != STATUS_DYING)
+ return true;
+
+ return false;
+ }
+
+ comp_status = amd_comp_status_find_by_instance_id(instance_id);
+ if (comp_status) {
+ status = amd_comp_status_get_status(comp_status);
+ if (status != COMP_STATUS_DESTROYED)
+ return true;
+
+ return false;
+ }
+
+ return false;
+}
+
+static int __on_launch_app_start_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_request_h req = (amd_request_h)arg3;
+ bundle *kb = data;
+ const char *instance_id;
+ const char *launch_mode;
+ uid_t uid;
+
+ instance_id = bundle_get_val(kb, AUL_K_INSTANCE_ID);
+ if (!instance_id)
+ return AMD_NOTI_CONTINUE;
+
+ launch_mode = bundle_get_val(kb, APP_SVC_K_LAUNCH_MODE);
+ if (!launch_mode || !strcmp(launch_mode, "single"))
+ return AMD_NOTI_CONTINUE;
+
+ uid = amd_request_get_target_uid(req);
+ if (__app_group_is_group_mode(kb, uid)) {
+ if (!__is_running_instance(kb, uid)) {
+ bundle_del(kb, AUL_K_NEW_INSTANCE);
+ bundle_add(kb, AUL_K_NEW_INSTANCE, "true");
+ }
+ } else {
+ _W("Wrong request");
+ bundle_del(kb, AUL_K_INSTANCE_ID);
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+int _app_group_init(void)
+{
+ int r;
+
+ _D("app group init");
+ r = _app_group_wayland_init();
+ if (r < 0) {
+ _E("Failed to initialize app group wayland");
+ return -1;
+ }
+
+ r = _app_group_request_init();
+ if (r < 0) {
+ _E("Failed to initialize app group request");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
+ __on_app_status_add);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_APP_REGISTER_PID,
+ __on_app_status_app_register_pid);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_UPDATE_STATUS_END,
+ __on_app_status_update_status_end);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_TERM_BG_APPS,
+ __on_app_status_term_bg_apps);
+ amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_ADD,
+ __on_comp_status_add);
+ amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_NOTIFY_EXIT,
+ __on_comp_status_notify_exit);
+ amd_noti_listen(AMD_NOTI_MSG_COMP_STATUS_UPDATE_STATUS_END,
+ __on_comp_status_update_status_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ __on_launch_complete_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_END,
+ __on_launch_complete_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_STATUS_FG,
+ __on_launch_status_fg);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_TERM_APP_START,
+ __on_launch_term_app_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_TERM_BGAPP_START,
+ __on_launch_term_bgapp_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_UI_START,
+ __on_launch_prepare_ui_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_COMPONENT_BASED_START,
+ __on_launch_prepare_component_based_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_APP_START_START,
+ __on_launch_app_start_start);
+
+ return 0;
+}
+
+void _app_group_fini(void)
+{
+ _app_group_request_fini();
+ _app_group_wayland_fini();
+
+ if (__app_group_list)
+ g_list_free_full(__app_group_list, __destroy_app_group);
+
+ if (__recycle_bin)
+ g_list_free_full(__recycle_bin, __destroy_app_group_context);
+
+ _D("app group fini");
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <glib.h>
+#include <dlog.h>
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+#include <aul_sock.h>
+#include <system_info.h>
+#include <amd.h>
+
+#include "amd_screen_connector.h"
+#include "app_group.h"
+#include "app_group_request.h"
+#include "app_group_wayland.h"
+#include "app_group_private.h"
+
+static app_group_h __find_app_group_by_pid(pid_t pid)
+{
+ const char *id;
+
+ id = _app_group_get_id(pid);
+
+ return _app_group_find(id);
+}
+
+static app_group_node_h __find_app_group_node_by_pid(pid_t pid)
+{
+ const char *id;
+
+ id = _app_group_get_id(pid);
+
+ return _app_group_node_find(id);
+}
+
+static int __get_window_by_pid(pid_t pid)
+{
+ app_group_node_h node;
+
+ node = __find_app_group_node_by_pid(pid);
+
+ return _app_group_node_get_window(node);
+}
+
+static int __get_window_by_appid(const char *appid, uid_t uid)
+{
+ amd_app_status_h app_status;
+ pid_t pid;
+
+ app_status = amd_app_status_find_by_appid(appid, uid);
+ if (!app_status) {
+ _E("Failed to find app status. appid(%s)", appid);
+ return 0;
+ }
+
+ pid = amd_app_status_get_pid(app_status);
+
+ return __get_window_by_pid(pid);
+}
+
+static int __dispatch_app_group_get_window(amd_request_h req)
+{
+ app_group_node_h node;
+ const char *pid_str;
+ pid_t pid = -1;
+ int wid;
+ bundle *b;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str && isdigit(pid_str[0]))
+ pid = atoi(pid_str);
+
+ if (pid <= 1) {
+ _E("Invalid process ID(%d)", pid);
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ wid = _app_group_node_get_window(node);
+ if (wid <= 0)
+ _E("Failed to get window");
+
+ amd_request_send_result(req, wid);
+
+ _I("pid(%d), wid(%u)", pid, wid);
+
+ return 0;
+}
+
+static int __dispatch_app_group_set_window(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ pid_t pid = amd_request_get_pid(req);
+ app_group_node_h node;
+ const char *wid_str;
+ int wid = -1;
+ bundle *b;
+ int ret;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ return -1;
+ }
+
+ wid_str = bundle_get_val(b, AUL_K_WID);
+ if (wid_str && isdigit(wid_str[0]))
+ wid = atoi(wid_str);
+
+ if (wid <= 0) {
+ _E("Failed to get window ID");
+ return -1;
+ }
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ return -1;
+ }
+
+ ret = _app_group_node_set_window(node, wid);
+ if (ret < 0) {
+ _E("Failed to set window. pid(%d), wid(%d)",
+ pid, wid);
+ return -1;
+ }
+
+ _screen_connector_add_app_screen(pid, wid, NULL, uid);
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET, pid, wid, NULL, NULL);
+ _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_group_get_fg_flag(amd_request_h req)
+{
+ app_group_node_h node;
+ const char *pid_str;
+ pid_t pid = -1;
+ bundle *b;
+ bool fg;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str && isdigit(pid_str[0]))
+ pid = atoi(pid_str);
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ fg = _app_group_node_get_fg_flag(node);
+ amd_request_send_result(req, (int)fg);
+
+ _I("pid(%d), fg(%s)", pid, fg ? "true" : "false");
+
+ return 0;
+}
+
+static int __dispatch_app_group_clear_top(amd_request_h req)
+{
+ pid_t pid = amd_request_get_pid(req);
+ uid_t uid = amd_request_get_target_uid(req);
+ app_group_node_h node;
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ _app_group_node_clear_top(node, uid);
+ amd_request_send_result(req, 0);
+
+ _I("pid(%d)", pid);
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_leader_pid(amd_request_h req)
+{
+ app_group_h app_group;
+ const char *pid_str;
+ pid_t leader_pid;
+ pid_t pid = -1;
+ bundle *b;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ pid_str = bundle_get_val(b, AUL_K_PID);
+ if (pid_str && isdigit(pid_str[0]))
+ pid = atoi(pid_str);
+
+ app_group = __find_app_group_by_pid(pid);
+ if (!app_group) {
+ _E("Failed to find app group. pid(%d)", pid);
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ leader_pid = _app_group_get_leader_pid(app_group);
+ amd_request_send_result(req, leader_pid);
+ _I("pid(%d), leader_pid(%d)", pid, leader_pid);
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_leader_pids(amd_request_h req)
+{
+ unsigned char empty[1] = { 0, };
+ pid_t *pids = NULL;
+ int cnt = 0;
+
+ _app_group_get_leader_pids(&cnt, &pids);
+
+ if (pids == NULL || cnt == 0) {
+ amd_request_send_raw(req, APP_GROUP_GET_LEADER_PIDS, empty, 0);
+ } else {
+ amd_request_send_raw(req, APP_GROUP_GET_LEADER_PIDS,
+ (unsigned char *)pids, cnt * sizeof(int));
+ }
+
+ if (pids != NULL)
+ free(pids);
+
+ _I("count(%d)", cnt);
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_idle_pids(amd_request_h req)
+{
+ unsigned char empty[1] = { 0, };
+ pid_t *pids = NULL;
+ int cnt = 0;
+
+ _app_group_get_idle_pids(&cnt, &pids);
+ if (pids == NULL || cnt == 0) {
+ amd_request_send_raw(req, APP_GROUP_GET_IDLE_PIDS, empty, 0);
+ } else {
+ amd_request_send_raw(req, APP_GROUP_GET_IDLE_PIDS,
+ (unsigned char *)pids, cnt * sizeof(int));
+ }
+
+ if (pids != NULL)
+ free(pids);
+
+ _I("count(%d)", cnt);
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_group_pids(amd_request_h req)
+{
+ unsigned char empty[1] = { 0 };
+ app_group_h app_group;
+ pid_t leader_pid = -1;
+ pid_t *pids = NULL;
+ int cnt = 0;
+ char *buf;
+ bundle *b;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
+ return -1;
+ }
+
+ bundle_get_str(b, AUL_K_LEADER_PID, &buf);
+ if (buf && isdigit(buf[0]))
+ leader_pid = atoi(buf);
+
+ if (leader_pid <= 1) {
+ _E("Failed to get leader process ID");
+ amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
+ return -1;
+ }
+
+ app_group = __find_app_group_by_pid(leader_pid);
+ _app_group_get_group_pids(app_group, &cnt, &pids);
+ if (pids == NULL || cnt == 0) {
+ amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS, empty, 0);
+ } else {
+ amd_request_send_raw(req, APP_GROUP_GET_GROUP_PIDS,
+ (unsigned char *)pids, cnt * sizeof(int));
+ }
+
+ if (pids != NULL)
+ free(pids);
+
+ _I("leader_pid(%d), count(%d)", leader_pid, cnt);
+
+ return 0;
+}
+
+static int __dispatch_app_group_lower(amd_request_h req)
+{
+ pid_t pid = amd_request_get_pid(req);
+ app_group_node_h node;
+ bool exit = false;
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ _app_group_node_lower(node, &exit);
+ amd_request_send_result(req, (int)exit);
+ _I("pid(%d), exit(%s)", pid, exit ? "true" : "false");
+
+ return 0;
+}
+
+static int __app_group_activate_below(pid_t pid, uid_t uid,
+ const char *below_appid)
+{
+ int below_wid;
+ int wid;
+
+ if (!below_appid) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ wid = __get_window_by_pid(pid);
+ if (wid == 0) {
+ _E("Caller(%d) window is not ready", pid);
+ return -1;
+ }
+
+ below_wid = __get_window_by_appid(below_appid, uid);
+ if (below_wid == 0) {
+ _E("Below app(%s) window is not ready", below_appid);
+ return -1;
+ }
+
+ _app_group_wayland_activate_below(wid, below_wid);
+
+ return 0;
+}
+
+static int __dispatch_app_group_activate_below(amd_request_h req)
+{
+ const char *appid;
+ int ret;
+ bundle *b;
+ pid_t pid;
+ uid_t uid;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get appid");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ pid = amd_request_get_pid(req);
+ uid = amd_request_get_target_uid(req);
+
+ ret = __app_group_activate_below(pid, uid, appid);
+ amd_request_send_result(req, ret);
+ _I("pid(%d), appid(%s), result(%d)", pid, appid, ret);
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_ACTIVATE_BELOW, pid, (int)uid,
+ (void *)appid, b);
+
+ return 0;
+}
+
+static int __app_group_activate_above(pid_t pid, uid_t uid,
+ const char *above_appid)
+{
+ int above_wid;
+ int wid;
+
+ if (!above_appid) {
+ _E("Invalid parameter");
+ return -1;
+ }
+
+ wid = __get_window_by_pid(pid);
+ if (wid == 0) {
+ _E("Caller(%d) window is not ready", pid);
+ return -1;
+ }
+
+ above_wid = __get_window_by_appid(above_appid, uid);
+ if (above_wid == 0) {
+ _E("Above app(%s) window is not ready", above_appid);
+ return -1;
+ }
+
+ _app_group_wayland_activate_above(wid, above_wid);
+
+ return 0;
+}
+
+static int __dispatch_app_group_activate_above(amd_request_h req)
+{
+ const char *appid;
+ int ret;
+ bundle *b;
+ pid_t pid;
+ uid_t uid;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ appid = bundle_get_val(b, AUL_K_APPID);
+ if (!appid) {
+ _E("Failed to get appid");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ pid = amd_request_get_pid(req);
+ uid = amd_request_get_target_uid(req);
+
+ ret = __app_group_activate_above(pid, uid, appid);
+ amd_request_send_result(req, ret);
+ _I("pid(%d), appid(%s), result(%d)", pid, appid, ret);
+
+ return 0;
+}
+
+static int __app_window_attach(const char *parent_appid,
+ const char *child_appid, uid_t uid)
+{
+ int parent_wid;
+ int child_wid;
+
+ parent_wid = __get_window_by_appid(parent_appid, uid);
+ if (parent_wid == 0) {
+ _E("Parent(%s) window is not ready", parent_appid);
+ return -ENOENT;
+ }
+
+ child_wid = __get_window_by_appid(child_appid, uid);
+ if (child_wid == 0) {
+ _E("Child(%s) window is not ready", child_appid);
+ return -ENOENT;
+ }
+
+ _app_group_wayland_attach_window(parent_wid, child_wid);
+
+ return 0;
+}
+
+static int __dispatch_app_window_attach(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *parent_appid;
+ const char *child_appid;
+ int ret;
+
+ if (!b) {
+ _E("Invalid bundle");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ parent_appid = bundle_get_val(b, AUL_K_PARENT_APPID);
+ if (!parent_appid) {
+ _E("Invalid parameters");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ child_appid = bundle_get_val(b, AUL_K_CHILD_APPID);
+ if (!child_appid) {
+ _E("Invalid parameters");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ ret = __app_window_attach(parent_appid, child_appid, uid);
+ amd_request_send_result(req, ret);
+ _I("parent appid(%s), child appid(%s), result(%d)",
+ parent_appid, child_appid, ret);
+
+ return ret;
+}
+
+static int __app_window_detach(const char *appid, uid_t uid)
+{
+ int wid;
+
+ wid = __get_window_by_appid(appid, uid);
+ if (wid == 0) {
+ _E("%s window(%u) is invalid", appid, wid);
+ return -ENOENT;
+ }
+
+ _app_group_wayland_detach_window(wid);
+
+ return 0;
+}
+
+static int __dispatch_app_window_detach(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ bundle *b = amd_request_get_bundle(req);
+ const char *child_appid;
+ int ret;
+
+ if (!b) {
+ _E("Invalid bundle");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ child_appid = bundle_get_val(b, AUL_K_CHILD_APPID);
+ if (!child_appid) {
+ _E("Invalid parameters");
+ amd_request_send_result(req, -EINVAL);
+ return -EINVAL;
+ }
+
+ ret = __app_window_detach(child_appid, uid);
+ amd_request_send_result(req, ret);
+ _I("child appid(%s), result(%d)", child_appid, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_group_set_window_v2(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ pid_t pid = amd_request_get_pid(req);
+ app_group_node_h node;
+ const char *id;
+ const char *wid_str;
+ int wid = 0;
+ bundle *b;
+ int ret;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ return -1;
+ }
+
+ id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!id) {
+ _E("Failed to get instance ID");
+ return -1;
+ }
+
+ wid_str = bundle_get_val(b, AUL_K_WID);
+ if (wid_str && isdigit(wid_str[0]))
+ wid = (uint32_t)atoi(wid_str);
+
+ if (wid <= 0) {
+ _E("Failed to get window ID");
+ return -1;
+ }
+
+ node = _app_group_node_find(id);
+ if (!node) {
+ _E("Failed to find app group node. id(%s)", id);
+ return -1;
+ }
+
+ ret = _app_group_node_set_window(node, wid);
+ if (ret < 0) {
+ _E("Failed to set window. id(%s), wid(%u)",
+ id, wid);
+ return -1;
+ }
+
+ _screen_connector_add_app_screen(pid, wid, id, uid);
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET,
+ pid, wid, (void *)id, NULL);
+ _I("id(%s), wid(%u), result(%d)", id, wid, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_group_lower_v2(amd_request_h req)
+{
+ app_group_node_h node;
+ const char *id;
+ bool exit = false;
+ bundle *b;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!id) {
+ _E("Failed to get instance ID");
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ node = _app_group_node_find(id);
+ if (!node) {
+ _E("Failed to find app group node. id(%s)", id);
+ amd_request_send_result(req, 0);
+ return -1;
+ }
+
+ _app_group_node_lower(node, &exit);
+ amd_request_send_result(req, (int)exit);
+ _I("id(%s), exit(%s)", id, exit ? "true" : "false");
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_leader_ids(amd_request_h req)
+{
+ char **leader_ids;
+ int cnt = 0;
+ bundle *b;
+ int ret;
+ int i;
+
+ b = bundle_create();
+ if (!b) {
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ leader_ids = _app_group_get_leader_ids(&cnt);
+ if (!leader_ids) {
+ amd_request_send_result(req, -1);
+ bundle_free(b);
+ return -1;
+ }
+
+ bundle_add_str_array(b, AUL_K_LEADER_IDS,
+ (const char **)leader_ids, cnt);
+ for (i = 0; i < cnt; i++) {
+ if (leader_ids[i])
+ free(leader_ids[i]);
+ }
+ free(leader_ids);
+
+ ret = aul_sock_send_bundle_with_fd(amd_request_remove_fd(req),
+ APP_GET_INFO_OK, b, AUL_SOCK_NOREPLY);
+ bundle_free(b);
+
+ _I("count(%d), result(%d)", cnt, ret);
+
+ return 0;
+}
+
+static void __foreach_group_info(const char *id, pid_t pid, int wid,
+ bool fg, void *user_data)
+{
+ amd_request_h req = (amd_request_h)user_data;
+ int fd = amd_request_get_fd(req);
+ amd_app_status_h app_status;
+ amd_comp_status_h comp_status;
+ int app_type;
+ int status;
+ char buf[32];
+ bundle *b;
+ int ret;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status) {
+ _E("Failed to get app status");
+ return;
+ }
+
+ b = bundle_create();
+ if (!b) {
+ _E("Out of memory");
+ return;
+ }
+
+ bundle_add(b, AUL_K_INSTANCE_ID, id);
+ snprintf(buf, sizeof(buf), "%d", pid);
+ bundle_add(b, AUL_K_PID, buf);
+ bundle_add(b, AUL_K_APPID, amd_app_status_get_appid(app_status));
+ bundle_add(b, AUL_K_PKGID, amd_app_status_get_pkgid(app_status));
+ snprintf(buf, sizeof(buf), "%d", (int)wid);
+ bundle_add(b, AUL_K_WID, buf);
+ snprintf(buf, sizeof(buf), "%d", (int)fg);
+ bundle_add(b, AUL_K_FG_FLAG, buf);
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ comp_status = amd_comp_status_find_by_instance_id(id);
+ status = amd_comp_status_get_status(comp_status);
+ } else {
+ status = amd_app_status_get_status(app_status);
+ }
+ snprintf(buf, sizeof(buf), "%d", status);
+ bundle_add(b, AUL_K_STATUS, buf);
+
+ ret = aul_sock_send_bundle_with_fd(fd, APP_GET_INFO_OK, b,
+ AUL_SOCK_ASYNC);
+ if (ret < 0)
+ _E("Failed to send bundle. result(%d)", ret);
+ bundle_free(b);
+}
+
+static int __dispatch_app_group_get_group_info(amd_request_h req)
+{
+ app_group_h group;
+ int group_count;
+ const char *id;
+ bundle *b;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ id = bundle_get_val(b, AUL_K_LEADER_ID);
+ if (!id) {
+ _E("Failed to get leader id");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ group = _app_group_find(id);
+ if (!group) {
+ SECURE_LOGE("Failed to find app group. id(%s)", id);
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ group_count = _app_group_get_count(group);
+ amd_socket_send_result(amd_request_get_fd(req), group_count, false);
+
+ _app_group_foreach_context(group, __foreach_group_info, req);
+
+ _I("leader(%s), count(%d)", id, group_count);
+
+ return 0;
+}
+
+static int __dispatch_app_group_get_idle_info(amd_request_h req)
+{
+ int idle_count;
+
+ idle_count = _app_group_get_idle_count();
+ amd_socket_send_result(amd_request_get_fd(req), idle_count, false);
+
+ _app_group_foreach_idle_context(__foreach_group_info, req);
+
+ _I("count(%d)", idle_count);
+
+ return 0;
+}
+
+static int __dispatch_app_group_add(amd_request_h req)
+{
+ uid_t uid = amd_request_get_target_uid(req);
+ pid_t pid = amd_request_get_pid(req);
+ app_group_node_h node;
+ app_group_node_h new_node;
+ const char *wid_str;
+ int wid = -1;
+ bundle *b;
+ int ret;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ return -EINVAL;
+ }
+
+ wid_str = bundle_get_val(b, AUL_K_WID);
+ if (wid_str && isdigit(wid_str[0]))
+ wid = atoi(wid_str);
+
+ if (wid <= 0) {
+ _E("Failed to get window ID");
+ return -EINVAL;
+ }
+
+ node = _app_group_node_find_by_wid(wid);
+ if (node) {
+ _E("Already exists. wid(%d)", wid);
+ return -EALREADY;
+ }
+
+ node = __find_app_group_node_by_pid(pid);
+ if (!node) {
+ _E("Failed to find app group node. pid(%d)", pid);
+ return -EINVAL;
+ }
+
+ new_node = _app_group_node_add_node(node);
+ if (!new_node) {
+ _E("Failed to add new node. pid(%d), wid(%d)", pid, wid);
+ return -ENOMEM;
+ }
+
+ ret = _app_group_node_set_window(new_node, wid);
+ if (ret < 0)
+ _E("Failed to set window. pid(%d), wid(%d)", pid, wid);
+
+ _screen_connector_add_app_screen(pid, wid, NULL, uid);
+ amd_noti_send(AMD_NOTI_MSG_APP_GROUP_WINDOW_SET, pid, wid, NULL, NULL);
+ _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
+
+ return ret;
+}
+
+static int __dispatch_app_group_remove(amd_request_h req)
+{
+ pid_t pid = amd_request_get_pid(req);
+ app_group_node_h node;
+ const char *wid_str;
+ int wid = -1;
+ bundle *b;
+ int ret;
+
+ b = amd_request_get_bundle(req);
+ if (!b) {
+ _E("Failed to get bundle");
+ return -EINVAL;
+ }
+
+ wid_str = bundle_get_val(b, AUL_K_WID);
+ if (wid_str && isdigit(wid_str[0]))
+ wid = atoi(wid_str);
+
+ if (wid <= 0) {
+ _E("Failed to get window ID");
+ return -EINVAL;
+ }
+
+ node = _app_group_node_find_by_wid(wid);
+ if (!node) {
+ _E("Failed to find node. pid(%d), wid(%d)", pid, wid);
+ return -EINVAL;
+ }
+
+ ret = _app_group_node_remove_node(node);
+ if (ret < 0)
+ _E("Failed to remove node. pid(%d), wid(%d)", pid, wid);
+
+ _I("pid(%d), wid(%d), result(%d)", pid, wid, ret);
+
+ return ret;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = APP_GROUP_GET_WINDOW,
+ .callback = __dispatch_app_group_get_window
+ },
+ {
+ .cmd = APP_GROUP_SET_WINDOW,
+ .callback = __dispatch_app_group_set_window
+ },
+ {
+ .cmd = APP_GROUP_GET_FG,
+ .callback = __dispatch_app_group_get_fg_flag
+ },
+ {
+ .cmd = APP_GROUP_GET_LEADER_PID,
+ .callback = __dispatch_app_group_get_leader_pid
+ },
+ {
+ .cmd = APP_GROUP_GET_LEADER_PIDS,
+ .callback = __dispatch_app_group_get_leader_pids
+ },
+ {
+ .cmd = APP_GROUP_GET_GROUP_PIDS,
+ .callback = __dispatch_app_group_get_group_pids
+ },
+ {
+ .cmd = APP_GROUP_GET_IDLE_PIDS,
+ .callback = __dispatch_app_group_get_idle_pids
+ },
+ {
+ .cmd = APP_GROUP_LOWER,
+ .callback = __dispatch_app_group_lower
+ },
+ { .cmd = APP_GROUP_CLEAR_TOP,
+ .callback = __dispatch_app_group_clear_top
+ },
+ {
+ .cmd = APP_GROUP_ACTIVATE_BELOW,
+ .callback = __dispatch_app_group_activate_below
+ },
+ {
+ .cmd = APP_GROUP_ACTIVATE_ABOVE,
+ .callback = __dispatch_app_group_activate_above
+ },
+ {
+ .cmd = APP_WINDOW_ATTACH,
+ .callback = __dispatch_app_window_attach
+ },
+ { .cmd = APP_WINDOW_DETACH,
+ .callback = __dispatch_app_window_detach
+ },
+ {
+ .cmd = APP_GROUP_SET_WINDOW_V2,
+ .callback = __dispatch_app_group_set_window_v2
+ },
+ {
+ .cmd = APP_GROUP_LOWER_V2,
+ .callback = __dispatch_app_group_lower_v2
+ },
+ {
+ .cmd = APP_GROUP_GET_LEADER_IDS,
+ .callback = __dispatch_app_group_get_leader_ids
+ },
+ {
+ .cmd = APP_GROUP_GET_GROUP_INFO,
+ .callback = __dispatch_app_group_get_group_info
+ },
+ {
+ .cmd = APP_GROUP_GET_IDLE_INFO,
+ .callback = __dispatch_app_group_get_idle_info
+ },
+ {
+ .cmd = APP_GROUP_ADD,
+ .callback = __dispatch_app_group_add
+ },
+ {
+ .cmd = APP_GROUP_REMOVE,
+ .callback = __dispatch_app_group_remove
+ },
+};
+
+static int __verify_instance_cynara_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ bundle *b = amd_request_get_bundle(req);
+ pid_t pid = amd_request_get_pid(req);
+ amd_app_status_h app_status;
+ amd_comp_status_h comp_status;
+ const char *inst_id;
+ const char *id;
+ int app_type;
+
+ if (!b) {
+ _E("Failed to get bundle");
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ id = bundle_get_val(b, AUL_K_INSTANCE_ID);
+ if (!id) {
+ _E("Failed to get instance ID");
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status) {
+ _E("Failed to find app status. pid(%d)", pid);
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type == AMD_AT_COMPONENT_BASED_APP) {
+ comp_status = amd_comp_status_find_by_instance_id(id);
+ if (!comp_status) {
+ _E("Failed to find comp status. instance(%s)", id);
+ return AMD_CYNARA_RET_DENIED;
+ }
+
+ if (amd_comp_status_get_pid(comp_status) != pid) {
+ _E("Reject request! instance(%s:%d) doesn't exist",
+ id, pid);
+ return AMD_CYNARA_RET_DENIED;
+ }
+ } else {
+ inst_id = amd_app_status_get_instance_id(app_status);
+ if (!inst_id || strcmp(inst_id, id) != 0) {
+ _E("Reject request! instance(%s:%d) doesn't exist",
+ id, pid);
+ return AMD_CYNARA_RET_DENIED;
+ }
+ }
+
+ return AMD_CYNARA_RET_ALLOWED;
+}
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_WINDOW_ATTACH,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+ {
+ .cmd = APP_WINDOW_DETACH,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+ {
+ .cmd = APP_GROUP_SET_WINDOW_V2,
+ .checker = __verify_instance_cynara_checker,
+ .data = NULL,
+ .priority = 10
+ },
+ {
+ .cmd = APP_GROUP_LOWER_V2,
+ .checker = __verify_instance_cynara_checker,
+ .data = NULL,
+ .priority = 10
+ },
+ {
+ .cmd = APP_GROUP_GET_LEADER_IDS,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+ {
+ .cmd = APP_GROUP_GET_IDLE_INFO,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+};
+
+int _app_group_request_init(void)
+{
+ int r;
+
+ _D("app group request init");
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ _E("Failed to register checkers");
+ return -1;
+ }
+
+ return 0;
+}
+
+void _app_group_request_fini(void)
+{
+ _D("app group request fini");
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <amd.h>
+#include <dlog.h>
+#include <tizen-extension-client-protocol.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+
+#include "app_group_private.h"
+
+struct wayland_context_s {
+ struct wl_display *display;
+ struct tizen_policy *tizen_policy;
+ uint32_t tizen_policy_id;
+ bool tizen_policy_initialized;
+};
+
+static struct wayland_context_s __context;
+
+int _app_group_wayland_lower_window(int wid)
+{
+ if (!__context.tizen_policy_initialized) {
+ _E("tizen_policy is not initialized");
+ return -1;
+ }
+
+ tizen_policy_lower_by_res_id(__context.tizen_policy, wid);
+ wl_display_roundtrip(__context.display);
+
+ return 0;
+}
+
+int _app_group_wayland_attach_window(int parent_wid, int child_wid)
+{
+ if (!__context.tizen_policy_initialized) {
+ _E("tizen_policy is not initialized");
+ return -1;
+ }
+
+ tizen_policy_set_transient_for(__context.tizen_policy,
+ child_wid, parent_wid);
+ wl_display_roundtrip(__context.display);
+ _W("[__ATTACH__] parent_wid(%d), child_wid(%d)",
+ parent_wid, child_wid);
+
+ return 0;
+}
+
+int _app_group_wayland_detach_window(int child_wid)
+{
+ if (!__context.tizen_policy_initialized) {
+ _E("tizen_policy is not initialized");
+ return -1;
+ }
+
+ tizen_policy_unset_transient_for(__context.tizen_policy, child_wid);
+ wl_display_roundtrip(__context.display);
+ _W("[__DETACH__] child_wid(%d)", child_wid);
+
+ return 0;
+}
+
+int _app_group_wayland_activate_below(int wid, int below_wid)
+{
+ if (!__context.tizen_policy_initialized) {
+ _E("tizen_policy is not initialized");
+ return -1;
+ }
+
+ tizen_policy_activate_below_by_res_id(__context.tizen_policy,
+ below_wid, wid);
+ wl_display_roundtrip(__context.display);
+
+ return 0;
+}
+
+int _app_group_wayland_activate_above(int wid, int above_wid)
+{
+ if (!__context.tizen_policy_initialized) {
+ _E("tizen_policy is not initialized");
+ return -1;
+ }
+
+ tizen_policy_activate_above_by_res_id(__context.tizen_policy,
+ above_wid, wid);
+ wl_display_roundtrip(__context.display);
+
+ return 0;
+}
+
+static void __wl_conformant(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ uint32_t is_conformant)
+{
+}
+
+static void __wl_conformant_area(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ uint32_t conformant_part,
+ uint32_t state,
+ int32_t x, int32_t y, int32_t w, int32_t h)
+{
+}
+
+static void __wl_notification_done(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface,
+ int32_t level,
+ uint32_t state)
+{
+}
+
+static void __wl_transient_for_done(void *data,
+ struct tizen_policy *tizen_policy,
+ uint32_t child_id)
+{
+}
+
+static void __wl_scr_mode_done(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface,
+ uint32_t mode,
+ uint32_t state)
+{
+}
+
+static void __wl_iconify_state_changed(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ uint32_t iconified,
+ uint32_t force)
+{
+}
+
+static void __wl_supported_aux_hints(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ struct wl_array *hints,
+ uint32_t num_hints)
+{
+}
+
+static void __wl_allowed_aux_hint(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ int id)
+{
+}
+
+static void __wl_aux_message(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface_resource,
+ const char *key,
+ const char *val,
+ struct wl_array *options)
+{
+}
+
+static void __wl_conformant_region(void *data,
+ struct tizen_policy *tizen_policy,
+ struct wl_surface *surface,
+ uint32_t conformant_part,
+ uint32_t state,
+ int32_t x, int32_t y, int32_t w, int32_t h,
+ uint32_t serial)
+{
+}
+
+static const struct tizen_policy_listener __tizen_policy_listener = {
+ __wl_conformant,
+ __wl_conformant_area,
+ __wl_notification_done,
+ __wl_transient_for_done,
+ __wl_scr_mode_done,
+ __wl_iconify_state_changed,
+ __wl_supported_aux_hints,
+ __wl_allowed_aux_hint,
+ __wl_aux_message,
+ __wl_conformant_region,
+};
+
+static int __on_wayland_listener_tizen_policy(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+ struct wl_registry *reg = (struct wl_registry *)arg3;
+
+ if (!__context.tizen_policy) {
+ __context.display = amd_wayland_get_display();
+ __context.tizen_policy_id = id;
+ __context.tizen_policy = wl_registry_bind(reg, id,
+ &tizen_policy_interface, 7);
+ if (__context.tizen_policy) {
+ tizen_policy_add_listener(__context.tizen_policy,
+ &__tizen_policy_listener,
+ __context.display);
+ amd_wayland_set_tizen_policy(__context.tizen_policy);
+ __context.tizen_policy_initialized = true;
+ }
+ _D("tizen_policy(%p)", __context.tizen_policy);
+ }
+
+ return 0;
+}
+
+static int __on_wayland_listener_listener_remove(const char *msg, int arg1,
+ int arg2, void *arg3, bundle *data)
+{
+ uint32_t id = (uint32_t)arg1;
+
+ if (__context.tizen_policy_id == id && __context.tizen_policy) {
+ tizen_policy_destroy(__context.tizen_policy);
+ __context.tizen_policy = NULL;
+ __context.tizen_policy_id = 0;
+ __context.tizen_policy_initialized = false;
+ amd_wayland_set_tizen_policy(__context.tizen_policy);
+ _W("tizen policy is destroyed");
+ }
+
+ return 0;
+}
+
+int _app_group_wayland_init(void)
+{
+ _D("app group wayland init");
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_POLICY,
+ __on_wayland_listener_tizen_policy);
+ amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
+ __on_wayland_listener_listener_remove);
+
+ return 0;
+}
+
+void _app_group_wayland_fini(void)
+{
+ _D("app group wayland fini");
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#include "status.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_UI_CORE"
+
+pid_t _status_get_effective_pid(pid_t pid)
+{
+ amd_app_status_h app_status;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (!app_status) {
+ _W("Failed to find app status info. pid(%d)", pid);
+ return -1;
+ }
+
+ return amd_app_status_get_pid(app_status);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+
+#include <dlog.h>
+
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#include "amd_screen_connector.h"
+#include "app_group.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_UI_CORE"
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("ui-core init");
+ if (_app_group_init() < 0)
+ return -1;
+
+ if (_screen_connector_init() < 0)
+ return -1;
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("ui-core fini");
+ _screen_connector_fini();
+ _app_group_fini();
+}
+
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_WATCH_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_WATCH} ${AMD_MOD_WATCH_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WATCH} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WATCH} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_WATCH} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_WATCH} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_WATCH} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * 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_WATCH_LOGGER_H__
+#define __AMD_WATCH_LOGGER_H__
+
+int _watch_logger_init(void);
+
+void _watch_logger_fini(void);
+
+int _watch_logger_print(const char *tag, const char *format, ...);
+
+#endif /* __AMD_WATCH_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_WATCH"
--- /dev/null
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <glib.h>
+#include <aul.h>
+#include <bundle_internal.h>
+#include <amd.h>
+
+#include "amd_watch_logger.h"
+#include "amd_watch_private.h"
+
+struct watch_info {
+ char *appid;
+ char *pkgid;
+ int pid;
+ uid_t uid;
+ bool is_faulted;
+};
+
+static GList *__update_list;
+
+static void __send_dead_signal(const char *appid, pid_t pid, uid_t uid,
+ bool is_faulted)
+{
+ char buf[32];
+ bundle *envelope;
+
+ envelope = bundle_create();
+ if (envelope == NULL) {
+ _E("Out of memory");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", pid);
+ bundle_add(envelope, AUL_K_PID, buf);
+ bundle_add(envelope, AUL_K_APPID, appid);
+ bundle_add(envelope, AUL_K_IS_FAULT, is_faulted ? "true" : "false");
+
+ amd_app_com_send("watch.dead", pid, envelope, uid);
+ bundle_free(envelope);
+ _I("Send dead signal %s:%d:%u:%d", appid, pid, uid, is_faulted);
+ _watch_logger_print("Send Dead", "appid(%s), pid(%d) "
+ "uid(%d), is_faulted(%d)", appid, pid, uid, is_faulted);
+}
+
+static void __send_launch_signal(const char *appid, const char *viewer,
+ pid_t pid, uid_t uid)
+{
+ char buf[32];
+ bundle *envelope;
+
+ envelope = bundle_create();
+ if (envelope == NULL) {
+ _E("Out of memory");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", pid);
+ bundle_add(envelope, AUL_K_PID, buf);
+ bundle_add(envelope, AUL_K_APPID, appid);
+ bundle_add(envelope, AUL_K_WIDGET_VIEWER, viewer);
+
+ amd_app_com_send("watch.launch", pid, envelope, uid);
+ bundle_free(envelope);
+ _I("Send launch signal %s:%d:%u", appid, pid, uid);
+ _watch_logger_print("Send Launch", "appid(%s), pid(%d) "
+ "uid(%d)", appid, pid, uid);
+}
+
+static void __destroy_watch_info(gpointer data)
+{
+ struct watch_info *info = (struct watch_info *)data;
+
+ if (info == NULL)
+ return;
+
+ if (info->pkgid)
+ free(info->pkgid);
+ if (info->appid)
+ free(info->appid);
+ free(info);
+}
+
+static struct watch_info *__create_watch_info(const char *appid,
+ const char *pkgid, bool is_faulted, pid_t pid, uid_t uid)
+{
+ struct watch_info *info;
+
+ info = malloc(sizeof(struct watch_info));
+ if (info == NULL) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ info->appid = strdup(appid);
+ if (info->appid == NULL) {
+ _E("Out of memory");
+ free(info);
+ return NULL;
+ }
+
+ info->pkgid = strdup(pkgid);
+ if (info->pkgid == NULL) {
+ _E("Out of memory");
+ free(info->appid);
+ free(info);
+ return NULL;
+ }
+
+ info->is_faulted = is_faulted;
+ info->pid = pid;
+ info->uid = uid;
+
+ return info;
+}
+
+static void __watch_flush_update_list(const char *pkgid, uid_t uid)
+{
+ struct watch_info *info;
+ GList *iter;
+
+ if (__update_list == NULL)
+ return;
+
+ iter = __update_list;
+ while (iter) {
+ info = (struct watch_info *)iter->data;
+ iter = g_list_next(iter);
+ if ((uid < REGULAR_UID_MIN || info->uid == uid) &&
+ !strcmp(info->pkgid, pkgid)) {
+ __update_list = g_list_remove(__update_list, info);
+ __send_dead_signal(info->appid, info->pid, info->uid,
+ true);
+ __destroy_watch_info(info);
+ }
+ }
+}
+
+static struct watch_info *__find_watch_info(GList *list, const char *appid,
+ uid_t uid)
+{
+ struct watch_info *info;
+ GList *iter;
+
+ iter = list;
+ while (iter) {
+ info = (struct watch_info *)iter->data;
+ if (!strcmp(info->appid, appid) && info->uid == uid)
+ return info;
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static int __update_watch_info(const char *appid, const char *pkgid,
+ bool is_faulted, pid_t pid, uid_t uid, GList **list)
+{
+ struct watch_info *info;
+
+ info = __find_watch_info(*list, appid, uid);
+ if (info) {
+ info->pid = pid;
+ info->is_faulted = is_faulted;
+ return 0;
+ }
+
+ info = __create_watch_info(appid, pkgid, is_faulted, pid, uid);
+ if (info == NULL)
+ return -1;
+
+ *list = g_list_append(*list, info);
+
+ return 0;
+}
+
+static int __on_app_dead(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+ int pid = arg1;
+ uid_t uid = (uid_t)arg2;
+ const char *appid;
+ const char *pkgid;
+ bool is_faulted;
+ int r;
+ int app_type;
+
+ if (app_status == NULL)
+ return 0;
+
+ app_type = amd_app_status_get_app_type(app_status);
+ if (app_type != AMD_AT_WATCH_APP)
+ return 0;
+
+ appid = amd_app_status_get_appid(app_status);
+ pkgid = amd_app_status_get_pkgid(app_status);
+ is_faulted = !amd_app_status_is_exiting(app_status);
+
+ if (amd_appinfo_is_pkg_updating(pkgid)) {
+ r = __update_watch_info(appid, pkgid, is_faulted, pid, uid,
+ &__update_list);
+ if (r == 0)
+ return 0;
+ }
+
+ __send_dead_signal(appid, pid, uid, is_faulted);
+
+ return 0;
+}
+
+static int __on_package_update_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ const char *pkgid = (const char *)arg3;
+
+ __watch_flush_update_list(pkgid, uid);
+
+ return 0;
+}
+
+static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comptype;
+ const char *appid;
+ const char *viewer;
+ const char *val;
+ uid_t uid;
+
+ comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comptype && !strcmp(comptype, APP_TYPE_WATCH)) {
+ appid = bundle_get_val(data, AUL_K_APPID);
+ if (appid == NULL)
+ return 0;
+
+ viewer = bundle_get_val(data, AUL_K_WIDGET_VIEWER);
+ if (viewer == NULL)
+ return 0;
+
+ val = bundle_get_val(data, AUL_K_TARGET_UID);
+ if (!val || !isdigit(*val))
+ return 0;
+
+ uid = strtoul(val, NULL, 10);
+ __send_launch_signal(appid, viewer, pid, uid);
+ }
+
+ return 0;
+}
+
+static int __on_package_update_error(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ const char *pkgid = (const char *)arg3;
+
+ __watch_flush_update_list(pkgid, uid);
+
+ return 0;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("watch init");
+ _watch_logger_init();
+
+ amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
+ __on_app_dead);
+ amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
+ __on_package_update_end);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ __on_launch_complete_start);
+ amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
+ __on_package_update_error);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("watch finish");
+
+ if (__update_list)
+ g_list_free_full(__update_list, __destroy_watch_info);
+ _watch_logger_fini();
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <amd.h>
+
+#include "amd_logger.h"
+#include "amd_watch_private.h"
+
+#define LOG_FILE "amd_watch.log"
+#define LOG_PATH LOGGER_PATH "/" LOG_FILE
+
+static amd_logger_h __logger;
+
+int _watch_logger_print(const char *tag, const char *format, ...)
+{
+ char format_buf[LOG_MAX_STRING_SIZE];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(format_buf, sizeof(format_buf), format, ap);
+ va_end(ap);
+
+ return amd_logger_print(__logger, tag, format_buf);
+}
+
+int _watch_logger_init(void)
+{
+ int ret;
+
+ _D("watch logger init");
+ ret = amd_logger_create(LOG_PATH, &__logger);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void _watch_logger_fini(void)
+{
+ _D("watch logger fini");
+ amd_logger_destroy(__logger);
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_WATCHDOG_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_WATCHDOG} ${AMD_MOD_WATCHDOG_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WATCHDOG} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WATCHDOG} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_WATCHDOG} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_WATCHDOG} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ INIPARSER_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_WATCHDOG} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/conf/amd_watchdog.conf DESTINATION
+ ${AMD_MODULES_DIR}/conf)
--- /dev/null
+[Setting]
+# Watchdog timer: "enable-by-default" or "enable-on-demand"(default)
+Watchdog=enable-on-demand
+# Watchdog timer interval: 10 seconds (default)
+WatchdogInterval=10000
+# Watchdog timer maximum retry count: 1 (default)
+WatchdogMaxRetryCount=1
--- /dev/null
+/*
+ * Copyright (c) 2018 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_WATCHDOG_CONFIG_H__
+#define __AMD_WATCHDOG_CONFIG_H__
+
+#include <stdbool.h>
+
+enum watchdog_operation_state_e {
+ WATCHDOG_ENABLE_BY_DEFAULT,
+ WATCHDOG_ENABLE_ON_DEMAND
+};
+
+int _watchdog_config_init(void);
+
+void _watchdog_config_fini(void);
+
+int _watchdog_config_get_operation_state(void);
+
+unsigned int _watchdog_config_get_interval(void);
+
+unsigned int _watchdog_config_get_max_retry_count(void);
+
+#endif /* __AMD_WATCHDOG_CONFIG_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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_WATCHDOG_LOGGER_H__
+#define __AMD_WATCHDOG_LOGGER_H__
+
+int _watchdog_logger_init(void);
+
+void _watchdog_logger_fini(void);
+
+int _watchdog_logger_print(const char *tag, const char *format, ...);
+
+#endif /* __AMD_WATCHDOG_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_WATCHDOG"
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_watchdog.h>
+#include <aul_sock.h>
+#include <bundle_internal.h>
+#include <amd.h>
+
+#include "amd_watchdog_config.h"
+#include "amd_watchdog_logger.h"
+#include "amd_watchdog_private.h"
+
+#define RESOURCED_FREEZER_PATH "/Org/Tizen/ResourceD/Freezer"
+#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
+#define RESOURCED_FREEZER_SIGNAL "FreezerState"
+
+typedef struct watchdog_s {
+ GDBusConnection *conn;
+ guint listener;
+ guint retry_handler;
+ unsigned int interval;
+ int max_retry_count;
+ GList *proc_contexts;
+} watchdog;
+
+typedef struct proc_context_s {
+ pid_t pid;
+ uid_t uid;
+ bool frozen;
+ bool watchdog_enable;
+ guint timer;
+ int retry_count;
+ int kick_count;
+ struct timespec resp_time;
+} proc_context;
+
+static watchdog __watchdog;
+
+static proc_context *__create_proc_context(pid_t pid, uid_t uid)
+{
+ proc_context *ctx;
+
+ ctx = calloc(1, sizeof(proc_context));
+ if (!ctx) {
+ _E("Out of memory");
+ return NULL;
+ }
+
+ ctx->pid = pid;
+ ctx->uid = uid;
+
+ return ctx;
+}
+
+static void __destroy_proc_context(gpointer data)
+{
+ proc_context *ctx = (proc_context *)data;
+
+ if (ctx->timer > 0)
+ g_source_remove(ctx->timer);
+
+ free(ctx);
+}
+
+static proc_context *__find_proc_context(pid_t pid)
+{
+ proc_context *ctx;
+ GList *iter;
+
+ iter = __watchdog.proc_contexts;
+ while (iter) {
+ ctx = (proc_context *)iter->data;
+ if (ctx && ctx->pid == pid)
+ return ctx;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static const char *__get_appid(pid_t pid)
+{
+ amd_app_status_h app_status;
+ const char *appid = NULL;
+
+ app_status = amd_app_status_find_by_effective_pid(pid);
+ if (app_status)
+ appid = amd_app_status_get_appid(app_status);
+
+ return appid ? appid : "Unknown";
+}
+
+static bundle *__create_bundle(unsigned int interval)
+{
+ char buf[32];
+ bundle *b;
+ int ret;
+
+ b = bundle_create();
+ if (!b) {
+ _E("Failed to create bundle");
+ return NULL;
+ }
+
+ if (interval != 0) {
+ snprintf(buf, sizeof(buf), "%u", interval);
+ ret = bundle_add(b, AUL_K_INTERVAL, buf);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Failed to add interval(%s)", buf);
+ bundle_free(b);
+ return NULL;
+ }
+ }
+
+ return b;
+}
+
+static int __send_request(proc_context *ctx, int cmd, unsigned int interval)
+{
+ bundle *b;
+ int ret;
+
+ b = __create_bundle(interval);
+ if (!b)
+ return -ENOMEM;
+
+ ret = aul_sock_send_bundle(ctx->pid, ctx->uid, cmd, b,
+ AUL_SOCK_NOREPLY);
+ bundle_free(b);
+ if (ret < 0) {
+ _E("Failed to send request(%d), pid(%d)", cmd, ctx->pid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static gboolean __timeout_handler(gpointer data)
+{
+ proc_context *ctx = (proc_context *)data;
+
+ _E("Timer expired. pid(%d), resp_time(%ld.%ld)",
+ ctx->pid,
+ ctx->resp_time.tv_sec,
+ ctx->resp_time.tv_nsec);
+
+ if (ctx->retry_count < __watchdog.max_retry_count) {
+ ctx->retry_count++;
+ return G_SOURCE_CONTINUE;
+ }
+
+ _E("pid(%d) will be terminated", ctx->pid);
+ amd_signal_send_watchdog(ctx->pid, SIGKILL);
+ _watchdog_logger_print("SIGKILL", "pid(%d), appid(%s)",
+ ctx->pid, __get_appid(ctx->pid));
+
+ return G_SOURCE_REMOVE;
+}
+
+static void __watchdog_set_timer(proc_context *ctx)
+{
+ if (!ctx->timer) {
+ ctx->timer = g_timeout_add(__watchdog.interval + 1000,
+ __timeout_handler, ctx);
+ }
+}
+
+static void __watchdog_unset_timer(proc_context *ctx)
+{
+ if (ctx->timer) {
+ g_source_remove(ctx->timer);
+ ctx->timer = 0;
+ }
+}
+
+static int __dispatch_watchdog_enable(amd_request_h req)
+{
+ int pid = amd_request_get_pid(req);
+ proc_context *ctx;
+ int ret;
+
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) context", pid);
+ return -1;
+ }
+
+ if (ctx->watchdog_enable) {
+ _W("Watchdog timer is already enabled. pid(%d)", pid);
+ return 0;
+ }
+
+ if (!ctx->frozen)
+ __watchdog_set_timer(ctx);
+
+ ctx->watchdog_enable = true;
+
+ ret = __send_request(ctx, WATCHDOG_ENABLE, __watchdog.interval);
+
+ _I("pid(%d), result(%d)", pid, ret);
+ _watchdog_logger_print("ENABLE", "pid(%d), appid(%s)",
+ pid, __get_appid(pid));
+
+ return 0;
+}
+
+static int __dispatch_watchdog_disable(amd_request_h req)
+{
+ int pid = amd_request_get_pid(req);
+ proc_context *ctx;
+ int ret;
+
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) context", pid);
+ return -1;
+ }
+
+ if (!ctx->watchdog_enable) {
+ _W("Watchdog timer is already disabled. pid(%d)", pid);
+ return 0;
+
+ }
+
+ __watchdog_unset_timer(ctx);
+
+ ctx->watchdog_enable = false;
+ ctx->retry_count = 0;
+ ctx->kick_count = 0;
+ ctx->resp_time.tv_sec = 0;
+ ctx->resp_time.tv_nsec = 0;
+
+ ret = __send_request(ctx, WATCHDOG_DISABLE, 0);
+
+ _I("pid(%d), result(%d)", pid, ret);
+ _watchdog_logger_print("DISABLE", "pid(%d), appid(%s)",
+ pid, __get_appid(pid));
+
+ return 0;
+}
+
+static int __dispatch_watchdog_kick(amd_request_h req)
+{
+ int pid = amd_request_get_pid(req);
+ proc_context *ctx;
+
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) context", pid);
+ return -1;
+ }
+
+ if (!ctx->watchdog_enable) {
+ _W("watchdog timer is not enabled. pid(%d)", pid);
+ return -1;
+ }
+
+ __watchdog_unset_timer(ctx);
+ __watchdog_set_timer(ctx);
+
+ ctx->kick_count++;
+
+ _I("pid(%d), kick count(%d)", pid, ctx->kick_count);
+ _watchdog_logger_print("KICK", "count(%d), pid(%d), appid(%s)",
+ ctx->kick_count, pid, __get_appid(pid));
+
+ return 0;
+}
+
+static int __dispatch_watchdog_ping(amd_request_h req)
+{
+ int pid = amd_request_get_pid(req);
+ proc_context *ctx;
+
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) context", pid);
+ return -1;
+ }
+
+ if (!ctx->watchdog_enable) {
+ _W("watchdog timer is not enabled. pid(%d)", pid);
+ return -1;
+ }
+
+ __watchdog_unset_timer(ctx);
+ __watchdog_set_timer(ctx);
+ clock_gettime(CLOCK_MONOTONIC, &ctx->resp_time);
+ ctx->retry_count = 0;
+
+ _I("pid(%d), resp_time(%ld.%ld)",
+ pid, ctx->resp_time.tv_sec, ctx->resp_time.tv_nsec);
+ _watchdog_logger_print("PING", "pid(%d), appid(%s)",
+ pid, __get_appid(pid));
+
+ return 0;
+}
+
+static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ int pid = arg1;
+ proc_context *ctx;
+
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _W("Failed to find process(%d) context", pid);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ __watchdog.proc_contexts = g_list_remove(__watchdog.proc_contexts, ctx);
+ __destroy_proc_context(ctx);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_app_status_add(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ amd_app_status_h app_status = (amd_app_status_h)arg3;
+ int pid = amd_app_status_get_pid(app_status);
+ uid_t uid;
+ proc_context *ctx;
+ int operation_state;
+
+ ctx = __find_proc_context(pid);
+ if (ctx) {
+ _W("Process(%d) context already exists", pid);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ uid = amd_app_status_get_uid(app_status);
+ ctx = __create_proc_context(pid, uid);
+ if (!ctx) {
+ _E("Failed to create process(%d) context", pid);
+ return AMD_NOTI_CONTINUE;
+ }
+
+ __watchdog.proc_contexts = g_list_append(__watchdog.proc_contexts, ctx);
+
+ operation_state = _watchdog_config_get_operation_state();
+ if (operation_state == WATCHDOG_ENABLE_BY_DEFAULT) {
+ __watchdog_set_timer(ctx);
+ ctx->watchdog_enable = true;
+ _watchdog_logger_print("ENABLE", "pid(%d), appid(%s)",
+ pid, amd_app_status_get_appid(app_status));
+ }
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static int __on_signal_send_watchdog_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *b)
+{
+ int pid = arg1;
+ proc_context *ctx;
+
+ _W("Watchdog pid(%d)", pid);
+ ctx = __find_proc_context(pid);
+ if (!ctx)
+ return AMD_NOTI_CONTINUE;
+
+ __watchdog_unset_timer(ctx);
+
+ return AMD_NOTI_CONTINUE;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = WATCHDOG_ENABLE,
+ .callback = __dispatch_watchdog_enable
+ },
+ {
+ .cmd = WATCHDOG_DISABLE,
+ .callback = __dispatch_watchdog_disable
+ },
+ {
+ .cmd = WATCHDOG_KICK,
+ .callback = __dispatch_watchdog_kick
+ },
+ {
+ .cmd = WATCHDOG_PING,
+ .callback = __dispatch_watchdog_ping
+ },
+};
+
+static void __on_freezer_state_changed(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ gint pid = -1;
+ gint status = -1;
+ proc_context *ctx;
+
+ if (!g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL)) {
+ g_variant_get(parameters, "(ii)", &status, &pid);
+ ctx = __find_proc_context(pid);
+ if (!ctx) {
+ _E("Failed to find process(%d) context", pid);
+ return;
+ }
+
+ /* 0: SET_FOREGRD, 1: SET_BACKGRD, */
+ ctx->frozen = (bool)status;
+ if (ctx->frozen) {
+ __watchdog_unset_timer(ctx);
+ } else {
+ if (ctx->watchdog_enable)
+ __watchdog_set_timer(ctx);
+ }
+
+ _W("pid(%d), freezer state(%s)",
+ pid, status ? "BACKGRD" : "FOREGRD");
+ _watchdog_logger_print("FREEZER",
+ "state(%s), pid(%d), appid(%s)",
+ status ? "BACKGRD" : "FOREGRD",
+ pid, __get_appid(pid));
+ }
+}
+
+static int __listen_freezer_state(void *user_data)
+{
+ GError *err = NULL;
+
+ if (__watchdog.listener)
+ return 0;
+
+ if (!__watchdog.conn) {
+ __watchdog.conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!__watchdog.conn) {
+ _E("Failed to connecto D-Bus daemon. err(%s)",
+ err->message);
+ g_error_free(err);
+ return -1;
+ }
+ }
+
+ __watchdog.listener = g_dbus_connection_signal_subscribe(
+ __watchdog.conn,
+ NULL,
+ RESOURCED_FREEZER_INTERFACE,
+ RESOURCED_FREEZER_SIGNAL,
+ RESOURCED_FREEZER_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ __on_freezer_state_changed,
+ NULL,
+ NULL);
+ if (!__watchdog.listener) {
+ _E("Failed to subscribe freezer state");
+ return -1;
+ }
+
+ _I("%s is subscribed", RESOURCED_FREEZER_SIGNAL);
+
+ return 0;
+}
+
+static void __ignore_freezer_state(void)
+{
+ if (!__watchdog.conn)
+ return;
+
+ if (__watchdog.listener) {
+ g_dbus_connection_signal_unsubscribe(__watchdog.conn,
+ __watchdog.listener);
+ __watchdog.listener = 0;
+ }
+
+ g_object_unref(__watchdog.conn);
+ __watchdog.conn = NULL;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ _D("init");
+
+ _watchdog_logger_init();
+ _watchdog_config_init();
+
+ __watchdog.interval = _watchdog_config_get_interval();
+ __watchdog.max_retry_count = _watchdog_config_get_max_retry_count();
+
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ _E("Failed to register cmds");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD,
+ __on_app_status_add);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+ __on_app_status_cleanup);
+ amd_noti_listen(AMD_NOTI_MSG_SIGNAL_SEND_WATCHDOG_START,
+ __on_signal_send_watchdog_start);
+
+ amd_signal_add_ready_cb(__listen_freezer_state, NULL);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("fini");
+
+ if (__watchdog.retry_handler)
+ g_source_remove(__watchdog.retry_handler);
+
+ __ignore_freezer_state();
+
+ if (__watchdog.proc_contexts) {
+ g_list_free_full(__watchdog.proc_contexts,
+ __destroy_proc_context);
+ }
+
+ _watchdog_config_fini();
+ _watchdog_logger_fini();
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iniparser.h>
+
+#include "amd_watchdog_config.h"
+#include "amd_watchdog_private.h"
+
+#define CONFIG_PATH "/usr/share/amd/conf/amd_watchdog.conf"
+#define CONFIG_SECTION_NAME "Setting"
+#define CONFIG_KEY_WATCHDOG "Watchdog"
+#define CONFIG_KEY_INTERVAL "WatchdogInterval"
+#define CONFIG_KEY_MAX_RETRY_COUNT "WatchdogMaxRetryCount"
+
+struct watchdog_config_s {
+ int state;
+ unsigned int interval;
+ unsigned int max_retry_count;
+};
+
+static struct watchdog_config_s __config;
+
+static int __watchdog_config_get_int(dictionary *d,
+ const char *section, const char *key)
+{
+ char buf[512];
+
+ snprintf(buf, sizeof(buf), "%s:%s", section, key);
+
+ return iniparser_getint(d, buf, -1);
+}
+
+static const char *__watchdog_config_get_string(dictionary *d,
+ const char *section, const char *key)
+{
+ char buf[512];
+
+ snprintf(buf, sizeof(buf), "%s:%s", section, key);
+
+ return iniparser_getstring(d, buf, NULL);
+}
+
+static int __watchdog_config_load(const char *path)
+{
+ dictionary *d;
+ const char *str;
+ int r;
+
+ r = access(path, R_OK);
+ if (r != 0) {
+ _E("Failed to access %s. errno(%d)", path, errno);
+ return -1;
+ }
+
+ d = iniparser_load(path);
+ if (!d) {
+ _E("Failed to load %s by iniparser", path);
+ return -1;
+ }
+
+ str = __watchdog_config_get_string(d, CONFIG_SECTION_NAME,
+ CONFIG_KEY_WATCHDOG);
+ if (str && !strcmp(str, "enable-by-default"))
+ __config.state = WATCHDOG_ENABLE_BY_DEFAULT;
+ _W("Operation state: %s", str);
+
+ r = __watchdog_config_get_int(d, CONFIG_SECTION_NAME,
+ CONFIG_KEY_INTERVAL);
+ if (r > 0) {
+ __config.interval = r;
+ _W("Interval: %u", __config.interval);
+ }
+
+ r = __watchdog_config_get_int(d, CONFIG_SECTION_NAME,
+ CONFIG_KEY_MAX_RETRY_COUNT);
+ if (r > 0) {
+ __config.max_retry_count = r;
+ _W("Maximum retry count: %u", __config.max_retry_count);
+ }
+
+ iniparser_freedict(d);
+
+ return 0;
+}
+
+int _watchdog_config_get_operation_state(void)
+{
+ return __config.state;
+}
+
+unsigned int _watchdog_config_get_interval(void)
+{
+ return __config.interval;
+}
+
+unsigned int _watchdog_config_get_max_retry_count(void)
+{
+ return __config.max_retry_count;
+}
+
+int _watchdog_config_init(void)
+{
+ _D("Watchdog config init");
+
+ __config.state = WATCHDOG_ENABLE_ON_DEMAND;
+ __config.interval = 10000; /* 10 secdons */
+ __config.max_retry_count = 1;
+
+ if (__watchdog_config_load(CONFIG_PATH) < 0)
+ _W("Failed to load watchdog config");
+
+ return 0;
+}
+
+void _watchdog_config_fini(void)
+{
+ _D("Watchdog config fini");
+ __config.state = WATCHDOG_ENABLE_ON_DEMAND;
+ __config.interval = 0;
+ __config.max_retry_count = 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <amd.h>
+
+#include "amd_watchdog_logger.h"
+#include "amd_watchdog_private.h"
+
+#define LOG_FILE "amd_watchdog.log"
+#define LOG_PATH LOGGER_PATH "/" LOG_FILE
+
+static amd_logger_h __logger;
+
+int _watchdog_logger_print(const char *tag, const char *format, ...)
+{
+ char format_buf[256];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(format_buf, sizeof(format_buf), format, ap);
+ va_end(ap);
+
+ return amd_logger_print(__logger, tag, format_buf);
+}
+
+int _watchdog_logger_init(void)
+{
+ int ret;
+
+ _D("Watchdog logger init");
+ ret = amd_logger_create(LOG_PATH, &__logger);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void _watchdog_logger_fini(void)
+{
+ _D("Watchdog logger fini");
+ amd_logger_destroy(__logger);
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_WAYLAND_CORE_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_WAYLAND_CORE} ${AMD_MOD_WAYLAND_CORE_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WAYLAND_CORE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_WAYLAND_CORE} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_WAYLAND_CORE} PUBLIC
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ TIZEN_EXTENSION_CLIENT_DEPS
+ WAYLAND_CLIENT_DEPS
+ WAYLAND_TBM_CLIENT_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_WAYLAND_CORE} DESTINATION
+ ${AMD_MODULES_DIR}/mod COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2017 - 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tizen-extension-client-protocol.h>
+#include <amd.h>
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_WAYLAND_CORE"
+
+#define PATH_RUN_WAYLAND "/run/wayland-0"
+#define PATH_RUN_WMREADY "/run/.wm_ready"
+#define PATH_RUN "/run"
+
+struct file_monitor_s {
+ bool wl_ready;
+ bool wm_ready;
+ amd_inotify_watch_info_h handle;
+};
+
+struct wl_source_s {
+ struct wl_display *display;
+ struct wl_registry *registry;
+ GSource *gsource;
+ GPollFD *gfd;
+ bool prepared;
+};
+
+static struct file_monitor_s __file_monitor;
+static struct wl_source_s __wl_source;
+static int __retry_cnt;
+
+static void __wl_listener_cb(void *data, struct wl_registry *reg,
+ unsigned int id, const char *interface, unsigned int version)
+{
+ char buf[512];
+
+ if (!interface)
+ return;
+
+ _W("interface(%s), id(%u), version(%u)", interface, id, version);
+ snprintf(buf, sizeof(buf), "wayland.listener.%s", interface);
+ amd_noti_send(buf, (int)id, (int)version, reg, NULL);
+}
+
+static void __wl_listener_remove_cb(void *data, struct wl_registry *reg,
+ unsigned int id)
+{
+ _W("id(%u)", id);
+ amd_noti_send(AMD_NOTI_MSG_WAYLAND_LISTENER_REMOVE,
+ (int)id, 0, reg, NULL);
+}
+
+static const struct wl_registry_listener __registry_listener = {
+ __wl_listener_cb,
+ __wl_listener_remove_cb
+};
+
+static gboolean __wl_source_prepare(GSource *source, gint *timeout)
+{
+ if (__wl_source.prepared)
+ return FALSE;
+
+ while (wl_display_prepare_read(__wl_source.display) != 0) {
+ if (wl_display_dispatch_pending(__wl_source.display) < 0)
+ _W("Failed to dispatch queue pending");
+ }
+
+ __wl_source.prepared = true;
+
+ wl_display_flush(__wl_source.display);
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean __wl_source_check(GSource *source)
+{
+ if (g_source_is_destroyed(source)) {
+ if (__wl_source.display && __wl_source.prepared)
+ wl_display_cancel_read(__wl_source.display);
+ _E("Display source(%p) already destroyed", source);
+ return FALSE;
+ }
+
+ if (!__wl_source.prepared)
+ return FALSE;
+
+ if (__wl_source.gfd->revents & (G_IO_HUP | G_IO_ERR)) {
+ wl_display_cancel_read(__wl_source.display);
+ _E("Error: revents(%x)", __wl_source.gfd->revents);
+ __wl_source.prepared = false;
+ g_source_destroy(source);
+ abort();
+ return FALSE;
+ }
+
+ if (__wl_source.gfd->revents & G_IO_IN) {
+ if (wl_display_read_events(__wl_source.display) < 0)
+ _W("Failed to read events");
+ __wl_source.prepared = false;
+ return TRUE;
+ }
+
+ wl_display_cancel_read(__wl_source.display);
+ __wl_source.prepared = false;
+
+ return FALSE;
+}
+
+static gboolean __wl_source_dispatch(GSource *source, GSourceFunc callback,
+ gpointer data)
+{
+ if (g_source_is_destroyed(source)) {
+ _E("Source(%p) is already destroyed", source);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (__wl_source.gfd->revents & (G_IO_HUP | G_IO_ERR)) {
+ _E("Error: revents(%x)", __wl_source.gfd->revents);
+ g_source_destroy(source);
+ abort();
+ return G_SOURCE_REMOVE;
+ }
+
+ if (__wl_source.gfd->revents & G_IO_IN) {
+ if (wl_display_dispatch_pending(__wl_source.display) < 0)
+ _W("Failed to dispatch queue pending");
+ }
+
+ wl_display_flush(__wl_source.display);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static GSourceFuncs __wl_source_funcs = {
+ .prepare = __wl_source_prepare,
+ .check = __wl_source_check,
+ .dispatch = __wl_source_dispatch,
+ .finalize = NULL
+};
+
+static void __wl_source_fini(void)
+{
+ if (__wl_source.gfd) {
+ g_source_remove_poll(__wl_source.gsource, __wl_source.gfd);
+ g_free(__wl_source.gfd);
+ __wl_source.gfd = NULL;
+ }
+
+ if (__wl_source.gsource != NULL &&
+ !g_source_is_destroyed(__wl_source.gsource)) {
+ g_source_destroy(__wl_source.gsource);
+ g_source_unref(__wl_source.gsource);
+ __wl_source.gsource = NULL;
+ }
+
+ if (__wl_source.registry) {
+ wl_registry_destroy(__wl_source.registry);
+ __wl_source.registry = NULL;
+ }
+
+ if (__wl_source.display) {
+ wl_display_disconnect(__wl_source.display);
+ __wl_source.display = NULL;
+ amd_wayland_set_display(NULL);
+ }
+}
+
+static int __wl_source_init(void)
+{
+ int r;
+
+ __wl_source.display = wl_display_connect(NULL);
+ if (!__wl_source.display) {
+ _E("Failed to connect wayland display");
+ return -1;
+ }
+ amd_wayland_set_display(__wl_source.display);
+
+ __wl_source.registry = wl_display_get_registry(__wl_source.display);
+ if (!__wl_source.registry) {
+ _E("Failed to get wayland registry");
+ return -1;
+ }
+
+ wl_registry_add_listener(__wl_source.registry,
+ &__registry_listener, NULL);
+ wl_display_flush(__wl_source.display);
+
+ r = wl_display_roundtrip(__wl_source.display);
+ if (r < 0)
+ _W("wl_display_roundtrip() is failed. result(%d)", r);
+
+ __wl_source.gsource = g_source_new(&__wl_source_funcs, sizeof(GSource));
+ if (!__wl_source.gsource) {
+ _E("Failed to create GSource");
+ return -1;
+ }
+
+ __wl_source.gfd = (GPollFD *)g_malloc(sizeof(GPollFD));
+ if (!__wl_source.gfd) {
+ _E("Failed to create GPollFD");
+ return -1;
+ }
+
+ __wl_source.gfd->fd = wl_display_get_fd(__wl_source.display);
+ __wl_source.gfd->events = G_IO_IN | G_IO_ERR;
+ __wl_source.gfd->revents = 0;
+
+ g_source_add_poll(__wl_source.gsource, __wl_source.gfd);
+ g_source_set_callback(__wl_source.gsource, NULL,
+ __wl_source.display, NULL);
+ g_source_set_priority(__wl_source.gsource, G_PRIORITY_DEFAULT);
+ g_source_attach(__wl_source.gsource, NULL);
+
+ return 0;
+}
+
+static gboolean __init_wl(gpointer data)
+{
+ _I("Initialize Wayland");
+ if (__wl_source_init() < 0) {
+ __retry_cnt++;
+ if (__retry_cnt > 10) {
+ _E("Failed to initialize wayland: Retry(%d)", __retry_cnt);
+ __wl_source_fini();
+ g_timeout_add_seconds(1, __init_wl, NULL);
+ return G_SOURCE_REMOVE;
+ }
+ __wl_source_fini();
+ return G_SOURCE_CONTINUE;
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static bool __wayland_monitor_cb(const char *event_name, void *data)
+{
+ if (event_name == NULL)
+ return true;
+
+ if (strcmp(event_name, "wayland-0") == 0) {
+ _D("%s is created", event_name);
+ __file_monitor.wl_ready = true;
+ } else if (strcmp(event_name, ".wm_ready") == 0) {
+ _D("%s is created", event_name);
+ __file_monitor.wm_ready = true;
+ }
+
+ if (__file_monitor.wm_ready && __file_monitor.wl_ready) {
+ g_idle_add(__init_wl, NULL);
+ __file_monitor.handle = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+static int __file_monitor_init(void)
+{
+ if (!__file_monitor.wl_ready) {
+ if (access(PATH_RUN_WAYLAND, F_OK) == 0) {
+ _D("%s exists", PATH_RUN_WAYLAND);
+ __file_monitor.wl_ready = true;
+ }
+ }
+
+ if (!__file_monitor.wm_ready) {
+ if (access(PATH_RUN_WMREADY, F_OK) == 0) {
+ _D("%s exists", PATH_RUN_WMREADY);
+ __file_monitor.wm_ready = true;
+ }
+ }
+
+ if (__file_monitor.wl_ready && __file_monitor.wm_ready) {
+ g_idle_add(__init_wl, NULL);
+ return 0;
+ }
+
+ __file_monitor.handle = amd_inotify_add_watch(PATH_RUN, IN_CREATE,
+ __wayland_monitor_cb, NULL);
+ if (__file_monitor.handle == NULL) {
+ _E("Failed to add inotify watch");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __file_monitor_fini(void)
+{
+ if (__file_monitor.handle)
+ amd_inotify_rm_watch(__file_monitor.handle);
+}
+
+static gboolean __idle_cb(gpointer data)
+{
+ _D("wayland core init");
+
+ if (__file_monitor_init() < 0)
+ return G_SOURCE_CONTINUE;
+
+ return G_SOURCE_REMOVE;
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ _D("wayland core init");
+
+ g_idle_add(__idle_cb, NULL);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ _D("wayland core finish");
+
+ __file_monitor_fini();
+ __wl_source_fini();
+ __retry_cnt = 0;
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_WIDGET_SRCS)
+
+ADD_LIBRARY(${TARGET_AMD_MOD_WIDGET} ${AMD_MOD_WIDGET_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WIDGET} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AMD_MOD_WIDGET} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/api)
+
+TARGET_LINK_LIBRARIES(${TARGET_AMD_MOD_WIDGET} PRIVATE ${TARGET_LIB_AMD})
+
+APPLY_PKG_CONFIG(${TARGET_AMD_MOD_WIDGET} PUBLIC
+ AUL_DEPS
+ BUNDLE_DEPS
+ DLOG_DEPS
+ GIO_DEPS
+ GLIB_DEPS
+ PKGMGR_INFO_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_AMD_MOD_WIDGET} DESTINATION ${AMD_MODULES_DIR}/mod
+ COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2018 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_WIDGET_LOGGER_H__
+#define __AMD_WIDGET_LOGGER_H__
+
+int _widget_logger_init(void);
+
+void _widget_logger_fini(void);
+
+int _widget_logger_print(const char *tag, const char *format, ...);
+
+#endif /* __AMD_WIDGET_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#pragma once
+
+#include <amd_mod_common.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AMD_WIDGET"
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2017 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.
+ */
+
+#define _GNU_SOURCE
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_svc.h>
+#include <aul_sock.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <pkgmgr-info.h>
+#include <aul_widget.h>
+#include <amd.h>
+
+#include "amd_widget_logger.h"
+#include "amd_widget_private.h"
+#include "aul_svc_priv_key.h"
+
+#ifndef AUL_K_WIDGET_OPERATION
+#define AUL_K_WIDGET_OPERATION "__WIDGET_OP__"
+#endif
+#define MAX_NR_OF_DESCRIPTORS 2
+#define MAX_PID_STR_BUFSZ 20
+#define DISABLE_ENDPOINT "widget.disable"
+
+typedef struct _widget_t {
+ char *pkg_id;
+ char *widget_id;
+ int pid;
+ pid_t viewer_pid;
+ uid_t uid;
+ GList *instances;
+} widget_t;
+
+struct restart_widget_info {
+ char *appid;
+ char *pkgid;
+ GList *widget_list;
+ bool is_faulted;
+ int status;
+ pid_t pid;
+ uid_t uid;
+ pid_t viewer_pid;
+ int count;
+ guint timer;
+};
+
+struct restart_info {
+ char *appid;
+ int count;
+ guint timer;
+};
+
+struct widget_status_info {
+ const char *endpoint;
+ const char *widget_id;
+ const char *instance_id;
+ const char *pkg_id;
+ const char *is_fault;
+ int status;
+ int pid;
+ uid_t uid;
+};
+
+static GList *__widgets;
+static GList *__update_widgets;
+static GList *__oom_restart_widgets;
+static GList *__restart_widgets;
+
+static widget_t *__create_widget(const char *widget_id, const char *pkgid,
+ pid_t pid, uid_t uid);
+static void __free_widget(gpointer data);
+
+static int __send_status_info(struct widget_status_info *info)
+{
+ char buf[MAX_PID_STR_BUFSZ];
+ bundle *envelope;
+ int r;
+
+ envelope = bundle_create();
+ if (envelope == NULL) {
+ LOGE("Out of memory");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", info->pid);
+ bundle_add(envelope, AUL_K_COM_SENDER_PID, buf);
+ bundle_add(envelope, AUL_K_WIDGET_ID, info->widget_id);
+ bundle_add_byte(envelope, AUL_K_WIDGET_STATUS,
+ &info->status, sizeof(int));
+
+ if (info->instance_id) {
+ bundle_add(envelope, AUL_K_WIDGET_INSTANCE_ID,
+ info->instance_id);
+ }
+ if (info->pkg_id)
+ bundle_add(envelope, AUL_K_PKGID, info->pkg_id);
+ if (info->is_fault)
+ bundle_add(envelope, AUL_K_IS_FAULT, info->is_fault);
+
+ r = amd_app_com_send(info->endpoint, info->pid, envelope, info->uid);
+ bundle_free(envelope);
+ LOGW("endpoint(%s), widget(%s:%d), status(%d), is_faulted(%s)",
+ info->endpoint, info->widget_id,
+ info->pid, info->status,
+ info->is_fault);
+ _widget_logger_print("SEND_STATUS", "widget(%s), pid(%d) "
+ "status(%d), is_faulted(%s)",
+ info->widget_id, info->pid,
+ info->status, info->is_fault);
+ return r;
+}
+
+static void __free_widget(gpointer data)
+{
+ widget_t *widget = (widget_t *)data;
+
+ if (widget->pkg_id)
+ free(widget->pkg_id);
+ if (widget->widget_id)
+ free(widget->widget_id);
+ if (widget->instances)
+ g_list_free_full(widget->instances, free);
+ free(widget);
+}
+
+static widget_t *__create_widget(const char *widget_id, const char *pkgid,
+ pid_t pid, uid_t uid)
+{
+ widget_t *widget;
+
+ widget = (widget_t *)calloc(1, sizeof(widget_t));
+ if (widget == NULL) {
+ LOGE("Out of memory");
+ return NULL;
+ }
+
+ widget->widget_id = strdup(widget_id);
+ if (widget->widget_id == NULL) {
+ LOGE("Out of memory");
+ free(widget);
+ return NULL;
+ }
+
+ if (pkgid) {
+ widget->pkg_id = strdup(pkgid);
+ if (widget->pkg_id == NULL) {
+ LOGE("Out of memory");
+ free(widget->widget_id);
+ free(widget);
+ return NULL;
+ }
+ }
+
+ widget->pid = pid;
+ widget->uid = uid;
+
+ return widget;
+}
+
+static widget_t *__find_widget(const char *widget_id, int pid, uid_t uid)
+{
+ GList *widget_list = __widgets;
+ widget_t *widget;
+
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (strcmp(widget->widget_id, widget_id) == 0) {
+ if (widget->pid == pid && widget->uid == uid)
+ return widget;
+ }
+
+ widget_list = widget_list->next;
+ }
+
+ return NULL;
+}
+
+static widget_t *__find_instance(const char *widget_id, const char *instance_id)
+{
+ GList *widget_list = __widgets;
+ GList *instance_list;
+ widget_t *widget;
+
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (strcmp(widget->widget_id, widget_id) == 0
+ && widget->instances) {
+ instance_list = g_list_find_custom(widget->instances,
+ instance_id, (GCompareFunc)g_strcmp0);
+
+ if (instance_list)
+ return widget;
+ }
+
+ widget_list = widget_list->next;
+ }
+
+ return NULL;
+}
+
+static bool __widget_exist(int pid, uid_t uid)
+{
+ GList *widget_list = __widgets;
+ widget_t *widget;
+
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (widget->pid == pid && widget->uid == uid)
+ return true;
+
+ widget_list = widget_list->next;
+ }
+ return false;
+}
+
+static int __get_viewer_pid(bundle *kb)
+{
+ const char *pid_str;
+ int pid;
+
+ pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+ if (pid_str == NULL)
+ pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
+
+ if (pid_str == NULL)
+ return -1;
+
+ pid = atoi(pid_str);
+ if (pid <= 1)
+ return -1;
+ return pid;
+}
+
+static int __widget_pre_add(bundle *kb, int pid, uid_t uid)
+{
+ widget_t *widget;
+ const char *widget_id;
+ const char *instance_id;
+ const char *operation;
+ pid_t viewer_pid;
+ char *error_desc;
+
+ if (!kb) {
+ LOGE("Invalid parameter");
+ error_desc = "bundle NULL";
+ goto error;
+ }
+
+ operation = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
+ if (!operation || strcmp(operation, "create") != 0) {
+ error_desc = "operation";
+ goto error;
+ }
+
+ widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
+ if (!widget_id) {
+ error_desc = "widget id";
+ goto error;
+ }
+
+ instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
+ if (!instance_id) {
+ error_desc = "instance id";
+ goto error;
+ }
+
+ widget = __find_instance(widget_id, instance_id);
+ if (!widget) {
+ widget = __find_widget(widget_id, pid, uid);
+ if (!widget) {
+ widget = __create_widget(widget_id, NULL, pid, uid);
+ if (!widget) {
+ error_desc = "create widget";
+ goto error;
+ }
+
+ __widgets = g_list_append(__widgets, widget);
+ }
+ } else {
+ if (widget->pid != pid) {
+ LOGW("Process ID(%d) of %s is changed to %d",
+ widget->pid, widget_id, pid);
+ widget->pid = pid;
+ }
+ }
+
+ viewer_pid = __get_viewer_pid(kb);
+ widget->viewer_pid = viewer_pid;
+ _widget_logger_print("PRE_ADD", "instance(%s), pid(%d), viewer_pid(%d)",
+ instance_id, pid, viewer_pid);
+
+ return 0;
+error:
+ _widget_logger_print(
+ "PRE_ADD", "Fail to PRE_ADD REASON(%s)", error_desc);
+ return -1;
+}
+
+static int __widget_add(const char *widget_id, const char *instance_id,
+ int pid, uid_t uid)
+{
+ widget_t *widget;
+ char *id;
+ char *error_desc;
+
+ if (!widget_id || !instance_id) {
+ if (!widget_id)
+ error_desc = "widget id";
+ else
+ error_desc = "instance id";
+ goto error;
+ }
+
+ id = strdup(instance_id);
+ if (!id) {
+ error_desc = "instance_id dup";
+ goto error;
+ }
+
+ widget = __find_instance(widget_id, instance_id);
+ if (!widget) {
+ widget = __find_widget(widget_id, pid, uid);
+ if (!widget) {
+ widget = __create_widget(widget_id, NULL, pid, uid);
+ if (!widget) {
+ LOGE("out of memory");
+ free(id);
+ error_desc = "create widget";
+ goto error;
+ }
+
+ __widgets = g_list_append(__widgets, widget);
+ }
+ widget->pid = pid;
+ widget->instances = g_list_append(widget->instances, id);
+ } else {
+ LOGW("instance recovery: %s - %s(%d)",
+ widget_id, instance_id, pid);
+ if (widget->pid != pid) {
+ LOGW("Process ID(%d) of %s is changed to %d",
+ widget->pid, widget_id, pid);
+ widget->pid = pid;
+ }
+ free(id);
+ }
+
+ LOGD("widget instance added: %s - %s (%d:%d)", widget_id, instance_id,
+ uid, pid);
+ return 0;
+error:
+ _widget_logger_print(
+ "ADD", "Fail to ADD REASON(%s)", error_desc);
+ return -1;
+}
+
+static int __widget_del(const char *widget_id, const char *instance_id)
+{
+ widget_t *widget;
+ GList *stored_list;
+
+ if (!widget_id || !instance_id)
+ return -1;
+
+ widget = __find_instance(widget_id, instance_id);
+ if (!widget) {
+ LOGE("Failed to find instance(%s) of widget(%s)",
+ instance_id, widget_id);
+ return -1;
+ }
+ stored_list = g_list_find_custom(widget->instances, instance_id,
+ (GCompareFunc)g_strcmp0);
+
+ if (stored_list) {
+ LOGW("widget instace deleted: %s - %s (%d:%d)",
+ widget->widget_id,
+ instance_id,
+ widget->uid,
+ widget->pid);
+ widget->instances = g_list_remove_link(widget->instances,
+ stored_list);
+ if (!widget->instances) {
+ __widgets = g_list_remove(__widgets, widget);
+ __free_widget(widget);
+ }
+
+ free(stored_list->data);
+ g_list_free(stored_list);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int __widget_list(const char *widget_id, amd_request_h req)
+{
+ bundle *rvalue;
+ widget_t *widget;
+ GList *widget_list = __widgets;
+ GList *instance_list;
+ char pid_buf[10];
+ int fd;
+
+ if (!widget_id)
+ return -1;
+
+ rvalue = bundle_create();
+ if (!rvalue) {
+ LOGE("out of memory");
+ return -1;
+ }
+
+ LOGD("start instance list");
+
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (strcmp(widget->widget_id, widget_id) == 0) {
+ instance_list = widget->instances;
+ snprintf(pid_buf, sizeof(pid_buf), "%d", widget->pid);
+ while (instance_list) {
+ LOGD("%s - %s", widget_id,
+ (const char *)instance_list->data);
+ bundle_add_str(rvalue, instance_list->data,
+ pid_buf);
+ instance_list = instance_list->next;
+ }
+ }
+ widget_list = widget_list->next;
+ }
+
+ LOGD("end instance list");
+
+ fd = amd_request_remove_fd(req);
+ aul_sock_send_bundle_with_fd(fd, 0, rvalue, AUL_SOCK_NOREPLY);
+ bundle_free(rvalue);
+
+ return 0;
+}
+
+static int __widget_update(const char *widget_id, amd_request_h req)
+{
+ char *instance_id = NULL;
+ char *appid = NULL;
+ bundle *kb = amd_request_get_bundle(req);
+ int ret = -1;
+ widget_t *widget;
+ GList *widget_list = __widgets;
+ bool dummy;
+ bool dummy_mode;
+
+ if (!kb || !widget_id) {
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_APPID, &appid);
+ if (!appid) {
+ LOGE("missing appid:%s", widget_id);
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
+ if (!instance_id) { /* all instances */
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (strcmp(widget->widget_id, widget_id) == 0
+ && widget->pid > 0) {
+ bundle_del(kb, AUL_K_TARGET_PID);
+ bundle_add_byte(kb, AUL_K_TARGET_PID,
+ (void *)&widget->pid,
+ sizeof(widget->pid));
+
+ ret = amd_launch_start_app(appid, req, &dummy,
+ &dummy_mode, false);
+ LOGD("update widget: %s(%d)", widget->widget_id,
+ widget->pid);
+ }
+ widget_list = widget_list->next;
+ }
+ } else {
+ widget = __find_instance(widget_id, instance_id);
+ if (widget) {
+ if (widget->pid == -1) {
+ LOGW("widget process is not running: %s",
+ widget->widget_id);
+ return ret;
+ }
+ bundle_del(kb, AUL_K_TARGET_PID);
+ bundle_add_byte(kb, AUL_K_TARGET_PID,
+ (void *)&widget->pid, sizeof(widget->pid));
+ }
+ ret = amd_launch_start_app(appid, req, &dummy, &dummy_mode, false);
+ LOGD("update widget: %s", widget_id);
+ }
+
+ return ret;
+}
+
+static int __widget_cleanup(int pid, uid_t uid, int viewer_pid)
+{
+ GList *widget_list = __widgets;
+ widget_t *widget;
+ amd_app_status_h viewer_status;
+
+ LOGD("viewer pid %d", viewer_pid);
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ widget_list = widget_list->next;
+ if (widget->pid == pid && widget->uid == uid) {
+ viewer_status = amd_app_status_find_by_pid(viewer_pid);
+ if (viewer_status == NULL) {
+ __widgets = g_list_remove(__widgets, widget);
+ __free_widget(widget);
+ LOGW("remove widget(%d) from list", pid);
+ } else {
+ LOGW("viewer pid(%d), widget pid(%d)",
+ viewer_pid, pid);
+ widget->pid = -1;
+ }
+ }
+ }
+
+ LOGW("cleanup widget %d:%d", pid, uid);
+
+ return 0;
+}
+
+static int __viewer_widget_cleanup(int viewer_pid, uid_t uid)
+{
+ GList *widget_list = __widgets;
+ widget_t *widget;
+
+ LOGD("viewer pid %d", viewer_pid);
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ widget_list = widget_list->next;
+ if (widget->viewer_pid == viewer_pid) {
+ __widgets = g_list_remove(__widgets, widget);
+ LOGW("remove widget(%s) from list", widget->widget_id);
+ __free_widget(widget);
+ }
+ }
+ LOGW("cleanup widget from viewer %d:%d", viewer_pid, uid);
+
+ return 0;
+}
+
+static int __widget_get_pid(const char *widget_id, const char *instance_id)
+{
+ widget_t *widget;
+
+ widget = __find_instance(widget_id, instance_id);
+ if (!widget)
+ return -1;
+
+ return widget->pid;
+}
+
+static int __widget_count(const char *widget_id, uid_t uid)
+{
+ widget_t *widget;
+ GList *widget_list = __widgets;
+ GList *instance_list;
+ int count = 0;
+
+ if (!widget_id)
+ return -1;
+
+ while (widget_list) {
+ widget = (widget_t *)widget_list->data;
+ if (strcmp(widget->widget_id, widget_id) == 0 &&
+ widget->uid == uid) {
+ instance_list = widget->instances;
+ if (instance_list)
+ count += g_list_length(instance_list);
+ }
+ widget_list = widget_list->next;
+ }
+ LOGW("widget(%s) count: %d", widget_id, count);
+
+ return count;
+}
+
+static int __widget_verify_cmd(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ const char *command;
+ const char *instance_id;
+ const char *widget_id;
+ widget_t *widget;
+ char *error_desc;
+
+ if (!kb) {
+ LOGE("invalid argument");
+ error_desc = "bundle NULL";
+ goto error;
+ }
+
+ widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
+ if (!widget_id) {
+ LOGE("widget id is NULL");
+ error_desc = "widget id";
+ goto error;
+ }
+
+ instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
+ if (!instance_id) {
+ LOGE("widget instance is NULL");
+ error_desc = "instance id";
+ goto error;
+ }
+
+ command = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
+ if (!command) {
+ LOGE("widget command is NULL");
+ error_desc = "command is null";
+ goto error;
+ }
+
+ if (strcmp(command, "create") == 0)
+ return 0;
+
+ widget = __find_instance(widget_id, instance_id);
+ if (!widget) {
+ LOGE("invalid command: %s - target instance %s is not exist",
+ command, instance_id);
+ error_desc = "invalid command";
+ goto error;
+ }
+
+ return 0;
+error:
+ _widget_logger_print(
+ "VERIFY_CMD", "Fail to PRE_ADD REASON(%s)", error_desc);
+ return -1;
+}
+
+static int __validate_widget_owner(amd_request_h req)
+{
+ amd_app_status_h status;
+ const char *appid;
+ char *widget_id = NULL;
+ const char *appid_part = NULL;
+ bundle *kb = amd_request_get_bundle(req);
+
+ status = amd_app_status_find_by_pid(amd_request_get_pid(req));
+ if (!status)
+ return -1;
+
+ appid = amd_app_status_get_appid(status);
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ if (!widget_id || !appid)
+ return -1;
+
+ appid_part = g_strstr_len(widget_id, strlen(widget_id), "@");
+ if (appid_part)
+ appid_part = appid_part + 1;
+ else
+ appid_part = widget_id;
+
+ return strcmp(appid_part, appid);
+}
+
+static int __dispatch_widget_change_status(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ amd_app_status_h caller_status;
+ const char *caller_pkgid;
+ const char *caller_appid = NULL;
+ const char *status;
+ int pid;
+
+ if (__validate_widget_owner(req) < 0) {
+ LOGE("Invalid sender");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ status = bundle_get_val(kb, AUL_K_STATUS);
+ if (status == NULL) {
+ LOGE("Failed to get status");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ pid = amd_request_get_pid(req);
+ caller_status = amd_app_status_find_by_pid(pid);
+ if (!caller_status)
+ return 0; /* not app? */
+
+ caller_pkgid = amd_app_status_get_pkgid(caller_status);
+ if (!caller_pkgid) {
+ LOGE("can not get caller pkgid");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ caller_appid = amd_app_status_get_appid(caller_status);
+ if (!caller_appid) {
+ LOGE("can not get caller appid");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ LOGI("send status %d, %s, %s, %s", pid, caller_appid,
+ caller_pkgid, status);
+
+ aul_send_app_status_change_signal(pid,
+ caller_appid,
+ caller_pkgid,
+ status,
+ APP_TYPE_WIDGET);
+ _widget_logger_print("CHANGE_STATUS", "widget_id(%s), status(%s)",
+ caller_appid, status);
+ return amd_request_send_result(req, 0);
+}
+
+static int __dispatch_widget_add_del(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *widget_id = NULL;
+ char *instance_id = NULL;
+ int ret;
+ int cmd = amd_request_get_cmd(req);
+ const char *tag;
+
+ if (cmd == WIDGET_ADD && __validate_widget_owner(req) != 0) {
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ if (!widget_id) {
+ LOGE("Failed to get widget id");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
+ if (!instance_id) {
+ LOGE("Failed to get instance id");
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ if (amd_request_get_cmd(req) == WIDGET_ADD) {
+ ret = __widget_add(widget_id, instance_id,
+ amd_request_get_pid(req),
+ amd_request_get_uid(req));
+ tag = "ADD";
+ } else {
+ ret = __widget_del(widget_id, instance_id);
+ tag = "DEL";
+ }
+
+ amd_request_send_result(req, ret);
+ LOGW("[%s:%d] Instance ID(%s), Result(%d)",
+ aul_cmd_convert_to_string(cmd),
+ cmd, instance_id, ret);
+ _widget_logger_print(tag, "instance(%s), result(%d)",
+ instance_id, ret);
+ return ret;
+}
+
+static int __validate_widget_caller(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *appid = NULL;
+ amd_appinfo_h target;
+ const char *target_pkgid;
+ amd_app_status_h caller_status;
+ const char *caller_pkgid;
+ pid_t caller_pid = amd_request_get_pid(req);
+ char attr[512] = { 0, };
+ int r;
+
+ if (amd_request_get_uid(req) < REGULAR_UID_MIN) {
+ LOGD("bypass caller package check");
+ return 0;
+ }
+
+ bundle_get_str(kb, AUL_K_APPID, &appid);
+ if (!appid) {
+ LOGE("no appid provided");
+ return -1;
+ }
+
+ target = amd_appinfo_find(amd_request_get_uid(req), appid);
+ if (!target) {
+ LOGE("can not find appinfo of %s", appid);
+ return -1;
+ }
+
+ target_pkgid = amd_appinfo_get_value(target, AMD_AIT_PKGID);
+ if (!target_pkgid) {
+ LOGE("can not get pkgid of %s", appid);
+ return -1;
+ }
+
+ caller_status = amd_app_status_find_by_effective_pid(caller_pid);
+ if (!caller_status) {
+ r = amd_proc_get_attr(caller_pid, attr, sizeof(attr));
+ if (r != 0) {
+ LOGE("Failed to get attr. caller(%d)", caller_pid);
+ return -1;
+ }
+
+ if (!strcmp(attr, "User"))
+ return 0;
+
+ LOGE("Reject request. caller(%d)", caller_pid);
+ return -1;
+ }
+
+ caller_pkgid = amd_app_status_get_pkgid(caller_status);
+ if (!caller_pkgid) {
+ LOGE("can not get caller pkgid");
+ return -1;
+ }
+
+ LOGD("compare pkgid %s:%s", caller_pkgid, target_pkgid);
+ if (strcmp(caller_pkgid, target_pkgid) == 0)
+ return 0;
+
+ return -1;
+}
+
+static int __send_message(int sock, const struct iovec *vec, int vec_size,
+ const int *desc, int nr_desc)
+{
+ struct msghdr msg = {0,};
+ int sndret;
+ int desclen = 0;
+ struct cmsghdr *cmsg = NULL;
+ char buff[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)] = {0,};
+
+ if (vec == NULL || vec_size < 1)
+ return -EINVAL;
+ if (nr_desc < 0 || nr_desc > MAX_NR_OF_DESCRIPTORS)
+ return -EINVAL;
+ if (desc == NULL)
+ nr_desc = 0;
+
+ msg.msg_iov = (struct iovec *)vec;
+ msg.msg_iovlen = vec_size;
+
+ /* sending ancillary data */
+ if (nr_desc > 0) {
+ msg.msg_control = buff;
+ msg.msg_controllen = sizeof(buff);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg == NULL)
+ return -EINVAL;
+
+ /* packing files descriptors */
+ if (nr_desc > 0) {
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ desclen = cmsg->cmsg_len =
+ CMSG_LEN(sizeof(int) * nr_desc);
+ memcpy((int *)CMSG_DATA(cmsg), desc,
+ sizeof(int) * nr_desc);
+ cmsg = CMSG_NXTHDR(&msg, cmsg);
+ LOGD("packing file descriptors done");
+ }
+
+ /* finished packing updating the corect length */
+ msg.msg_controllen = desclen;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+
+ sndret = sendmsg(sock, &msg, 0);
+ LOGD("sendmsg ret : %d", sndret);
+ if (sndret < 0)
+ return -errno;
+
+ return sndret;
+}
+
+static int __dispatch_widget_get_content(amd_request_h req)
+{
+ int handles[2] = {0,};
+ char iobuf[1];
+ struct iovec vec = {
+ .iov_base = iobuf,
+ .iov_len = sizeof(iobuf)
+ };
+ int msglen = 0;
+ int ret;
+ bundle *kb = amd_request_get_bundle(req);
+ struct timeval tv;
+ int pid;
+ char *widget_id = NULL;
+ char *instance_id = NULL;
+
+ if (__validate_widget_caller(req) != 0) {
+ amd_request_send_result(req, -EILLEGALACCESS);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
+
+ pid = __widget_get_pid(widget_id, instance_id);
+ if (pid < 0) {
+ LOGE("can not find widget");
+ amd_request_send_result(req, -ENOENT);
+ return -1;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) {
+ LOGE("error create socket pair");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ if (handles[0] == -1) {
+ LOGE("error socket open");
+ amd_request_send_result(req, -1);
+ return -1;
+ }
+
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+
+ ret = setsockopt(handles[1], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ if (ret < 0) {
+ LOGE("cannot set SO_RCVTIMEO for socket %d", handles[0]);
+ amd_request_send_result(req, -1);
+ goto out;
+ }
+
+ ret = aul_sock_send_bundle(pid, amd_request_get_target_uid(req),
+ amd_request_get_cmd(req), amd_request_get_bundle(req),
+ AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ LOGE("error while sending bundle");
+ amd_request_send_result(req, -1);
+ goto out;
+ }
+
+ msglen = __send_message(ret, &vec, 1, &(handles[0]), 1);
+ if (msglen < 0) {
+ LOGE("Error[%d]: while sending message to widget", -msglen);
+ amd_request_send_result(req, -1);
+ ret = -1;
+ goto out;
+ }
+
+ msglen = __send_message(amd_request_get_fd(req), &vec, 1,
+ &(handles[1]), 1);
+ if (msglen < 0) {
+ LOGE("Error[%d]: while sending message to caller", -msglen);
+ amd_request_send_result(req, -1);
+ ret = -1;
+ }
+
+out:
+ close(handles[0]);
+ close(handles[1]);
+
+ return ret;
+}
+
+static int __dispatch_widget_list(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *widget_id = NULL;
+ int ret;
+
+ if (__validate_widget_caller(req) < 0) {
+ amd_request_send_result(req, -EILLEGALACCESS);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ if (!widget_id) {
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ ret = __widget_list(widget_id, req);
+
+ return ret;
+}
+
+static int __dispatch_widget_update(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *widget_id = NULL;
+ int ret;
+
+ if (__validate_widget_caller(req) < 0) {
+ amd_request_send_result(req, -EILLEGALACCESS);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ if (!widget_id) {
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+
+ /* update will pass bundle by app_control */
+ amd_request_set_cmd(req, APP_START_ASYNC);
+
+ ret = __widget_update(widget_id, req);
+ if (ret < 0)
+ return -1;
+
+ _widget_logger_print("UPDATE", "widget_id(%s), result(%d)",
+ widget_id, ret);
+
+ return 0;
+}
+
+static int __dispatch_widget_count(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *widget_id = NULL;
+ int count;
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ if (!widget_id) {
+ LOGE("Failed to get widget id. caller(%d)",
+ amd_request_get_pid(req));
+ amd_request_send_result(req, -EINVAL);
+ return -1;
+ }
+ count = __widget_count(widget_id, amd_request_get_uid(req));
+ LOGD("dispatch widget count %d", count);
+ amd_request_send_result(req, count);
+
+ _widget_logger_print("COUNT", "widget_id(%s), count(%d)",
+ widget_id, count);
+
+ return 0;
+}
+
+static bundle *__create_bundle(widget_t *widget)
+{
+ char buf[MAX_PID_STR_BUFSZ];
+ amd_app_status_h app_status;
+ bundle *b;
+
+ app_status = amd_app_status_find_by_pid(widget->pid);
+ if (app_status == NULL)
+ return NULL;
+
+ b = bundle_create();
+ if (b == NULL) {
+ LOGE("Out of memory");
+ return NULL;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", widget->pid);
+ bundle_add_str(b, AUL_K_PID, buf);
+ bundle_add_str(b, AUL_K_APPID, amd_app_status_get_appid(app_status));
+ bundle_add_str(b, AUL_K_PKGID, amd_app_status_get_pkgid(app_status));
+ bundle_add_str(b, AUL_K_EXEC, amd_app_status_get_app_path(app_status));
+ bundle_add_str(b, AUL_K_WIDGET_ID, widget->widget_id);
+
+ return b;
+}
+
+static int __send_running_info(widget_t *widget, int fd)
+{
+ char buf[MAX_PID_STR_BUFSZ];
+ const char *instance_id;
+ unsigned int surf;
+ bundle_raw *b_raw = NULL;
+ int len = 0;
+ GList *iter;
+ bundle *b;
+ int r;
+
+ b = __create_bundle(widget);
+ if (b == NULL) {
+ LOGE("Failed to create bundle");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ return -1;
+ }
+
+ iter = widget->instances;
+ while (iter) {
+ instance_id = (const char *)iter->data;
+ surf = 0;
+ amd_noti_send(AMD_NOTI_MSG_WIDGET_RUNNING_INFO_SEND,
+ GPOINTER_TO_INT(&surf), (int)widget->uid,
+ (void *)instance_id, NULL);
+ snprintf(buf, sizeof(buf), "%u", surf);
+ bundle_del(b, AUL_K_WID);
+ bundle_add_str(b, AUL_K_WID, buf);
+ bundle_del(b, AUL_K_WIDGET_INSTANCE_ID);
+ bundle_add_str(b, AUL_K_WIDGET_INSTANCE_ID, instance_id);
+
+ bundle_encode(b, &b_raw, &len);
+ if (b_raw == NULL) {
+ LOGE("Failed to encode bundle");
+ aul_sock_send_raw_with_fd(fd, APP_GET_INFO_ERROR,
+ NULL, 0, AUL_SOCK_NOREPLY);
+ bundle_free(b);
+ return -1;
+ }
+
+ r = aul_sock_send_raw_with_fd(fd, APP_GET_INFO_OK,
+ (unsigned char *)b_raw, len,
+ AUL_SOCK_ASYNC | AUL_SOCK_BUNDLE);
+ if (r < 0) {
+ LOGE("Failed to send raw data: %d", r);
+ free(b_raw);
+ bundle_free(b);
+ return -1;
+ }
+ free(b_raw);
+ b_raw = NULL;
+
+ iter = g_list_next(iter);
+ }
+ free(b_raw);
+ bundle_free(b);
+
+ return 0;
+}
+
+static int __dispatch_widget_running_info(amd_request_h req)
+{
+ uid_t target_uid = amd_request_get_target_uid(req);
+ int fd = amd_request_remove_fd(req);
+ widget_t *widget;
+ GList *iter;
+ int count = 0;
+ int r;
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ if (widget && widget->uid == target_uid)
+ count += g_list_length(widget->instances);
+
+ iter = g_list_next(iter);
+ }
+
+ if (count == 0) {
+ LOGE("Widget doesn't exist");
+ amd_socket_send_result(fd, -1, true);
+ return -1;
+ }
+ amd_socket_send_result(fd, count, false);
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ if (widget && widget->uid == target_uid) {
+ r = __send_running_info(widget, fd);
+ if (r < 0)
+ break;
+ }
+ iter = g_list_next(iter);
+ }
+ close(fd);
+
+ return 0;
+}
+
+static int __app_term_by_pid_async_checker(amd_cynara_caller_info_h info,
+ amd_request_h req, void *data)
+{
+ int pid;
+ char *term_pid;
+ bundle *kb;
+ amd_app_status_h status;
+ amd_appinfo_h ai;
+ const char *comp_type;
+
+ kb = amd_request_get_bundle(req);
+ if (kb == NULL) {
+ LOGE("Failed to get bundle");
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_APPID, &term_pid);
+ if (term_pid == NULL) {
+ LOGE("Failed to get process id");
+ return -1;
+ }
+
+ pid = atoi(term_pid);
+ status = amd_app_status_find_by_pid(pid);
+ if (!status) {
+ LOGE("Failed to find app status. pid(%d)", pid);
+ return -1;
+ }
+
+ ai = amd_appinfo_find(amd_request_get_target_uid(req),
+ amd_app_status_get_appid(status));
+ if (!ai) {
+ LOGE("Failed to find appinfo");
+ return -1;
+ }
+
+ comp_type = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (!comp_type)
+ return -1;
+
+ if (strcmp(comp_type, APP_TYPE_WIDGET) == 0) {
+ return amd_cynara_simple_checker(info, req,
+ PRIVILEGE_WIDGET_VIEWER);
+ }
+
+ return amd_cynara_simple_checker(info, req, data);
+}
+
+static int __dispatch_widget_disable(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ char *widget_id = NULL;
+ char *ambient = NULL;
+ int ret;
+ int sender_pid = amd_request_get_pid(req);
+ uid_t sender_uid = amd_request_get_uid(req);
+
+ if (__validate_widget_caller(req) < 0) {
+ LOGE("widget dispatch validate error");
+ amd_request_send_result(req, -EILLEGALACCESS);
+ return -1;
+ }
+
+ bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
+ bundle_get_str(kb, AUL_K_WIDGET_DISABLE, &ambient);
+
+ ret = aul_widget_service_set_disable_db(widget_id, (bool)atoi(ambient));
+ if (ret) {
+ LOGE("widget set disable db error");
+ amd_request_send_result(req, ret);
+ return -1;
+ }
+
+ ret = amd_app_com_send(DISABLE_ENDPOINT, getpgid(sender_pid), kb, sender_uid);
+ if (ret < 0) {
+ _E("send disable error:%d", ret);
+ amd_request_send_result(req, -ECOMM);
+ return -1;
+ }
+ amd_request_send_result(req, 0);
+
+ return 0;
+}
+
+static int __dispatch_widget_event(amd_request_h req)
+{
+ bundle *kb = amd_request_get_bundle(req);
+ uid_t target_uid = amd_request_get_target_uid(req);
+ int ret;
+
+ if (!kb) {
+ _E("Invalid request");
+ return -EINVAL;
+ }
+
+ ret = amd_app_com_send("widget.event", getpid(), kb, target_uid);
+
+ _W("[__WIDGET_EVENT__] caller(%d), result(%d)",
+ amd_request_get_pid(req), ret);
+ return ret;
+}
+
+static amd_request_cmd_dispatch __dispatch_table[] = {
+ {
+ .cmd = WIDGET_ADD,
+ .callback = __dispatch_widget_add_del
+ },
+ {
+ .cmd = WIDGET_DEL,
+ .callback = __dispatch_widget_add_del
+ },
+ {
+ .cmd = WIDGET_LIST,
+ .callback = __dispatch_widget_list
+ },
+ {
+ .cmd = WIDGET_UPDATE,
+ .callback = __dispatch_widget_update
+ },
+ {
+ .cmd = WIDGET_COUNT,
+ .callback = __dispatch_widget_count
+ },
+ {
+ .cmd = WIDGET_GET_CONTENT,
+ .callback = __dispatch_widget_get_content
+ },
+ {
+ .cmd = WIDGET_RUNNING_INFO,
+ .callback = __dispatch_widget_running_info
+ },
+ {
+ .cmd = WIDGET_CHANGE_STATUS,
+ .callback = __dispatch_widget_change_status
+ },
+ {
+ .cmd = WIDGET_DISABLE,
+ .callback = __dispatch_widget_disable
+ },
+ {
+ .cmd = WIDGET_EVENT,
+ .callback = __dispatch_widget_event
+ },
+};
+
+static amd_cynara_checker __cynara_checkers[] = {
+ {
+ .cmd = APP_TERM_BY_PID_ASYNC,
+ .checker = __app_term_by_pid_async_checker,
+ .data = PRIVILEGE_APPMANAGER_KILL,
+ .priority = 10
+ },
+ {
+ .cmd = WIDGET_RUNNING_INFO,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+ {
+ .cmd = WIDGET_DISABLE,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PACKAGEMANAGER_ADMIN,
+ .priority = 10
+ },
+ {
+ .cmd = WIDGET_EVENT,
+ .checker = amd_cynara_simple_checker,
+ .data = PRIVILEGE_PLATFORM,
+ .priority = 10
+ },
+};
+
+static void __destroy_restart_widget_info(gpointer data)
+{
+ struct restart_widget_info *info = (struct restart_widget_info *)data;
+
+ if (info == NULL)
+ return;
+
+ if (info->timer > 0)
+ g_source_remove(info->timer);
+ if (info->widget_list)
+ g_list_free_full(info->widget_list, free);
+ if (info->pkgid)
+ free(info->pkgid);
+ if (info->appid)
+ free(info->appid);
+ free(info);
+}
+
+static struct restart_widget_info *__create_restart_widget_info(
+ amd_app_status_h app_status)
+{
+ struct restart_widget_info *info;
+ const char *appid = amd_app_status_get_appid(app_status);
+ const char *pkgid = amd_app_status_get_pkgid(app_status);
+ widget_t *widget;
+ char *widget_id;
+ GList *iter;
+
+ info = calloc(1, sizeof(struct restart_widget_info));
+ if (info == NULL) {
+ LOGE("Out of memory");
+ return NULL;
+ }
+
+ info->appid = strdup(appid);
+ if (info->appid == NULL) {
+ LOGE("Out of memory");
+ free(info);
+ return NULL;
+ }
+
+ info->pkgid = strdup(pkgid);
+ if (info->pkgid == NULL) {
+ LOGE("Out of memory");
+ free(info->appid);
+ free(info);
+ return NULL;
+ }
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ iter = g_list_next(iter);
+
+ widget_id = strdup(widget->widget_id);
+ if (widget_id == NULL) {
+ LOGE("Out of memory");
+ __destroy_restart_widget_info(info);
+ return NULL;
+ }
+
+ info->widget_list = g_list_append(info->widget_list, widget_id);
+ }
+
+ info->is_faulted = !amd_app_status_is_exiting(app_status);
+ info->pid = amd_app_status_get_pid(app_status);
+ info->uid = amd_app_status_get_uid(app_status);
+ info->viewer_pid = amd_app_status_get_first_caller_pid(app_status);
+ info->count = 1;
+
+ return info;
+}
+
+static struct restart_widget_info *__find_restart_widget_info(const char *appid,
+ uid_t uid)
+{
+ struct restart_widget_info *info;
+ GList *iter;
+
+ iter = __restart_widgets;
+ while (iter) {
+ info = (struct restart_widget_info *)iter->data;
+ if (!strcmp(info->appid, appid) && info->uid == uid)
+ return info;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static gboolean __restart_timeout_handler(void *data)
+{
+ struct restart_widget_info *info = (struct restart_widget_info *)data;
+
+ LOGW("appid (%s)", info->appid);
+ __restart_widgets = g_list_remove(__restart_widgets, info);
+ /* timer source will be removed after returing this callback */
+ info->timer = 0;
+ __destroy_restart_widget_info(info);
+
+ return G_SOURCE_REMOVE;
+}
+
+static bool __check_restart(amd_app_status_h app_status)
+{
+ struct restart_widget_info *info;
+ const char *appid = amd_app_status_get_appid(app_status);;
+ uid_t uid = amd_app_status_get_uid(app_status);
+
+ info = __find_restart_widget_info(appid, uid);
+ if (info == NULL) {
+ info = __create_restart_widget_info(app_status);
+ if (info == NULL)
+ return false;
+
+ __restart_widgets = g_list_append(__restart_widgets, info);
+ info->timer = g_timeout_add(10 * 1000,
+ __restart_timeout_handler, info);
+ } else {
+ info->count++;
+ if (info->count > 5) {
+ LOGW("Failed to recover the widget(%s:%u)",
+ info->appid, info->uid);
+ __restart_widgets = g_list_remove(__restart_widgets,
+ info);
+ __destroy_restart_widget_info(info);
+ return false;
+ }
+
+ if (info->timer > 0) {
+ g_source_remove(info->timer);
+ info->timer = g_timeout_add(10 * 1000,
+ __restart_timeout_handler, info);
+ }
+ }
+
+ LOGD("appid(%s), uid(%u), count(%d)", appid, uid, info->count);
+
+ return true;
+}
+
+static void __widget_send_dead_signal(pid_t pid, uid_t uid, const char *pkgid,
+ bool is_faulted)
+{
+ widget_t *widget;
+ GList *iter;
+ struct widget_status_info info = {
+ .endpoint = "widget.status",
+ .widget_id = NULL,
+ .instance_id = NULL,
+ .pkg_id = pkgid,
+ .is_fault = is_faulted ? "true" : "false",
+ .status = AUL_WIDGET_LIFE_CYCLE_EVENT_APP_DEAD,
+ .pid = pid,
+ .uid = uid
+ };
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ if (widget->pid == pid && widget->uid == uid) {
+ info.widget_id = widget->widget_id;
+ __send_status_info(&info);
+ }
+ iter = g_list_next(iter);
+ }
+}
+
+static void __widget_send_restart_signal(pid_t pid, uid_t uid, pid_t viewer_pid,
+ const char *pkgid, bool is_faulted)
+{
+ widget_t *widget;
+ GList *iter;
+ amd_app_status_h app_status;
+ struct widget_status_info info;
+
+ app_status = amd_app_status_find_by_pid(viewer_pid);
+ if (app_status == NULL)
+ return;
+
+ info.endpoint = amd_app_status_get_appid(app_status);
+ info.widget_id = NULL;
+ info.instance_id = NULL;
+ info.pkg_id = pkgid;
+ info.is_fault = is_faulted ? "true" : "false";
+ info.status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST;
+ info.pid = pid;
+ info.uid = uid;
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ if (widget->pid == pid && widget->uid == uid) {
+ info.widget_id = widget->widget_id;
+ __send_status_info(&info);
+ }
+ iter = g_list_next(iter);
+ }
+}
+
+static widget_t *__find_pending_restart_widget(const char *widget_id, pid_t pid,
+ uid_t uid, GList *pending_list)
+{
+ widget_t *widget;
+ GList *iter;
+
+ iter = pending_list;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ if (!strcmp(widget->widget_id, widget_id) &&
+ widget->uid == uid &&
+ widget->pid == pid)
+ return widget;
+
+ iter = g_list_next(iter);
+ }
+
+ return NULL;
+}
+
+static int __add_pending_restart_info(pid_t pid, uid_t uid,
+ const char *pkgid, GList **pending_list)
+{
+ widget_t *widget;
+ widget_t *pending_info;
+ GList *iter;
+
+ iter = __widgets;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ iter = g_list_next(iter);
+
+ pending_info = __find_pending_restart_widget(widget->widget_id,
+ pid, widget->uid, *pending_list);
+ if (pending_info == NULL && widget->pid == pid) {
+ pending_info = __create_widget(widget->widget_id,
+ pkgid, widget->pid, widget->uid);
+ if (pending_info == NULL)
+ return -1;
+ *pending_list = g_list_append(*pending_list,
+ pending_info);
+ LOGW("adding pending restart info: %s, %d, %d",
+ widget->widget_id, widget->pid,
+ widget->uid);
+ }
+ }
+
+ return 0;
+}
+
+static void __flush_pending_restart_list(const char *pkgid, uid_t uid,
+ GList **pending_list)
+{
+ widget_t *widget;
+ GList *iter;
+ struct widget_status_info info = {
+ .endpoint = "widget.status",
+ .widget_id = NULL,
+ .instance_id = NULL,
+ .pkg_id = NULL,
+ .is_fault = "true",
+ .status = AUL_WIDGET_LIFE_CYCLE_EVENT_APP_DEAD,
+ .pid = -1,
+ .uid = 0
+ };
+
+ if (pending_list == NULL || *pending_list == NULL)
+ return;
+
+ iter = *pending_list;
+ while (iter) {
+ widget = (widget_t *)iter->data;
+ iter = g_list_next(iter);
+ if ((uid < REGULAR_UID_MIN || uid == widget->uid) &&
+ (pkgid == NULL ||
+ !strcmp(widget->pkg_id, pkgid))) {
+ *pending_list = g_list_remove(*pending_list, widget);
+ info.widget_id = widget->widget_id;
+ info.pkg_id = widget->pkg_id;
+ info.pid = widget->pid;
+ info.uid = widget->uid;
+ LOGW("sending pending restart status: %s, %d, %d",
+ info.widget_id, info.pid, info.uid);
+ __send_status_info(&info);
+ __free_widget(widget);
+ }
+ }
+}
+
+static void __widget_flush_oom_restart_list(void)
+{
+ __flush_pending_restart_list(NULL, 0, &__oom_restart_widgets);
+}
+
+static void __widget_flush_update_list(const char *pkgid, uid_t uid)
+{
+ __flush_pending_restart_list(pkgid, uid, &__update_widgets);
+}
+
+static int __on_app_dead(const char *msg, int arg1, int arg2, void *arg3,
+ bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+ int pid = arg1;
+ uid_t uid = arg2;
+ widget_t *info;
+ pid_t viewer_pid = amd_app_status_get_first_caller_pid(app_status);
+ bool is_faulted = !amd_app_status_is_exiting(app_status);
+ const char *appid = amd_app_status_get_appid(app_status);
+ const char *pkgid = amd_app_status_get_pkgid(app_status);
+ bool can_restart;
+ bool is_widget;
+ int r;
+
+ is_widget = __widget_exist(pid, uid);
+ if (!is_widget)
+ return 0;
+
+ can_restart = __check_restart(app_status);
+ if (!can_restart || !is_faulted) {
+ __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
+ return 0;
+ }
+
+ /*
+ * Screen info should be removed before send dead signal
+ * If not, _app_status_cleanup will send
+ * AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE
+ * event to the viewer and recreated instance with same
+ * instance id info will be removed by
+ * AUL_SCREEN_CONNECTOR_EVENT_TYPE_REMOVE event.
+ */
+ amd_noti_send(AMD_NOTI_MSG_WIDGET_ON_APP_DEAD_RESTART,
+ pid, (int)uid, NULL, NULL);
+ if (amd_util_check_oom()) {
+ info = __find_pending_restart_widget(appid, pid, uid,
+ __oom_restart_widgets);
+ if (info)
+ return 0;
+
+ r = __add_pending_restart_info(pid, uid, pkgid,
+ &__oom_restart_widgets);
+ if (r == 0) {
+ LOGW("%s:%d is added on pending list", appid, pid);
+ __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
+ return 0;
+ }
+ } else if (amd_appinfo_is_pkg_updating(pkgid)) {
+ LOGW("%s:%d is updating", appid, pid);
+ /*
+ * If widget package is in update process
+ * widget dead signal will be sent after
+ * update process is completed so that
+ * viewer can restart widget at that time.
+ */
+ __widget_send_restart_signal(pid, uid, viewer_pid, pkgid,
+ is_faulted);
+
+ r = __add_pending_restart_info(pid, uid, pkgid,
+ &__update_widgets);
+ if (r == 0)
+ return 0;
+
+ __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
+ return 0;
+ }
+
+ __widget_send_restart_signal(pid, uid, viewer_pid, pkgid,
+ is_faulted);
+ __widget_send_dead_signal(pid, uid, pkgid, is_faulted);
+ LOGW("Sent widget(%s:%d) dead signal", appid, pid);
+
+ return 0;
+}
+
+static int __on_app_status_destroy(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_app_status_h app_status = arg3;
+
+ if (amd_app_status_get_app_type(app_status) == AMD_AT_WIDGET_APP) {
+ __widget_cleanup(amd_app_status_get_pid(app_status),
+ amd_app_status_get_uid(app_status),
+ amd_app_status_get_first_caller_pid(app_status));
+ } else {
+ LOGW("cleanup viewer start");
+ __viewer_widget_cleanup(amd_app_status_get_pid(app_status),
+ amd_app_status_get_uid(app_status));
+ }
+
+ return 0;
+}
+
+static int __on_launching_widget(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ amd_request_h req = arg3;
+
+ if (__widget_verify_cmd(req) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int __on_package_update_end(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ const char *pkgid = (const char *)arg3;
+
+ __widget_flush_update_list(pkgid, uid);
+
+ return 0;
+}
+
+static int __on_low_memory_normal(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ __widget_flush_oom_restart_list();
+
+ return 0;
+}
+
+static void __widget_verify_instance(bundle *kb, int pid, uid_t uid)
+{
+ const char *operation;
+ const char *instance_id;
+ const char *widget_id;
+ widget_t *widget;
+ struct widget_status_info info;
+
+ if (kb == NULL)
+ return;
+
+ operation = bundle_get_val(kb, AUL_K_WIDGET_OPERATION);
+ if (operation == NULL)
+ return;
+
+ if (strcmp(operation, "create") != 0)
+ return;
+
+ widget_id = bundle_get_val(kb, AUL_K_WIDGET_ID);
+ if (widget_id == NULL)
+ return;
+
+ instance_id = bundle_get_val(kb, AUL_K_WIDGET_INSTANCE_ID);
+ if (instance_id == NULL)
+ return;
+
+ widget = __find_instance(widget_id, instance_id);
+ if (widget)
+ return;
+
+ info.endpoint = bundle_get_val(kb, AUL_K_WIDGET_VIEWER);
+ if (info.endpoint == NULL)
+ return;
+
+ info.widget_id = widget_id;
+ info.instance_id = instance_id;
+ info.pkg_id = NULL;
+ info.is_fault = NULL;
+ info.status = AUL_WIDGET_INSTANCE_EVENT_CREATE_ABORTED;
+ info.pid = pid;
+ info.uid = uid;
+
+ LOGW("Send create aborted event %s:%s:%s",
+ info.endpoint, info.widget_id, info.instance_id);
+ __send_status_info(&info);
+}
+
+static int __on_launch_recv_timeout(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = (uid_t)arg2;
+
+ __widget_verify_instance(data, pid, uid);
+
+ return 0;
+}
+
+static int __on_launch_complete_start(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = (int)arg1;
+ amd_appinfo_h ai = (amd_appinfo_h)arg3;
+ const char *comptype;
+ const char *val;
+ uid_t uid;
+
+ comptype = amd_appinfo_get_value(ai, AMD_AIT_COMPTYPE);
+ if (comptype && !strcmp(comptype, APP_TYPE_WIDGET)) {
+ val = bundle_get_val(data, AUL_K_TARGET_UID);
+ if (!val || !isdigit(*val))
+ return 0;
+
+ uid = strtoul(val, NULL, 10);
+ __widget_pre_add(data, pid, uid);
+ }
+
+
+ return 0;
+}
+
+static int __on_launch_recv_error(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ int pid = arg1;
+ uid_t uid = (uid_t)arg2;
+
+ __widget_verify_instance(data, pid, uid);
+
+ return 0;
+}
+
+static int __on_package_update_error(const char *msg, int arg1, int arg2,
+ void *arg3, bundle *data)
+{
+ uid_t uid = (uid_t)arg1;
+ const char *pkgid = (const char *)arg3;
+
+ __widget_flush_update_list(pkgid, uid);
+
+ return 0;
+}
+
+static void __check_disabled_appinfo(const char *appid, uid_t uid)
+{
+ pkgmgrinfo_appinfo_h handle = NULL;
+ int ret;
+
+ ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(appid, uid, &handle);
+ if (ret != PMINFO_R_OK) {
+ LOGE("Failed to get disabled appinfo. appid(%s), uid(%u)",
+ appid, uid);
+ return;
+ }
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+
+ LOGW("[__WIDGET__] widget(%s) is disabled", appid);
+}
+
+static int __widget_viewer_checker(amd_cynara_caller_info_h info, amd_request_h req)
+{
+ char *appid = NULL;
+ const char *apptype;
+ amd_appinfo_h appinfo;
+ bundle *appcontrol = amd_request_get_bundle(req);
+ uid_t target_uid = amd_request_get_target_uid(req);
+
+ if (!appcontrol) {
+ LOGE("wrong argument");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ bundle_get_str(appcontrol, AUL_K_APPID, &appid);
+ if (!appid) {
+ LOGE("can not resolve appid. request denied.");
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ appinfo = amd_appinfo_find(target_uid, appid);
+ if (!appinfo) {
+ LOGE("can not resolve appinfo of %s. request denied.", appid);
+ __check_disabled_appinfo(appid, target_uid);
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ apptype = amd_appinfo_get_value(appinfo, AMD_AIT_COMPTYPE);
+ if (!apptype) {
+ LOGE("can not resolve apptype of %s. request denied.", appid);
+ return AMD_CYNARA_RET_ERROR;
+ }
+
+ if (!strcmp(apptype, APP_TYPE_WIDGET) ||
+ !strcmp(apptype, APP_TYPE_WATCH))
+ return amd_cynara_simple_checker(info, req, PRIVILEGE_WIDGET_VIEWER);
+
+ LOGE("illegal app type of request: %s - " \
+ "only widget or watch apps are allowed", apptype);
+
+ return AMD_CYNARA_RET_ERROR;
+}
+
+static int __appcontrol_sub_checker(amd_cynara_caller_info_h info, amd_request_h req)
+{
+ bundle *appcontrol;
+ char *op = NULL;
+ int ret;
+
+ appcontrol = amd_request_get_bundle(req);
+ if (!appcontrol)
+ return AMD_CYNARA_RET_CONTINUE;
+
+ ret = bundle_get_str(appcontrol, AUL_SVC_K_OPERATION, &op);
+ if (ret != BUNDLE_ERROR_NONE)
+ return AMD_CYNARA_RET_CONTINUE;
+
+ if (!op || strcmp(op, AUL_SVC_OPERATION_LAUNCH_WIDGET))
+ return AMD_CYNARA_RET_CONTINUE;
+
+ return __widget_viewer_checker(info, req);
+}
+
+EXPORT int AMD_MOD_INIT(void)
+{
+ int r;
+
+ LOGD("widget init");
+ _widget_logger_init();
+ r = amd_request_register_cmds(__dispatch_table,
+ ARRAY_SIZE(__dispatch_table));
+ if (r < 0) {
+ LOGE("Failed to register cmds");
+ return -1;
+ }
+
+ r = amd_cynara_register_checkers(__cynara_checkers,
+ ARRAY_SIZE(__cynara_checkers));
+ if (r < 0) {
+ LOGE("Failed to register checkers");
+ return -1;
+ }
+
+ amd_noti_listen(AMD_NOTI_MSG_MAIN_APP_DEAD,
+ __on_app_dead);
+ amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_DESTROY,
+ __on_app_status_destroy);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_PREPARE_WIDGET,
+ __on_launching_widget);
+ amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_END,
+ __on_package_update_end);
+ amd_noti_listen(AMD_NOTI_MSG_UTIL_LOW_MEMORY_NORMAL,
+ __on_low_memory_normal);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_RECV_TIMEOUT,
+ __on_launch_recv_timeout);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_COMPLETE_START,
+ __on_launch_complete_start);
+ amd_noti_listen(AMD_NOTI_MSG_LAUNCH_RECV_ERROR,
+ __on_launch_recv_error);
+ amd_noti_listen(AMD_NOTI_MSG_APPINFO_PACKAGE_UPDATE_ERROR,
+ __on_package_update_error);
+
+ amd_cynara_sub_checker_add("appcontrol", __appcontrol_sub_checker);
+
+ return 0;
+}
+
+EXPORT void AMD_MOD_FINI(void)
+{
+ LOGD("widget fini");
+
+ if (__restart_widgets) {
+ g_list_free_full(__restart_widgets,
+ __destroy_restart_widget_info);
+ }
+
+ if (__update_widgets)
+ g_list_free_full(__update_widgets, __free_widget);
+
+ if (__widgets)
+ g_list_free_full(__widgets, __free_widget);
+
+ _widget_logger_fini();
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <amd.h>
+
+#include "amd_widget_logger.h"
+#include "amd_widget_private.h"
+
+#define LOG_FILE "amd_widget.log"
+#define LOG_PATH LOGGER_PATH "/" LOG_FILE
+#define LOG_MAX_STRING_SIZE 256
+
+static amd_logger_h __logger;
+
+int _widget_logger_print(const char *tag, const char *format, ...)
+{
+ char format_buf[LOG_MAX_STRING_SIZE];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(format_buf, sizeof(format_buf), format, ap);
+ va_end(ap);
+
+ return amd_logger_print(__logger, tag, format_buf);
+}
+
+int _widget_logger_init(void)
+{
+ int ret;
+
+ _D("widget logger init");
+ ret = amd_logger_create(LOG_PATH, &__logger);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void _widget_logger_fini(void)
+{
+ _D("widget logger fini");
+ amd_logger_destroy(__logger);
+}