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 "log_print.h"
28 #include "metadata/appid_meta_data.h"
29 #include "metadata/meta_data_manager.h"
30 #include "metadata/store_meta_data.h"
31 #include "permission/permission_validator.h"
32 #include "utils/anonymous.h"
33
34 namespace OHOS::DistributedObject {
35 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
36 using StoreMetaData = OHOS::DistributedData::StoreMetaData;
37 using FeatureSystem = OHOS::DistributedData::FeatureSystem;
38 __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_;
Factory()39 ObjectServiceImpl::Factory::Factory()
40 {
41 FeatureSystem::GetInstance().RegisterCreator(
42 "data_object",
43 []() {
44 return std::make_shared<ObjectServiceImpl>();
45 },
46 FeatureSystem::BIND_NOW);
47 }
48
~Factory()49 ObjectServiceImpl::Factory::~Factory()
50 {
51 }
52
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)53 int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const std::string &sessionId,
54 const std::string &deviceId, const std::map<std::string, std::vector<uint8_t>> &data,
55 sptr<IRemoteObject> callback)
56 {
57 ZLOGI("begin.");
58 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
59 int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
60 if (status != OBJECT_SUCCESS) {
61 return status;
62 }
63 if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) {
64 ZLOGE("object save permission denied");
65 return OBJECT_PERMISSION_DENIED;
66 }
67 status = ObjectStoreManager::GetInstance()->Save(bundleName, sessionId, data, deviceId, callback);
68 if (status != OBJECT_SUCCESS) {
69 ZLOGE("save fail %{public}d", status);
70 }
71 return status;
72 }
73
OnInitialize()74 int32_t ObjectServiceImpl::OnInitialize()
75 {
76 ZLOGI("Initialize");
77 auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
78 if (localDeviceId.empty()) {
79 ZLOGE("failed to get local device id");
80 return OBJECT_INNER_ERROR;
81 }
82 auto token = IPCSkeleton::GetCallingTokenID();
83 const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId();
84 const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token);
85 StoreMetaData saveMeta;
86 saveMeta.appType = "default";
87 saveMeta.deviceId = localDeviceId;
88 saveMeta.storeId = DistributedObject::ObjectCommon::OBJECTSTORE_DB_STOREID;
89 saveMeta.isAutoSync = false;
90 saveMeta.isBackup = false;
91 saveMeta.isEncrypt = false;
92 saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel();
93 saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel();
94 saveMeta.user = std::to_string(userId);
95 saveMeta.account = accountId;
96 saveMeta.tokenId = token;
97 saveMeta.securityLevel = DistributedKv::SecurityLevel::S1;
98 saveMeta.area = 1;
99 saveMeta.uid = IPCSkeleton::GetCallingUid();
100 saveMeta.storeType = ObjectDistributedType::OBJECT_SINGLE_VERSION;
101 saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta);
102 ObjectStoreManager::GetInstance()->SetData(saveMeta.dataDir, std::to_string(userId));
103 auto saved = DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta);
104 if (!saved) {
105 ZLOGE("SaveMeta failed");
106 return OBJECT_INNER_ERROR;
107 }
108 DistributedData::AppIDMetaData appIdMeta;
109 appIdMeta.bundleName = saveMeta.bundleName;
110 appIdMeta.appId = saveMeta.appId;
111 saved = DistributedData::MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true);
112 if (!saved) {
113 ZLOGE("Save appIdMeta failed");
114 }
115 ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s",
116 saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str());
117 return OBJECT_SUCCESS;
118 }
119
OnUserChange(uint32_t code,const std::string & user,const std::string & account)120 int32_t ObjectServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account)
121 {
122 if (code == uint32_t(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) {
123 Clear();
124 }
125 return Feature::OnUserChange(code, user, account);
126 }
127
ObjectStoreRevokeSave(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)128 int32_t ObjectServiceImpl::ObjectStoreRevokeSave(
129 const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
130 {
131 ZLOGI("begin.");
132 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
133 int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
134 if (status != OBJECT_SUCCESS) {
135 return status;
136 }
137 if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) {
138 ZLOGE("object revoke save permission denied");
139 return OBJECT_PERMISSION_DENIED;
140 }
141 status = ObjectStoreManager::GetInstance()->RevokeSave(bundleName, sessionId, callback);
142 if (status != OBJECT_SUCCESS) {
143 ZLOGE("revoke save fail %{public}d", status);
144 }
145 return OBJECT_SUCCESS;
146 }
147
ObjectStoreRetrieve(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)148 int32_t ObjectServiceImpl::ObjectStoreRetrieve(
149 const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
150 {
151 ZLOGI("begin.");
152 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
153 int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
154 if (status != OBJECT_SUCCESS) {
155 return status;
156 }
157 if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) {
158 ZLOGE("object retrieve permission denied");
159 return OBJECT_PERMISSION_DENIED;
160 }
161 status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback);
162 if (status != OBJECT_SUCCESS) {
163 ZLOGE("retrieve fail %{public}d", status);
164 }
165 return OBJECT_SUCCESS;
166 }
167
RegisterDataObserver(const std::string & bundleName,const std::string & sessionId,sptr<IRemoteObject> callback)168 int32_t ObjectServiceImpl::RegisterDataObserver(
169 const std::string &bundleName, const std::string &sessionId, sptr<IRemoteObject> callback)
170 {
171 ZLOGD("begin.");
172 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
173 int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
174 if (status != OBJECT_SUCCESS) {
175 return status;
176 }
177 auto pid = IPCSkeleton::GetCallingPid();
178 ObjectStoreManager::GetInstance()->RegisterRemoteCallback(bundleName, sessionId, pid, tokenId, callback);
179 return OBJECT_SUCCESS;
180 }
181
UnregisterDataChangeObserver(const std::string & bundleName,const std::string & sessionId)182 int32_t ObjectServiceImpl::UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId)
183 {
184 ZLOGD("begin.");
185 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
186 int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId);
187 if (status != OBJECT_SUCCESS) {
188 return status;
189 }
190 auto pid = IPCSkeleton::GetCallingPid();
191 ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(bundleName, pid, tokenId, sessionId);
192 return OBJECT_SUCCESS;
193 }
194
IsBundleNameEqualTokenId(const std::string & bundleName,const std::string & sessionId,const uint32_t & tokenId)195 int32_t ObjectServiceImpl::IsBundleNameEqualTokenId(
196 const std::string &bundleName, const std::string &sessionId, const uint32_t &tokenId)
197 {
198 DistributedData::CheckerManager::StoreInfo storeInfo;
199 storeInfo.uid = IPCSkeleton::GetCallingUid();
200 storeInfo.tokenId = tokenId;
201 storeInfo.bundleName = bundleName;
202 storeInfo.storeId = sessionId;
203 std::string appId = DistributedData::CheckerManager::GetInstance().GetAppId(storeInfo);
204 if (appId.empty()) {
205 ZLOGE("object bundleName wrong, bundleName = %{public}s, uid = %{public}d, tokenId = 0x%{public}x",
206 bundleName.c_str(), storeInfo.uid, storeInfo.tokenId);
207 return OBJECT_PERMISSION_DENIED;
208 }
209 return OBJECT_SUCCESS;
210 }
211
Clear()212 void ObjectServiceImpl::Clear()
213 {
214 ZLOGI("begin.");
215 int32_t status = ObjectStoreManager::GetInstance()->Clear();
216 if (status != OBJECT_SUCCESS) {
217 ZLOGE("save fail %{public}d", status);
218 }
219 return;
220 }
221
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)222 int32_t ObjectServiceImpl::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index)
223 {
224 ZLOGI("begin. %{public}s", bundleName.c_str());
225 int32_t result = ObjectStoreManager::GetInstance()->DeleteByAppId(bundleName);
226 if (result != OBJECT_SUCCESS) {
227 pid_t uid = IPCSkeleton::GetCallingUid();
228 ZLOGE("Delete fail %{public}d, bundleName = %{public}s, uid = %{public}d",
229 result, bundleName.c_str(), uid);
230 }
231 return result;
232 }
233
ResolveAutoLaunch(const std::string & identifier,DistributedDB::AutoLaunchParam & param)234 int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m)
235 {
236 ZLOGI("ObjectServiceImpl::ResolveAutoLaunch start");
237 ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
238 param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(),
239 DistributedData::Anonymous::Change(identifier).c_str());
240 std::vector<StoreMetaData> metaData;
241 auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid, param.userId });
242 if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
243 ZLOGE("no store in user:%{public}s", param.userId.c_str());
244 return OBJECT_STORE_NOT_FOUND;
245 }
246
247 for (const auto &storeMeta : metaData) {
248 if (storeMeta.storeType < StoreMetaData::StoreType::STORE_OBJECT_BEGIN
249 || storeMeta.storeType > StoreMetaData::StoreType::STORE_OBJECT_END) {
250 continue;
251 }
252 auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId,
253 storeMeta.storeId, true);
254 if (identifier != identifierTag) {
255 continue;
256 }
257 if (storeMeta.bundleName == DistributedData::Bootstrap::GetInstance().GetProcessLabel()) {
258 int32_t status = DistributedObject::ObjectStoreManager::GetInstance()->Open();
259 if (status != OBJECT_SUCCESS) {
260 ZLOGE("Open fail %{public}d", status);
261 continue;
262 }
263 DistributedObject::ObjectStoreManager::GetInstance()->CloseAfterMinute();
264 return OBJECT_SUCCESS;
265 }
266 }
267 return OBJECT_SUCCESS;
268 }
269
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & appId)270 int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId)
271 {
272 ZLOGI("ObjectServiceImpl::OnAppExit uid=%{public}d, pid=%{public}d, tokenId=%{public}d, bundleName=%{public}s",
273 uid, pid, tokenId, appId.c_str());
274 ObjectStoreManager::GetInstance()->UnregisterRemoteCallback(appId, pid, tokenId);
275 return FeatureSystem::STUB_SUCCESS;
276 }
277
ObjectServiceImpl()278 ObjectServiceImpl::ObjectServiceImpl()
279 {
280 }
281
OnBind(const BindInfo & bindInfo)282 int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo)
283 {
284 executors_ = bindInfo.executors;
285 ObjectStoreManager::GetInstance()->SetThreadPool(executors_);
286 return 0;
287 }
288 } // namespace OHOS::DistributedObject
289