• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "call_records_handler.h"
17 
18 #include "call_manager_base.h"
19 #include "call_manager_errors.h"
20 #include "call_manager_inner_type.h"
21 #include "ffrt.h"
22 #include "call_number_utils.h"
23 
24 namespace OHOS {
25 namespace Telephony {
CallRecordsHandler()26 CallRecordsHandler::CallRecordsHandler() : callDataPtr_(nullptr)
27 {
28     callDataPtr_ = DelayedSingleton<CallDataBaseHelper>::GetInstance();
29     if (callDataPtr_ == nullptr) {
30         TELEPHONY_LOGE("callDataPtr_ is nullptr!");
31     }
32 }
33 
QueryCallerInfo(ContactInfo & contactInfo,std::string phoneNumber)34 void CallRecordsHandler::QueryCallerInfo(ContactInfo &contactInfo, std::string phoneNumber)
35 {
36     std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
37     if (callDataPtr == nullptr) {
38         TELEPHONY_LOGE("callDataPtr is nullptr!");
39         return;
40     }
41     DataShare::DataSharePredicates predicates;
42     predicates.EqualTo(CALL_DETAIL_INFO, phoneNumber);
43     predicates.And();
44     predicates.EqualTo(CALL_CONTENT_TYPE, CALL_PHONE);
45     bool ret = callDataPtr->Query(contactInfo, predicates);
46     if (!ret) {
47         TELEPHONY_LOGE("Query contact database fail!");
48     }
49 }
50 
AddCallLogInfo(const CallRecordInfo & info)51 int32_t CallRecordsHandler::AddCallLogInfo(const CallRecordInfo &info)
52 {
53     if (callDataPtr_ == nullptr) {
54         TELEPHONY_LOGE("callDataPtr is nullptr!");
55         return TELEPHONY_ERR_LOCAL_PTR_NULL;
56     }
57     std::string numberLocation = CheckNumberLocationInfo(info);
58     ContactInfo contactInfo = {
59         .name = "",
60         .number = "",
61         .isContacterExists = false,
62         .ringtonePath = "",
63         .isSendToVoicemail = false,
64         .isEcc = false,
65         .isVoiceMail = false,
66     };
67     QueryCallerInfo(contactInfo, std::string(info.phoneNumber));
68     std::string displayName = "";
69     if (std::string(contactInfo.name) != "") {
70         displayName = std::string(contactInfo.name);
71     } else if (info.numberMarkInfo.markType == MarkType::MARK_TYPE_YELLOW_PAGE && !info.numberMarkInfo.isCloud) {
72         displayName = std::string(info.numberMarkInfo.markContent);
73     }
74 
75     DataShare::DataShareValuesBucket bucket;
76     TELEPHONY_LOGI("callLog Insert begin");
77     MakeCallLogInsertBucket(bucket, info, displayName, numberLocation);
78     bool ret = callDataPtr_->Insert(bucket);
79     if (!ret) {
80         TELEPHONY_LOGE("Add call log database fail!");
81         return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
82     }
83     DeleteCallLogForLimit(info);
84     return TELEPHONY_SUCCESS;
85 }
86 
DeleteCallLogForLimit(const CallRecordInfo & info)87 void CallRecordsHandler::DeleteCallLogForLimit(const CallRecordInfo &info)
88 {
89     DataShare::DataSharePredicates queryPredicates;
90     if (info.answerType == CallAnswerType::CALL_ANSWER_BLOCKED) {
91         queryPredicates.EqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_BLOCKED));
92     } else {
93         queryPredicates.NotEqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_BLOCKED));
94     }
95     queryPredicates.OrderByDesc(CALL_CREATE_TIME);
96     queryPredicates.Limit(-1, LOG_LIMIT_NUM);
97     callDataPtr_->QueryAndDeleteLimitedIds(queryPredicates);
98 }
99 
MakeCallLogInsertBucket(DataShare::DataShareValuesBucket & bucket,const CallRecordInfo & info,std::string displayName,std::string numberLocation)100 void CallRecordsHandler::MakeCallLogInsertBucket(DataShare::DataShareValuesBucket &bucket,
101     const CallRecordInfo &info, std::string displayName, std::string numberLocation)
102 {
103     bucket.Put(CALL_PHONE_NUMBER, std::string(info.phoneNumber));
104     bucket.Put(CALL_DISPLAY_NAME, displayName);
105     bucket.Put(CALL_DIRECTION, static_cast<int32_t>(info.directionType));
106     bucket.Put(CALL_VOICEMAIL_URI, std::string(""));
107     bucket.Put(CALL_SIM_TYPE, 0);
108     bucket.Put(CALL_IS_HD, static_cast<int32_t>(info.callType));
109     bucket.Put(CALL_IS_READ, 0);
110     bucket.Put(CALL_RING_DURATION, static_cast<int32_t>(info.ringDuration));
111     bucket.Put(CALL_TALK_DURATION, static_cast<int32_t>(info.callDuration));
112     bucket.Put(CALL_FORMAT_NUMBER, std::string(info.formattedNumber));
113     bucket.Put(CALL_QUICKSEARCH_KEY, std::string(""));
114     bucket.Put(CALL_NUMBER_TYPE, 0);
115     bucket.Put(CALL_NUMBER_TYPE_NAME, std::string(""));
116     bucket.Put(CALL_BEGIN_TIME, info.callBeginTime);
117     bucket.Put(CALL_END_TIME, info.callEndTime);
118     bucket.Put(CALL_ANSWER_STATE, static_cast<int32_t>(info.answerType));
119     bucket.Put(CALL_CREATE_TIME, info.callCreateTime);
120     bucket.Put(CALL_NUMBER_LOCATION, numberLocation);
121     bucket.Put(CALL_PHOTO_ID, 0);
122     bucket.Put(CALL_SLOT_ID, info.slotId);
123     bucket.Put(CALL_FEATURES, info.features);
124 }
125 
CheckNumberLocationInfo(const CallRecordInfo & info)126 std::string CallRecordsHandler::CheckNumberLocationInfo(const CallRecordInfo &info)
127 {
128     std::string str(info.numberLocation);
129     if (str == "default") {
130         TELEPHONY_LOGI("AddCallLogInfo, number location is default");
131         str = "";
132         DelayedSingleton<CallNumberUtils>::GetInstance()->QueryNumberLocationInfo(str, std::string(info.phoneNumber));
133     }
134     if (str == "") {
135         str = "N";
136     }
137     return str;
138 }
139 
QueryAndNotifyUnReadMissedCall()140 int32_t CallRecordsHandler::QueryAndNotifyUnReadMissedCall()
141 {
142     if (callDataPtr_ == nullptr) {
143         TELEPHONY_LOGE("callDataPtr is nullptr!");
144         return TELEPHONY_ERR_LOCAL_PTR_NULL;
145     }
146     missedCallNotification_ = std::make_shared<MissedCallNotification>();
147     if (missedCallNotification_ == nullptr) {
148         TELEPHONY_LOGE("missedCallNotification_ is null!");
149         return TELEPHONY_ERR_LOCAL_PTR_NULL;
150     }
151     DataShare::DataSharePredicates predicates;
152     std::map<std::string, int32_t> phoneNumAndUnreadCountMap;
153     predicates.EqualTo(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_UNREAD));
154     predicates.And();
155     predicates.EqualTo(CALL_DIRECTION, static_cast<int32_t>(CallDirection::CALL_DIRECTION_IN));
156     predicates.And();
157     predicates.EqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_MISSED));
158     bool ret = callDataPtr_->QueryCallLog(phoneNumAndUnreadCountMap, predicates);
159     if (phoneNumAndUnreadCountMap.empty() || !ret) {
160         TELEPHONY_LOGE("Don't have unread missed call in call log!");
161         return TELEPHONY_ERR_DATABASE_READ_FAIL;
162     }
163     int32_t result = missedCallNotification_->NotifyUnReadMissedCall(phoneNumAndUnreadCountMap);
164     if (result != TELEPHONY_SUCCESS) {
165         TELEPHONY_LOGE("Notify unread missed call error!");
166         return TELEPHONY_ERR_PUBLISH_BROADCAST_FAIL;
167     }
168     return TELEPHONY_SUCCESS;
169 }
170 
CallRecordsHandlerService()171 CallRecordsHandlerService::CallRecordsHandlerService() : handler_(nullptr) {}
172 
~CallRecordsHandlerService()173 CallRecordsHandlerService::~CallRecordsHandlerService() {}
174 
Start()175 void CallRecordsHandlerService::Start()
176 {
177     handler_ = std::make_shared<CallRecordsHandler>();
178     return;
179 }
180 
StoreCallRecord(const CallRecordInfo & info)181 int32_t CallRecordsHandlerService::StoreCallRecord(const CallRecordInfo &info)
182 {
183     if (handler_.get() == nullptr) {
184         TELEPHONY_LOGE("handler_ is nullptr");
185         return TELEPHONY_ERR_LOCAL_PTR_NULL;
186     }
187     ffrt::submit([=]() { handler_->AddCallLogInfo(info); });
188     return TELEPHONY_SUCCESS;
189 }
190 
RemoveMissedIncomingCallNotification()191 int32_t CallRecordsHandlerService::RemoveMissedIncomingCallNotification()
192 {
193     std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
194     if (callDataPtr == nullptr) {
195         TELEPHONY_LOGE("callDataPtr is nullptr!");
196         return TELEPHONY_ERR_LOCAL_PTR_NULL;
197     }
198     DataShare::DataSharePredicates predicates;
199     DataShare::DataShareValuesBucket bucket;
200     bucket.Put(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_READ));
201     predicates.EqualTo(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_UNREAD));
202     predicates.And();
203     predicates.EqualTo(CALL_DIRECTION, static_cast<int32_t>(CallDirection::CALL_DIRECTION_IN));
204     predicates.And();
205     predicates.EqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_MISSED));
206     bool ret = callDataPtr->Update(predicates, bucket);
207     if (ret) {
208         TELEPHONY_LOGE("Update call log database fail!");
209         return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
210     }
211     TELEPHONY_LOGI("Update call log database success!");
212     return TELEPHONY_SUCCESS;
213 }
214 
QueryUnReadMissedCallLog()215 int32_t CallRecordsHandlerService::QueryUnReadMissedCallLog()
216 {
217     if (handler_.get() == nullptr) {
218         TELEPHONY_LOGE("handler_ is nullptr");
219         return TELEPHONY_ERR_LOCAL_PTR_NULL;
220     }
221     ffrt::submit([=]() { handler_->QueryAndNotifyUnReadMissedCall(); });
222     return TELEPHONY_SUCCESS;
223 }
224 } // namespace Telephony
225 } // namespace OHOS
226