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 "pdp_profile_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 "pdp_profile_data.h"
28 #include "permission_util.h"
29 #include "preferences_util.h"
30 #include "rdb_errno.h"
31 #include "rdb_utils.h"
32 #include "telephony_datashare_stub_impl.h"
33 #include "uri.h"
34 #include "utility"
35
36 namespace OHOS {
37 using AppExecFwk::Ability;
38 using AppExecFwk::AbilityLoader;
39 namespace Telephony {
40 const int32_t CHANGED_ROWS = 0;
41 static const std::map<std::string, PdpProfileUriType> pdpProfileUriMap_ = {
42 { "/net/pdp_profile", PdpProfileUriType::PDP_PROFILE },
43 { "/net/pdp_profile/reset", PdpProfileUriType::RESET },
44 { "/net/pdp_profile/preferapn", PdpProfileUriType::PREFER_APN },
45 };
46
PdpProfileAbility()47 PdpProfileAbility::PdpProfileAbility() : DataShareExtAbility() {}
48
~PdpProfileAbility()49 PdpProfileAbility::~PdpProfileAbility() {}
50
Create()51 PdpProfileAbility* PdpProfileAbility::Create()
52 {
53 DATA_STORAGE_LOGI("PdpProfileAbility::Create begin.");
54 auto self = new PdpProfileAbility();
55 self->DoInit();
56 return self;
57 }
58
DoInit()59 void PdpProfileAbility::DoInit()
60 {
61 if (initDatabaseDir && initRdbStore) {
62 DATA_STORAGE_LOGE("DoInit has done");
63 return;
64 }
65 auto abilityContext = AbilityRuntime::Context::GetApplicationContext();
66 if (abilityContext == nullptr) {
67 DATA_STORAGE_LOGE("DoInit GetAbilityContext is null");
68 return;
69 }
70 // switch database dir to el1 for init before unlock
71 abilityContext->SwitchArea(0);
72 std::string path = abilityContext->GetDatabaseDir();
73 DATA_STORAGE_LOGI("GetDatabaseDir: %{public}s", path.c_str());
74 if (!path.empty()) {
75 initDatabaseDir = true;
76 path.append("/");
77 helper_.UpdateDbPath(path);
78 auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
79 if (preferencesUtil != nullptr) {
80 preferencesUtil->UpdatePath(path);
81 }
82 int rdbInitCode = helper_.Init();
83 if (rdbInitCode == NativeRdb::E_OK) {
84 initRdbStore = true;
85 } else {
86 DATA_STORAGE_LOGE("DoInit rdb init fail!");
87 initRdbStore = false;
88 }
89 } else {
90 DATA_STORAGE_LOGE("DoInit##databaseDir is empty!");
91 initDatabaseDir = false;
92 }
93 }
94
OnConnect(const AAFwk::Want & want)95 sptr<IRemoteObject> PdpProfileAbility::OnConnect(const AAFwk::Want &want)
96 {
97 DATA_STORAGE_LOGI("PdpProfileAbility %{public}s begin.", __func__);
98 Extension::OnConnect(want);
99 sptr<DataShare::TelephonyDataShareStubImpl> remoteObject =
100 new (std::nothrow) DataShare::TelephonyDataShareStubImpl();
101 if (remoteObject == nullptr) {
102 DATA_STORAGE_LOGE("%{public}s No memory allocated for DataShareStubImpl", __func__);
103 return nullptr;
104 }
105 remoteObject->SetPdpProfileAbility(std::static_pointer_cast<PdpProfileAbility>(shared_from_this()));
106 DATA_STORAGE_LOGI("PdpProfileAbility %{public}s end.", __func__);
107 return remoteObject->AsObject();
108 }
109
OnStart(const AppExecFwk::Want & want)110 void PdpProfileAbility::OnStart(const AppExecFwk::Want &want)
111 {
112 DATA_STORAGE_LOGI("PdpProfileAbility::OnStart");
113 Extension::OnStart(want);
114 DoInit();
115 }
116
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)117 int PdpProfileAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
118 {
119 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
120 DATA_STORAGE_LOGE("Permission denied!");
121 return DATA_STORAGE_ERR_PERMISSION_ERR;
122 }
123 if (!IsInitOk()) {
124 return DATA_STORAGE_ERROR;
125 }
126 std::lock_guard<std::mutex> guard(lock_);
127 Uri tempUri = uri;
128 PdpProfileUriType pdpProfileUriType = ParseUriType(tempUri);
129 int64_t id = DATA_STORAGE_ERROR;
130 if (pdpProfileUriType == PdpProfileUriType::PDP_PROFILE) {
131 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
132 helper_.Insert(id, values, TABLE_PDP_PROFILE);
133 } else {
134 DATA_STORAGE_LOGE("PdpProfileAbility::Insert##uri = %{public}s", uri.ToString().c_str());
135 }
136 return id;
137 }
138
GetQueryKey(const std::string & queryString,const std::string & key)139 std::string PdpProfileAbility::GetQueryKey(const std::string &queryString, const std::string &key)
140 {
141 size_t pos = queryString.find(key);
142 if (pos != std::string::npos) {
143 return queryString.substr(pos + key.length());
144 }
145 return "";
146 }
147
GetPreferApn(const std::string & queryString)148 int PdpProfileAbility::GetPreferApn(const std::string &queryString)
149 {
150 auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
151 if (preferencesUtil == nullptr) {
152 DATA_STORAGE_LOGE("preferencesUtil is nullptr!");
153 return NativePreferences::E_ERROR;
154 }
155 return preferencesUtil->ObtainInt(PREFER_APN_ID + GetQueryKey(queryString, "simId="), INVALID_PROFILE_ID);
156 }
157
SetPreferApn(int simId,int profileId)158 int PdpProfileAbility::SetPreferApn(int simId, int profileId)
159 {
160 auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
161 if (preferencesUtil == nullptr) {
162 DATA_STORAGE_LOGE("preferencesUtil is nullptr!");
163 return NativePreferences::E_ERROR;
164 }
165 return preferencesUtil->SaveInt(PREFER_APN_ID + std::to_string(simId), profileId);
166 }
167
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns,DataShare::DatashareBusinessError & businessError)168 std::shared_ptr<DataShare::DataShareResultSet> PdpProfileAbility::Query(const Uri &uri,
169 const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns,
170 DataShare::DatashareBusinessError &businessError)
171 {
172 if (!PermissionUtil::CheckPermission(Permission::GET_TELEPHONY_STATE)) {
173 DATA_STORAGE_LOGE("Permission denied!");
174 return nullptr;
175 }
176 std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult = nullptr;
177 if (!IsInitOk()) {
178 return nullptr;
179 }
180 Uri tempUri = uri;
181 PdpProfileUriType pdpProfileUriType = ParseUriType(tempUri);
182 if (pdpProfileUriType == PdpProfileUriType::PDP_PROFILE || pdpProfileUriType == PdpProfileUriType::PREFER_APN) {
183 NativeRdb::AbsRdbPredicates *absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_PDP_PROFILE);
184 if (absRdbPredicates == nullptr) {
185 DATA_STORAGE_LOGE("PdpProfileAbility::Query NativeRdb::AbsRdbPredicates is null!");
186 return sharedPtrResult;
187 }
188 NativeRdb::RdbPredicates rdbPredicates("");
189 if (pdpProfileUriType == PdpProfileUriType::PREFER_APN) {
190 DataShare::DataSharePredicates preferapnPredicates;
191 preferapnPredicates.EqualTo(PdpProfileData::PROFILE_ID, GetPreferApn(tempUri.GetQuery()));
192 rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), preferapnPredicates);
193 } else if (pdpProfileUriType == PdpProfileUriType::PDP_PROFILE) {
194 rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
195 }
196 auto result = helper_.Query(rdbPredicates, columns);
197 if (result == nullptr) {
198 DATA_STORAGE_LOGE("PdpProfileAbility::Query NativeRdb::ResultSet is null!");
199 delete absRdbPredicates;
200 return nullptr;
201 }
202 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
203 sharedPtrResult = std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
204 delete absRdbPredicates;
205 return sharedPtrResult;
206 }
207 DATA_STORAGE_LOGE("PdpProfileAbility::Query##uri = %{public}s", uri.ToString().c_str());
208 return sharedPtrResult;
209 }
210
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)211 int PdpProfileAbility::Update(
212 const Uri &uri, const DataShare::DataSharePredicates &predicates,
213 const DataShare::DataShareValuesBucket &value)
214 {
215 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
216 DATA_STORAGE_LOGE("Permission denied!");
217 return DATA_STORAGE_ERR_PERMISSION_ERR;
218 }
219 int result = DATA_STORAGE_ERROR;
220 if (!IsInitOk()) {
221 return result;
222 }
223 std::lock_guard<std::mutex> guard(lock_);
224 Uri tempUri = uri;
225 PdpProfileUriType pdpProfileUriType = ParseUriType(tempUri);
226 NativeRdb::AbsRdbPredicates *absRdbPredicates = nullptr;
227 switch (pdpProfileUriType) {
228 case PdpProfileUriType::PDP_PROFILE: {
229 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_PDP_PROFILE);
230 break;
231 }
232 case PdpProfileUriType::RESET: {
233 result = helper_.ResetApn();
234 if (result != NativeRdb::E_OK) {
235 DATA_STORAGE_LOGE("PdpProfileAbility::Update ResetApn fail!");
236 result = static_cast<int>(LoadProFileErrorType::RESET_APN_FAIL);
237 }
238 break;
239 }
240 case PdpProfileUriType::PREFER_APN: {
241 result = (UpdatePreferApn(value) == NativeRdb::E_OK)
242 ? NativeRdb::E_OK
243 : static_cast<int>(LoadProFileErrorType::PREFER_APN_FAIL);
244 break;
245 }
246 default:
247 DATA_STORAGE_LOGE("PdpProfileAbility::Update##uri = %{public}s", uri.ToString().c_str());
248 break;
249 }
250 if (absRdbPredicates != nullptr) {
251 int changedRows = CHANGED_ROWS;
252 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
253 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
254 result = helper_.Update(changedRows, values, rdbPredicates);
255 delete absRdbPredicates;
256 absRdbPredicates = nullptr;
257 } else if (result == DATA_STORAGE_ERROR) {
258 DATA_STORAGE_LOGE("PdpProfileAbility::Update NativeRdb::AbsRdbPredicates is null!");
259 }
260 return result;
261 }
262
UpdatePreferApn(const DataShare::DataShareValuesBucket & sharedValue)263 int PdpProfileAbility::UpdatePreferApn(const DataShare::DataShareValuesBucket &sharedValue)
264 {
265 OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(sharedValue);
266 int result = DATA_STORAGE_ERROR;
267 NativeRdb::ValueObject valueObject;
268 if (!HasColumnValue(value, PdpProfileData::PROFILE_ID, valueObject)) {
269 return result;
270 }
271 double temp = 0;
272 int profileId = INVALID_PROFILE_ID;
273 if (valueObject.GetDouble(temp) == NativeRdb::E_OK) {
274 profileId = ceil(temp);
275 }
276 if (!HasColumnValue(value, PdpProfileData::SIM_ID, valueObject)) {
277 return result;
278 }
279 int simId = DEFAULT_SIM_ID;
280 if (valueObject.GetDouble(temp) == NativeRdb::E_OK) {
281 simId = ceil(temp);
282 }
283 return SetPreferApn(simId, profileId);
284 }
285
HasColumnValue(const OHOS::NativeRdb::ValuesBucket & value,const char * columnName,NativeRdb::ValueObject & valueObject)286 bool PdpProfileAbility::HasColumnValue(
287 const OHOS::NativeRdb::ValuesBucket &value, const char *columnName, NativeRdb::ValueObject &valueObject)
288 {
289 if (!value.HasColumn(columnName)) {
290 DATA_STORAGE_LOGE("the column in valuesBucket does not exist!");
291 return false;
292 }
293 bool isExistValue = value.GetObject(columnName, valueObject);
294 if (!isExistValue) {
295 DATA_STORAGE_LOGE("failed to get value in valuesBucket!");
296 return false;
297 }
298 return true;
299 }
300
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)301 int PdpProfileAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
302 {
303 if (!PermissionUtil::CheckPermission(Permission::SET_TELEPHONY_STATE)) {
304 DATA_STORAGE_LOGE("Permission denied!");
305 return DATA_STORAGE_ERR_PERMISSION_ERR;
306 }
307 int result = DATA_STORAGE_ERROR;
308 if (!IsInitOk()) {
309 return result;
310 }
311 std::lock_guard<std::mutex> guard(lock_);
312 Uri tempUri = uri;
313 PdpProfileUriType pdpProfileUriType = ParseUriType(tempUri);
314 if (pdpProfileUriType == PdpProfileUriType::PDP_PROFILE) {
315 NativeRdb::AbsRdbPredicates *absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_PDP_PROFILE);
316 if (absRdbPredicates != nullptr) {
317 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates);
318 int deletedRows = CHANGED_ROWS;
319 result = helper_.Delete(deletedRows, rdbPredicates);
320 delete absRdbPredicates;
321 absRdbPredicates = nullptr;
322 } else {
323 DATA_STORAGE_LOGE("PdpProfileAbility::Delete NativeRdb::AbsRdbPredicates is null!");
324 }
325 } else {
326 DATA_STORAGE_LOGI("PdpProfileAbility::Delete##uri = %{public}s", uri.ToString().c_str());
327 }
328 return result;
329 }
330
IsInitOk()331 bool PdpProfileAbility::IsInitOk()
332 {
333 if (!initDatabaseDir) {
334 DATA_STORAGE_LOGE("PdpProfileAbility::IsInitOk initDatabaseDir failed!");
335 return false;
336 }
337 if (!initRdbStore) {
338 DATA_STORAGE_LOGE("PdpProfileAbility::IsInitOk initRdbStore failed!");
339 return false;
340 }
341 return true;
342 }
343
GetType(const Uri & uri)344 std::string PdpProfileAbility::GetType(const Uri &uri)
345 {
346 DATA_STORAGE_LOGI("PdpProfileAbility::GetType##uri = %{public}s", uri.ToString().c_str());
347 std::string retval(uri.ToString());
348 return retval;
349 }
350
OpenFile(const Uri & uri,const std::string & mode)351 int PdpProfileAbility::OpenFile(const Uri &uri, const std::string &mode)
352 {
353 DATA_STORAGE_LOGI("PdpProfileAbility::OpenFile##uri = %{public}s", uri.ToString().c_str());
354 Uri tempUri = uri;
355 PdpProfileUriType pdpProfileUriType = ParseUriType(tempUri);
356 return static_cast<int>(pdpProfileUriType);
357 }
358
ParseUriType(Uri & uri)359 PdpProfileUriType PdpProfileAbility::ParseUriType(Uri &uri)
360 {
361 DATA_STORAGE_LOGI("PdpProfileAbility::ParseUriType start");
362 PdpProfileUriType pdpProfileUriType = PdpProfileUriType::UNKNOW;
363 std::string uriPath = uri.ToString();
364 if (!uriPath.empty()) {
365 helper_.ReplaceAllStr(uriPath, ":///", "://");
366 Uri tempUri(uriPath);
367 std::string path = tempUri.GetPath();
368 if (!path.empty() && !pdpProfileUriMap_.empty()) {
369 DATA_STORAGE_LOGI("PdpProfileAbility::ParseUriType##path = %{public}s", path.c_str());
370 auto it = pdpProfileUriMap_.find(path);
371 if (it != pdpProfileUriMap_.end()) {
372 pdpProfileUriType = it->second;
373 DATA_STORAGE_LOGI("PdpProfileAbility::ParseUriType##pdpProfileUriType = %{public}d",
374 pdpProfileUriType);
375 }
376 }
377 }
378 return pdpProfileUriType;
379 }
380
ConvertPredicates(const std::string & tableName,const DataShare::DataSharePredicates & predicates)381 OHOS::NativeRdb::RdbPredicates PdpProfileAbility::ConvertPredicates(
382 const std::string &tableName, const DataShare::DataSharePredicates &predicates)
383 {
384 OHOS::NativeRdb::RdbPredicates res = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName);
385 return res;
386 }
387 } // namespace Telephony
388 } // namespace OHOS
389