100600bfbSopenharmony_ci/* 200600bfbSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 300600bfbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 400600bfbSopenharmony_ci * you may not use this file except in compliance with the License. 500600bfbSopenharmony_ci * You may obtain a copy of the License at 600600bfbSopenharmony_ci * 700600bfbSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 800600bfbSopenharmony_ci * 900600bfbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1000600bfbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1100600bfbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1200600bfbSopenharmony_ci * See the License for the specific language governing permissions and 1300600bfbSopenharmony_ci * limitations under the License. 1400600bfbSopenharmony_ci */ 1500600bfbSopenharmony_ci#include "dump_manager_client.h" 1600600bfbSopenharmony_ci#include <iservice_registry.h> 1700600bfbSopenharmony_ci#include <string_ex.h> 1800600bfbSopenharmony_ci#include <unistd.h> 1900600bfbSopenharmony_ci#include "common.h" 2000600bfbSopenharmony_ci#include "hilog_wrapper.h" 2100600bfbSopenharmony_ci#include "dump_errors.h" 2200600bfbSopenharmony_ci#include "inner/dump_service_id.h" 2300600bfbSopenharmony_ci#include "dump_on_demand_load.h" 2400600bfbSopenharmony_cinamespace OHOS { 2500600bfbSopenharmony_cinamespace HiviewDFX { 2600600bfbSopenharmony_cistatic constexpr int32_t SLEEP_DUR = 5 * 1000 * 1000; 2700600bfbSopenharmony_cistatic constexpr int32_t SLEEP_UNIT = 100 * 1000; 2800600bfbSopenharmony_ci 2900600bfbSopenharmony_ciDumpManagerClient::DumpManagerClient() 3000600bfbSopenharmony_ci{ 3100600bfbSopenharmony_ci} 3200600bfbSopenharmony_ci 3300600bfbSopenharmony_ciDumpManagerClient::~DumpManagerClient() 3400600bfbSopenharmony_ci{ 3500600bfbSopenharmony_ci Reset(); 3600600bfbSopenharmony_ci} 3700600bfbSopenharmony_ci 3800600bfbSopenharmony_ciint32_t DumpManagerClient::Request(std::vector<std::u16string> &args, int outfd) 3900600bfbSopenharmony_ci{ 4000600bfbSopenharmony_ci if ((args.size() < 1) || (outfd < 0)) { 4100600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "args or outfd failed."); 4200600bfbSopenharmony_ci return DumpStatus::DUMP_FAIL; 4300600bfbSopenharmony_ci } 4400600bfbSopenharmony_ci for (size_t i = 0; i < args.size(); i++) { 4500600bfbSopenharmony_ci std::string trimArg = TrimStr(Str16ToStr8(args[i])); 4600600bfbSopenharmony_ci if (strlen(trimArg.c_str()) < 1) { 4700600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "trimArg empty."); 4800600bfbSopenharmony_ci return DumpStatus::DUMP_FAIL; 4900600bfbSopenharmony_ci } 5000600bfbSopenharmony_ci } 5100600bfbSopenharmony_ci if (Connect() != ERR_OK) { 5200600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "Connect failed."); 5300600bfbSopenharmony_ci return DumpStatus::DUMP_FAIL; 5400600bfbSopenharmony_ci } 5500600bfbSopenharmony_ci int32_t ret = proxy_->Request(args, outfd); 5600600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "debug|ret=%{public}d", ret); 5700600bfbSopenharmony_ci return ret; 5800600bfbSopenharmony_ci} 5900600bfbSopenharmony_ci 6000600bfbSopenharmony_ciErrCode DumpManagerClient::Connect() 6100600bfbSopenharmony_ci{ 6200600bfbSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 6300600bfbSopenharmony_ci if (proxy_ != nullptr) { 6400600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "proxy_ is not nullptr."); 6500600bfbSopenharmony_ci return ERR_OK; 6600600bfbSopenharmony_ci } 6700600bfbSopenharmony_ci sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 6800600bfbSopenharmony_ci if (sam == nullptr) { 6900600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "sam is nullptr."); 7000600bfbSopenharmony_ci return ERROR_GET_SYSTEM_ABILITY_MANAGER; 7100600bfbSopenharmony_ci } 7200600bfbSopenharmony_ci sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_SYS_HIDUMPER_ABILITY_ID); 7300600bfbSopenharmony_ci if (remoteObject == nullptr) { 7400600bfbSopenharmony_ci ErrCode retStart = OnDemandStart(sam, remoteObject); 7500600bfbSopenharmony_ci if (remoteObject == nullptr || retStart != ERR_OK) { 7600600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "remoteObject is nullptr."); 7700600bfbSopenharmony_ci return ERROR_GET_DUMPER_SERVICE; 7800600bfbSopenharmony_ci } 7900600bfbSopenharmony_ci } 8000600bfbSopenharmony_ci deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new DumpManagerDeathRecipient()); 8100600bfbSopenharmony_ci if (deathRecipient_ == nullptr) { 8200600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "deathRecipient_ is nullptr."); 8300600bfbSopenharmony_ci return ERR_NO_MEMORY; 8400600bfbSopenharmony_ci } 8500600bfbSopenharmony_ci if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient_))) { 8600600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "IsProxyObject failed."); 8700600bfbSopenharmony_ci return ERROR_ADD_DEATH_RECIPIENT; 8800600bfbSopenharmony_ci } 8900600bfbSopenharmony_ci proxy_ = iface_cast<IDumpBroker>(remoteObject); 9000600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "debug|connected"); 9100600bfbSopenharmony_ci return ERR_OK; 9200600bfbSopenharmony_ci} 9300600bfbSopenharmony_ci 9400600bfbSopenharmony_cibool DumpManagerClient::IsConnected() 9500600bfbSopenharmony_ci{ 9600600bfbSopenharmony_ci return (proxy_ != nullptr); 9700600bfbSopenharmony_ci} 9800600bfbSopenharmony_ci 9900600bfbSopenharmony_civoid DumpManagerClient::Reset() 10000600bfbSopenharmony_ci{ 10100600bfbSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 10200600bfbSopenharmony_ci if (proxy_ == nullptr) { 10300600bfbSopenharmony_ci return; 10400600bfbSopenharmony_ci } 10500600bfbSopenharmony_ci auto serviceRemote = proxy_->AsObject(); 10600600bfbSopenharmony_ci if (serviceRemote != nullptr) { 10700600bfbSopenharmony_ci serviceRemote->RemoveDeathRecipient(deathRecipient_); 10800600bfbSopenharmony_ci proxy_ = nullptr; 10900600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "debug|disconnected"); 11000600bfbSopenharmony_ci } 11100600bfbSopenharmony_ci} 11200600bfbSopenharmony_ci 11300600bfbSopenharmony_civoid DumpManagerClient::ResetProxy(const wptr<IRemoteObject>& remote) 11400600bfbSopenharmony_ci{ 11500600bfbSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 11600600bfbSopenharmony_ci if (proxy_ == nullptr) { 11700600bfbSopenharmony_ci return; 11800600bfbSopenharmony_ci } 11900600bfbSopenharmony_ci auto serviceRemote = proxy_->AsObject(); 12000600bfbSopenharmony_ci if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) { 12100600bfbSopenharmony_ci serviceRemote->RemoveDeathRecipient(deathRecipient_); 12200600bfbSopenharmony_ci proxy_ = nullptr; 12300600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "debug|disconnected"); 12400600bfbSopenharmony_ci } 12500600bfbSopenharmony_ci} 12600600bfbSopenharmony_ci 12700600bfbSopenharmony_civoid DumpManagerClient::DumpManagerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote) 12800600bfbSopenharmony_ci{ 12900600bfbSopenharmony_ci if (remote == nullptr) { 13000600bfbSopenharmony_ci return; 13100600bfbSopenharmony_ci } 13200600bfbSopenharmony_ci DumpManagerClient::GetInstance().ResetProxy(remote); 13300600bfbSopenharmony_ci} 13400600bfbSopenharmony_ci 13500600bfbSopenharmony_ciErrCode DumpManagerClient::OnDemandStart(sptr<ISystemAbilityManager> sam, sptr<IRemoteObject> &remoteObject) 13600600bfbSopenharmony_ci{ 13700600bfbSopenharmony_ci sptr<OnDemandLoadCallback> loadCallback = new OnDemandLoadCallback(); 13800600bfbSopenharmony_ci int32_t result = sam->LoadSystemAbility(DFX_SYS_HIDUMPER_ABILITY_ID, loadCallback); 13900600bfbSopenharmony_ci if (result != ERR_OK) { 14000600bfbSopenharmony_ci DUMPER_HILOGE(MODULE_CLIENT, "systemAbilityId:%{public}d load failed, result code:%{public}d", 14100600bfbSopenharmony_ci DFX_SYS_HIDUMPER_ABILITY_ID, result); 14200600bfbSopenharmony_ci return ERROR_GET_DUMPER_SERVICE; 14300600bfbSopenharmony_ci } 14400600bfbSopenharmony_ci 14500600bfbSopenharmony_ci int32_t loop = SLEEP_DUR / SLEEP_UNIT; 14600600bfbSopenharmony_ci while (loop-- > 0) { 14700600bfbSopenharmony_ci if (!loadCallback->CheckLoadSystemAbilityStatus()) { 14800600bfbSopenharmony_ci usleep(SLEEP_UNIT); 14900600bfbSopenharmony_ci continue; 15000600bfbSopenharmony_ci } 15100600bfbSopenharmony_ci remoteObject = sam->CheckSystemAbility(DFX_SYS_HIDUMPER_ABILITY_ID); 15200600bfbSopenharmony_ci if (remoteObject != nullptr) { 15300600bfbSopenharmony_ci return ERR_OK; 15400600bfbSopenharmony_ci } else { 15500600bfbSopenharmony_ci usleep(SLEEP_UNIT); 15600600bfbSopenharmony_ci } 15700600bfbSopenharmony_ci } 15800600bfbSopenharmony_ci 15900600bfbSopenharmony_ci DUMPER_HILOGD(MODULE_CLIENT, "debug|on demand start fail"); 16000600bfbSopenharmony_ci return ERROR_GET_DUMPER_SERVICE; 16100600bfbSopenharmony_ci} 16200600bfbSopenharmony_ci} // namespace HiviewDFX 16300600bfbSopenharmony_ci} // namespace OHOS 164