1 /*
2 * Copyright (c) 2021-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 #include "sim_ability.h"
17
18 #include "ability_context.h"
19 #include "ability_loader.h"
20 #include "abs_rdb_predicates.h"
21 #include "abs_shared_result_set.h"
22 #include "data_storage_errors.h"
23 #include "data_storage_log_wrapper.h"
24 #include "datashare_ext_ability.h"
25 #include "datashare_predicates.h"
26 #include "new"
27 #include "permission_util.h"
28 #include "rdb_errno.h"
29 #include "rdb_utils.h"
30 #include "sim_data.h"
31 #include "telephony_datashare_stub_impl.h"
32 #include "uri.h"
33 #include "utility"
34 #include "values_bucket.h"
35
36 namespace OHOS {
37 using AbilityRuntime::Extension;
38 using AbilityRuntime::Runtime;
39 using AppExecFwk::Ability;
40 using AppExecFwk::AbilityLoader;
41 namespace Telephony {
42 const int32_t CHANGED_ROWS = 0;
43 static const std::map<std::string, SimUriType> simUriMap_ = {
44 { "/sim/sim_info", SimUriType::SIM_INFO },
45 { "/sim/sim_info/set_card", SimUriType::SET_CARD },
46 };
47
SimAbility()48 SimAbility::SimAbility() : DataShareExtAbility() {}
49
~SimAbility()50 SimAbility::~SimAbility() {}
51
Create()52 SimAbility* SimAbility::Create()
53 {
54 DATA_STORAGE_LOGI("SimAbility::Create begin.");
55 auto self = new SimAbility();
56 self->DoInit();
57 return self;
58 }
59
TelephonyDataShareCreator(const std::unique_ptr<Runtime> & runtime)60 static DataShare::DataShareExtAbility *TelephonyDataShareCreator(const std::unique_ptr<Runtime> &runtime)
61 {
62 DATA_STORAGE_LOGI("sim TelephonyDataCreator::%{public}s begin.", __func__);
63 return SimAbility::Create();
64 }
65
RegisterDataShareCreator()66 __attribute__((constructor)) void RegisterDataShareCreator()
67 {
68 DATA_STORAGE_LOGI("TelephonyDataCreator::%{public}s", __func__);
69 DataShare::DataShareExtAbility::SetCreator(TelephonyDataShareCreator);
70 }
71
DoInit()72 void SimAbility::DoInit()
73 {
74 if (initDatabaseDir && initRdbStore) {
75 DATA_STORAGE_LOGI("DoInit has done");
76 return;
77 }
78 auto abilityContext = AbilityRuntime::Context::GetApplicationContext();
79 if (abilityContext == nullptr) {
80 DATA_STORAGE_LOGE("DoInit GetAbilityContext is null");
81 return;
82 }
83 // switch database dir to el1 for init before unlock
84 abilityContext->SwitchArea(0);
85 std::string path = abilityContext->GetDatabaseDir();
86 DATA_STORAGE_LOGI("GetDatabaseDir: %{public}s", path.c_str());
87 if (!path.empty()) {
88 initDatabaseDir = true;
89 path.append("/");
90 helper_.UpdateDbPath(path);
91 if (helper_.Init() == NativeRdb::E_OK) {
92 initRdbStore = true;
93 } else {
94 DATA_STORAGE_LOGE("DoInit rdb init failed!");
95 initRdbStore = false;
96 }
97 } else {
98 DATA_STORAGE_LOGE("DoInit##databaseDir is empty!");
99 initDatabaseDir = false;
100 }
101 }
102
OnConnect(const AAFwk::Want & want)103 sptr<IRemoteObject> SimAbility::OnConnect(const AAFwk::Want &want)
104 {
105 DATA_STORAGE_LOGI("SimAbility %{public}s begin.", __func__);
106 Extension::OnConnect(want);
107 sptr<DataShare::TelephonyDataShareStubImpl> remoteObject =
108 new (std::nothrow) DataShare::TelephonyDataShareStubImpl();
109 if (remoteObject == nullptr) {
110 DATA_STORAGE_LOGE("%{public}s No memory allocated for DataShareStubImpl", __func__);
111 return nullptr;
112 }
113 remoteObject->SetSimAbility(std::static_pointer_cast<SimAbility>(shared_from_this()));
114 DATA_STORAGE_LOGI("SimAbility %{public}s end.", __func__);
115 return remoteObject->AsObject();
116 }
117
OnStart(const AppExecFwk::Want & want)118 void SimAbility::OnStart(const AppExecFwk::Want &want)
119 {
120 DATA_STORAGE_LOGI("SimAbility::OnStart");
121 Extension::OnStart(want);
122 DoInit();
123 }
124
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)125 int SimAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
126 {
127 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
128 DATA_STORAGE_LOGE("Permission denied!");
129 return DATA_STORAGE_ERR_PERMISSION_ERR;
130 }
131 if (!IsInitOk()) {
132 return DATA_STORAGE_ERROR;
133 }
134 std::lock_guard<std::mutex> guard(lock_);
135 Uri tempUri = uri;
136 SimUriType simUriType = ParseUriType(tempUri);
137 int64_t id = DATA_STORAGE_ERROR;
138 if (simUriType == SimUriType::SIM_INFO) {
139 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
140 helper_.Insert(id, values, TABLE_SIM_INFO);
141 } else {
142 DATA_STORAGE_LOGI("SimAbility::Insert##uri = %{public}s", uri.ToString().c_str());
143 }
144 return id;
145 }
146
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns,DataShare::DatashareBusinessError & businessError)147 std::shared_ptr<DataShare::DataShareResultSet> SimAbility::Query(
148 const Uri &uri, const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns,
149 DataShare::DatashareBusinessError &businessError)
150 {
151 if (!PermissionUtil::CheckPermission(Permission::GET_TELEPHONY_STATE)) {
152 DATA_STORAGE_LOGE("Permission denied!");
153 return nullptr;
154 }
155 std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult = nullptr;
156 if (!IsInitOk()) {
157 return nullptr;
158 }
159 Uri tempUri = uri;
160 SimUriType simUriType = ParseUriType(tempUri);
161 if (simUriType == SimUriType::SIM_INFO) {
162 NativeRdb::AbsRdbPredicates *absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SIM_INFO);
163 if (absRdbPredicates != nullptr) {
164 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
165 auto resultSet = helper_.Query(rdbPredicates, columns);
166 if (resultSet == nullptr) {
167 DATA_STORAGE_LOGE("SimAbility::Query NativeRdb::ResultSet is null!");
168 delete absRdbPredicates;
169 absRdbPredicates = nullptr;
170 return nullptr;
171 }
172 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet);
173 sharedPtrResult = std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
174 delete absRdbPredicates;
175 absRdbPredicates = nullptr;
176 } else {
177 DATA_STORAGE_LOGE("SimAbility::Query NativeRdb::AbsRdbPredicates is null!");
178 }
179 } else {
180 DATA_STORAGE_LOGI("SimAbility::Query failed##uri = %{public}s", uri.ToString().c_str());
181 }
182 return sharedPtrResult;
183 }
184
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)185 int SimAbility::Update(
186 const Uri &uri, const DataShare::DataSharePredicates &predicates,
187 const DataShare::DataShareValuesBucket &value)
188 {
189 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
190 DATA_STORAGE_LOGE("Permission denied!");
191 return DATA_STORAGE_ERR_PERMISSION_ERR;
192 }
193 int result = DATA_STORAGE_ERROR;
194 if (!IsInitOk()) {
195 return result;
196 }
197 std::lock_guard<std::mutex> guard(lock_);
198 Uri tempUri = uri;
199 SimUriType simUriType = ParseUriType(tempUri);
200 switch (simUriType) {
201 case SimUriType::SIM_INFO: {
202 NativeRdb::AbsRdbPredicates *absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SIM_INFO);
203 if (absRdbPredicates != nullptr) {
204 int changedRows = CHANGED_ROWS;
205 NativeRdb::RdbPredicates rdbPredicates =
206 ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
207 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
208 result = helper_.Update(changedRows, values, rdbPredicates);
209 delete absRdbPredicates;
210 absRdbPredicates = nullptr;
211 } else {
212 DATA_STORAGE_LOGE("SimAbility::Update NativeRdb::AbsRdbPredicates is null!");
213 }
214 break;
215 }
216 case SimUriType::SET_CARD: {
217 result = SetCard(value);
218 if (result != NativeRdb::E_OK) {
219 DATA_STORAGE_LOGE("SimAbility::Update SetCard failed!");
220 result = static_cast<int>(LoadProFileErrorType::SET_CARD_FAIL);
221 }
222 break;
223 }
224 default:
225 DATA_STORAGE_LOGI("SimAbility::Update##uri = %{public}s", uri.ToString().c_str());
226 break;
227 }
228 return result;
229 }
230
SetCard(const DataShare::DataShareValuesBucket & sharedValue)231 int SimAbility::SetCard(const DataShare::DataShareValuesBucket &sharedValue)
232 {
233 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
234 DATA_STORAGE_LOGE("Permission denied!");
235 return DATA_STORAGE_ERR_PERMISSION_ERR;
236 }
237 OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(sharedValue);
238 int result = DATA_STORAGE_ERROR;
239 if (!value.HasColumn(SimData::SIM_ID)) {
240 DATA_STORAGE_LOGE("SimAbility::Update##the sim_id in valuesBucket does not exist!");
241 return result;
242 }
243 if (!value.HasColumn(SimData::CARD_TYPE)) {
244 DATA_STORAGE_LOGE("SimAbility::Update##the card_type in valuesBucket does not exist!");
245 return result;
246 }
247 NativeRdb::ValueObject valueObject;
248 bool isExistSimId = value.GetObject(SimData::SIM_ID, valueObject);
249 if (!isExistSimId) {
250 DATA_STORAGE_LOGE("SimAbility::Update##failed to get sim_id value in valuesBucket!");
251 return result;
252 }
253 int simId = 0;
254 valueObject.GetInt(simId);
255
256 bool isExistCardType = value.GetObject(SimData::CARD_TYPE, valueObject);
257 if (!isExistCardType) {
258 DATA_STORAGE_LOGE("SimAbility::Update##failed to get card_type value in valuesBucket!");
259 return result;
260 }
261 int cardType = 0;
262 valueObject.GetInt(cardType);
263 result = helper_.SetDefaultCardByType(simId, cardType);
264 return result;
265 }
266
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)267 int SimAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
268 {
269 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
270 DATA_STORAGE_LOGE("Permission denied!");
271 return DATA_STORAGE_ERR_PERMISSION_ERR;
272 }
273 int result = DATA_STORAGE_ERROR;
274 if (!IsInitOk()) {
275 return result;
276 }
277 std::lock_guard<std::mutex> guard(lock_);
278 Uri tempUri = uri;
279 SimUriType simUriType = ParseUriType(tempUri);
280 if (simUriType == SimUriType::SIM_INFO) {
281 NativeRdb::AbsRdbPredicates *absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SIM_INFO);
282 if (absRdbPredicates != nullptr) {
283 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
284 int deletedRows = 0;
285 result = helper_.Delete(deletedRows, rdbPredicates);
286 delete absRdbPredicates;
287 absRdbPredicates = nullptr;
288 } else {
289 DATA_STORAGE_LOGE("SimAbility::Update NativeRdb::AbsRdbPredicates is null!");
290 }
291 } else {
292 DATA_STORAGE_LOGI("SimAbility::Delete failed##uri = %{public}s", uri.ToString().c_str());
293 }
294 return result;
295 }
296
IsInitOk()297 bool SimAbility::IsInitOk()
298 {
299 if (!initDatabaseDir) {
300 DATA_STORAGE_LOGE("SimAbility::IsInitOk initDatabaseDir failed!");
301 } else if (!initRdbStore) {
302 DATA_STORAGE_LOGE("SimAbility::IsInitOk initRdbStore failed!");
303 }
304 return initDatabaseDir && initRdbStore;
305 }
306
GetType(const Uri & uri)307 std::string SimAbility::GetType(const Uri &uri)
308 {
309 DATA_STORAGE_LOGI("SimAbility::GetType##uri = %{public}s", uri.ToString().c_str());
310 std::string retval(uri.ToString());
311 return retval;
312 }
313
OpenFile(const Uri & uri,const std::string & mode)314 int SimAbility::OpenFile(const Uri &uri, const std::string &mode)
315 {
316 DATA_STORAGE_LOGI("SimAbility::OpenFile##uri = %{public}s", uri.ToString().c_str());
317 Uri tempUri = uri;
318 SimUriType simUriType = ParseUriType(tempUri);
319 return static_cast<int>(simUriType);
320 }
321
ParseUriType(Uri & uri)322 SimUriType SimAbility::ParseUriType(Uri &uri)
323 {
324 DATA_STORAGE_LOGI("SimAbility::ParseUriType start");
325 SimUriType simUriType = SimUriType::UNKNOW;
326 std::string uriPath = uri.ToString();
327 if (!uriPath.empty()) {
328 helper_.ReplaceAllStr(uriPath, ":///", "://");
329 Uri tempUri(uriPath);
330 std::string path = tempUri.GetPath();
331 if (!path.empty() && !simUriMap_.empty()) {
332 DATA_STORAGE_LOGI("SimAbility::ParseUriType##path = %{public}s", path.c_str());
333 auto it = simUriMap_.find(path);
334 if (it != simUriMap_.end()) {
335 simUriType = it->second;
336 DATA_STORAGE_LOGI("SimAbility::ParseUriType##simUriType = %{public}d", simUriType);
337 }
338 }
339 }
340 return simUriType;
341 }
342
ConvertPredicates(const std::string & tableName,const DataShare::DataSharePredicates & predicates)343 OHOS::NativeRdb::RdbPredicates SimAbility::ConvertPredicates(
344 const std::string &tableName, const DataShare::DataSharePredicates &predicates)
345 {
346 OHOS::NativeRdb::RdbPredicates res = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName);
347 return res;
348 }
349 } // namespace Telephony
350 } // namespace OHOS
351