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_log_wrapper.h"
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "message_parcel.h"
22 #include "os_account_manager.h"
23 #include "singleton.h"
24 #include "system_ability_definition.h"
25 #include "ipc_skeleton.h"
26 #include "telephony_extension_wrapper.h"
27
28 namespace OHOS {
29 namespace Notification {
30 namespace {
31 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
32 constexpr const char *SETTINGS_DATASHARE_URI =
33 "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
34 constexpr const char *USER_SETTINGS_DATA_URI =
35 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
36 constexpr const char *USER_SETTINGS_DATA_SECURE_URI =
37 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_";
38 constexpr const char *FOCUS_MODE_ENABLE_URI = "?Proxy=true&key=focus_mode_enable";
39 constexpr const char *FOCUS_MODE_PROFILE_URI = "?Proxy=true&key=focus_mode_profile";
40 constexpr const char *FOCUS_MODE_CALL_POLICY_URI = "?Proxy=true&key=focus_mode_call_message_policy";
41 constexpr const char *FOCUS_MODE_REPEAT_CALLERS_ENABLE_URI = "?Proxy=true&key=focus_mode_repeate_callers_enable";
42 constexpr const char *UNIFIED_GROUP_ENABLE_URI = "?Proxy=true&key=unified_group_enable";
43 constexpr const char *CONTACT_URI = "datashare:///com.ohos.contactsdataability";
44 constexpr const char *CALLLOG_URI = "datashare:///com.ohos.calllogability";
45 constexpr const char *CALL_SUBSECTION = "datashare:///com.ohos.calllogability/calls/calllog?Proxy=true";
46 constexpr const char *PHONE_NUMBER = "phone_number";
47 constexpr const char *IS_DELETED = "is_deleted";
48 constexpr const char *TYPE_ID = "type_id";
49 constexpr const char *DETAIL_INFO = "detail_info";
50 constexpr const char *FORMAT_PHONE_NUMBER = "format_phone_number";
51 constexpr const char *FAVORITE = "favorite";
52 constexpr const char *FOCUS_MODE_LIST = "focus_mode_list";
53 constexpr const char *ADVANCED_DATA_COLUMN_KEYWORD = "KEYWORD";
54 constexpr const char *ADVANCED_DATA_COLUMN_VALUE = "VALUE";
55 constexpr const char *CALL_DIRECTION = "call_direction";
56 constexpr const char *CREATE_TIME = "create_time";
57 constexpr const unsigned int PHONE_NUMBER_LENGTH = 7;
58 constexpr const unsigned int MAX_TIME_INTERVAL = 15 * 60;
59 constexpr const int TYPE_ID_FIVE = 5;
60 constexpr const int ERROR_QUERY_INFO_FAILED = -1;
61 constexpr const int QUERY_INFO_SUCCESS = 1;
62 std::vector<std::string> QUERY_CONTACT_COLUMN_LIST = {FORMAT_PHONE_NUMBER, FAVORITE, FOCUS_MODE_LIST, DETAIL_INFO};
63 } // namespace
AdvancedDatashareHelper()64 AdvancedDatashareHelper::AdvancedDatashareHelper()
65 {
66 CreateDataShareHelper();
67 }
68
CreateDataShareHelper()69 std::shared_ptr<DataShare::DataShareHelper> AdvancedDatashareHelper::CreateDataShareHelper()
70 {
71 sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72 if (saManager == nullptr) {
73 ANS_LOGE("The sa manager is nullptr.");
74 return nullptr;
75 }
76 sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
77 if (remoteObj == nullptr) {
78 ANS_LOGE("The remoteObj is nullptr.");
79 return nullptr;
80 }
81 return DataShare::DataShareHelper::Creator(remoteObj, SETTINGS_DATASHARE_URI, SETTINGS_DATA_EXT_URI);
82 }
83
CreateContactDataShareHelper(std::string uri)84 std::shared_ptr<DataShare::DataShareHelper> AdvancedDatashareHelper::CreateContactDataShareHelper(std::string uri)
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, uri);
97 }
98
Query(Uri & uri,const std::string & key,std::string & value)99 bool AdvancedDatashareHelper::Query(Uri &uri, const std::string &key, std::string &value)
100 {
101 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = CreateDataShareHelper();
102 if (dataShareHelper == nullptr) {
103 ANS_LOGE("The data share helper is nullptr.");
104 return false;
105 }
106 DataShare::DataSharePredicates predicates;
107 std::vector<std::string> columns;
108 predicates.EqualTo(ADVANCED_DATA_COLUMN_KEYWORD, key);
109 auto result = dataShareHelper->Query(uri, predicates, columns);
110 if (result == nullptr) {
111 ANS_LOGE("Query error, result is null.");
112 dataShareHelper->Release();
113 return false;
114 }
115 if (result->GoToFirstRow() != DataShare::E_OK) {
116 ANS_LOGE("Query failed, go to first row error.");
117 result->Close();
118 dataShareHelper->Release();
119 return false;
120 }
121 int32_t columnIndex;
122 result->GetColumnIndex(ADVANCED_DATA_COLUMN_VALUE, columnIndex);
123 result->GetString(columnIndex, value);
124 result->Close();
125 ANS_LOGD("Query success, value[%{public}s]", value.c_str());
126 dataShareHelper->Release();
127 return true;
128 }
129
QueryContact(Uri & uri,const std::string & phoneNumber,const std::string & policy)130 ErrCode AdvancedDatashareHelper::QueryContact(Uri &uri, const std::string &phoneNumber, const std::string &policy)
131 {
132 std::string identity = IPCSkeleton::ResetCallingIdentity();
133 std::shared_ptr<DataShare::DataShareHelper> helper = CreateContactDataShareHelper(CONTACT_URI);
134 if (helper == nullptr) {
135 ANS_LOGE("The data share helper is nullptr.");
136 return ERROR_QUERY_INFO_FAILED;
137 }
138 DataShare::DataSharePredicates predicates;
139 predicates.EqualTo(IS_DELETED, 0);
140 predicates.EqualTo(TYPE_ID, TYPE_ID_FIVE);
141 if (phoneNumber.size() >= PHONE_NUMBER_LENGTH) {
142 predicates.EndsWith(DETAIL_INFO,
143 phoneNumber.substr(phoneNumber.size() - PHONE_NUMBER_LENGTH, phoneNumber.size()));
144 } else {
145 predicates.EqualTo(DETAIL_INFO, phoneNumber);
146 }
147 auto resultSet = helper->Query(uri, predicates, QUERY_CONTACT_COLUMN_LIST);
148 IPCSkeleton::SetCallingIdentity(identity);
149 if (resultSet == nullptr) {
150 ANS_LOGE("Query error, resultSet is null.");
151 helper->Release();
152 return ERROR_QUERY_INFO_FAILED;
153 }
154 int isFound = 0;
155 int rowCount = 0;
156 resultSet->GetRowCount(rowCount);
157 if (rowCount <= 0) {
158 ANS_LOGI("Query success, but rowCount is 0.");
159 } else {
160 int resultId = -1;
161 #ifdef ENABLE_ANS_TELEPHONY_CUST_WRAPPER
162 resultId = TEL_EXTENTION_WRAPPER->GetCallerIndex(resultSet, phoneNumber);
163 ANS_LOGI("QueryContact resultId: %{public}d.", resultId);
164 #endif
165 if ((phoneNumber.size() >= PHONE_NUMBER_LENGTH && resultSet->GoToRow(resultId) == DataShare::E_OK) ||
166 (phoneNumber.size() < PHONE_NUMBER_LENGTH && resultSet->GoToFirstRow() == DataShare::E_OK)) {
167 isFound = dealWithContactResult(helper, resultSet, policy) ? QUERY_INFO_SUCCESS : ERR_OK;
168 }
169 }
170 resultSet->Close();
171 helper->Release();
172 return isFound;
173 }
174
dealWithContactResult(std::shared_ptr<DataShare::DataShareHelper> helper,std::shared_ptr<DataShare::DataShareResultSet> resultSet,const std::string & policy)175 bool AdvancedDatashareHelper::dealWithContactResult(std::shared_ptr<DataShare::DataShareHelper> helper,
176 std::shared_ptr<DataShare::DataShareResultSet> resultSet, const std::string &policy)
177 {
178 bool isNoNeedSilent = false;
179 int32_t columnIndex;
180 int32_t favorite;
181 std::string focus_mode_list;
182 switch (atoi(policy.c_str())) {
183 case ContactPolicy::ALLOW_FAVORITE_CONTACTS:
184 do {
185 resultSet->GetColumnIndex(FAVORITE, columnIndex);
186 resultSet->GetInt(columnIndex, favorite);
187 isNoNeedSilent = favorite == 1;
188 if (isNoNeedSilent) {
189 break;
190 }
191 } while (resultSet->GoToNextRow() == DataShare::E_OK);
192 ANS_LOGI("dealWithContactResult: favorite = %{public}d", favorite);
193 break;
194 case ContactPolicy::ALLOW_SPECIFIED_CONTACTS:
195 do {
196 resultSet->GetColumnIndex(FOCUS_MODE_LIST, columnIndex);
197 resultSet->GetString(columnIndex, focus_mode_list);
198 if (focus_mode_list.empty() || focus_mode_list.c_str()[0] == '0') {
199 isNoNeedSilent = false;
200 }
201 if (focus_mode_list.c_str()[0] == '1') {
202 isNoNeedSilent = true;
203 break;
204 }
205 } while (resultSet->GoToNextRow() == DataShare::E_OK);
206 ANS_LOGI("dealWithContactResult: focus_mode_list = %{public}s", focus_mode_list.c_str());
207 break;
208 default:
209 isNoNeedSilent = true;
210 break;
211 }
212 return isNoNeedSilent;
213 }
214
isRepeatCall(const std::string & phoneNumber)215 bool AdvancedDatashareHelper::isRepeatCall(const std::string &phoneNumber)
216 {
217 std::string identity = IPCSkeleton::ResetCallingIdentity();
218 std::shared_ptr<DataShare::DataShareHelper> helper = CreateContactDataShareHelper(CALLLOG_URI);
219 if (helper == nullptr) {
220 ANS_LOGE("The data share helper is nullptr.");
221 return false;
222 }
223 bool isRepeat = false;
224 DataShare::DataSharePredicates predicates;
225 std::vector<std::string> columns;
226 Uri uri(CALL_SUBSECTION);
227 predicates.EqualTo(PHONE_NUMBER, phoneNumber);
228 predicates.EqualTo(CALL_DIRECTION, 0);
229 predicates.OrderByDesc(CREATE_TIME);
230 columns.push_back(CREATE_TIME);
231 auto resultSet = helper->Query(uri, predicates, columns);
232 IPCSkeleton::SetCallingIdentity(identity);
233 if (resultSet == nullptr) {
234 helper->Release();
235 return false;
236 }
237 int rowCount = 0;
238 resultSet->GetRowCount(rowCount);
239 if (rowCount > 0) {
240 int32_t callTime = 0;
241 if (resultSet->GoToFirstRow() == 0) {
242 int32_t columnIndex;
243 resultSet->GetColumnIndex(CREATE_TIME, columnIndex);
244 resultSet->GetInt(columnIndex, callTime);
245 }
246 if (time(NULL) - callTime < MAX_TIME_INTERVAL) {
247 isRepeat = true;
248 }
249 }
250 resultSet->Close();
251 helper->Release();
252 return isRepeat;
253 }
254
GetFocusModeEnableUri(const int32_t & userId) const255 std::string AdvancedDatashareHelper::GetFocusModeEnableUri(const int32_t &userId) const
256 {
257 return USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + FOCUS_MODE_ENABLE_URI;
258 }
259
GetFocusModeProfileUri(const int32_t & userId) const260 std::string AdvancedDatashareHelper::GetFocusModeProfileUri(const int32_t &userId) const
261 {
262 return USER_SETTINGS_DATA_SECURE_URI + std::to_string(userId) + FOCUS_MODE_PROFILE_URI;
263 }
264
GetFocusModeCallPolicyUri(const int32_t & userId) const265 std::string AdvancedDatashareHelper::GetFocusModeCallPolicyUri(const int32_t &userId) const
266 {
267 return USER_SETTINGS_DATA_URI + std::to_string(userId) + FOCUS_MODE_CALL_POLICY_URI;
268 }
269
GetFocusModeRepeatCallUri(const int32_t & userId) const270 std::string AdvancedDatashareHelper::GetFocusModeRepeatCallUri(const int32_t &userId) const
271 {
272 return USER_SETTINGS_DATA_URI + std::to_string(userId) + FOCUS_MODE_REPEAT_CALLERS_ENABLE_URI;
273 }
274 } // namespace Notification
275 } // namespace OHOS
276