1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "cooperate_server.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <chrono> 19c29fa5a6Sopenharmony_ci 20c29fa5a6Sopenharmony_ci#include <tokenid_kit.h> 21c29fa5a6Sopenharmony_ci 22c29fa5a6Sopenharmony_ci#include "accesstoken_kit.h" 23c29fa5a6Sopenharmony_ci#include "cooperate_params.h" 24c29fa5a6Sopenharmony_ci#include "default_params.h" 25c29fa5a6Sopenharmony_ci#include "devicestatus_define.h" 26c29fa5a6Sopenharmony_ci#include "ipc_skeleton.h" 27c29fa5a6Sopenharmony_ci#include "utility.h" 28c29fa5a6Sopenharmony_ci 29c29fa5a6Sopenharmony_ci#undef LOG_TAG 30c29fa5a6Sopenharmony_ci#define LOG_TAG "CooperateServer" 31c29fa5a6Sopenharmony_ci 32c29fa5a6Sopenharmony_cinamespace OHOS { 33c29fa5a6Sopenharmony_cinamespace Msdp { 34c29fa5a6Sopenharmony_cinamespace DeviceStatus { 35c29fa5a6Sopenharmony_cinamespace { 36c29fa5a6Sopenharmony_ciconstexpr int32_t REPEAT_ONCE { 1 }; 37c29fa5a6Sopenharmony_ciconstexpr int32_t DEFAULT_UNLOAD_COOLING_TIME_MS { 60000 }; 38c29fa5a6Sopenharmony_ciconstexpr int32_t SYNC_TASK_TIMEOUT_DURATION { 2500 }; 39c29fa5a6Sopenharmony_ci} 40c29fa5a6Sopenharmony_ci 41c29fa5a6Sopenharmony_ciCooperateServer::CooperateServer(IContext *context) 42c29fa5a6Sopenharmony_ci : context_(context) 43c29fa5a6Sopenharmony_ci{} 44c29fa5a6Sopenharmony_ci 45c29fa5a6Sopenharmony_ciint32_t CooperateServer::Enable(CallingContext &context, MessageParcel &data, MessageParcel &reply) 46c29fa5a6Sopenharmony_ci{ 47c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 48c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 49c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 50c29fa5a6Sopenharmony_ci return ret; 51c29fa5a6Sopenharmony_ci } 52c29fa5a6Sopenharmony_ci DefaultParam param; 53c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 54c29fa5a6Sopenharmony_ci FI_HILOGE("DefaultParam::Unmarshalling fail"); 55c29fa5a6Sopenharmony_ci return RET_ERR; 56c29fa5a6Sopenharmony_ci } 57c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 58c29fa5a6Sopenharmony_ci if (unloadTimerId_ >= 0) { 59c29fa5a6Sopenharmony_ci context_->GetTimerManager().RemoveTimer(unloadTimerId_); 60c29fa5a6Sopenharmony_ci } 61c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 62c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 63c29fa5a6Sopenharmony_ci cooperate->Enable(context.tokenId, context.pid, param.userData); 64c29fa5a6Sopenharmony_ci return RET_OK; 65c29fa5a6Sopenharmony_ci} 66c29fa5a6Sopenharmony_ci 67c29fa5a6Sopenharmony_ciint32_t CooperateServer::Disable(CallingContext &context, MessageParcel &data, MessageParcel &reply) 68c29fa5a6Sopenharmony_ci{ 69c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 70c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 71c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 72c29fa5a6Sopenharmony_ci return ret; 73c29fa5a6Sopenharmony_ci } 74c29fa5a6Sopenharmony_ci DefaultParam param; 75c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 76c29fa5a6Sopenharmony_ci FI_HILOGE("DefaultParam::Unmarshalling fail"); 77c29fa5a6Sopenharmony_ci return RET_ERR; 78c29fa5a6Sopenharmony_ci } 79c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 80c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 81c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 82c29fa5a6Sopenharmony_ci cooperate->Disable(context.pid, param.userData); 83c29fa5a6Sopenharmony_ci unloadTimerId_ = context_->GetTimerManager().AddTimer(DEFAULT_UNLOAD_COOLING_TIME_MS, REPEAT_ONCE, 84c29fa5a6Sopenharmony_ci []() { 85c29fa5a6Sopenharmony_ci FI_HILOGI("Unload \'cooperate\' module"); 86c29fa5a6Sopenharmony_ci }); 87c29fa5a6Sopenharmony_ci if (unloadTimerId_ < 0) { 88c29fa5a6Sopenharmony_ci FI_HILOGE("AddTimer failed, will not unload Cooperate"); 89c29fa5a6Sopenharmony_ci } 90c29fa5a6Sopenharmony_ci return RET_OK; 91c29fa5a6Sopenharmony_ci} 92c29fa5a6Sopenharmony_ci 93c29fa5a6Sopenharmony_ciint32_t CooperateServer::Start(CallingContext &context, MessageParcel &data, MessageParcel &reply) 94c29fa5a6Sopenharmony_ci{ 95c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 96c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 97c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 98c29fa5a6Sopenharmony_ci return ret; 99c29fa5a6Sopenharmony_ci } 100c29fa5a6Sopenharmony_ci StartCooperateParam param; 101c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 102c29fa5a6Sopenharmony_ci FI_HILOGE("StartCooperateParam::Unmarshalling fail"); 103c29fa5a6Sopenharmony_ci return RET_ERR; 104c29fa5a6Sopenharmony_ci } 105c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 106c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 107c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 108c29fa5a6Sopenharmony_ci return cooperate->Start(context.pid, param.userData, param.remoteNetworkId, param.startDeviceId); 109c29fa5a6Sopenharmony_ci} 110c29fa5a6Sopenharmony_ci 111c29fa5a6Sopenharmony_ciint32_t CooperateServer::Stop(CallingContext &context, MessageParcel &data, MessageParcel &reply) 112c29fa5a6Sopenharmony_ci{ 113c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 114c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 115c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 116c29fa5a6Sopenharmony_ci return ret; 117c29fa5a6Sopenharmony_ci } 118c29fa5a6Sopenharmony_ci StopCooperateParam param; 119c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 120c29fa5a6Sopenharmony_ci FI_HILOGE("StopCooperateParam::Unmarshalling fail"); 121c29fa5a6Sopenharmony_ci return RET_ERR; 122c29fa5a6Sopenharmony_ci } 123c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 124c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 125c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 126c29fa5a6Sopenharmony_ci return cooperate->Stop(context.pid, param.userData, param.isUnchained); 127c29fa5a6Sopenharmony_ci} 128c29fa5a6Sopenharmony_ci 129c29fa5a6Sopenharmony_ciint32_t CooperateServer::AddWatch(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply) 130c29fa5a6Sopenharmony_ci{ 131c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 132c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 133c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 134c29fa5a6Sopenharmony_ci return ret; 135c29fa5a6Sopenharmony_ci } 136c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 137c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 138c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 139c29fa5a6Sopenharmony_ci switch (id) { 140c29fa5a6Sopenharmony_ci case CooperateRequestID::REGISTER_LISTENER: { 141c29fa5a6Sopenharmony_ci return cooperate->RegisterListener(context.pid); 142c29fa5a6Sopenharmony_ci } 143c29fa5a6Sopenharmony_ci case CooperateRequestID::REGISTER_HOTAREA_LISTENER: { 144c29fa5a6Sopenharmony_ci return cooperate->RegisterHotAreaListener(context.pid); 145c29fa5a6Sopenharmony_ci } 146c29fa5a6Sopenharmony_ci case CooperateRequestID::REGISTER_EVENT_LISTENER: { 147c29fa5a6Sopenharmony_ci RegisterEventListenerParam param; 148c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 149c29fa5a6Sopenharmony_ci FI_HILOGE("RegisterEventListenerParam::Unmarshalling fail"); 150c29fa5a6Sopenharmony_ci return RET_ERR; 151c29fa5a6Sopenharmony_ci } 152c29fa5a6Sopenharmony_ci return cooperate->RegisterEventListener(context.pid, param.networkId); 153c29fa5a6Sopenharmony_ci } 154c29fa5a6Sopenharmony_ci default: { 155c29fa5a6Sopenharmony_ci FI_HILOGE("Unexpected request ID (%{public}u)", id); 156c29fa5a6Sopenharmony_ci return RET_ERR; 157c29fa5a6Sopenharmony_ci } 158c29fa5a6Sopenharmony_ci } 159c29fa5a6Sopenharmony_ci} 160c29fa5a6Sopenharmony_ci 161c29fa5a6Sopenharmony_ciint32_t CooperateServer::RemoveWatch(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply) 162c29fa5a6Sopenharmony_ci{ 163c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 164c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 165c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 166c29fa5a6Sopenharmony_ci return ret; 167c29fa5a6Sopenharmony_ci } 168c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 169c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 170c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 171c29fa5a6Sopenharmony_ci switch (id) { 172c29fa5a6Sopenharmony_ci case CooperateRequestID::UNREGISTER_LISTENER: { 173c29fa5a6Sopenharmony_ci return cooperate->UnregisterListener(context.pid); 174c29fa5a6Sopenharmony_ci } 175c29fa5a6Sopenharmony_ci case CooperateRequestID::UNREGISTER_HOTAREA_LISTENER: { 176c29fa5a6Sopenharmony_ci return cooperate->UnregisterHotAreaListener(context.pid); 177c29fa5a6Sopenharmony_ci } 178c29fa5a6Sopenharmony_ci case CooperateRequestID::UNREGISTER_EVENT_LISTENER: { 179c29fa5a6Sopenharmony_ci UnregisterEventListenerParam param; 180c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 181c29fa5a6Sopenharmony_ci FI_HILOGE("UnregisterEventListenerParam::Unmarshalling fail"); 182c29fa5a6Sopenharmony_ci return RET_ERR; 183c29fa5a6Sopenharmony_ci } 184c29fa5a6Sopenharmony_ci return cooperate->UnregisterEventListener(context.pid, param.networkId); 185c29fa5a6Sopenharmony_ci } 186c29fa5a6Sopenharmony_ci default: { 187c29fa5a6Sopenharmony_ci FI_HILOGE("Unexpected request ID (%{public}u)", id); 188c29fa5a6Sopenharmony_ci return RET_ERR; 189c29fa5a6Sopenharmony_ci } 190c29fa5a6Sopenharmony_ci } 191c29fa5a6Sopenharmony_ci} 192c29fa5a6Sopenharmony_ci 193c29fa5a6Sopenharmony_ciint32_t CooperateServer::SetParam(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply) 194c29fa5a6Sopenharmony_ci{ 195c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 196c29fa5a6Sopenharmony_ci return RET_ERR; 197c29fa5a6Sopenharmony_ci} 198c29fa5a6Sopenharmony_ci 199c29fa5a6Sopenharmony_ciint32_t CooperateServer::GetParam(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply) 200c29fa5a6Sopenharmony_ci{ 201c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 202c29fa5a6Sopenharmony_ci if (int32_t ret = CheckPermission(context); ret != RET_OK) { 203c29fa5a6Sopenharmony_ci FI_HILOGE("CheckPermission failed, ret:%{public}d", ret); 204c29fa5a6Sopenharmony_ci return ret; 205c29fa5a6Sopenharmony_ci } 206c29fa5a6Sopenharmony_ci CHKPR(context_, RET_ERR); 207c29fa5a6Sopenharmony_ci ICooperate* cooperate = context_->GetPluginManager().LoadCooperate(); 208c29fa5a6Sopenharmony_ci CHKPR(cooperate, RET_ERR); 209c29fa5a6Sopenharmony_ci auto enterStamp = std::chrono::steady_clock::now(); 210c29fa5a6Sopenharmony_ci auto checkParcelValid = [&enterStamp] () { 211c29fa5a6Sopenharmony_ci auto duration = std::chrono::duration_cast<std::chrono::milliseconds>( 212c29fa5a6Sopenharmony_ci std::chrono::steady_clock::now() - enterStamp).count(); 213c29fa5a6Sopenharmony_ci return duration < SYNC_TASK_TIMEOUT_DURATION; 214c29fa5a6Sopenharmony_ci }; 215c29fa5a6Sopenharmony_ci switch (id) { 216c29fa5a6Sopenharmony_ci case CooperateRequestID::GET_COOPERATE_STATE: { 217c29fa5a6Sopenharmony_ci GetCooperateStateParam param; 218c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 219c29fa5a6Sopenharmony_ci FI_HILOGE("GetCooperateStateParam::Unmarshalling fail"); 220c29fa5a6Sopenharmony_ci return RET_ERR; 221c29fa5a6Sopenharmony_ci } 222c29fa5a6Sopenharmony_ci return cooperate->GetCooperateState(context.pid, param.userData, param.networkId); 223c29fa5a6Sopenharmony_ci } 224c29fa5a6Sopenharmony_ci case CooperateRequestID::GET_COOPERATE_STATE_SYNC: { 225c29fa5a6Sopenharmony_ci GetCooperateStateSyncParam param; 226c29fa5a6Sopenharmony_ci if (!param.Unmarshalling(data)) { 227c29fa5a6Sopenharmony_ci FI_HILOGE("GetCooperateStateParam::Unmarshalling fail"); 228c29fa5a6Sopenharmony_ci return RET_ERR; 229c29fa5a6Sopenharmony_ci } 230c29fa5a6Sopenharmony_ci bool state { false }; 231c29fa5a6Sopenharmony_ci if (cooperate->GetCooperateState(param.udId, state) != RET_OK) { 232c29fa5a6Sopenharmony_ci FI_HILOGE("GetCooperateState failed"); 233c29fa5a6Sopenharmony_ci return RET_ERR; 234c29fa5a6Sopenharmony_ci } 235c29fa5a6Sopenharmony_ci FI_HILOGI("GetCooperateState for udId:%{public}s successfully, state:%{public}s", 236c29fa5a6Sopenharmony_ci Utility::Anonymize(param.udId).c_str(), state ? "true" : "false"); 237c29fa5a6Sopenharmony_ci if (!checkParcelValid()) { 238c29fa5a6Sopenharmony_ci FI_HILOGE("CheckParcelValid failed"); 239c29fa5a6Sopenharmony_ci return RET_ERR; 240c29fa5a6Sopenharmony_ci } 241c29fa5a6Sopenharmony_ci if (!BooleanReply(state).Marshalling(reply)) { 242c29fa5a6Sopenharmony_ci FI_HILOGE("Marshalling state failed"); 243c29fa5a6Sopenharmony_ci return RET_ERR; 244c29fa5a6Sopenharmony_ci } 245c29fa5a6Sopenharmony_ci return RET_OK; 246c29fa5a6Sopenharmony_ci } 247c29fa5a6Sopenharmony_ci default: { 248c29fa5a6Sopenharmony_ci FI_HILOGE("Unexpected request ID (%{public}u)", id); 249c29fa5a6Sopenharmony_ci return RET_ERR; 250c29fa5a6Sopenharmony_ci } 251c29fa5a6Sopenharmony_ci } 252c29fa5a6Sopenharmony_ci} 253c29fa5a6Sopenharmony_ci 254c29fa5a6Sopenharmony_ciint32_t CooperateServer::Control(CallingContext &context, uint32_t id, MessageParcel &data, MessageParcel &reply) 255c29fa5a6Sopenharmony_ci{ 256c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 257c29fa5a6Sopenharmony_ci return RET_ERR; 258c29fa5a6Sopenharmony_ci} 259c29fa5a6Sopenharmony_ci 260c29fa5a6Sopenharmony_cibool CooperateServer::CheckCooperatePermission(CallingContext &context) 261c29fa5a6Sopenharmony_ci{ 262c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 263c29fa5a6Sopenharmony_ci Security::AccessToken::AccessTokenID callerToken = context.tokenId; 264c29fa5a6Sopenharmony_ci int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, 265c29fa5a6Sopenharmony_ci COOPERATE_PERMISSION); 266c29fa5a6Sopenharmony_ci return result == Security::AccessToken::PERMISSION_GRANTED; 267c29fa5a6Sopenharmony_ci} 268c29fa5a6Sopenharmony_ci 269c29fa5a6Sopenharmony_cibool CooperateServer::IsSystemServiceCalling(CallingContext &context) 270c29fa5a6Sopenharmony_ci{ 271c29fa5a6Sopenharmony_ci const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(context.tokenId); 272c29fa5a6Sopenharmony_ci if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE || 273c29fa5a6Sopenharmony_ci flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { 274c29fa5a6Sopenharmony_ci FI_HILOGD("system service calling, flag:%{public}u", flag); 275c29fa5a6Sopenharmony_ci return true; 276c29fa5a6Sopenharmony_ci } 277c29fa5a6Sopenharmony_ci return false; 278c29fa5a6Sopenharmony_ci} 279c29fa5a6Sopenharmony_ci 280c29fa5a6Sopenharmony_cibool CooperateServer::IsSystemCalling(CallingContext &context) 281c29fa5a6Sopenharmony_ci{ 282c29fa5a6Sopenharmony_ci if (IsSystemServiceCalling(context)) { 283c29fa5a6Sopenharmony_ci return true; 284c29fa5a6Sopenharmony_ci } 285c29fa5a6Sopenharmony_ci return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(context.fullTokenId); 286c29fa5a6Sopenharmony_ci} 287c29fa5a6Sopenharmony_ci 288c29fa5a6Sopenharmony_ciint32_t CooperateServer::CheckPermission(CallingContext &context) 289c29fa5a6Sopenharmony_ci{ 290c29fa5a6Sopenharmony_ci if (!IsSystemCalling(context)) { 291c29fa5a6Sopenharmony_ci FI_HILOGE("The caller is not system hap"); 292c29fa5a6Sopenharmony_ci return COMMON_NOT_SYSTEM_APP; 293c29fa5a6Sopenharmony_ci } 294c29fa5a6Sopenharmony_ci if (!CheckCooperatePermission(context)) { 295c29fa5a6Sopenharmony_ci FI_HILOGE("The caller has no COOPERATE_MANAGER permission"); 296c29fa5a6Sopenharmony_ci return COMMON_PERMISSION_CHECK_ERROR; 297c29fa5a6Sopenharmony_ci } 298c29fa5a6Sopenharmony_ci return RET_OK; 299c29fa5a6Sopenharmony_ci} 300c29fa5a6Sopenharmony_ci} // namespace DeviceStatus 301c29fa5a6Sopenharmony_ci} // namespace Msdp 302c29fa5a6Sopenharmony_ci} // namespace OHOS