1 /* 2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "distributed_sched_test_util.h" 17 18 #include <future> 19 20 #include "accesstoken_kit.h" 21 #include "bundle_installer_interface.h" 22 #include "if_system_ability_manager.h" 23 #include "iservice_registry.h" 24 #include "nativetoken_kit.h" 25 #include "nocopyable.h" 26 #include "status_receiver_host.h" 27 #include "status_receiver_interface.h" 28 #include "system_ability_definition.h" 29 #include "token_setproc.h" 30 31 #include "dtbschedmgr_log.h" 32 33 namespace OHOS { 34 namespace DistributedSchedule { 35 using namespace AppExecFwk; 36 namespace { 37 const std::string TAG = "DistributedSchedUtil"; 38 const char* DISTSCHED_PROCESS_NAME = "distributedsched"; 39 constexpr int32_t DMS_LOAD_SA_TIMEOUT_MS = 10000; 40 constexpr int32_t USER_ID = 100; 41 constexpr int32_t PERMS_NUM = 4; 42 constexpr int32_t FAILED_RETURN = -1; 43 } 44 45 class StatusReceiverImpl : public StatusReceiverHost { 46 public: 47 StatusReceiverImpl(); 48 ~StatusReceiverImpl() override; 49 void OnStatusNotify(const int progress) override; 50 void OnFinished(const int32_t resultCode, const std::string &resultMsg) override; 51 52 private: 53 mutable std::promise<std::string> resultMsgSignal_; 54 int iProgress_ = 0; 55 56 DISALLOW_COPY_AND_MOVE(StatusReceiverImpl); 57 }; 58 StatusReceiverImpl()59 StatusReceiverImpl::StatusReceiverImpl() 60 { 61 HILOGI("create status receiver instance"); 62 } 63 ~StatusReceiverImpl()64 StatusReceiverImpl::~StatusReceiverImpl() 65 { 66 HILOGI("destroy status receiver instance"); 67 } 68 OnStatusNotify(const int progress)69 void StatusReceiverImpl::OnStatusNotify(const int progress) 70 { 71 iProgress_ = progress; 72 HILOGI("OnStatusNotify progress:%{public}d", progress); 73 } 74 OnFinished(const int32_t resultCode,const std::string & resultMsg)75 void StatusReceiverImpl::OnFinished(const int32_t resultCode, const std::string &resultMsg) 76 { 77 HILOGI("on finished result is %{public}d, %{public}s", resultCode, resultMsg.c_str()); 78 resultMsgSignal_.set_value(resultMsg); 79 } 80 81 sptr<IRemoteObject> DistributedSchedUtil::remote_ = nullptr; 82 std::mutex DistributedSchedUtil::remoteMutex_; 83 std::condition_variable DistributedSchedUtil::remoteConVar_; 84 MockPermission()85 void DistributedSchedUtil::MockPermission() 86 { 87 static const char *perms[] = { 88 "ohos.permission.ABILITY_BACKGROUND_COMMUNICATION", 89 "ohos.permission.ACCESS_SERVICE_DM", 90 "ohos.permission.DISTRIBUTED_DATASYNC", 91 "ohos.permission.RUNNING_STATE_OBSERVER" 92 93 }; 94 MockProcessAndPermission(DISTSCHED_PROCESS_NAME, perms, PERMS_NUM); 95 } 96 MockBundlePermission()97 void DistributedSchedUtil::MockBundlePermission() 98 { 99 static const char *perms[] = { 100 "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED" 101 }; 102 MockProcessAndPermission("DistributedSchedPermissionTest", perms, sizeof(perms) / sizeof(perms[0])); 103 } 104 MockManageMissions()105 void DistributedSchedUtil::MockManageMissions() 106 { 107 static const char *perms[] = { 108 "ohos.permission.MANAGE_MISSIONS" 109 }; 110 MockProcessAndPermission("DistributedSchedPermissionTest", perms, sizeof(perms) / sizeof(perms[0])); 111 } 112 MockProcess(const char * processName)113 void DistributedSchedUtil::MockProcess(const char* processName) 114 { 115 MockProcessAndPermission(processName); 116 } 117 GetBundleManager()118 sptr<AppExecFwk::IBundleMgr> DistributedSchedUtil::GetBundleManager() 119 { 120 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 121 if (samgrProxy == nullptr) { 122 return nullptr; 123 } 124 sptr<IRemoteObject> bmsProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 125 if (bmsProxy == nullptr) { 126 HILOGE("failed to get bms from samgr"); 127 return nullptr; 128 } 129 return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy); 130 } 131 MockProcessAndPermission(const char * processName,const char * perms[],int32_t permsNum)132 void DistributedSchedUtil::MockProcessAndPermission(const char* processName, const char *perms[], int32_t permsNum) 133 { 134 uint64_t tokenId; 135 NativeTokenInfoParams infoInstance = { 136 .dcapsNum = 0, 137 .permsNum = permsNum, 138 .aclsNum = 0, 139 .dcaps = nullptr, 140 .perms = perms, 141 .acls = nullptr, 142 .processName = processName, 143 .aplStr = "system_core", 144 }; 145 tokenId = GetAccessTokenId(&infoInstance); 146 SetSelfTokenID(tokenId); 147 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo(); 148 } 149 LoadDistributedSchedService()150 bool DistributedSchedUtil::LoadDistributedSchedService() 151 { 152 std::unique_lock<std::mutex> lock(remoteMutex_); 153 sptr<DistributedSchedLoadCallback> loadCallback(new DistributedSchedLoadCallback()); 154 if (loadCallback == nullptr) { 155 HILOGE("loadCallback is nullptr"); 156 return false; 157 } 158 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 159 if (samgrProxy == nullptr) { 160 HILOGE("get samgr failed"); 161 return false; 162 } 163 int32_t ret = samgrProxy->LoadSystemAbility(DISTRIBUTED_SCHED_SA_ID, loadCallback); 164 if (ret != ERR_OK) { 165 HILOGE("load dms SA failed"); 166 return false; 167 } 168 auto waitStatus = remoteConVar_.wait_for(lock, std::chrono::milliseconds(DMS_LOAD_SA_TIMEOUT_MS), 169 []() { return remote_ != nullptr; }); 170 if (!waitStatus) { 171 HILOGE("dms SA load timeout"); 172 return false; 173 } 174 return true; 175 } 176 LoadSystemAbilitySuccessNotify(const sptr<IRemoteObject> & remoteObject)177 void DistributedSchedUtil::LoadSystemAbilitySuccessNotify(const sptr<IRemoteObject>& remoteObject) 178 { 179 std::lock_guard<std::mutex> lock(remoteMutex_); 180 remote_ = remoteObject; 181 remoteConVar_.notify_one(); 182 } 183 LoadSystemAbilityFailNotify()184 void DistributedSchedUtil::LoadSystemAbilityFailNotify() 185 { 186 std::lock_guard<std::mutex> lock(remoteMutex_); 187 remote_ = nullptr; 188 } 189 OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)190 void DistributedSchedLoadCallback::OnLoadSystemAbilitySuccess( 191 int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject) 192 { 193 HILOGD("called."); 194 DistributedSchedUtil::LoadSystemAbilitySuccessNotify(remoteObject); 195 } 196 OnLoadSystemAbilityFail(int32_t systemAbilityId)197 void DistributedSchedLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) 198 { 199 HILOGD("called."); 200 DistributedSchedUtil::LoadSystemAbilityFailNotify(); 201 } 202 } 203 }