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