1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "ObjectServiceImpl"
17 
18 #include "object_service_impl.h"
19 
20 #include <ipc_skeleton.h>
21 
22 #include "accesstoken_kit.h"
23 #include "account/account_delegate.h"
24 #include "bootstrap.h"
25 #include "checker/checker_manager.h"
26 #include "device_manager_adapter.h"
27 #include "directory/directory_manager.h"
28 #include "dump/dump_manager.h"
29 #include "eventcenter/event_center.h"
30 #include "log_print.h"
31 #include "metadata/appid_meta_data.h"
32 #include "metadata/meta_data_manager.h"
33 #include "metadata/store_meta_data.h"
34 #include "object_asset_loader.h"
35 #include "object_dms_handler.h"
36 #include "snapshot/bind_event.h"
37 #include "store/auto_cache.h"
38 #include "utils/anonymous.h"
39 #include "object_radar_reporter.h"
40 
41 namespace OHOS::DistributedObject {
42 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
43 using StoreMetaData = OHOS::DistributedData::StoreMetaData;
44 using FeatureSystem = OHOS::DistributedData::FeatureSystem;
45 using DumpManager = OHOS::DistributedData::DumpManager;
46 __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_;
Factory()47 ObjectServiceImpl::Factory::Factory()
48 {
49     FeatureSystem::GetInstance().RegisterCreator(
50         "data_object",
51         []() {
52             return std::make_shared<ObjectServiceImpl>();
53         },
54         FeatureSystem::BIND_NOW);
55     staticActs_ = std::make_shared<ObjectStatic>();
56     FeatureSystem::GetInstance().RegisterStaticActs("data_object", staticActs_);
57 }
58 
~Factory()59 ObjectServiceImpl::Factory::~Factory()
60 {
61 }
62 
ObjectStoreSave(const std::string & bundleName,const std::string & sessionId,const std::string & deviceId,const std::map<std::string,std::vector<uint8_t>> & data,sptr<IRemoteObject> callback)63 int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const std::string &sessionId,
64     const std::string &deviceId, const std::map<std::string, std::vector<uint8_t>> &data,
65     sptr<IRemoteObject> callback)
66 {
67     ZLOGI("begin.");
68     ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE,
69         ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE);
70     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
71     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
72     if (status != OBJECT_SUCCESS) {
73         return status;
74     }
75     status = ObjectStoreManager::GetInstance()->Save(bundleName, sessionId, data, deviceId, callback);
76     if (status != OBJECT_SUCCESS) {
77         ZLOGE("save fail %{public}d", status);
78     }
79     ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE,
80         ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS);
81     return status;
82 }
83 
OnAssetChanged(const std::string & bundleName,const std::string & sessionId,const std::string & deviceId,const ObjectStore::Asset & assetValue)84 int32_t ObjectServiceImpl::OnAssetChanged(const std::string &bundleName, const std::string &sessionId,
85     const std::string &deviceId, const ObjectStore::Asset &assetValue)
86 {
87     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
88     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
89     if (status != OBJECT_SUCCESS) {
90         return status;
91     }
92     status = ObjectStoreManager::GetInstance()->OnAssetChanged(tokenId, bundleName, sessionId, deviceId, assetValue);
93     if (status != OBJECT_SUCCESS) {
94         ZLOGE("file transfer failed fail %{public}d", status);
95     }
96     return status;
97 }
98 
BindAssetStore(const std::string & bundleName,const std::string & sessionId,ObjectStore::Asset & asset,ObjectStore::AssetBindInfo & bindInfo)99 int32_t ObjectServiceImpl::BindAssetStore(const std::string &bundleName, const std::string &sessionId,
100     ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo)
101 {
102     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
103     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
104     if (status != OBJECT_SUCCESS) {
105         return status;
106     }
107     status = ObjectStoreManager::GetInstance()->BindAsset(tokenId, bundleName, sessionId, asset, bindInfo);
108     if (status != OBJECT_SUCCESS) {
109         ZLOGE("bind asset fail %{public}d, bundleName:%{public}s, sessionId:%{public}s, assetName:%{public}s", status,
110             bundleName.c_str(), sessionId.c_str(), asset.name.c_str());
111     }
112     return status;
113 }
114 
IsContinue(bool & result)115 int32_t ObjectServiceImpl::IsContinue(bool &result)
116 {
117     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
118     Security::AccessToken::HapTokenInfo tokenInfo;
119     auto status = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
120     if (status != 0) {
121         ZLOGE("Get hap token info failed, tokenId: %{public}u, status: %{public}d", tokenId, status);
122         return status;
123     }
124     result = ObjectDmsHandler::GetInstance().IsContinue(tokenInfo.bundleName);
125     return OBJECT_SUCCESS;
126 }
127 
OnInitialize()128 int32_t ObjectServiceImpl::OnInitialize()
129 {
130     ZLOGI("Initialize");
131     auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
132     if (localDeviceId.empty()) {
133         ZLOGE("failed to get local device id");
134         return OBJECT_INNER_ERROR;
135     }
136     auto token = IPCSkeleton::GetCallingTokenID();
137     const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId();
138     const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token);
139     StoreMetaData saveMeta;
140     saveMeta.appType = "default";
141     saveMeta.deviceId = localDeviceId;
142     saveMeta.storeId = DistributedObject::ObjectCommon::OBJECTSTORE_DB_STOREID;
143     saveMeta.isAutoSync = false;
144     saveMeta.isBackup = false;
145     saveMeta.isEncrypt = false;
146     saveMeta.bundleName =  DistributedData::Bootstrap::GetInstance().GetProcessLabel();
147     saveMeta.appId =  DistributedData::Bootstrap::GetInstance().GetProcessLabel();
148     saveMeta.user = std::to_string(userId);
149     saveMeta.account = accountId;
150     saveMeta.tokenId = token;
151     saveMeta.securityLevel = DistributedKv::SecurityLevel::S1;
152     saveMeta.area = DistributedKv::Area::EL1;
153     saveMeta.uid = IPCSkeleton::GetCallingUid();
154     saveMeta.storeType = ObjectDistributedType::OBJECT_SINGLE_VERSION;
155     saveMeta.dataType = DistributedKv::DataType::TYPE_DYNAMICAL;
156     saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta);
157     ObjectStoreManager::GetInstance()->SetData(saveMeta.dataDir, std::to_string(userId));
158     bool isSaved = DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta) &&
159                    DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta, true);
160     if (!isSaved) {
161         ZLOGE("SaveMeta failed");
162         return OBJECT_INNER_ERROR;
163     }
164     DistributedData::AppIDMetaData appIdMeta;
165     appIdMeta.bundleName = saveMeta.bundleName;
166     appIdMeta.appId = saveMeta.appId;
167     isSaved = DistributedData::MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true);
168     if (!isSaved) {
169         ZLOGE("Save appIdMeta failed");
170     }
171     ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s",
172         saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str());
173     RegisterObjectServiceInfo();
174     RegisterHandler();
175     ObjectDmsHandler::GetInstance().RegisterDmsEvent();
176     return OBJECT_SUCCESS;
177 }
178 
OnUserChange(uint32_t code,const std::string & user,const std::string & account)179 int32_t ObjectServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account)
180 {
181     if (code == static_cast<uint32_t>(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) {
182         Clear();
183     }
184     return Feature::OnUserChange(code, user, account);
185 }
186 
ObjectStoreRevokeSave(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)187 int32_t ObjectServiceImpl::ObjectStoreRevokeSave(
188     const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
189 {
190     ZLOGI("begin.");
191     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
192     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
193     if (status != OBJECT_SUCCESS) {
194         return status;
195     }
196     status = ObjectStoreManager::GetInstance()->RevokeSave(bundleName, sessionId, callback);
197     if (status != OBJECT_SUCCESS) {
198         ZLOGE("revoke save fail %{public}d", status);
199         return status;
200     }
201     return OBJECT_SUCCESS;
202 }
203 
ObjectStoreRetrieve(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)204 int32_t ObjectServiceImpl::ObjectStoreRetrieve(
205     const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
206 {
207     ZLOGI("begin.");
208     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
209     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
210     if (status != OBJECT_SUCCESS) {
211         return status;
212     }
213     status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback, tokenId);
214     if (status != OBJECT_SUCCESS) {
215         ZLOGE("retrieve fail %{public}d", status);
216         return status;
217     }
218     return OBJECT_SUCCESS;
219 }
220 
RegisterDataObserver(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)221 int32_t ObjectServiceImpl::RegisterDataObserver(
222     const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
223 {
224     ZLOGD("begin.");
225     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
226     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
227     if (status != OBJECT_SUCCESS) {
228         return status;
229     }
230     auto pid = IPCSkeleton::GetCallingPid();
231     ObjectStoreManager::GetInstance()->RegisterRemoteCallback(bundleName, sessionId, pid, tokenId, callback);
232     return OBJECT_SUCCESS;
233 }
234 
UnregisterDataChangeObserver(const std::string & bundleName,const std::string & sessionId)235 int32_t ObjectServiceImpl::UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId)
236 {
237     ZLOGD("begin.");
238     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
239     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
240     if (status != OBJECT_SUCCESS) {
241         return status;
242     }
243     auto pid = IPCSkeleton::GetCallingPid();
244     ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(bundleName, pid, tokenId, sessionId);
245     return OBJECT_SUCCESS;
246 }
247 
DeleteSnapshot(const std::string & bundleName,const std::string & sessionId)248 int32_t ObjectServiceImpl::DeleteSnapshot(const std::string &bundleName, const std::string &sessionId)
249 {
250     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
251     int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
252     if (status != OBJECT_SUCCESS) {
253         return status;
254     }
255     ObjectStoreManager::GetInstance()->DeleteSnapshot(bundleName, sessionId);
256     return OBJECT_SUCCESS;
257 }
258 
IsBundleNameEqualTokenId(const std::string & bundleName,const std::string & sessionId,const uint32_t & tokenId)259 int32_t ObjectServiceImpl::IsBundleNameEqualTokenId(
260     const std::string &bundleName, const std::string &sessionId, const uint32_t &tokenId)
261 {
262     DistributedData::CheckerManager::StoreInfo storeInfo;
263     storeInfo.uid = IPCSkeleton::GetCallingUid();
264     storeInfo.tokenId = tokenId;
265     storeInfo.bundleName = bundleName;
266     storeInfo.storeId = sessionId;
267     std::string appId = DistributedData::CheckerManager::GetInstance().GetAppId(storeInfo);
268     if (appId.empty()) {
269         ZLOGE("object bundleName wrong, bundleName = %{public}s, uid = %{public}d, tokenId = %{public}s",
270               bundleName.c_str(), storeInfo.uid, Anonymous::Change(std::to_string(storeInfo.tokenId)).c_str());
271         return OBJECT_PERMISSION_DENIED;
272     }
273     return OBJECT_SUCCESS;
274 }
275 
Clear()276 void ObjectServiceImpl::Clear()
277 {
278     ZLOGI("begin.");
279     int32_t status = ObjectStoreManager::GetInstance()->Clear();
280     if (status != OBJECT_SUCCESS) {
281         ZLOGE("save fail %{public}d", status);
282     }
283 }
284 
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)285 int32_t ObjectServiceImpl::ObjectStatic::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index)
286 {
287     int32_t result = ObjectStoreManager::GetInstance()->DeleteByAppId(bundleName, user);
288     if (result != OBJECT_SUCCESS) {
289         ZLOGE("Delete object data failed, result:%{public}d, bundleName:%{public}s, user:%{public}d, index:%{public}d",
290             result, bundleName.c_str(), user, index);
291         return result;
292     }
293     ZLOGI("Delete object data, bundleName:%{public}s, userId:%{public}d, index:%{public}d", bundleName.c_str(), user,
294         index);
295     return result;
296 }
297 
ResolveAutoLaunch(const std::string & identifier,DistributedDB::AutoLaunchParam & param)298 int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam &param)
299 {
300     ZLOGI("start, user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
301         param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(),
302         DistributedData::Anonymous::Change(identifier).c_str());
303     std::vector<StoreMetaData> metaData;
304     auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid });
305     if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
306         ZLOGE("no store in user:%{public}s", param.userId.c_str());
307         return OBJECT_STORE_NOT_FOUND;
308     }
309 
310     for (const auto &storeMeta : metaData) {
311         if (storeMeta.storeType < StoreMetaData::StoreType::STORE_OBJECT_BEGIN
312             || storeMeta.storeType > StoreMetaData::StoreType::STORE_OBJECT_END) {
313             continue;
314         }
315         auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId,
316                                                                                          storeMeta.storeId, true);
317         if (identifier != identifierTag) {
318             continue;
319         }
320         if (storeMeta.bundleName == DistributedData::Bootstrap::GetInstance().GetProcessLabel()) {
321             int32_t status = DistributedObject::ObjectStoreManager::GetInstance()->Open();
322             if (status != OBJECT_SUCCESS) {
323                 ZLOGE("Open fail %{public}d", status);
324                 continue;
325             }
326             DistributedObject::ObjectStoreManager::GetInstance()->CloseAfterMinute();
327             ZLOGI("Auto launch, close after a minute");
328             return OBJECT_SUCCESS;
329         }
330     }
331     return OBJECT_SUCCESS;
332 }
333 
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & appId)334 int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId)
335 {
336     ZLOGI("ObjectServiceImpl::OnAppExit uid=%{public}d, pid=%{public}d, tokenId=%{public}d, bundleName=%{public}s",
337           uid, pid, tokenId, appId.c_str());
338     ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(appId, pid, tokenId);
339     return FeatureSystem::STUB_SUCCESS;
340 }
341 
ObjectServiceImpl()342 ObjectServiceImpl::ObjectServiceImpl()
343 {
344     auto process = [](const Event& event) {
345         auto& evt = static_cast<const BindEvent&>(event);
346         auto eventInfo = evt.GetBindInfo();
347         StoreMetaData meta;
348         meta.storeId = eventInfo.storeName;
349         meta.bundleName = eventInfo.bundleName;
350         meta.user = std::to_string(eventInfo.user);
351         meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
352         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) {
353             ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
354                 meta.GetStoreAlias().c_str());
355             return;
356         }
357         auto store = AutoCache::GetInstance().GetStore(meta, {});
358         if (store == nullptr) {
359             ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str());
360             return;
361         }
362         auto bindAssets = ObjectStoreManager::GetInstance()->GetSnapShots(eventInfo.bundleName, eventInfo.storeName);
363         store->BindSnapshots(bindAssets);
364     };
365     EventCenter::GetInstance().Subscribe(BindEvent::BIND_SNAPSHOT, process);
366 }
367 
RegisterObjectServiceInfo()368 void ObjectServiceImpl::RegisterObjectServiceInfo()
369 {
370     DumpManager::Config serviceInfoConfig;
371     serviceInfoConfig.fullCmd = "--feature-info";
372     serviceInfoConfig.abbrCmd = "-f";
373     serviceInfoConfig.dumpName = "FEATURE_INFO";
374     serviceInfoConfig.dumpCaption = { "| Display all the service statistics" };
375     DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig);
376 }
377 
RegisterHandler()378 void ObjectServiceImpl::RegisterHandler()
379 {
380     Handler handler =
381         std::bind(&ObjectServiceImpl::DumpObjectServiceInfo, this, std::placeholders::_1, std::placeholders::_2);
382     DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler);
383 }
384 
DumpObjectServiceInfo(int fd,std::map<std::string,std::vector<std::string>> & params)385 void ObjectServiceImpl::DumpObjectServiceInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
386 {
387     (void)params;
388     std::string info;
389     dprintf(fd, "-------------------------------------ObjectServiceInfo------------------------------\n%s\n",
390         info.c_str());
391 }
~ObjectServiceImpl()392 ObjectServiceImpl::~ObjectServiceImpl()
393 {
394     DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this));
395 }
396 
OnBind(const BindInfo & bindInfo)397 int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo)
398 {
399     executors_ = bindInfo.executors;
400     ObjectStoreManager::GetInstance()->SetThreadPool(executors_);
401     ObjectAssetLoader::GetInstance()->SetThreadPool(executors_);
402     return 0;
403 }
404 } // namespace OHOS::DistributedObject
405