/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "ObjectServiceImpl" #include "object_service_impl.h" #include #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "bootstrap.h" #include "checker/checker_manager.h" #include "device_manager_adapter.h" #include "directory/directory_manager.h" #include "dump/dump_manager.h" #include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "object_asset_loader.h" #include "object_dms_handler.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" #include "utils/anonymous.h" #include "object_radar_reporter.h" namespace OHOS::DistributedObject { using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using StoreMetaData = OHOS::DistributedData::StoreMetaData; using FeatureSystem = OHOS::DistributedData::FeatureSystem; using DumpManager = OHOS::DistributedData::DumpManager; __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_; ObjectServiceImpl::Factory::Factory() { FeatureSystem::GetInstance().RegisterCreator( "data_object", []() { return std::make_shared(); }, FeatureSystem::BIND_NOW); staticActs_ = std::make_shared(); FeatureSystem::GetInstance().RegisterStaticActs("data_object", staticActs_); } ObjectServiceImpl::Factory::~Factory() { } int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const std::map> &data, sptr callback) { ZLOGI("begin."); ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } status = ObjectStoreManager::GetInstance()->Save(bundleName, sessionId, data, deviceId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); } ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS); return status; } int32_t ObjectServiceImpl::OnAssetChanged(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const ObjectStore::Asset &assetValue) { uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } status = ObjectStoreManager::GetInstance()->OnAssetChanged(tokenId, bundleName, sessionId, deviceId, assetValue); if (status != OBJECT_SUCCESS) { ZLOGE("file transfer failed fail %{public}d", status); } return status; } int32_t ObjectServiceImpl::BindAssetStore(const std::string &bundleName, const std::string &sessionId, ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) { uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } status = ObjectStoreManager::GetInstance()->BindAsset(tokenId, bundleName, sessionId, asset, bindInfo); if (status != OBJECT_SUCCESS) { ZLOGE("bind asset fail %{public}d, bundleName:%{public}s, sessionId:%{public}s, assetName:%{public}s", status, bundleName.c_str(), sessionId.c_str(), asset.name.c_str()); } return status; } int32_t ObjectServiceImpl::IsContinue(bool &result) { uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); Security::AccessToken::HapTokenInfo tokenInfo; auto status = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); if (status != 0) { ZLOGE("Get hap token info failed, tokenId: %{public}u, status: %{public}d", tokenId, status); return status; } result = ObjectDmsHandler::GetInstance().IsContinue(tokenInfo.bundleName); return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::OnInitialize() { ZLOGI("Initialize"); auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (localDeviceId.empty()) { ZLOGE("failed to get local device id"); return OBJECT_INNER_ERROR; } auto token = IPCSkeleton::GetCallingTokenID(); const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token); StoreMetaData saveMeta; saveMeta.appType = "default"; saveMeta.deviceId = localDeviceId; saveMeta.storeId = DistributedObject::ObjectCommon::OBJECTSTORE_DB_STOREID; saveMeta.isAutoSync = false; saveMeta.isBackup = false; saveMeta.isEncrypt = false; saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); saveMeta.user = std::to_string(userId); saveMeta.account = accountId; saveMeta.tokenId = token; saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; saveMeta.area = DistributedKv::Area::EL1; saveMeta.uid = IPCSkeleton::GetCallingUid(); saveMeta.storeType = ObjectDistributedType::OBJECT_SINGLE_VERSION; saveMeta.dataType = DistributedKv::DataType::TYPE_DYNAMICAL; saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); ObjectStoreManager::GetInstance()->SetData(saveMeta.dataDir, std::to_string(userId)); bool isSaved = DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta) && DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta, true); if (!isSaved) { ZLOGE("SaveMeta failed"); return OBJECT_INNER_ERROR; } DistributedData::AppIDMetaData appIdMeta; appIdMeta.bundleName = saveMeta.bundleName; appIdMeta.appId = saveMeta.appId; isSaved = DistributedData::MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true); if (!isSaved) { ZLOGE("Save appIdMeta failed"); } ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str()); RegisterObjectServiceInfo(); RegisterHandler(); ObjectDmsHandler::GetInstance().RegisterDmsEvent(); return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) { if (code == static_cast(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) { Clear(); } return Feature::OnUserChange(code, user, account); } int32_t ObjectServiceImpl::ObjectStoreRevokeSave( const std::string &bundleName, const std::string &sessionId, sptr callback) { ZLOGI("begin."); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } status = ObjectStoreManager::GetInstance()->RevokeSave(bundleName, sessionId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("revoke save fail %{public}d", status); return status; } return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::ObjectStoreRetrieve( const std::string &bundleName, const std::string &sessionId, sptr callback) { ZLOGI("begin."); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback, tokenId); if (status != OBJECT_SUCCESS) { ZLOGE("retrieve fail %{public}d", status); return status; } return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::RegisterDataObserver( const std::string &bundleName, const std::string &sessionId, sptr callback) { ZLOGD("begin."); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } auto pid = IPCSkeleton::GetCallingPid(); ObjectStoreManager::GetInstance()->RegisterRemoteCallback(bundleName, sessionId, pid, tokenId, callback); return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId) { ZLOGD("begin."); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } auto pid = IPCSkeleton::GetCallingPid(); ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(bundleName, pid, tokenId, sessionId); return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) { uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } ObjectStoreManager::GetInstance()->DeleteSnapshot(bundleName, sessionId); return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::IsBundleNameEqualTokenId( const std::string &bundleName, const std::string &sessionId, const uint32_t &tokenId) { DistributedData::CheckerManager::StoreInfo storeInfo; storeInfo.uid = IPCSkeleton::GetCallingUid(); storeInfo.tokenId = tokenId; storeInfo.bundleName = bundleName; storeInfo.storeId = sessionId; std::string appId = DistributedData::CheckerManager::GetInstance().GetAppId(storeInfo); if (appId.empty()) { ZLOGE("object bundleName wrong, bundleName = %{public}s, uid = %{public}d, tokenId = %{public}s", bundleName.c_str(), storeInfo.uid, Anonymous::Change(std::to_string(storeInfo.tokenId)).c_str()); return OBJECT_PERMISSION_DENIED; } return OBJECT_SUCCESS; } void ObjectServiceImpl::Clear() { ZLOGI("begin."); int32_t status = ObjectStoreManager::GetInstance()->Clear(); if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); } } int32_t ObjectServiceImpl::ObjectStatic::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) { int32_t result = ObjectStoreManager::GetInstance()->DeleteByAppId(bundleName, user); if (result != OBJECT_SUCCESS) { ZLOGE("Delete object data failed, result:%{public}d, bundleName:%{public}s, user:%{public}d, index:%{public}d", result, bundleName.c_str(), user, index); return result; } ZLOGI("Delete object data, bundleName:%{public}s, userId:%{public}d, index:%{public}d", bundleName.c_str(), user, index); return result; } int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { ZLOGI("start, user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(), DistributedData::Anonymous::Change(identifier).c_str()); std::vector metaData; auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid }); if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { ZLOGE("no store in user:%{public}s", param.userId.c_str()); return OBJECT_STORE_NOT_FOUND; } for (const auto &storeMeta : metaData) { if (storeMeta.storeType < StoreMetaData::StoreType::STORE_OBJECT_BEGIN || storeMeta.storeType > StoreMetaData::StoreType::STORE_OBJECT_END) { continue; } auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); if (identifier != identifierTag) { continue; } if (storeMeta.bundleName == DistributedData::Bootstrap::GetInstance().GetProcessLabel()) { int32_t status = DistributedObject::ObjectStoreManager::GetInstance()->Open(); if (status != OBJECT_SUCCESS) { ZLOGE("Open fail %{public}d", status); continue; } DistributedObject::ObjectStoreManager::GetInstance()->CloseAfterMinute(); ZLOGI("Auto launch, close after a minute"); return OBJECT_SUCCESS; } } return OBJECT_SUCCESS; } int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) { ZLOGI("ObjectServiceImpl::OnAppExit uid=%{public}d, pid=%{public}d, tokenId=%{public}d, bundleName=%{public}s", uid, pid, tokenId, appId.c_str()); ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(appId, pid, tokenId); return FeatureSystem::STUB_SUCCESS; } ObjectServiceImpl::ObjectServiceImpl() { auto process = [](const Event& event) { auto& evt = static_cast(event); auto eventInfo = evt.GetBindInfo(); StoreMetaData meta; meta.storeId = eventInfo.storeName; meta.bundleName = eventInfo.bundleName; meta.user = std::to_string(eventInfo.user); meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); return; } auto store = AutoCache::GetInstance().GetStore(meta, {}); if (store == nullptr) { ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); return; } auto bindAssets = ObjectStoreManager::GetInstance()->GetSnapShots(eventInfo.bundleName, eventInfo.storeName); store->BindSnapshots(bindAssets); }; EventCenter::GetInstance().Subscribe(BindEvent::BIND_SNAPSHOT, process); } void ObjectServiceImpl::RegisterObjectServiceInfo() { DumpManager::Config serviceInfoConfig; serviceInfoConfig.fullCmd = "--feature-info"; serviceInfoConfig.abbrCmd = "-f"; serviceInfoConfig.dumpName = "FEATURE_INFO"; serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); } void ObjectServiceImpl::RegisterHandler() { Handler handler = std::bind(&ObjectServiceImpl::DumpObjectServiceInfo, this, std::placeholders::_1, std::placeholders::_2); DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); } void ObjectServiceImpl::DumpObjectServiceInfo(int fd, std::map> ¶ms) { (void)params; std::string info; dprintf(fd, "-------------------------------------ObjectServiceInfo------------------------------\n%s\n", info.c_str()); } ObjectServiceImpl::~ObjectServiceImpl() { DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); } int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo) { executors_ = bindInfo.executors; ObjectStoreManager::GetInstance()->SetThreadPool(executors_); ObjectAssetLoader::GetInstance()->SetThreadPool(executors_); return 0; } } // namespace OHOS::DistributedObject