1 /*
2 * Copyright (C) 2023 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 #include "vcard_encoder.h"
16
17 #include "telephony_errors.h"
18 #include "telephony_log_wrapper.h"
19 #include "vcard_constant.h"
20 #include "vcard_contact.h"
21
22 namespace OHOS {
23 namespace Telephony {
VCardEncoder(int32_t cardType,const std::string & charset)24 VCardEncoder::VCardEncoder(int32_t cardType, const std::string &charset)
25 {
26 constructor_ = std::make_shared<VCardConstructor>(cardType, charset);
27 }
28
ContructVCard(std::vector<std::vector<int>> contactIdLists,int32_t & errorCode)29 std::string VCardEncoder::ContructVCard(std::vector<std::vector<int>> contactIdLists, int32_t &errorCode)
30 {
31 std::string result = "";
32 for (int i = 0; i < (int32_t)contactIdLists.size(); i++) {
33 std::vector<int> contactIdList = contactIdLists[i];
34 TELEPHONY_LOGW("export progress %{public}d / %{public}d", i, (int32_t)contactIdLists.size());
35 auto rawResultSet = GetRawContactResultSet(contactIdList);
36 if (rawResultSet == nullptr) {
37 TELEPHONY_LOGE("QueryRawContactId failed");
38 errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
39 return "";
40 }
41 int rowCount = 0;
42 rawResultSet->GetRowCount(rowCount);
43 TELEPHONY_LOGI("rawResultSet rowCount = %{public}d", rowCount);
44 if (rowCount == 0) {
45 TELEPHONY_LOGW("rawResultSet is empty");
46 continue;
47 }
48 std::vector<int32_t> rawContactIdList;
49 int resultSetNum = rawResultSet->GoToFirstRow();
50 while (resultSetNum == 0) {
51 int32_t index = 0;
52 int32_t rawContactId = 0;
53 rawResultSet->GetColumnIndex(RawContact::ID, index);
54 rawResultSet->GetInt(index, rawContactId);
55 rawContactIdList.push_back(rawContactId);
56 resultSetNum = rawResultSet->GoToNextRow();
57 }
58 rawResultSet->Close();
59 TELEPHONY_LOGW("rawContactIdListSize = %{public}d", (int32_t)rawContactIdList.size());
60 if (rawContactIdList.size() == 0) {
61 continue;
62 }
63 auto contactDataResultSet = QueryContactData(rawContactIdList, errorCode);
64 if (contactDataResultSet == nullptr) {
65 TELEPHONY_LOGE("QueryContactData failed");
66 continue;
67 }
68 ProcessContactData(result, contactDataResultSet, errorCode);
69 }
70 TELEPHONY_LOGW("ContructVCard Success");
71 if (phoneNumberEncodedCallback_ != nullptr) {
72 constructor_->SetPhoneNumberEncodedCallback(phoneNumberEncodedCallback_);
73 }
74 return result;
75 }
76
SetPhoneNumberEncodedCallback(std::shared_ptr<PhoneNumberEncodedCallback> PhoneNumberEncodedCallback)77 void VCardEncoder::SetPhoneNumberEncodedCallback(std::shared_ptr<PhoneNumberEncodedCallback> PhoneNumberEncodedCallback)
78 {
79 phoneNumberEncodedCallback_ = PhoneNumberEncodedCallback;
80 }
81
QueryContactData(const std::vector<int32_t> & rawContactIdList,int32_t & errorCode)82 std::shared_ptr<DataShare::DataShareResultSet> VCardEncoder::QueryContactData(
83 const std::vector<int32_t> &rawContactIdList, int32_t &errorCode)
84 {
85 std::vector<std::string> columns;
86 DataShare::DataSharePredicates predicates;
87 for (size_t i = 0; i< rawContactIdList.size(); i++) {
88 predicates.EqualTo(ContactData::RAW_CONTACT_ID, rawContactIdList[i]);
89 if (i != rawContactIdList.size() - 1) {
90 predicates.Or();
91 }
92 }
93 auto contactDataResultSet = VCardRdbHelper::GetInstance().QueryContactData(columns, predicates);
94 if (contactDataResultSet == nullptr) {
95 TELEPHONY_LOGE("QueryContactData failed");
96 errorCode = TELEPHONY_ERR_READ_DATA_FAIL;
97 return nullptr;
98 }
99 return contactDataResultSet;
100 }
101
ProcessContactData(std::string & result,std::shared_ptr<DataShare::DataShareResultSet> contactDataResultSet,int32_t & errorCode)102 void VCardEncoder::ProcessContactData(std::string &result,
103 std::shared_ptr<DataShare::DataShareResultSet> contactDataResultSet, int32_t &errorCode)
104 {
105 if (contactDataResultSet == nullptr) {
106 TELEPHONY_LOGE("QueryContactData failed");
107 errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
108 return;
109 }
110
111 int32_t contactDataResult = contactDataResultSet->GoToFirstRow();
112 if (contactDataResult != DataShare::E_OK) {
113 TELEPHONY_LOGE("GoToFirstRow failed");
114 errorCode = TELEPHONY_ERR_FAIL;
115 contactDataResultSet->Close();
116 return;
117 }
118
119 std::shared_ptr<VCardContact> contact = std::make_shared<VCardContact>();
120 int32_t currentRawContactId = -1;
121 do {
122 int32_t rawContactId = 0;
123 int32_t index = 0;
124 contactDataResultSet->GetColumnIndex(ContactData::RAW_CONTACT_ID, index);
125 contactDataResultSet->GetInt(index, rawContactId);
126
127 if (rawContactId != currentRawContactId) {
128 if (currentRawContactId != -1) {
129 result += constructor_->ContactVCard(contact);
130 }
131 currentRawContactId = rawContactId;
132 contact = std::make_shared<VCardContact>();
133 }
134 contact->BuildOneData(contactDataResultSet);
135 contactDataResult = contactDataResultSet->GoToNextRow();
136 } while (contactDataResult == DataShare::E_OK);
137
138 if (currentRawContactId != -1) {
139 result += constructor_->ContactVCard(contact);
140 }
141
142 contactDataResultSet->Close();
143 }
144
GetRawContactResultSet(std::vector<int> contactIdList)145 std::shared_ptr<DataShare::DataShareResultSet> VCardEncoder::GetRawContactResultSet(std::vector<int> contactIdList)
146 {
147 std::vector<std::string> columns;
148 columns.push_back(RawContact::ID);
149 DataShare::DataSharePredicates predicates;
150 predicates.BeginWrap();
151 for (size_t i = 0; i < contactIdList.size(); i++) {
152 predicates.EqualTo(RawContact::CONTACT_ID, contactIdList[i]);
153 if (i != contactIdList.size() - 1) {
154 predicates.Or();
155 }
156 }
157 predicates.EndWrap();
158 predicates.And();
159 predicates.EqualTo(RawContact::IS_DELETED, CONTACTS_NOT_DELETED);
160 predicates.And();
161 predicates.NotEqualTo(RawContact::PRIMARY_CONTACT, TELEPHONY_ERROR);
162 return VCardRdbHelper::GetInstance().QueryRawContact(columns, predicates);
163 }
164
165 } // namespace Telephony
166 } // namespace OHOS