169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include "appspawn_message.h" 1769570cc8Sopenharmony_ci#include "appspawn_server.h" 1869570cc8Sopenharmony_ci#include <errno.h> 1969570cc8Sopenharmony_ci#include <time.h> 2069570cc8Sopenharmony_ci 2169570cc8Sopenharmony_ci#include "iproxy_server.h" 2269570cc8Sopenharmony_ci#include "iunknown.h" 2369570cc8Sopenharmony_ci#include "ipc_skeleton.h" 2469570cc8Sopenharmony_ci#include "message.h" 2569570cc8Sopenharmony_ci#include "ohos_errno.h" 2669570cc8Sopenharmony_ci#include "ohos_init.h" 2769570cc8Sopenharmony_ci#include "samgr_lite.h" 2869570cc8Sopenharmony_ci#include "service.h" 2969570cc8Sopenharmony_ci#include "securec.h" 3069570cc8Sopenharmony_ci 3169570cc8Sopenharmony_cistatic const int INVALID_PID = -1; 3269570cc8Sopenharmony_cistatic const int CLIENT_ID = 100; 3369570cc8Sopenharmony_ci 3469570cc8Sopenharmony_ci#ifdef OHOS_DEBUG 3569570cc8Sopenharmony_ciuint64_t DiffTime(const struct timespec *startTime, const struct timespec *endTime) 3669570cc8Sopenharmony_ci{ 3769570cc8Sopenharmony_ci uint64_t diff = (uint64_t)((endTime->tv_sec - startTime->tv_sec) * 1000000); // 1000000 s-us 3869570cc8Sopenharmony_ci if (endTime->tv_nsec > startTime->tv_nsec) { 3969570cc8Sopenharmony_ci diff += (endTime->tv_nsec - startTime->tv_nsec) / 1000; // 1000 ns - us 4069570cc8Sopenharmony_ci } else { 4169570cc8Sopenharmony_ci diff -= (startTime->tv_nsec - endTime->tv_nsec) / 1000; // 1000 ns - us 4269570cc8Sopenharmony_ci } 4369570cc8Sopenharmony_ci return diff; 4469570cc8Sopenharmony_ci} 4569570cc8Sopenharmony_ci#endif 4669570cc8Sopenharmony_ci 4769570cc8Sopenharmony_citypedef struct AppSpawnFeatureApi { 4869570cc8Sopenharmony_ci INHERIT_SERVER_IPROXY; 4969570cc8Sopenharmony_ci} AppSpawnFeatureApi; 5069570cc8Sopenharmony_ci 5169570cc8Sopenharmony_citypedef struct AppSpawnService { 5269570cc8Sopenharmony_ci INHERIT_SERVICE; 5369570cc8Sopenharmony_ci INHERIT_IUNKNOWNENTRY(AppSpawnFeatureApi); 5469570cc8Sopenharmony_ci Identity identity; 5569570cc8Sopenharmony_ci} AppSpawnService; 5669570cc8Sopenharmony_ci 5769570cc8Sopenharmony_cistatic const char *GetName(Service *service) 5869570cc8Sopenharmony_ci{ 5969570cc8Sopenharmony_ci UNUSED(service); 6069570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] get service name %s.", APPSPAWN_SERVICE_NAME); 6169570cc8Sopenharmony_ci return APPSPAWN_SERVICE_NAME; 6269570cc8Sopenharmony_ci} 6369570cc8Sopenharmony_ci 6469570cc8Sopenharmony_cistatic BOOL Initialize(Service *service, Identity identity) 6569570cc8Sopenharmony_ci{ 6669570cc8Sopenharmony_ci if (service == NULL) { 6769570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] initialize, service NULL!"); 6869570cc8Sopenharmony_ci return FALSE; 6969570cc8Sopenharmony_ci } 7069570cc8Sopenharmony_ci 7169570cc8Sopenharmony_ci AppSpawnService *spawnService = (AppSpawnService *)service; 7269570cc8Sopenharmony_ci spawnService->identity = identity; 7369570cc8Sopenharmony_ci 7469570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] initialize, identity<%d, %d>", \ 7569570cc8Sopenharmony_ci identity.serviceId, identity.featureId); 7669570cc8Sopenharmony_ci return TRUE; 7769570cc8Sopenharmony_ci} 7869570cc8Sopenharmony_ci 7969570cc8Sopenharmony_cistatic BOOL MessageHandle(Service *service, Request *msg) 8069570cc8Sopenharmony_ci{ 8169570cc8Sopenharmony_ci UNUSED(service); 8269570cc8Sopenharmony_ci UNUSED(msg); 8369570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] message handle not support yet!"); 8469570cc8Sopenharmony_ci return FALSE; 8569570cc8Sopenharmony_ci} 8669570cc8Sopenharmony_ci 8769570cc8Sopenharmony_cistatic TaskConfig GetTaskConfig(Service *service) 8869570cc8Sopenharmony_ci{ 8969570cc8Sopenharmony_ci UNUSED(service); 9069570cc8Sopenharmony_ci TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK}; 9169570cc8Sopenharmony_ci return config; 9269570cc8Sopenharmony_ci} 9369570cc8Sopenharmony_ci 9469570cc8Sopenharmony_cistatic int GetMessageSt(MessageSt *msgSt, IpcIo *req) 9569570cc8Sopenharmony_ci{ 9669570cc8Sopenharmony_ci if (msgSt == NULL || req == NULL) { 9769570cc8Sopenharmony_ci return EC_FAILURE; 9869570cc8Sopenharmony_ci } 9969570cc8Sopenharmony_ci 10069570cc8Sopenharmony_ci size_t len = 0; 10169570cc8Sopenharmony_ci char* str = ReadString(req, &len); 10269570cc8Sopenharmony_ci if (str == NULL || len == 0) { 10369570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] invoke, get data failed."); 10469570cc8Sopenharmony_ci return EC_FAILURE; 10569570cc8Sopenharmony_ci } 10669570cc8Sopenharmony_ci 10769570cc8Sopenharmony_ci int ret = SplitMessage(str, len, msgSt); // after split message, str no need to free(linux version) 10869570cc8Sopenharmony_ci return ret; 10969570cc8Sopenharmony_ci} 11069570cc8Sopenharmony_ci 11169570cc8Sopenharmony_cistatic AppSpawnContentLite *g_appSpawnContentLite = NULL; 11269570cc8Sopenharmony_ciAppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcName, uint32_t longProcNameLen, int cold) 11369570cc8Sopenharmony_ci{ 11469570cc8Sopenharmony_ci UNUSED(longProcName); 11569570cc8Sopenharmony_ci UNUSED(longProcNameLen); 11669570cc8Sopenharmony_ci APPSPAWN_LOGI("AppSpawnCreateContent %s", socketName); 11769570cc8Sopenharmony_ci AppSpawnContentLite *appSpawnContent = (AppSpawnContentLite *)malloc(sizeof(AppSpawnContentLite)); 11869570cc8Sopenharmony_ci APPSPAWN_CHECK(appSpawnContent != NULL, return NULL, "Failed to alloc memory for appspawn"); 11969570cc8Sopenharmony_ci int ret = memset_s(appSpawnContent, sizeof(AppSpawnContentLite), 0, sizeof(AppSpawnContentLite)); 12069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(appSpawnContent); 12169570cc8Sopenharmony_ci return NULL, "Failed to memset content"); 12269570cc8Sopenharmony_ci appSpawnContent->content.longProcName = NULL; 12369570cc8Sopenharmony_ci appSpawnContent->content.longProcNameLen = 0; 12469570cc8Sopenharmony_ci g_appSpawnContentLite = appSpawnContent; 12569570cc8Sopenharmony_ci return appSpawnContent; 12669570cc8Sopenharmony_ci} 12769570cc8Sopenharmony_ci 12869570cc8Sopenharmony_cistatic int Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) 12969570cc8Sopenharmony_ci{ 13069570cc8Sopenharmony_ci#ifdef OHOS_DEBUG 13169570cc8Sopenharmony_ci struct timespec tmStart = {0}; 13269570cc8Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &tmStart); 13369570cc8Sopenharmony_ci#endif 13469570cc8Sopenharmony_ci 13569570cc8Sopenharmony_ci UNUSED(iProxy); 13669570cc8Sopenharmony_ci UNUSED(origin); 13769570cc8Sopenharmony_ci 13869570cc8Sopenharmony_ci if (reply == NULL || funcId != ID_CALL_CREATE_SERVICE || req == NULL) { 13969570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] invoke, funcId %d invalid, reply %d.", funcId, INVALID_PID); 14069570cc8Sopenharmony_ci WriteInt64(reply, INVALID_PID); 14169570cc8Sopenharmony_ci return EC_BADPTR; 14269570cc8Sopenharmony_ci } 14369570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] invoke."); 14469570cc8Sopenharmony_ci AppSpawnClientLite client = {}; 14569570cc8Sopenharmony_ci client.client.id = CLIENT_ID; 14669570cc8Sopenharmony_ci client.client.flags = 0; 14769570cc8Sopenharmony_ci if (GetMessageSt(&client.message, req) != EC_SUCCESS) { 14869570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] invoke, parse failed! reply %d.", INVALID_PID); 14969570cc8Sopenharmony_ci WriteInt64(reply, INVALID_PID); 15069570cc8Sopenharmony_ci return EC_FAILURE; 15169570cc8Sopenharmony_ci } 15269570cc8Sopenharmony_ci 15369570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] invoke, msg<%s,%s,%d,%d %d>", client.message.bundleName, client.message.identityID, 15469570cc8Sopenharmony_ci client.message.uID, client.message.gID, client.message.capsCnt); 15569570cc8Sopenharmony_ci pid_t newPid = 0; 15669570cc8Sopenharmony_ci int ret = AppSpawnProcessMsg(&g_appSpawnContentLite->content, &client.client, &newPid); 15769570cc8Sopenharmony_ci if (ret != 0) { 15869570cc8Sopenharmony_ci newPid = -1; 15969570cc8Sopenharmony_ci } 16069570cc8Sopenharmony_ci FreeMessageSt(&client.message); 16169570cc8Sopenharmony_ci WriteInt64(reply, newPid); 16269570cc8Sopenharmony_ci 16369570cc8Sopenharmony_ci#ifdef OHOS_DEBUG 16469570cc8Sopenharmony_ci struct timespec tmEnd = {0}; 16569570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &tmEnd); 16669570cc8Sopenharmony_ci long long diff = DiffTime(&tmStart, &tmEnd); 16769570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] invoke, reply pid %d, timeused %lld ns.", newPid, diff); 16869570cc8Sopenharmony_ci#else 16969570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] invoke, reply pid %d.", newPid); 17069570cc8Sopenharmony_ci#endif // OHOS_DEBUG 17169570cc8Sopenharmony_ci 17269570cc8Sopenharmony_ci return ((newPid > 0) ? EC_SUCCESS : EC_FAILURE); 17369570cc8Sopenharmony_ci} 17469570cc8Sopenharmony_ci 17569570cc8Sopenharmony_cistatic AppSpawnService g_appSpawnService = { 17669570cc8Sopenharmony_ci .GetName = GetName, 17769570cc8Sopenharmony_ci .Initialize = Initialize, 17869570cc8Sopenharmony_ci .MessageHandle = MessageHandle, 17969570cc8Sopenharmony_ci .GetTaskConfig = GetTaskConfig, 18069570cc8Sopenharmony_ci SERVER_IPROXY_IMPL_BEGIN, 18169570cc8Sopenharmony_ci .Invoke = Invoke, 18269570cc8Sopenharmony_ci IPROXY_END, 18369570cc8Sopenharmony_ci}; 18469570cc8Sopenharmony_ci 18569570cc8Sopenharmony_civoid AppSpawnInit(void) 18669570cc8Sopenharmony_ci{ 18769570cc8Sopenharmony_ci if (SAMGR_GetInstance()->RegisterService((Service *)&g_appSpawnService) != TRUE) { 18869570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] register service failed!"); 18969570cc8Sopenharmony_ci return; 19069570cc8Sopenharmony_ci } 19169570cc8Sopenharmony_ci 19269570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] register service succeed."); 19369570cc8Sopenharmony_ci 19469570cc8Sopenharmony_ci if (SAMGR_GetInstance()->RegisterDefaultFeatureApi(APPSPAWN_SERVICE_NAME, \ 19569570cc8Sopenharmony_ci GET_IUNKNOWN(g_appSpawnService)) != TRUE) { 19669570cc8Sopenharmony_ci (void)SAMGR_GetInstance()->UnregisterService(APPSPAWN_SERVICE_NAME); 19769570cc8Sopenharmony_ci APPSPAWN_LOGE("[appspawn] register featureapi failed!"); 19869570cc8Sopenharmony_ci return; 19969570cc8Sopenharmony_ci } 20069570cc8Sopenharmony_ci 20169570cc8Sopenharmony_ci APPSPAWN_LOGI("[appspawn] register featureapi succeed."); 20269570cc8Sopenharmony_ci} 20369570cc8Sopenharmony_ci 20469570cc8Sopenharmony_ciSYSEX_SERVICE_INIT(AppSpawnInit); 205