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