/* * Copyright 2020 Samsung Electronics Co., Ltd * * Licensed under the Flora License, Version 1.1 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://floralicense.org/license/ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT 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 "application_manager_aul.h" #include "service_common.h" #include #include #include #include CApplicationManagerAul::CApplicationManagerAul() { } CApplicationManagerAul::~CApplicationManagerAul() { } static void print_duration(std::string func, std::chrono::time_point started) { const std::chrono::milliseconds threshold(100); auto finished = std::chrono::steady_clock::now(); auto interval = finished - started; if (interval > threshold) { long long int count = static_cast( std::chrono::duration_cast(interval).count()); MAS_LOGE("%s %lld", func.c_str(), count); } } bool CApplicationManagerAul::is_application_running(pid_t pid) { auto started = std::chrono::steady_clock::now(); int status = aul_app_get_status_bypid(pid); if (0 > status) { MAS_LOGE("The process %d does not exist : %d", pid, status); print_duration(__func__, started); return false; } print_duration(__func__, started); return true; } bool CApplicationManagerAul::is_application_running(const std::string& appid) { auto started = std::chrono::steady_clock::now(); bool ret = (!!aul_app_is_running(appid.c_str())); print_duration(__func__, started); return ret; } bool CApplicationManagerAul::bring_app_to_foreground(const std::string& appid) { bool ret = true; /* Bring MA client to foreground - is there a better way other than launching? */ bundle *b = NULL; b = bundle_create(); if (NULL == b) { MAS_LOGE("Failed creating bundle for aul operation"); return -1; } int result = aul_launch_app_async(appid.c_str(), b); if (result < AUL_R_OK) { MAS_LOGE("ERROR : aul_launch_app_async failed. app_id [%s] bundle[%p] result[%d : %s]", appid.c_str(), b, result, get_error_message(result)); ret = false; } if (b) bundle_free(b); b = NULL; return ret; } bool CApplicationManagerAul::launch_app_async(const std::string& appid, bool background) { bool ret = true; bundle *b = NULL; b = bundle_create(); if (NULL == b) { MAS_LOGE("Failed creating bundle for aul operation"); return false; } int result = aul_svc_set_background_launch(b, background); if (result < AUL_R_OK) { MAS_LOGE("ERROR : aul_svc_set_background_launch failed. app_id [%s] bundle[%p] result[%d : %s]", appid.c_str(), b, result, get_error_message(result)); } result = aul_launch_app_async(appid.c_str(), b); if (result < AUL_R_OK) { MAS_LOGE("ERROR : aul_launch_app_async failed. app_id [%s] bundle[%p] result[%d : %s]", appid.c_str(), b, result, get_error_message(result)); ret = false; } if (b) bundle_free(b); b = NULL; return ret; } boost::optional CApplicationManagerAul::get_appid_by_pid(pid_t pid) { const int max_retry_num = 3; boost::optional ret; bool succeeded = false; int retry_num = 0; char appid[MAX_APPID_LEN] = {'\0', }; typedef struct { std::string appid; std::chrono::time_point updated; } AppInfo; static std::map appids; if (appids.find(pid) != appids.end()) { auto info = appids[pid]; auto now = std::chrono::steady_clock::now(); if (now - info.updated < std::chrono::seconds(60)) { ret = info.appid; } } if (!ret) { do { if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) { appid[MAX_APPID_LEN - 1] = '\0'; ret = std::string{appid}; succeeded = true; appids[pid] = AppInfo{*ret, std::chrono::steady_clock::now()}; } retry_num++; } while (!succeeded && retry_num < max_retry_num); } return ret; } boost::optional CApplicationManagerAul::get_pid_by_appid(const std::string& appid) { boost::optional ret; typedef struct { pid_t pid; std::chrono::time_point updated; } AppInfo; static std::map pids; if (pids.find(appid) != pids.end()) { auto info = pids[appid]; auto now = std::chrono::steady_clock::now(); if (now - info.updated < std::chrono::seconds(10)) { ret = info.pid; } } if (!ret) { pid_t pid = aul_app_get_pid(appid.c_str()); if (pid >= 0) { ret = pid; pids[appid] = AppInfo{pid, std::chrono::steady_clock::now()}; } } return ret; }