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