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