1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci 16020a203aSopenharmony_ci#include "hiview_service_agent.h" 17020a203aSopenharmony_ci 18020a203aSopenharmony_ci#include "application_context.h" 19020a203aSopenharmony_ci#include "file_util.h" 20020a203aSopenharmony_ci#include "hiview_err_code.h" 21020a203aSopenharmony_ci#include "hiview_service_ability_proxy.h" 22020a203aSopenharmony_ci#include "iservice_registry.h" 23020a203aSopenharmony_ci#include "hiview_logger.h" 24020a203aSopenharmony_ci#include "storage_acl.h" 25020a203aSopenharmony_ci#include "string_util.h" 26020a203aSopenharmony_ci#include "system_ability_definition.h" 27020a203aSopenharmony_ci 28020a203aSopenharmony_cinamespace OHOS { 29020a203aSopenharmony_cinamespace HiviewDFX { 30020a203aSopenharmony_cinamespace { 31020a203aSopenharmony_ciDEFINE_LOG_TAG("HiviewServiceAgent"); 32020a203aSopenharmony_ci} 33020a203aSopenharmony_ci 34020a203aSopenharmony_ciHiviewServiceAgent& HiviewServiceAgent::GetInstance() 35020a203aSopenharmony_ci{ 36020a203aSopenharmony_ci static HiviewServiceAgent hiviewServiceAgent; 37020a203aSopenharmony_ci return hiviewServiceAgent; 38020a203aSopenharmony_ci} 39020a203aSopenharmony_ci 40020a203aSopenharmony_ciint32_t HiviewServiceAgent::List(const std::string& logType, std::vector<HiviewFileInfo>& fileInfos) 41020a203aSopenharmony_ci{ 42020a203aSopenharmony_ci auto service = GetRemoteService(); 43020a203aSopenharmony_ci if (service == nullptr) { 44020a203aSopenharmony_ci HIVIEW_LOGE("cannot get service."); 45020a203aSopenharmony_ci return HiviewNapiErrCode::ERR_DEFAULT; 46020a203aSopenharmony_ci } 47020a203aSopenharmony_ci HiviewServiceAbilityProxy proxy(service); 48020a203aSopenharmony_ci return proxy.List(logType, fileInfos); 49020a203aSopenharmony_ci} 50020a203aSopenharmony_ci 51020a203aSopenharmony_ciint32_t HiviewServiceAgent::Copy(const std::string& logType, const std::string& logName, const std::string& dest) 52020a203aSopenharmony_ci{ 53020a203aSopenharmony_ci return CopyOrMoveFile(logType, logName, dest, false); 54020a203aSopenharmony_ci} 55020a203aSopenharmony_ci 56020a203aSopenharmony_ciint32_t HiviewServiceAgent::Move(const std::string& logType, const std::string& logName, const std::string& dest) 57020a203aSopenharmony_ci{ 58020a203aSopenharmony_ci return CopyOrMoveFile(logType, logName, dest, true); 59020a203aSopenharmony_ci} 60020a203aSopenharmony_ci 61020a203aSopenharmony_ciint32_t HiviewServiceAgent::CopyOrMoveFile( 62020a203aSopenharmony_ci const std::string& logType, const std::string& logName, const std::string& dest, bool isMove) 63020a203aSopenharmony_ci{ 64020a203aSopenharmony_ci if (!CheckAndCreateHiviewDir(dest)) { 65020a203aSopenharmony_ci HIVIEW_LOGE("create dirs failed."); 66020a203aSopenharmony_ci return HiviewNapiErrCode::ERR_DEFAULT; 67020a203aSopenharmony_ci } 68020a203aSopenharmony_ci auto service = GetRemoteService(); 69020a203aSopenharmony_ci if (service == nullptr) { 70020a203aSopenharmony_ci HIVIEW_LOGE("cannot get service."); 71020a203aSopenharmony_ci return HiviewNapiErrCode::ERR_DEFAULT; 72020a203aSopenharmony_ci } 73020a203aSopenharmony_ci HiviewServiceAbilityProxy proxy(service); 74020a203aSopenharmony_ci return isMove ? proxy.Move(logType, logName, dest) : proxy.Copy(logType, logName, dest); 75020a203aSopenharmony_ci} 76020a203aSopenharmony_ci 77020a203aSopenharmony_ciint32_t HiviewServiceAgent::Remove(const std::string& logType, const std::string& logName) 78020a203aSopenharmony_ci{ 79020a203aSopenharmony_ci auto service = GetRemoteService(); 80020a203aSopenharmony_ci if (service == nullptr) { 81020a203aSopenharmony_ci HIVIEW_LOGE("cannot get service."); 82020a203aSopenharmony_ci return HiviewNapiErrCode::ERR_DEFAULT; 83020a203aSopenharmony_ci } 84020a203aSopenharmony_ci HiviewServiceAbilityProxy proxy(service); 85020a203aSopenharmony_ci return proxy.Remove(logType, logName); 86020a203aSopenharmony_ci} 87020a203aSopenharmony_ci 88020a203aSopenharmony_cisptr<IRemoteObject> HiviewServiceAgent::GetRemoteService() 89020a203aSopenharmony_ci{ 90020a203aSopenharmony_ci std::lock_guard<std::mutex> proxyGuard(proxyMutex_); 91020a203aSopenharmony_ci if (hiviewServiceAbilityProxy_ != nullptr) { 92020a203aSopenharmony_ci return hiviewServiceAbilityProxy_; 93020a203aSopenharmony_ci } 94020a203aSopenharmony_ci HIVIEW_LOGI("refresh remote service instance."); 95020a203aSopenharmony_ci auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 96020a203aSopenharmony_ci if (abilityManager == nullptr) { 97020a203aSopenharmony_ci return nullptr; 98020a203aSopenharmony_ci } 99020a203aSopenharmony_ci hiviewServiceAbilityProxy_ = abilityManager->CheckSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID); 100020a203aSopenharmony_ci if (hiviewServiceAbilityProxy_ == nullptr) { 101020a203aSopenharmony_ci HIVIEW_LOGE("get hiview ability failed."); 102020a203aSopenharmony_ci return nullptr; 103020a203aSopenharmony_ci } 104020a203aSopenharmony_ci deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new HiviewServiceDeathRecipient(*this)); 105020a203aSopenharmony_ci if (deathRecipient_ == nullptr) { 106020a203aSopenharmony_ci HIVIEW_LOGE("create service deathrecipient failed."); 107020a203aSopenharmony_ci hiviewServiceAbilityProxy_ = nullptr; 108020a203aSopenharmony_ci return nullptr; 109020a203aSopenharmony_ci } 110020a203aSopenharmony_ci hiviewServiceAbilityProxy_->AddDeathRecipient(deathRecipient_); 111020a203aSopenharmony_ci return hiviewServiceAbilityProxy_; 112020a203aSopenharmony_ci} 113020a203aSopenharmony_ci 114020a203aSopenharmony_civoid HiviewServiceAgent::ProcessDeathObserver(const wptr<IRemoteObject>& remote) 115020a203aSopenharmony_ci{ 116020a203aSopenharmony_ci std::lock_guard<std::mutex> proxyGuard(proxyMutex_); 117020a203aSopenharmony_ci if (hiviewServiceAbilityProxy_ == nullptr) { 118020a203aSopenharmony_ci HIVIEW_LOGW("hiview remote service died and local instance is null."); 119020a203aSopenharmony_ci return; 120020a203aSopenharmony_ci } 121020a203aSopenharmony_ci if (hiviewServiceAbilityProxy_ == remote.promote()) { 122020a203aSopenharmony_ci hiviewServiceAbilityProxy_->RemoveDeathRecipient(deathRecipient_); 123020a203aSopenharmony_ci hiviewServiceAbilityProxy_ = nullptr; 124020a203aSopenharmony_ci deathRecipient_ = nullptr; 125020a203aSopenharmony_ci HIVIEW_LOGW("hiview remote service died."); 126020a203aSopenharmony_ci } else { 127020a203aSopenharmony_ci HIVIEW_LOGW("unknown service died."); 128020a203aSopenharmony_ci } 129020a203aSopenharmony_ci} 130020a203aSopenharmony_ci 131020a203aSopenharmony_cibool HiviewServiceAgent::CheckAndCreateHiviewDir(const std::string& destDir) 132020a203aSopenharmony_ci{ 133020a203aSopenharmony_ci if (destDir.find("..") != std::string::npos) { 134020a203aSopenharmony_ci HIVIEW_LOGE("invalid destDir: %{public}s", destDir.c_str()); 135020a203aSopenharmony_ci return false; 136020a203aSopenharmony_ci } 137020a203aSopenharmony_ci std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context = 138020a203aSopenharmony_ci OHOS::AbilityRuntime::Context::GetApplicationContext(); 139020a203aSopenharmony_ci if (context == nullptr) { 140020a203aSopenharmony_ci HIVIEW_LOGE("Context is null."); 141020a203aSopenharmony_ci return false; 142020a203aSopenharmony_ci } 143020a203aSopenharmony_ci std::string baseDir = context->GetBaseDir(); 144020a203aSopenharmony_ci std::string cacheDir = context->GetCacheDir(); 145020a203aSopenharmony_ci if (baseDir.empty() || cacheDir.empty()) { 146020a203aSopenharmony_ci HIVIEW_LOGE("file dir is empty."); 147020a203aSopenharmony_ci return false; 148020a203aSopenharmony_ci } 149020a203aSopenharmony_ci int aclBaseRet = OHOS::StorageDaemon::AclSetAccess(baseDir, "g:1201:x"); 150020a203aSopenharmony_ci int aclCacheRet = OHOS::StorageDaemon::AclSetAccess(cacheDir, "g:1201:x"); 151020a203aSopenharmony_ci if (aclBaseRet != 0 || aclCacheRet != 0) { 152020a203aSopenharmony_ci HIVIEW_LOGE("set acl access for app failed."); 153020a203aSopenharmony_ci return false; 154020a203aSopenharmony_ci } 155020a203aSopenharmony_ci std::string hiviewDir = cacheDir + "/hiview"; 156020a203aSopenharmony_ci if (!CreateAndGrantAclPermission(hiviewDir)) { 157020a203aSopenharmony_ci HIVIEW_LOGE("create hiview dir failed."); 158020a203aSopenharmony_ci return false; 159020a203aSopenharmony_ci } 160020a203aSopenharmony_ci if (!destDir.empty() && !CreateDestDirs(hiviewDir, destDir)) { 161020a203aSopenharmony_ci HIVIEW_LOGE("create dest dir failed."); 162020a203aSopenharmony_ci return false; 163020a203aSopenharmony_ci } 164020a203aSopenharmony_ci return true; 165020a203aSopenharmony_ci} 166020a203aSopenharmony_ci 167020a203aSopenharmony_cibool HiviewServiceAgent::CreateDestDirs(const std::string& rootDir, const std::string& destDir) 168020a203aSopenharmony_ci{ 169020a203aSopenharmony_ci std::vector<std::string> dirNames; 170020a203aSopenharmony_ci StringUtil::SplitStr(destDir, "/", dirNames, false, true); 171020a203aSopenharmony_ci std::string fullPath(rootDir); 172020a203aSopenharmony_ci for (auto& dirName : dirNames) { 173020a203aSopenharmony_ci fullPath.append("/").append(dirName); 174020a203aSopenharmony_ci if (!CreateAndGrantAclPermission(fullPath)) { 175020a203aSopenharmony_ci return false; 176020a203aSopenharmony_ci } 177020a203aSopenharmony_ci } 178020a203aSopenharmony_ci return true; 179020a203aSopenharmony_ci} 180020a203aSopenharmony_ci 181020a203aSopenharmony_cibool HiviewServiceAgent::CreateAndGrantAclPermission(const std::string& dirPath) 182020a203aSopenharmony_ci{ 183020a203aSopenharmony_ci if (!FileUtil::FileExists(dirPath) && !FileUtil::ForceCreateDirectory(dirPath)) { 184020a203aSopenharmony_ci HIVIEW_LOGE("create dir failed."); 185020a203aSopenharmony_ci return false; 186020a203aSopenharmony_ci } 187020a203aSopenharmony_ci if (OHOS::StorageDaemon::AclSetAccess(dirPath, "g:1201:rwx") != 0) { 188020a203aSopenharmony_ci HIVIEW_LOGE("set acl access failed."); 189020a203aSopenharmony_ci return false; 190020a203aSopenharmony_ci } 191020a203aSopenharmony_ci return true; 192020a203aSopenharmony_ci} 193020a203aSopenharmony_ci} // namespace HiviewDFX 194020a203aSopenharmony_ci} // namespace OHOS