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