TizenRefApp-7393 Implement the update of Person Provider in a separate thread 58/91658/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 10 Oct 2016 14:11:38 +0000 (17:11 +0300)
committerAleksandr Sapozhnik <a.sapozhnik@samsung.com>
Tue, 11 Oct 2016 15:33:18 +0000 (08:33 -0700)
Change-Id: Iba084175fd83dfdfd2b700cb470316ce3bf61c40
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
lib-apps-common/inc/Model2/DataProvider.h
lib-apps-common/src/Model2/DataProvider.cpp
lib-contacts/inc/Contacts/List/ListView.h
lib-contacts/src/Contacts/List/ListSection.cpp
lib-contacts/src/Contacts/List/ListView.cpp
lib-contacts/src/Contacts/List/Model/PersonProvider.cpp

index 3c62389..081a63b 100644 (file)
@@ -69,6 +69,13 @@ namespace Model2
                void update();
 
                /**
+                * @brief Destroy dynamically allocated provider safely.
+                * @details If provider is currently busy the destruction is postponed.
+                * @remark No callbacks will be called after this method is called.
+                */
+               void destroy();
+
+               /**
                 * @brief Set whether to start update immediately when update() is called.
                 * @param[in]   isEnabled   Whether data update is enabled
                 */
@@ -130,10 +137,11 @@ namespace Model2
                void finishUpdate();
 
        private:
+               bool m_IsBusy;
                bool m_IsInitialized;
                bool m_IsUpdateEnabled;
                bool m_IsUpdatePending;
-               bool m_IsUpdating;
+               bool m_IsDestroyPending;
 
                InitializeCallback m_OnInitialized;
                InsertCallback m_OnInserted;
index 4b2809c..145eb49 100644 (file)
@@ -20,8 +20,9 @@
 using namespace Model2;
 
 DataProvider::DataProvider()
-       : m_IsInitialized(false),
-         m_IsUpdateEnabled(true), m_IsUpdatePending(false), m_IsUpdating(false)
+       : m_IsBusy(false), m_IsInitialized(false),
+         m_IsUpdateEnabled(true), m_IsUpdatePending(false),
+         m_IsDestroyPending(false)
 {
 }
 
@@ -39,11 +40,13 @@ const DataProvider::DataList &DataProvider::getDataList()
 
 void DataProvider::initialize(InitializeCallback callback)
 {
-       if (m_IsInitialized) {
+       if (m_IsInitialized || m_IsBusy) {
                return;
        }
 
+       m_IsBusy = true;
        m_OnInitialized = std::move(callback);
+
        startInit();
 }
 
@@ -53,19 +56,29 @@ void DataProvider::update()
                return;
        }
 
-       if (!m_IsUpdateEnabled || m_IsUpdating) {
+       if (!m_IsUpdateEnabled || m_IsBusy) {
                m_IsUpdatePending = true;
                return;
        }
 
+       m_IsBusy = true;
        m_IsUpdatePending = false;
-       m_IsUpdating = true;
        if (m_OnUpdateStarted) {
                m_OnUpdateStarted();
        }
+
        startUpdate();
 }
 
+void DataProvider::destroy()
+{
+       if (m_IsBusy) {
+               m_IsDestroyPending = true;
+       } else {
+               delete this;
+       }
+}
+
 void DataProvider::setUpdateEnabled(bool isEnabled)
 {
        m_IsUpdateEnabled = isEnabled;
@@ -102,16 +115,29 @@ void DataProvider::deleteDataItem(DataItem &dataItem)
 
 void DataProvider::finishInit(DataList dataList)
 {
+       if (m_IsDestroyPending) {
+               delete this;
+               return;
+       }
+
        m_DataList = std::move(dataList);
        m_IsInitialized = true;
 
        if (m_OnInitialized) {
                m_OnInitialized();
+               m_OnInitialized = nullptr;
        }
+
+       m_IsBusy = false;
 }
 
 void DataProvider::finishUpdate()
 {
+       if (m_IsDestroyPending) {
+               delete this;
+               return;
+       }
+
        for (auto it = m_DataList.begin(); it != m_DataList.end(); ) {
                auto changeType = (*it)->m_ChangeType;
                (*it)->onUpdated();
@@ -132,7 +158,7 @@ void DataProvider::finishUpdate()
                m_OnUpdateFinished();
        }
 
-       m_IsUpdating = false;
+       m_IsBusy = false;
        if (m_IsUpdatePending) {
                update();
        }
index 732d88a..26cd7a6 100644 (file)
@@ -75,6 +75,7 @@ namespace Contacts
                         * @param[in]   provider    Person provider
                         */
                        explicit ListView(Model::PersonProvider *provider);
+                       virtual ~ListView() override;
 
                        /**
                         * @brief Create person list view
@@ -114,7 +115,7 @@ namespace Contacts
                        void setUpdateEnabled(bool isEnabled);
 
                protected:
-                       Model::PersonProvider *getProvider() const;
+                       Model2::DataProvider *getProvider() const;
 
                        /**
                         * @brief Called when provider initialization is finished.
@@ -232,8 +233,8 @@ namespace Contacts
                        Section m_Sections[SectionMax];
 
                        std::map<Utils::UniString, PersonGroupItem *> m_PersonGroups;
-                       std::unique_ptr<Model::PersonProvider> m_PersonProvider;
-                       Model2::SearchProvider m_SearchProvider;
+                       Model2::DataProvider *m_PersonProvider;
+                       Model2::SearchProvider *m_SearchProvider;
 
                        FillFinishCallback m_OnFillFinished;
                };
index b385909..82bf1d6 100644 (file)
@@ -38,8 +38,8 @@ ListSection::ListSection(const char *title, DataProvider *provider, SectionMode
 
 ListSection::~ListSection()
 {
-       delete m_Provider;
        removeIndexItem();
+       m_Provider->destroy();
 }
 
 void ListSection::setUpdateEnabled(bool isEnabled)
index 5efbb1a..4064e7f 100644 (file)
@@ -68,8 +68,9 @@ ListView::ListView(Model::PersonProvider *provider)
          m_Index(nullptr), m_AddButton(nullptr),
          m_NoContentHelpText("IDS_PB_BODY_AFTER_YOU_CREATE_CONTACTS_THEY_WILL_BE_SHOWN_HERE"),
          m_IsSearching(false), m_IsEmpty(true),
-         m_HasAddButton(true), m_SearchField(nullptr), m_PersonProvider(provider),
-         m_SearchProvider(*m_PersonProvider, PersonComparator())
+         m_HasAddButton(true), m_SearchField(nullptr),
+         m_PersonProvider(provider),
+         m_SearchProvider(new SearchProvider(*m_PersonProvider, PersonComparator()))
 {
        auto strings = Common::getSelectViewStrings();
        strings.titleDefault = "IDS_PB_TAB_CONTACTS";
@@ -83,6 +84,12 @@ ListView::ListView(int filterType)
 {
 }
 
+ListView::~ListView()
+{
+       delete m_SearchProvider;
+       m_PersonProvider->destroy();
+}
+
 void ListView::setSectionVisibility(SectionId section, bool isVisible)
 {
        m_Sections[section].m_IsVisible = isVisible;
@@ -112,9 +119,9 @@ void ListView::setUpdateEnabled(bool isEnabled)
        }
 }
 
-PersonProvider *ListView::getProvider() const
+DataProvider *ListView::getProvider() const
 {
-       return m_PersonProvider.get();
+       return m_PersonProvider;
 }
 
 void ListView::onInitialized()
@@ -154,9 +161,9 @@ void ListView::onCreated()
        fillLayout();
        updateSection(SectionMyProfile);
 
-       m_SearchProvider.initialize(std::bind(&ListView::onInitialized, this));
-       m_SearchProvider.setInsertCallback(std::bind(&ListView::onPersonInserted, this, _1));
-       m_SearchProvider.setUpdateFinishCallback(std::bind(&ListView::onUpdateFinished, this));
+       m_SearchProvider->initialize(std::bind(&ListView::onInitialized, this));
+       m_SearchProvider->setInsertCallback(std::bind(&ListView::onPersonInserted, this, _1));
+       m_SearchProvider->setUpdateFinishCallback(std::bind(&ListView::onUpdateFinished, this));
 }
 
 void ListView::setFillFinishCallback(FillFinishCallback callback)
@@ -348,7 +355,8 @@ Ui::GenGroupItem *ListView::createListSection(SectionId sectionId)
        switch (sectionId) {
                case SectionFavorites:
                        title = "IDS_PB_HEADER_FAVOURITES";
-                       provider = new FavoritesProvider(FavoritesProvider::ModeDefault, m_PersonProvider->getFilterType());
+                       provider = new FavoritesProvider(FavoritesProvider::ModeDefault,
+                                       static_cast<PersonProvider &>(*m_PersonProvider).getFilterType());
                        break;
                case SectionMfc:
                        title = "IDS_PB_HEADER_MOST_FREQUENT_CONTACTS_ABB2";
@@ -369,7 +377,7 @@ void ListView::fillPersonList()
        if (m_PersonGroups.empty()) {
                PersonGroupItem *group = nullptr;
 
-               for (auto &&dataItem: m_SearchProvider.getDataList()) {
+               for (auto &&dataItem: m_SearchProvider->getDataList()) {
                        SearchData &searchData = static_cast<SearchData &>(*dataItem);
                        Person &person = static_cast<Person &>(searchData.getDataItem());
 
@@ -456,7 +464,7 @@ void ListView::updateEmptyLayout()
 
 void ListView::updateEmptyState()
 {
-       bool isEmpty = m_IsSearching ? m_SearchProvider.empty() : m_PersonGroups.empty();
+       bool isEmpty = m_IsSearching ? m_SearchProvider->empty() : m_PersonGroups.empty();
 
        updateIndex();
        updateSearchField();
@@ -845,7 +853,7 @@ void ListView::onSearchChanged(const char *str)
                updateAddButton();
        }
 
-       m_SearchProvider.search(str);
+       m_SearchProvider->search(str);
        elm_genlist_filter_set(m_Genlist->getEvasObject(), (void *) str);
        updateEmptyState();
 }
index d15c432..2262427 100644 (file)
@@ -230,13 +230,16 @@ void PersonProvider::startUpdate()
        int updateType = m_UpdateType;
        m_UpdateType = UpdateNone;
 
-       if (updateType & UpdateRecords) {
-               updateRecords();
-       }
-       if (updateType & UpdateList) {
-               updateList();
-       }
-       finishUpdate();
+       new Thread([this, updateType] {
+               contacts_connect_on_thread();
+               if (updateType & UpdateRecords) {
+                       updateRecords();
+               }
+               if (updateType & UpdateList) {
+                       updateList();
+               }
+               contacts_disconnect_on_thread();
+       }, std::bind(&PersonProvider::finishUpdate, this));
 }
 
 void PersonProvider::updateList()