TizenRefApp-7562 Potential crash during deleting ConvItem if popup of this item is... 13/95513/2
authorDenis Dolzhenko <d.dolzhenko@samsung.com>
Thu, 3 Nov 2016 11:52:27 +0000 (13:52 +0200)
committerDenis Dolzhenko <d.dolzhenko@samsung.com>
Thu, 3 Nov 2016 12:00:00 +0000 (14:00 +0200)
Change-Id: Iac407e57b52322e3fcef1730603910318032ee4f
Signed-off-by: Denis Dolzhenko <d.dolzhenko@samsung.com>
src/Common/View/inc/ContextPopup.h
src/Common/View/inc/PopupManager.h
src/Common/View/src/ContextPopup.cpp
src/Common/View/src/Popup.cpp
src/Common/View/src/PopupManager.cpp
src/Conversation/ConvList/Controller/src/ConvListItem.cpp
src/Conversation/Main/Controller/src/Conversation.cpp
src/MsgThread/Controller/src/MsgThread.cpp
src/Settings/Controller/src/MsgOnSimCard.cpp
src/Viewer/Controller/src/Viewer.cpp

index edaaa97fb724d8c18c251b799cd318d96cdcbfee..28077d8065ce4f6b0c22e078f3efce60425dc52d 100644 (file)
@@ -29,7 +29,6 @@ namespace Msg
     class ContextPopup;
     class ContextPopupItem;
     class Window;
-    class PopupManager;
 
     #define CTXPOPUP_ITEM_PRESSED_CB(ClassName, method) [](ContextPopupItem &item, void *userData) \
     {                                                                                              \
@@ -63,7 +62,6 @@ namespace Msg
     {
         public:
             ContextPopup(Evas_Object *parent);
-            ContextPopup(PopupManager &parent);
             virtual ~ContextPopup();
 
             ContextPopupItem *appendItem(const std::string &text, Evas_Object *icon = nullptr,
@@ -80,9 +78,6 @@ namespace Msg
 
             static void on_dismissed_cb(void *data, Evas_Object *obj, void *event_info);
             static void on_item_pressed_cb(void *data, Evas_Object * obj, void *event_info);
-
-        private:
-            PopupManager *m_pManager;
     };
 }
 
index 1e3fb801a97d4137bc11b8bcd07b9621829650d9..4ed0f47579f95392f0ea36001abc392a8bface96 100644 (file)
@@ -56,27 +56,37 @@ namespace Msg
             /**
              * @brief Destroys all popups (context and regular) created before.
              * If no popup was created nothing happens.
+             * @param[in] popupOwner if popupOwner pointer not nullptr only popup owner can destroy current popup.
              */
-            void reset();
+            void reset(void *popupOwner = nullptr);
 
             /**
              * @brief Destroys previous popup and register new in manager
              * @param[in] popup a new popup for register.
+             * @param[in] new popup owner
              */
-            void reset(Popup &popup);
+            void reset(Popup &popup, void *newOwner = nullptr);
 
             /**
              * @brief Creates popup-list.
-             * @param[in] type Type of list popup. Refer to PopupListType
+             * @param[in] new popup owner
              * @return created popup-list.
              */
-            PopupList &getPopupList(PopupList::PopupListType type = PopupList::ListPopup);
+            PopupList &getPopupList(void *newOwner = nullptr);
 
             /**
-             * @brief Creates popup.
+             * @brief Creates more-popup.
+             * @param[in] new popup owner
+             * @return created more-popup
+             */
+            PopupList &getMorePopup(void *newOwner = nullptr);
+
+            /**
+             * @brief Creates base-popup.
+             * @param[in] new popup owner
              * @return popup created.
              */
-            Popup &getPopup();
+            Popup &getPopup(void *newOwner = nullptr );
 
             /**
              * @brief Creates specific popup.
@@ -84,7 +94,7 @@ namespace Msg
              * @return popup created.
              */
             template<typename ClassName, typename... Args>
-            ClassName &getPopup(Args&&... args);
+            ClassName &getPopup(Args&&... args, void *newOwner = nullptr);
 
             /**
              * @brief Checks whether popup exists and it's visible.
@@ -92,28 +102,6 @@ namespace Msg
              */
             bool isPopupVisible() const;
 
-            /**
-             * @brief Destroys popup. If no popup exists nothing happens.
-             */
-            void resetPopup();
-
-            /**
-             * @brief Creates context popup.
-             * @return context popup created.
-             */
-            ContextPopup &getCtxPopup();
-
-            /**
-             * @brief Checks whether context popup exists and it's visible.
-             * @return true if context popup exists and it's visible, false otherwise.
-             */
-            bool isCtxPopupVisible() const;
-
-            /**
-             * @brief Destroys context popup. If no context popup exists nothing happens.
-             */
-            void resetCtxPopup();
-
             /**
              * @brief Process pause event
              */
@@ -121,20 +109,20 @@ namespace Msg
 
         private:
             void onHwBackButtonPopupClicked(Evas_Object *obj, void *eventInfo);
-            void onHwBackButtonCtxPopupClicked(Evas_Object *obj, void *eventInfo);
             void onHwMoreButtonPopupListClicked(Evas_Object *obj, void *eventInfo);
 
         private:
             Popup *m_pPopup;
-            ContextPopup *m_pCtxPopup;
             Window &m_Window;
+            void *m_pPopupOwner;
     };
 
     template<typename ClassName, typename... Args>
-    ClassName &PopupManager::getPopup(Args&&... args)
+    ClassName &PopupManager::getPopup(Args&&... args, void *newOwner)
     {
         reset();
         m_pPopup = new ClassName(*this, std::forward<Args>(args)...);
+        m_pPopupOwner = newOwner;
         eext_object_event_callback_add(*m_pPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonPopupClicked), this);
         return static_cast<ClassName&>(*m_pPopup);
     }
index e3689839cce7073da1346eb86dc82dc7c17de676..43e44791f05ad3a12e139d299b4d9b199b2ff1dc 100644 (file)
@@ -17,7 +17,6 @@
 #include "ContextPopup.h"
 #include "Window.h"
 #include "Logger.h"
-#include "PopupManager.h"
 
 using namespace Msg;
 
@@ -47,18 +46,6 @@ int ContextPopupItem::getId() const
 }
 
 // ContextPopup:
-ContextPopup::ContextPopup(Evas_Object *parent)
-    : m_pManager(nullptr)
-{
-    createContextPopup(parent);
-}
-
-ContextPopup::ContextPopup(PopupManager &parent)
-    : m_pManager(&parent)
-{
-    createContextPopup(parent.getWindow());
-}
-
 ContextPopup::~ContextPopup()
 {
     MSG_LOG("Destructor");
@@ -99,10 +86,7 @@ void ContextPopup::createContextPopup(Evas_Object *parent)
 
 void ContextPopup::destroy()
 {
-    if(m_pManager)
-        m_pManager->resetCtxPopup();
-    else
-        View::destroy();
+    View::destroy();
 }
 
 void ContextPopup::setDirectionPriority(Elm_Ctxpopup_Direction first, Elm_Ctxpopup_Direction second,
@@ -119,8 +103,7 @@ Elm_Ctxpopup_Direction ContextPopup::getDirection() const
 void ContextPopup::on_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
 {
     ContextPopup *self = static_cast<ContextPopup*>(data);
-    if(self->m_pManager)
-        self->m_pManager->resetCtxPopup();
+    self->destroy();
 }
 
 void ContextPopup::on_item_pressed_cb(void *data, Evas_Object *obj, void *event_info)
index dde804d0e0eba60b29e44254a7801e44dd489d55..b00fd20e90232ff856cfb57513cc9ca10e1894a5 100644 (file)
@@ -81,7 +81,7 @@ void Popup::create(Evas_Object *parent)
 void Popup::destroy()
 {
     if(m_pManager)
-        m_pManager->resetPopup();
+        m_pManager->reset();
     else
         View::destroy();
 }
index ef0e027710b3b59bc84f565629350f2d9c2f83ad..c57b4962d2269a53155e91fb372e494725e8a362 100644 (file)
@@ -24,8 +24,8 @@ using namespace Msg;
 
 PopupManager::PopupManager(Window &window)
     : m_pPopup(nullptr)
-    , m_pCtxPopup(nullptr)
     , m_Window(window)
+    , m_pPopupOwner(nullptr)
 {
 }
 
@@ -38,19 +38,22 @@ PopupManager::~PopupManager()
 {
 }
 
-bool PopupManager::isVisible() const
+void PopupManager::reset(void *popupOwner)
 {
-    return isPopupVisible() || isCtxPopupVisible();
-}
-
-void PopupManager::reset()
-{
-    resetCtxPopup();
-    resetPopup();
+    if(!popupOwner || (popupOwner == m_pPopupOwner))
+    {
+        if(m_pPopup)
+        {
+            m_pPopup->View::destroy();
+            m_pPopup = nullptr;
+        }
+        m_pPopupOwner = nullptr;
+    }
 }
 
-void PopupManager::reset(Popup &popup)
+void PopupManager::reset(Popup &popup, void *newOwner)
 {
+    m_pPopupOwner = newOwner;
     if(&popup != m_pPopup)
     {
         reset();
@@ -59,79 +62,45 @@ void PopupManager::reset(Popup &popup)
     }
 }
 
-Popup &PopupManager::getPopup()
-{
-    reset();
-    m_pPopup = new Popup(*this);
-    eext_object_event_callback_add(*m_pPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonPopupClicked), this);
-    return *m_pPopup;
-}
-
-PopupList &PopupManager::getPopupList(PopupList::PopupListType type)
+Popup &PopupManager::getPopup(void *newOwner)
 {
-    reset();
-    m_pPopup = new PopupList(*this, type);
-    eext_object_event_callback_add(*m_pPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonPopupClicked), this);
-    eext_object_event_callback_add(*m_pPopup, EEXT_CALLBACK_MORE, SMART_CALLBACK(PopupManager, onHwMoreButtonPopupListClicked), this);
-    return *static_cast<PopupList*>(m_pPopup);
+    auto &popup = getPopup<Popup>(newOwner);
+    return popup;
 }
 
-bool PopupManager::isPopupVisible() const
+PopupList &PopupManager::getPopupList(void *newOwner)
 {
-    return m_pPopup ? m_pPopup->isVisible() : false;
+    PopupList &popup = getPopup<PopupList, PopupList::PopupListType>(PopupList::ListPopup, newOwner);
+    eext_object_event_callback_add(popup, EEXT_CALLBACK_MORE, SMART_CALLBACK(PopupManager, onHwMoreButtonPopupListClicked), this);
+    return popup;
 }
 
-void PopupManager::resetPopup()
+PopupList &PopupManager::getMorePopup(void *newOwner)
 {
-    if(m_pPopup)
-    {
-        m_pPopup->View::destroy();
-        m_pPopup = nullptr;
-    }
+    PopupList &popup = getPopup<PopupList, PopupList::PopupListType>(PopupList::MoreMenuPopup, newOwner);
+    eext_object_event_callback_add(popup, EEXT_CALLBACK_MORE, SMART_CALLBACK(PopupManager, onHwMoreButtonPopupListClicked), this);
+    return popup;
 }
 
-ContextPopup &PopupManager::getCtxPopup()
-{
-    reset();
-    m_pCtxPopup = new ContextPopup(*this);
-    eext_object_event_callback_add(*m_pCtxPopup, EEXT_CALLBACK_BACK, SMART_CALLBACK(PopupManager, onHwBackButtonCtxPopupClicked), this);
-    return *m_pCtxPopup;
-}
-
-bool PopupManager::isCtxPopupVisible() const
-{
-    return m_pCtxPopup ? m_pCtxPopup->isVisible() : false;
-}
-
-void PopupManager::resetCtxPopup()
+bool PopupManager::isPopupVisible() const
 {
-    if(m_pCtxPopup)
-    {
-        m_pCtxPopup->View::destroy();
-        m_pCtxPopup = nullptr;
-    }
+    return m_pPopup ? m_pPopup->isVisible() : false;
 }
 
 void PopupManager::onHwBackButtonPopupClicked(Evas_Object *obj, void *eventInfo)
 {
-    resetPopup();
+    reset();
 }
 
 void PopupManager::onHwMoreButtonPopupListClicked(Evas_Object *obj, void *eventInfo)
 {
     if (m_pPopup->getDismissByMoreMenuKeyFlag())
-        resetPopup();
-}
-
-void PopupManager::onHwBackButtonCtxPopupClicked(Evas_Object *obj, void *eventInfo)
-{
-    resetCtxPopup();
+        reset();
 }
 
 void PopupManager::onPause()
 {
     if (m_pPopup && m_pPopup->getDismissByPauseAppFlag())
-        resetPopup();
-    resetCtxPopup();
+        reset();
 }
 
index 186c1d8e52e908727fe296021cbf730d18d85f2c..d9d5d0663320cb658a6e3f8917805fe7cbc6f4e2 100644 (file)
@@ -71,6 +71,7 @@ ConvListItem::ConvListItem(const MsgConversationItem &item,
 
 ConvListItem::~ConvListItem()
 {
+    m_App.getPopupManager().reset(this);
     for(auto *entity : m_BubbleEntityList)
     {
         delete entity;
@@ -335,7 +336,7 @@ void ConvListItem::showPopup()
 
 void ConvListItem::showMainListPopup()
 {
-    auto &listPopup = m_App.getPopupManager().getPopupList();
+    auto &listPopup = m_App.getPopupManager().getPopupList(this);
     listPopup.setTitle(msg("IDS_MSGF_BODY_MESSAGE_OPTIONS"));
 
     std::string msgText = getAllMsgText();
@@ -394,7 +395,7 @@ void ConvListItem::tryToDownloadMms(bool showToast)
 
 void ConvListItem::showDraftListPopup()
 {
-    auto &listPopup = m_App.getPopupManager().getPopupList();
+    auto &listPopup = m_App.getPopupManager().getPopupList(this);
     listPopup.setTitle(msg("IDS_MSGF_BODY_MESSAGE_OPTIONS"));
     listPopup.appendItem(msg("IDS_MSGF_OPT_EDIT_MESSAGE"), POPUPLIST_ITEM_PRESSED_CB(ConvListItem, onEditItemPressed), this);
     listPopup.appendItem(msg("IDS_MSG_OPT_DELETE"), POPUPLIST_ITEM_PRESSED_CB(ConvListItem, onDeleteItemPressed), this);
@@ -403,7 +404,7 @@ void ConvListItem::showDraftListPopup()
 
 void ConvListItem::showFailedToSendPopup()
 {
-    Popup &popup = m_App.getPopupManager().getPopup();
+    Popup &popup = m_App.getPopupManager().getPopup(this);
     popup.addButton(msgt("IDS_MSG_BUTTON_CANCEL_ABB"), Popup::CancelButtonId, POPUP_BUTTON_CB(ConvListItem, onCancelButtonClicked), this);
     popup.addButton(msgt("IDS_MSG_BUTTON_RESEND_ABB"), Popup::OkButtonId, POPUP_BUTTON_CB(ConvListItem, onFailedResendButtonClicked), this);
     popup.setTitle(msgt("IDS_MSG_HEADER_COULDNT_SEND_MESSAGE_ABB"));
@@ -414,7 +415,7 @@ void ConvListItem::showFailedToSendPopup()
 void ConvListItem::onDeleteItemPressed(PopupListItem &item)
 {
     item.getParent().destroy();
-    Popup &popup = m_App.getPopupManager().getPopup();
+    Popup &popup = m_App.getPopupManager().getPopup(this);
     popup.addButton(msgt("IDS_MSG_BUTTON_CANCEL_ABB"), Popup::CancelButtonId, POPUP_BUTTON_CB(ConvListItem, onCancelButtonClicked), this);
     popup.addButton(msgt("IDS_MSG_BUTTON_DELETE_ABB4"), Popup::OkButtonId, POPUP_BUTTON_CB(ConvListItem, onDeleteButtonClicked), this);
     popup.setTitle(msgt("IDS_MSG_HEADER_DELETE"));
@@ -531,7 +532,7 @@ void ConvListItem::onCopyToSimCardItemPressed(PopupListItem &item)
 void ConvListItem::onViewDetailsItemPressed(PopupListItem &item)
 {
     MSG_LOG("");
-    m_App.getPopupManager().getPopup<MsgDetailsPopup>(m_App, m_MsgId).show();
+    m_App.getPopupManager().getPopup<MsgDetailsPopup, App&, MsgId&>(m_App, m_MsgId, this).show();
 }
 
 void ConvListItem::onEditButtonClicked(Evas_Object *obj, void *event_info)
index 3b611e951725c8661b1fab1dcf949c72f5bf2e3e..45fd33c865439ca7df6beea1879ece987a5980cd 100644 (file)
@@ -932,7 +932,7 @@ void Conversation::showSendReadReportPopup()
 
 void Conversation::showMainPopup()
 {
-    PopupList &popup = getApp().getPopupManager().getPopupList(PopupList::MoreMenuPopup);
+    PopupList &popup = getApp().getPopupManager().getMorePopup();
     popup.appendItem(msg("IDS_MSG_OPT_DELETE"), POPUPLIST_ITEM_PRESSED_CB(Conversation, onDeleteItemPressed), this);
     if(m_AddressList && m_AddressList->getLength() == 1)
     {
index b6755bef34b0effe515aa33e16dee10ef6980ae9..3dbf3d5e6997ce8dcd6fd26e929580cab12a6866 100644 (file)
@@ -105,7 +105,7 @@ void MsgThread::onAttached(ViewItem &item)
 
 void MsgThread::showMainPopup()
 {
-    PopupList &popup = getApp().getPopupManager().getPopupList(PopupList::MoreMenuPopup);
+    PopupList &popup = getApp().getPopupManager().getMorePopup();
     if (!m_pThreadList->isEmpty())
     {
         popup.appendItem(msg("IDS_MSG_OPT_DELETE"), POPUPLIST_ITEM_PRESSED_CB(MsgThread, onDeleteItemPressed), this);
index 4cc9f82128198ed14da636c5e1ed97db99128086..4c8b37aadcb4576af3eea1bc9fcfeaed50c80384 100644 (file)
@@ -161,7 +161,7 @@ void MsgOnSimCard::showCopyDeletePopup()
 {
     if(!m_pList->isEmpty())
     {
-        PopupList &listPopup = getApp().getPopupManager().getPopupList(PopupList::MoreMenuPopup);
+        PopupList &listPopup = getApp().getPopupManager().getMorePopup();
         listPopup.appendItem(msg("IDS_MSG_OPT_COPY_TO_DEVICE_ABB"), POPUPLIST_ITEM_PRESSED_CB(MsgOnSimCard, onCopyToDeviceItemPressed), this);
         listPopup.appendItem(msg("IDS_MSG_OPT_DELETE"), POPUPLIST_ITEM_PRESSED_CB(MsgOnSimCard, onDeleteItemPressed), this);
         listPopup.show();
index 3342d65cb1865d14404d2ddee42cb8cbf52f4a57..3af28c677364f910edf28021c20c735ebb02c70e 100644 (file)
@@ -273,7 +273,7 @@ void Viewer::onHwMoreButtonClicked()
 {
     m_pSmilPlayer->stop();
 
-    PopupList &popup = getApp().getPopupManager().getPopupList(PopupList::MoreMenuPopup);
+    PopupList &popup = getApp().getPopupManager().getMorePopup();
     popup.appendItem(msg("IDS_MSG_OPT_DELETE"), POPUPLIST_ITEM_PRESSED_CB(Viewer, onDeleteItemPressed), this);
 
     if(!m_Msg->getText().empty())