TizenRefApp-5094 Implement provider for usual contacts in the contacts list 77/52977/4
authorSergei Kobec <s.kobec@samsung.com>
Mon, 30 Nov 2015 13:15:46 +0000 (15:15 +0200)
committerAleksandr Sapozhnik <a.sapozhnik@samsung.com>
Tue, 1 Dec 2015 10:01:29 +0000 (02:01 -0800)
Change-Id: I1002187c14429c296be29b13509e580341be2961
Signed-off-by: Sergei Kobec <s.kobec@samsung.com>
lib-contact/inc/Contacts/List/Model/ContactProvider.h [new file with mode: 0644]
lib-contact/src/Contacts/List/Model/ContactProvider.cpp [new file with mode: 0644]

diff --git a/lib-contact/inc/Contacts/List/Model/ContactProvider.h b/lib-contact/inc/Contacts/List/Model/ContactProvider.h
new file mode 100644 (file)
index 0000000..29fd2c9
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef CONTACTS_LIST_MODEL_CONTACT_PROVIDER_H
+#define CONTACTS_LIST_MODEL_CONTACT_PROVIDER_H
+
+#include <contacts.h>
+#include <functional>
+#include <unordered_map>
+
+namespace Contacts
+{
+       namespace List
+       {
+               namespace Model
+               {
+                       /**
+                        * @brief Provides list of contacts
+                        */
+                       class ContactProvider
+                       {
+                       public:
+
+                               /**
+                                * @brief Determines how to filter contact list
+                                */
+                               enum FilterType
+                               {
+                                       FilterNone      = 0,
+                                       FilterNumber    = 1 << 0,
+                                       FilterEmail     = 1 << 1
+                               };
+
+                               /**
+                                * @brief Person change callback
+                                * @param[in]    id            Person ID
+                                * @param[in]    changeType    Change type
+                                */
+                               typedef std::function<void(int id, contacts_changed_e changeType)> ChangeCallback;
+
+                               /**
+                                * @brief Person insert callback
+                                * @param[in]    record        Person record
+                                */
+                               typedef std::function<void(contacts_record_h record)> InsertCallback;
+
+                               /**
+                                * @brief Constructor
+                                * @param[in]    filterType    Contact filter
+                                */
+                               explicit ContactProvider(FilterType filterType);
+
+                               virtual ~ContactProvider() { };
+
+                               /**
+                                * @brief Get contact list
+                                * @return List of person records
+                                */
+                               virtual contacts_list_h getContactsList() const;
+
+                               /**
+                                * @brief Set person change callback
+                                * @remark It can be update or delete of person
+                                * @param[in]    id          Person ID
+                                * @param[in]    callback    Change callback
+                                */
+                               void setChangeCallback(int id, ChangeCallback callback);
+
+                               /**
+                                * @brief Unset person change callback
+                                * @param[in]    id    Person ID
+                                */
+                               void unsetChangeCallback(int id);
+
+                               /**
+                                * @brief Set person insert callback
+                                * @param[in]    callback    Create callback
+                                */
+                               void setInsertCallback(InsertCallback callback);
+
+                               /**
+                                * @brief Unset person insert callback
+                                */
+                               void unsetInsertCallback();
+
+                       private:
+                               void onChanged(const char *viewUri);
+                               void notify(contacts_changed_e changeType, contacts_record_h record);
+
+                               FilterType m_ListFilterType;
+                               int m_DbVersion;
+
+                               std::unordered_map<int, ChangeCallback> m_ChangeCallbacks;
+                               InsertCallback m_InsertCallback;
+                       };
+               }
+       }
+}
+
+#endif /* CONTACTS_LIST_MODEL_CONTACT_PROVIDER_H */
diff --git a/lib-contact/src/Contacts/List/Model/ContactProvider.cpp b/lib-contact/src/Contacts/List/Model/ContactProvider.cpp
new file mode 100644 (file)
index 0000000..63e1498
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Contacts/List/Model/ContactProvider.h"
+#include "Contacts/Utils.h"
+#include "Utils/Callback.h"
+
+using namespace Contacts::List::Model;
+
+namespace
+{
+       contacts_filter_h getProviderFilter(ContactProvider::FilterType filterType)
+       {
+               bool emptyFilter = true;
+               contacts_filter_h filter = nullptr;
+               contacts_filter_create(_contacts_person._uri, &filter);
+
+               if (filterType != ContactProvider::FilterNone) {
+                       if (filterType & ContactProvider::FilterNumber) {
+                               contacts_filter_add_bool(filter, _contacts_person.has_phonenumber, true);
+                               emptyFilter = false;
+                       }
+
+                       if (filterType & ContactProvider::FilterEmail) {
+                               if (!emptyFilter) {
+                                       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+                               }
+                               contacts_filter_add_bool(filter, _contacts_person.has_email, true);
+                       }
+               }
+
+               return filter;
+       }
+
+       contacts_record_h getPersonRecord(int contactId, ContactProvider::FilterType filterType)
+       {
+               contacts_filter_h filter = getProviderFilter(filterType);
+               contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+               contacts_filter_add_int(filter, _contacts_person.display_contact_id, CONTACTS_MATCH_EQUAL, contactId);
+
+               contacts_query_h query = nullptr;
+               contacts_query_create(_contacts_person._uri, &query);
+               contacts_query_set_filter(query, filter);
+
+               contacts_list_h list = nullptr;
+               contacts_db_get_records_with_query(query, 0, 1, &list);
+
+               contacts_record_h record = nullptr;
+               contacts_list_get_current_record_p(list, &record);
+
+               contacts_list_destroy(list, false);
+               contacts_query_destroy(query);
+               contacts_filter_destroy(filter);
+
+               return record;
+       }
+}
+
+ContactProvider::ContactProvider(ContactProvider::FilterType filterType)
+       : m_ListFilterType(filterType)
+{
+       contacts_db_get_current_version(&m_DbVersion);
+       contacts_db_add_changed_cb(_contacts_person._uri, makeCallbackWithLastParam(&ContactProvider::onChanged), this);
+}
+
+contacts_list_h ContactProvider::getContactsList() const
+{
+       contacts_list_h list = nullptr;
+       contacts_query_h query = nullptr;
+       unsigned projection[] = {
+               _contacts_person.display_name,
+               _contacts_person.image_thumbnail_path,
+               _contacts_person.display_name_index
+       };
+
+       contacts_query_create(_contacts_person._uri, &query);
+
+       contacts_filter_h contactsFilter = getProviderFilter(m_ListFilterType);
+       contacts_query_set_filter(query, contactsFilter);
+
+       contacts_query_set_projection(query, projection, sizeof(projection) / sizeof(*projection));
+       contacts_query_set_sort(query, _contacts_person.display_name, true);//Todo: Get sort option from settings
+       contacts_db_get_records_with_query(query, 0, 0, &list);
+
+       contacts_filter_destroy(contactsFilter);
+       contacts_query_destroy(query);
+
+       return list;
+}
+
+void ContactProvider::setChangeCallback(int id, ChangeCallback callback)
+{
+       m_ChangeCallbacks.insert({ id, std::move(callback) });
+}
+
+void ContactProvider::unsetChangeCallback(int id)
+{
+       m_ChangeCallbacks.erase(id);
+}
+
+void ContactProvider::setInsertCallback(InsertCallback callback)
+{
+       m_InsertCallback = std::move(callback);
+}
+
+void ContactProvider::unsetInsertCallback()
+{
+       m_InsertCallback = nullptr;
+}
+
+void ContactProvider::onChanged(const char *viewUri)
+{
+       contacts_list_h changes = nullptr;
+       contacts_db_get_changes_by_version(_contacts_contact_updated_info._uri, 0, m_DbVersion, &changes, &m_DbVersion);
+
+       contacts_record_h record = nullptr;
+       CONTACTS_LIST_FOREACH(changes, record) {
+               int contactId = 0;
+               int changeType = -1;
+
+               contacts_record_get_int(record, _contacts_contact_updated_info.contact_id, &contactId);
+               contacts_record_get_int(record, _contacts_contact_updated_info.type, &changeType);
+
+               contacts_record_h personRecord = getPersonRecord(contactId, m_ListFilterType);
+               notify(static_cast<contacts_changed_e>(changeType), personRecord);
+               contacts_record_destroy(personRecord, true);
+       }
+
+       contacts_list_destroy(changes, true);
+}
+
+void ContactProvider::notify(contacts_changed_e changeType, contacts_record_h record)
+{
+       int id = 0;
+       contacts_record_get_int(record, _contacts_person.id, &id);
+
+       switch (changeType) {
+               case CONTACTS_CHANGE_INSERTED:
+                       if (m_InsertCallback) {
+                               m_InsertCallback(record);
+                       }
+                       break;
+               case CONTACTS_CHANGE_UPDATED:
+               case CONTACTS_CHANGE_DELETED:
+                       auto it = m_ChangeCallbacks.find(id);
+                       if (it != m_ChangeCallbacks.end()) {
+                               it->second(it->first, changeType);
+                       }
+                       break;
+       }
+}