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_errors.h"
19 #include "call_manager_inner_type.h"
20 #include "ffrt.h"
21
22 namespace OHOS {
23 namespace Telephony {
CallRecordsHandler()24 CallRecordsHandler::CallRecordsHandler() : callDataPtr_(nullptr)
25 {
26 callDataPtr_ = DelayedSingleton<CallDataBaseHelper>::GetInstance();
27 if (callDataPtr_ == nullptr) {
28 TELEPHONY_LOGE("callDataPtr_ is nullptr!");
29 }
30 }
31
QueryCallerInfo(ContactInfo & contactInfo,std::string phoneNumber)32 void CallRecordsHandler::QueryCallerInfo(ContactInfo &contactInfo, std::string phoneNumber)
33 {
34 std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
35 if (callDataPtr == nullptr) {
36 TELEPHONY_LOGE("callDataPtr is nullptr!");
37 return;
38 }
39 DataShare::DataSharePredicates predicates;
40 predicates.EqualTo(CALL_DETAIL_INFO, phoneNumber);
41 predicates.And();
42 predicates.EqualTo(CALL_CONTENT_TYPE, CALL_PHONE);
43 bool ret = callDataPtr->Query(contactInfo, predicates);
44 if (!ret) {
45 TELEPHONY_LOGE("Query contact database fail!");
46 }
47 }
48
AddCallLogInfo(const CallRecordInfo & info)49 int32_t CallRecordsHandler::AddCallLogInfo(const CallRecordInfo &info)
50 {
51 if (callDataPtr_ == nullptr) {
52 TELEPHONY_LOGE("callDataPtr is nullptr!");
53 return TELEPHONY_ERR_LOCAL_PTR_NULL;
54 }
55 ContactInfo contactInfo = {
56 .name = "",
57 .number = "",
58 .isContacterExists = false,
59 .ringtonePath = "",
60 .isSendToVoicemail = false,
61 .isEcc = false,
62 .isVoiceMail = false,
63 };
64 QueryCallerInfo(contactInfo, std::string(info.phoneNumber));
65
66 DataShare::DataShareValuesBucket bucket;
67 TELEPHONY_LOGI("callLog Insert begin");
68 bucket.Put(CALL_PHONE_NUMBER, std::string(info.phoneNumber));
69 bucket.Put(CALL_DISPLAY_NAME, std::string(contactInfo.name));
70 bucket.Put(CALL_DIRECTION, static_cast<int32_t>(info.directionType));
71 bucket.Put(CALL_VOICEMAIL_URI, std::string(""));
72 bucket.Put(CALL_SIM_TYPE, 0);
73 bucket.Put(CALL_IS_HD, static_cast<int32_t>(info.callType));
74 bucket.Put(CALL_IS_READ, 0);
75 bucket.Put(CALL_RING_DURATION, static_cast<int32_t>(info.ringDuration));
76 bucket.Put(CALL_TALK_DURATION, static_cast<int32_t>(info.callDuration));
77 bucket.Put(CALL_FORMAT_NUMBER, std::string(info.formattedPhoneNumber));
78 bucket.Put(CALL_QUICKSEARCH_KEY, std::string(""));
79 bucket.Put(CALL_NUMBER_TYPE, 0);
80 bucket.Put(CALL_NUMBER_TYPE_NAME, std::string(""));
81 bucket.Put(CALL_BEGIN_TIME, info.callBeginTime);
82 bucket.Put(CALL_END_TIME, info.callEndTime);
83 bucket.Put(CALL_ANSWER_STATE, static_cast<int32_t>(info.answerType));
84 time_t timeStamp = time(0);
85 bucket.Put(CALL_CREATE_TIME, timeStamp);
86 bucket.Put(CALL_NUMBER_LOCATION, std::string(""));
87 bucket.Put(CALL_PHOTO_ID, 0);
88 bucket.Put(CALL_SLOT_ID, info.slotId);
89 bucket.Put(CALL_FEATURES, info.features);
90 bool ret = callDataPtr_->Insert(bucket);
91 if (!ret) {
92 TELEPHONY_LOGE("Add call log database fail!");
93 return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
94 }
95 return TELEPHONY_SUCCESS;
96 }
97
QueryAndNotifyUnReadMissedCall()98 int32_t CallRecordsHandler::QueryAndNotifyUnReadMissedCall()
99 {
100 if (callDataPtr_ == nullptr) {
101 TELEPHONY_LOGE("callDataPtr is nullptr!");
102 return TELEPHONY_ERR_LOCAL_PTR_NULL;
103 }
104 missedCallNotification_ = std::make_shared<MissedCallNotification>();
105 if (missedCallNotification_ == nullptr) {
106 TELEPHONY_LOGE("missedCallNotification_ is null!");
107 return TELEPHONY_ERR_LOCAL_PTR_NULL;
108 }
109 DataShare::DataSharePredicates predicates;
110 std::map<std::string, int32_t> phoneNumAndUnreadCountMap;
111 predicates.EqualTo(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_UNREAD));
112 predicates.And();
113 predicates.EqualTo(CALL_DIRECTION, static_cast<int32_t>(CallDirection::CALL_DIRECTION_IN));
114 predicates.And();
115 predicates.EqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_MISSED));
116 bool ret = callDataPtr_->QueryCallLog(phoneNumAndUnreadCountMap, predicates);
117 if (phoneNumAndUnreadCountMap.empty() || !ret) {
118 TELEPHONY_LOGE("Don't have unread missed call in call log!");
119 return TELEPHONY_ERR_DATABASE_READ_FAIL;
120 }
121 int32_t result = missedCallNotification_->NotifyUnReadMissedCall(phoneNumAndUnreadCountMap);
122 if (result != TELEPHONY_SUCCESS) {
123 TELEPHONY_LOGE("Notify unread missed call error!");
124 return TELEPHONY_ERR_PUBLISH_BROADCAST_FAIL;
125 }
126 return TELEPHONY_SUCCESS;
127 }
128
CallRecordsHandlerService()129 CallRecordsHandlerService::CallRecordsHandlerService() : handler_(nullptr) {}
130
~CallRecordsHandlerService()131 CallRecordsHandlerService::~CallRecordsHandlerService() {}
132
Start()133 void CallRecordsHandlerService::Start()
134 {
135 handler_ = std::make_shared<CallRecordsHandler>();
136 return;
137 }
138
StoreCallRecord(const CallRecordInfo & info)139 int32_t CallRecordsHandlerService::StoreCallRecord(const CallRecordInfo &info)
140 {
141 if (handler_.get() == nullptr) {
142 TELEPHONY_LOGE("handler_ is nullptr");
143 return TELEPHONY_ERR_LOCAL_PTR_NULL;
144 }
145 ffrt::submit([=]() { handler_->AddCallLogInfo(info); });
146 return TELEPHONY_SUCCESS;
147 }
148
RemoveMissedIncomingCallNotification()149 int32_t CallRecordsHandlerService::RemoveMissedIncomingCallNotification()
150 {
151 std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
152 if (callDataPtr == nullptr) {
153 TELEPHONY_LOGE("callDataPtr is nullptr!");
154 return TELEPHONY_ERR_LOCAL_PTR_NULL;
155 }
156 DataShare::DataSharePredicates predicates;
157 DataShare::DataShareValuesBucket bucket;
158 bucket.Put(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_READ));
159 predicates.EqualTo(CALL_IS_READ, static_cast<int32_t>(CallLogReadState::CALL_IS_UNREAD));
160 predicates.And();
161 predicates.EqualTo(CALL_DIRECTION, static_cast<int32_t>(CallDirection::CALL_DIRECTION_IN));
162 predicates.And();
163 predicates.EqualTo(CALL_ANSWER_STATE, static_cast<int32_t>(CallAnswerType::CALL_ANSWER_MISSED));
164 bool ret = callDataPtr->Update(predicates, bucket);
165 if (ret) {
166 TELEPHONY_LOGE("Update call log database fail!");
167 return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
168 }
169 TELEPHONY_LOGI("Update call log database success!");
170 return TELEPHONY_SUCCESS;
171 }
172
QueryUnReadMissedCallLog()173 int32_t CallRecordsHandlerService::QueryUnReadMissedCallLog()
174 {
175 if (handler_.get() == nullptr) {
176 TELEPHONY_LOGE("handler_ is nullptr");
177 return TELEPHONY_ERR_LOCAL_PTR_NULL;
178 }
179 ffrt::submit([=]() { handler_->QueryAndNotifyUnReadMissedCall(); });
180 return TELEPHONY_SUCCESS;
181 }
182 } // namespace Telephony
183 } // namespace OHOS
184