1 /*
2 * Copyright (C) 2024 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 "advanced_datashare_helper.h"
17
18 #include "ans_const_define.h"
19 #include "ans_log_wrapper.h"
20 #include "if_system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "message_parcel.h"
23 #include "os_account_manager.h"
24 #include "os_account_manager_helper.h"
25 #include "singleton.h"
26 #include "system_ability_definition.h"
27 #include "ipc_skeleton.h"
28 #include "telephony_extension_wrapper.h"
29
30 namespace OHOS {
31 namespace Notification {
32 bool AdvancedDatashareHelper::isDataShareReady_ = false;
33 namespace {
34 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
35 constexpr const char *SETTINGS_DATASHARE_URI =
36 "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
37 constexpr const char *USER_SETTINGS_DATA_URI =
38 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
39 constexpr const char *USER_SETTINGS_DATA_SECURE_URI =
40 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_";
41 constexpr const char *FOCUS_MODE_ENABLE_URI = "?Proxy=true&key=focus_mode_enable";
42 constexpr const char *FOCUS_MODE_PROFILE_URI = "?Proxy=true&key=focus_mode_profile";
43 constexpr const char *INTELLIGENT_EXPERIENCE_URI = "?Proxy=true&key=intelligent_experience";
44 constexpr const char *FOCUS_MODE_CALL_POLICY_URI = "?Proxy=true&key=focus_mode_call_message_policy";
45 constexpr const char *FOCUS_MODE_REPEAT_CALLERS_ENABLE_URI = "?Proxy=true&key=focus_mode_repeate_callers_enable";
46 constexpr const char *UNIFIED_GROUP_ENABLE_URI = "?Proxy=true&key=unified_group_enable";
47 constexpr const char *INTELLIGENT_SCENE_DATA = "?Proxy=true&key=intelligent_scene_data";
48 constexpr const char *INTELLIGENT_URI = "?Proxy=true&key=intelligent_uri";
49 constexpr const char *CONTACT_URI = "datashare:///com.ohos.contactsdataability";
50 constexpr const char *CALLLOG_URI = "datashare:///com.ohos.calllogability";
51 constexpr const char *CALL_SUBSECTION = "datashare:///com.ohos.calllogability/calls/calllog?Proxy=true";
52 constexpr const char *PHONE_NUMBER = "phone_number";
53 constexpr const char *IS_DELETED = "is_deleted";
54 constexpr const char *TYPE_ID = "type_id";
55 constexpr const char *DETAIL_INFO = "detail_info";
56 constexpr const char *FORMAT_PHONE_NUMBER = "format_phone_number";
57 constexpr const char *FAVORITE = "favorite";
58 constexpr const char *FOCUS_MODE_LIST = "focus_mode_list";
59 constexpr const char *MODE_ID = "modeId";
60 constexpr const char *ADVANCED_DATA_COLUMN_KEYWORD = "KEYWORD";
61 constexpr const char *ADVANCED_DATA_COLUMN_VALUE = "VALUE";
62 constexpr const char *CALL_DIRECTION = "call_direction";
63 constexpr const char *CREATE_TIME = "create_time";
64 constexpr const char *WHITE_LIST = "1";
65 constexpr const char *BLACK_LIST = "2";
66 constexpr const char *SUPPORT_INTEGELLIGENT_SCENE = "true";
67 constexpr const unsigned int PHONE_NUMBER_LENGTH = 7;
68 constexpr const unsigned int MAX_TIME_INTERVAL = 15 * 60;
69 constexpr const int TYPE_ID_FIVE = 5;
70 constexpr const int ERROR_QUERY_INFO_FAILED = -1;
71 constexpr const int QUERY_INFO_SUCCESS = 1;
72 std::vector<std::string> QUERY_CONTACT_COLUMN_LIST = {FORMAT_PHONE_NUMBER, FAVORITE, FOCUS_MODE_LIST, DETAIL_INFO};
73 std::vector<std::string> QUERY_INTELLIGENT_COLUMN_LIST = {FORMAT_PHONE_NUMBER, FOCUS_MODE_LIST, DETAIL_INFO};
74 } // namespace
AdvancedDatashareHelper()75 AdvancedDatashareHelper::AdvancedDatashareHelper()
76 {
77 CreateDataShareHelper();
78 }
79
CreateDataShareHelper()80 std::shared_ptr<DataShare::DataShareHelper> AdvancedDatashareHelper::CreateDataShareHelper()
81 {
82 if (!isDataShareReady_) {
83 ANS_LOGE("dataShare is not ready");
84 return nullptr;
85 }
86 sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
87 if (saManager == nullptr) {
88 ANS_LOGE("The sa manager is nullptr.");
89 return nullptr;
90 }
91 sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
92 if (remoteObj == nullptr) {
93 ANS_LOGE("The remoteObj is nullptr.");
94 return nullptr;
95 }
96 return DataShare::DataShareHelper::Creator(remoteObj, SETTINGS_DATASHARE_URI, SETTINGS_DATA_EXT_URI);
97 }
98
CreateContactDataShareHelper(std::string uri)99 std::shared_ptr<DataShare::DataShareHelper> AdvancedDatashareHelper::CreateContactDataShareHelper(std::string uri)
100 {
101 sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
102 if (saManager == nullptr) {
103 ANS_LOGE("The sa manager is nullptr.");
104 return nullptr;
105 }
106 sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
107 if (remoteObj == nullptr) {
108 ANS_LOGE("The remoteObj is nullptr.");
109 return nullptr;
110 }
111 return DataShare::DataShareHelper::Creator(remoteObj, uri);
112 }
113
CreateIntelligentDataShareHelper(std::string uri)114 std::shared_ptr<DataShare::DataShareHelper> AdvancedDatashareHelper::CreateIntelligentDataShareHelper(std::string uri)
115 {
116 sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
117 if (saManager == nullptr) {
118 ANS_LOGE("The sa manager is nullptr.");
119 return nullptr;
120 }
121 sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
122 if (remoteObj == nullptr) {
123 ANS_LOGE("The remoteObj is nullptr.");
124 return nullptr;
125 }
126 auto [error, helper] = DataShare::DataShareHelper::Create(remoteObj, uri, GetIntelligentUri());
127 if (error != DataShare::E_OK) {
128 ANS_LOGE("Create Intelligent DataShareHelper failed.");
129 return nullptr;
130 }
131 return helper;
132 }
133
Query(Uri & uri,const std::string & key,std::string & value)134 bool AdvancedDatashareHelper::Query(Uri &uri, const std::string &key, std::string &value)
135 {
136 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = CreateDataShareHelper();
137 if (dataShareHelper == nullptr) {
138 ANS_LOGE("The data share helper is nullptr.");
139 return false;
140 }
141 DataShare::DataSharePredicates predicates;
142 std::vector<std::string> columns;
143 predicates.EqualTo(ADVANCED_DATA_COLUMN_KEYWORD, key);
144 auto result = dataShareHelper->Query(uri, predicates, columns);
145 if (result == nullptr) {
146 ANS_LOGE("Query error, result is null.");
147 dataShareHelper->Release();
148 return false;
149 }
150 if (result->GoToFirstRow() != DataShare::E_OK) {
151 ANS_LOGE("Query failed, go to first row error.");
152 result->Close();
153 dataShareHelper->Release();
154 return false;
155 }
156 int32_t columnIndex;
157 result->GetColumnIndex(ADVANCED_DATA_COLUMN_VALUE, columnIndex);
158 result->GetString(columnIndex, value);
159 result->Close();
160 ANS_LOGD("Query success, value[%{public}s]", value.c_str());
161 dataShareHelper->Release();
162 return true;
163 }
164
QueryContact(Uri & uri,const std::string & phoneNumber,const std::string & policy,const std::string & profileId,const std::string isSupportIntelligentScene)165 ErrCode AdvancedDatashareHelper::QueryContact(Uri &uri, const std::string &phoneNumber, const std::string &policy,
166 const std::string &profileId, const std::string isSupportIntelligentScene)
167 {
168 std::string identity = IPCSkeleton::ResetCallingIdentity();
169 auto resultSet = GetContactResultSet(uri, phoneNumber, policy, profileId, isSupportIntelligentScene);
170 if (resultSet == nullptr) {
171 ANS_LOGE("QueryContact error, resultSet is null.");
172 return ERROR_QUERY_INFO_FAILED;
173 }
174 IPCSkeleton::SetCallingIdentity(identity);
175 int isFound = 0;
176 int rowCount = 0;
177 resultSet->GetRowCount(rowCount);
178 if (rowCount <= 0) {
179 ANS_LOGI("Query success, but rowCount is 0.");
180 if (atoi(policy.c_str()) == ContactPolicy::FORBID_SPECIFIED_CONTACTS) {
181 isFound = 1;
182 }
183 } else {
184 int resultId = -1;
185 #ifdef ENABLE_ANS_TELEPHONY_CUST_WRAPPER
186 resultId = TEL_EXTENTION_WRAPPER->GetCallerIndex(resultSet, phoneNumber);
187 ANS_LOGI("QueryContact resultId: %{public}d.", resultId);
188 #endif
189 if ((phoneNumber.size() >= PHONE_NUMBER_LENGTH && resultSet->GoToRow(resultId) == DataShare::E_OK) ||
190 (phoneNumber.size() < PHONE_NUMBER_LENGTH && resultSet->GoToFirstRow() == DataShare::E_OK)) {
191 isFound = dealWithContactResult(resultSet, policy) ? QUERY_INFO_SUCCESS : ERR_OK;
192 }
193 }
194 resultSet->Close();
195 return isFound;
196 }
197
GetContactResultSet(Uri & uri,const std::string & phoneNumber,const std::string & policy,const std::string & profileId,const std::string isSupportIntelligentScene)198 std::shared_ptr<DataShare::DataShareResultSet> AdvancedDatashareHelper::GetContactResultSet(Uri &uri,
199 const std::string &phoneNumber, const std::string &policy, const std::string &profileId,
200 const std::string isSupportIntelligentScene)
201 {
202 std::shared_ptr<DataShare::DataShareHelper> helper;
203 std::shared_ptr<DataShare::DataShareResultSet> resultSet;
204 if (isSupportIntelligentScene == SUPPORT_INTEGELLIGENT_SCENE &&
205 (atoi(policy.c_str()) == ContactPolicy::ALLOW_SPECIFIED_CONTACTS ||
206 atoi(policy.c_str()) == ContactPolicy::FORBID_SPECIFIED_CONTACTS)) {
207 helper = CreateIntelligentDataShareHelper(GetIntelligentData(INTELLIGENT_URI, KEY_INTELLIGENT_URI));
208 if (helper == nullptr) {
209 ANS_LOGE("GetContactResultSet, The data share helper is nullptr.");
210 return nullptr;
211 }
212 std::string focusModeList = atoi(policy.c_str()) == ContactPolicy::ALLOW_SPECIFIED_CONTACTS ?
213 WHITE_LIST : BLACK_LIST;
214 ANS_LOGI("GetContactResultSet, profileId: %{public}s, focusModeList: %{public}s",
215 profileId.c_str(), focusModeList.c_str());
216 DataShare::DataSharePredicates predicates;
217 predicates.EqualTo(MODE_ID, profileId);
218 predicates.EqualTo(FOCUS_MODE_LIST, focusModeList);
219 if (phoneNumber.size() >= PHONE_NUMBER_LENGTH) {
220 predicates.EndsWith(DETAIL_INFO,
221 phoneNumber.substr(phoneNumber.size() - PHONE_NUMBER_LENGTH, phoneNumber.size()));
222 } else {
223 predicates.EqualTo(DETAIL_INFO, phoneNumber);
224 }
225 resultSet = helper->Query(uri, predicates, QUERY_INTELLIGENT_COLUMN_LIST);
226 } else {
227 helper = CreateContactDataShareHelper(CONTACT_URI);
228 if (helper == nullptr) {
229 ANS_LOGE("GetContactResultSet, The data share helper is nullptr.");
230 return nullptr;
231 }
232 ANS_LOGE("GetContactResultSet, not support IntelligentScene.");
233 DataShare::DataSharePredicates predicates;
234 predicates.EqualTo(IS_DELETED, 0);
235 predicates.EqualTo(TYPE_ID, TYPE_ID_FIVE);
236 if (phoneNumber.size() >= PHONE_NUMBER_LENGTH) {
237 predicates.EndsWith(DETAIL_INFO,
238 phoneNumber.substr(phoneNumber.size() - PHONE_NUMBER_LENGTH, phoneNumber.size()));
239 } else {
240 predicates.EqualTo(DETAIL_INFO, phoneNumber);
241 }
242 resultSet = helper->Query(uri, predicates, QUERY_CONTACT_COLUMN_LIST);
243 }
244 helper->Release();
245 return resultSet;
246 }
247
dealWithContactResult(std::shared_ptr<DataShare::DataShareResultSet> resultSet,const std::string & policy)248 bool AdvancedDatashareHelper::dealWithContactResult(std::shared_ptr<DataShare::DataShareResultSet> resultSet,
249 const std::string &policy)
250 {
251 bool isNoNeedSilent = false;
252 int32_t columnIndex;
253 int32_t favorite;
254 std::string focus_mode_list;
255 switch (atoi(policy.c_str())) {
256 case ContactPolicy::ALLOW_FAVORITE_CONTACTS:
257 do {
258 resultSet->GetColumnIndex(FAVORITE, columnIndex);
259 resultSet->GetInt(columnIndex, favorite);
260 isNoNeedSilent = favorite == 1;
261 if (isNoNeedSilent) {
262 break;
263 }
264 } while (resultSet->GoToNextRow() == DataShare::E_OK);
265 ANS_LOGI("dealWithContactResult: favorite = %{public}d", favorite);
266 break;
267 case ContactPolicy::ALLOW_SPECIFIED_CONTACTS:
268 case ContactPolicy::FORBID_SPECIFIED_CONTACTS:
269 {
270 do {
271 resultSet->GetColumnIndex(FOCUS_MODE_LIST, columnIndex);
272 resultSet->GetString(columnIndex, focus_mode_list);
273 if (focus_mode_list.empty() || focus_mode_list.c_str()[0] == '0') {
274 isNoNeedSilent = false;
275 }
276 if (focus_mode_list.c_str()[0] == '1') {
277 isNoNeedSilent = true;
278 break;
279 }
280 if (focus_mode_list.c_str()[0] == '2') {
281 isNoNeedSilent = false;
282 break;
283 }
284 } while (resultSet->GoToNextRow() == DataShare::E_OK);
285 ANS_LOGI("dealWithContactResult: focus_mode_list = %{public}s", focus_mode_list.c_str());
286 break;
287 }
288 default:
289 isNoNeedSilent = true;
290 break;
291 }
292 return isNoNeedSilent;
293 }
294
isRepeatCall(const std::string & phoneNumber)295 bool AdvancedDatashareHelper::isRepeatCall(const std::string &phoneNumber)
296 {
297 std::string identity = IPCSkeleton::ResetCallingIdentity();
298 std::shared_ptr<DataShare::DataShareHelper> helper = CreateContactDataShareHelper(CALLLOG_URI);
299 if (helper == nullptr) {
300 ANS_LOGE("The data share helper is nullptr.");
301 return false;
302 }
303 bool isRepeat = false;
304 DataShare::DataSharePredicates predicates;
305 std::vector<std::string> columns;
306 Uri uri(CALL_SUBSECTION);
307 predicates.EqualTo(PHONE_NUMBER, phoneNumber);
308 predicates.EqualTo(CALL_DIRECTION, 0);
309 predicates.OrderByDesc(CREATE_TIME);
310 columns.push_back(CREATE_TIME);
311 auto resultSet = helper->Query(uri, predicates, columns);
312 IPCSkeleton::SetCallingIdentity(identity);
313 if (resultSet == nullptr) {
314 helper->Release();
315 return false;
316 }
317 int rowCount = 0;
318 resultSet->GetRowCount(rowCount);
319 if (rowCount > 0) {
320 int32_t callTime = 0;
321 if (resultSet->GoToFirstRow() == 0) {
322 int32_t columnIndex;
323 resultSet->GetColumnIndex(CREATE_TIME, columnIndex);
324 resultSet->GetInt(columnIndex, callTime);
325 }
326 if (time(NULL) - callTime < MAX_TIME_INTERVAL) {
327 isRepeat = true;
328 }
329 }
330 resultSet->Close();
331 helper->Release();
332 return isRepeat;
333 }
334
GetFocusModeEnableUri(const int32_t & userId) const335 std::string AdvancedDatashareHelper::GetFocusModeEnableUri(const int32_t &userId) const
336 {
337 return USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + FOCUS_MODE_ENABLE_URI;
338 }
339
GetFocusModeProfileUri(const int32_t & userId) const340 std::string AdvancedDatashareHelper::GetFocusModeProfileUri(const int32_t &userId) const
341 {
342 return USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + FOCUS_MODE_PROFILE_URI;
343 }
344
GetIntelligentExperienceUri(const int32_t & userId) const345 std::string AdvancedDatashareHelper::GetIntelligentExperienceUri(const int32_t &userId) const
346 {
347 return USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + INTELLIGENT_EXPERIENCE_URI;
348 }
349
GetFocusModeCallPolicyUri(const int32_t & userId) const350 std::string AdvancedDatashareHelper::GetFocusModeCallPolicyUri(const int32_t &userId) const
351 {
352 return USER_SETTINGS_DATA_URI + std::to_string(userId) + FOCUS_MODE_CALL_POLICY_URI;
353 }
354
GetFocusModeRepeatCallUri(const int32_t & userId) const355 std::string AdvancedDatashareHelper::GetFocusModeRepeatCallUri(const int32_t &userId) const
356 {
357 return USER_SETTINGS_DATA_URI + std::to_string(userId) + FOCUS_MODE_REPEAT_CALLERS_ENABLE_URI;
358 }
359
GetIntelligentData(const std::string & uri,const std::string & key)360 std::string AdvancedDatashareHelper::GetIntelligentData(const std::string &uri, const std::string &key)
361 {
362 std::string value;
363 int32_t userId = SUBSCRIBE_USER_INIT;
364 if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
365 ANS_LOGD("GetActiveUserId is false");
366 return "";
367 }
368
369 Uri tempUri(USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + uri);
370 bool ret = Query(tempUri, key, value);
371 if (!ret) {
372 ANS_LOGE("Query Intelligent Data id fail.");
373 return "";
374 }
375 return value + std::to_string(userId);
376 }
377
GetIntelligentUri()378 std::string AdvancedDatashareHelper::GetIntelligentUri()
379 {
380 return GetIntelligentData(INTELLIGENT_SCENE_DATA, KEY_INTELLIGENT_SCENE_DATA);
381 }
382
SetIsDataShareReady(bool isDataShareReady)383 void AdvancedDatashareHelper::SetIsDataShareReady(bool isDataShareReady)
384 {
385 isDataShareReady_ = isDataShareReady;
386 }
387 } // namespace Notification
388 } // namespace OHOS
389