Author: stippi Date: Sat Feb 27 18:26:46 2010 New Revision: 240 URL: http://mmlr.dyndns.org/changeset/240 Log: The BWebDownload was using BWebPage for stuff, but the BWebPage can be long gone when a BWebDownload wanted to use it. Now the class is more self-sufficient. One example of the problem was clicking a link that opens a blank page, then closing that page while the download was still loading. 1) The download finished notification never arrived and 2) clicking to cancel the download would crash after the download finished, since really it had already selfdestructed... Modified: webkit/trunk/WebKit/haiku/API/WebDownload.cpp webkit/trunk/WebKit/haiku/API/WebDownload.h webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.cpp webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.h webkit/trunk/WebKit/haiku/API/WebPage.cpp webkit/trunk/WebKit/haiku/API/WebPage.h webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Modified: webkit/trunk/WebKit/haiku/API/WebDownload.cpp ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebDownload.cpp Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebDownload.cpp Sat Feb 27 18:26:46 2010 (r240) @@ -29,18 +29,32 @@ #include "WebDownload.h" #include "WebDownloadPrivate.h" -#include "WebPage.h" +#include <Application.h> +#include <stdio.h> + +enum { + HANDLE_CANCEL = 'hdlc' +}; BWebDownload::BWebDownload(BPrivate::WebDownloadPrivate* data) : fData(data) { ASSERT(fData); + if (be_app->Lock()) { + be_app->AddHandler(this); + be_app->Unlock(); + } + fData->setDownload(this); } BWebDownload::~BWebDownload() { + if (be_app->Lock()) { + be_app->RemoveHandler(this); + be_app->Unlock(); + } delete fData; } @@ -54,7 +68,8 @@ // This is invoked from the client, within any thread, so we need to // dispatch this asynchronously so that it is actually handled in the // main thread. - fData->webPage()->cancelDownload(this); + BMessage message(HANDLE_CANCEL); + Looper()->PostMessage(&message, this); } void BWebDownload::SetProgressListener(const BMessenger& listener) @@ -87,3 +102,21 @@ return fData->expectedSize(); } +// #pragma mark - private + +void BWebDownload::MessageReceived(BMessage* message) +{ + switch (message->what) { + case HANDLE_CANCEL: + _HandleCancel(); + break; + default: + BHandler::MessageReceived(message); + } +} + +void BWebDownload::_HandleCancel() +{ + fData->cancel(); +} + Modified: webkit/trunk/WebKit/haiku/API/WebDownload.h ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebDownload.h Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebDownload.h Sat Feb 27 18:26:46 2010 (r240) @@ -27,7 +27,7 @@ #ifndef _WEB_DOWNLOAD_H_ #define _WEB_DOWNLOAD_H_ -#include <SupportDefs.h> +#include <Handler.h> namespace BPrivate { @@ -52,7 +52,7 @@ }; -class BWebDownload { +class BWebDownload : public BHandler { // TODO: Inherit from BReferenceable. public: void Start(); @@ -69,11 +69,17 @@ private: friend class BWebPage; + friend class BPrivate::WebDownloadPrivate; BWebDownload(BPrivate::WebDownloadPrivate* data); ~BWebDownload(); private: + virtual void MessageReceived(BMessage* message); + + void _HandleCancel(); + +private: BPrivate::WebDownloadPrivate* fData; }; Modified: webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.cpp ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.cpp Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.cpp Sat Feb 27 18:26:46 2010 (r240) @@ -43,9 +43,8 @@ namespace BPrivate { -WebDownloadPrivate::WebDownloadPrivate(BWebPage* webPage, const ResourceRequest& request) +WebDownloadPrivate::WebDownloadPrivate(const ResourceRequest& request) : m_webDownload(0) - , m_webPage(webPage) , m_resourceHandle(ResourceHandle::create(request, this, 0, false, false, false)) , m_currentSize(0) , m_expectedSize(0) @@ -55,12 +54,11 @@ , m_file() , m_lastProgressReportTime(0) { -printf("WebDownloadPrivate::WebDownloadPrivate()\n"); } -WebDownloadPrivate::WebDownloadPrivate(BWebPage* webPage, ResourceHandle* handle, +WebDownloadPrivate::WebDownloadPrivate(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response) - : m_webPage(webPage) + : m_webDownload(0) , m_resourceHandle(handle) , m_currentSize(0) , m_expectedSize(0) @@ -117,30 +115,26 @@ void WebDownloadPrivate::didFinishLoading(ResourceHandle* handle) { -printf("WebDownloadPrivate::didFinishLoading()\n"); - m_webPage->downloadFinished(handle, m_webDownload, B_DOWNLOAD_FINISHED); + handleFinished(handle, B_DOWNLOAD_FINISHED); } void WebDownloadPrivate::didFail(ResourceHandle* handle, const ResourceError& error) { -printf("WebDownloadPrivate::didFail()\n"); - m_webPage->downloadFinished(handle, m_webDownload, B_DOWNLOAD_FAILED); + handleFinished(handle, B_DOWNLOAD_FAILED); } void WebDownloadPrivate::wasBlocked(ResourceHandle* handle) { -printf("WebDownloadPrivate::wasBlocked()\n"); // FIXME: Implement this when we have the new frame loader signals // and error handling. - m_webPage->downloadFinished(handle, m_webDownload, B_DOWNLOAD_BLOCKED); + handleFinished(handle, B_DOWNLOAD_BLOCKED); } void WebDownloadPrivate::cannotShowURL(ResourceHandle* handle) { -printf("WebDownloadPrivate::cannotShowURL()\n"); // FIXME: Implement this when we have the new frame loader signals // and error handling. - m_webPage->downloadFinished(handle, m_webDownload, B_DOWNLOAD_CANNOT_SHOW_URL); + handleFinished(handle, B_DOWNLOAD_CANNOT_SHOW_URL); } void WebDownloadPrivate::setDownload(BWebDownload* download) @@ -163,5 +157,20 @@ m_progressListener = listener; } +// #pragma mark - private + +void WebDownloadPrivate::handleFinished(WebCore::ResourceHandle* handle, uint32 status) +{ + handle->setClient(0); + if (m_progressListener.IsValid()) { + BMessage message(B_DOWNLOAD_REMOVED); + message.AddPointer("download", m_webDownload); + // Block until the listener has released the object on it's side... + BMessage reply; + m_progressListener.SendMessage(&message, &reply); + } + delete m_webDownload; +} + } // namespace BPrivate Modified: webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.h ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.h Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebDownloadPrivate.h Sat Feb 27 18:26:46 2010 (r240) @@ -55,8 +55,8 @@ class WebDownloadPrivate : public Noncopyable, public WebCore::ResourceHandleClient { public: - WebDownloadPrivate(BWebPage*, const ResourceRequest&); - WebDownloadPrivate(BWebPage*, ResourceHandle*, const ResourceRequest&, const ResourceResponse&); + WebDownloadPrivate(const ResourceRequest&); + WebDownloadPrivate(ResourceHandle*, const ResourceRequest&, const ResourceResponse&); // ResourceHandleClient implementation virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); @@ -71,8 +71,6 @@ void cancel(); void setProgressListener(const BMessenger&); - BWebPage* webPage() const { return m_webPage; } - const BString& url() const { return m_url; } const BString& filename() const { return m_filename; } const BPath& path() const { return m_path; } @@ -80,8 +78,10 @@ off_t expectedSize() const { return m_expectedSize; } private: + void handleFinished(WebCore::ResourceHandle* handle, uint32 status); + +private: BWebDownload* m_webDownload; - BWebPage* m_webPage; RefPtr<ResourceHandle> m_resourceHandle; BString m_suggestedFileName; Modified: webkit/trunk/WebKit/haiku/API/WebPage.cpp ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebPage.cpp Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebPage.cpp Sat Feb 27 18:26:46 2010 (r240) @@ -103,9 +103,7 @@ HANDLE_CHANGE_TEXT_SIZE = 'txts', HANDLE_FIND_STRING = 'find', - HANDLE_RESEND_NOTIFICATIONS = 'rsnt', - - HANDLE_CANCEL_DOWNLOAD = 'cndn' + HANDLE_RESEND_NOTIFICATIONS = 'rsnt' }; using namespace WebCore; @@ -507,14 +505,14 @@ void BWebPage::requestDownload(const WebCore::ResourceRequest& request) { - BWebDownload* download = new BWebDownload(new BPrivate::WebDownloadPrivate(this, request)); + BWebDownload* download = new BWebDownload(new BPrivate::WebDownloadPrivate(request)); downloadCreated(download); } void BWebPage::requestDownload(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response) { - BWebDownload* download = new BWebDownload(new BPrivate::WebDownloadPrivate(this, handle, request, response)); + BWebDownload* download = new BWebDownload(new BPrivate::WebDownloadPrivate(handle, request, response)); downloadCreated(download); } @@ -530,27 +528,6 @@ } } -void BWebPage::downloadFinished(WebCore::ResourceHandle* handle, - BWebDownload* download, uint32 status) -{ - handle->setClient(0); - if (m_downloadListener.IsValid()) { - BMessage message(B_DOWNLOAD_REMOVED); - message.AddPointer("download", download); - // Block until the listener has released the object on it's side... - BMessage reply; - m_downloadListener.SendMessage(&message, &reply); - } - delete download; -} - -void BWebPage::cancelDownload(BWebDownload* download) -{ - BMessage message(HANDLE_CANCEL_DOWNLOAD); - message.AddPointer("download", download); - Looper()->PostMessage(&message, this); -} - void BWebPage::paint(BRect rect, bool contentChanged, bool immediate, bool repaintContentOnly) { @@ -724,9 +701,6 @@ } break; } - case HANDLE_CANCEL_DOWNLOAD: - handleCancelDownload(message); - break; default: BHandler::MessageReceived(message); @@ -924,15 +898,6 @@ // TODO: Other notifications... } -void BWebPage::handleCancelDownload(BMessage* message) -{ - BWebDownload* download; - if (message->FindPointer("download", reinterpret_cast<void**>(&download)) != B_OK) - return; - - download->fData->cancel(); -} - // #pragma mark - status_t BWebPage::dispatchMessage(BMessage& message) const Modified: webkit/trunk/WebKit/haiku/API/WebPage.h ============================================================================== --- webkit/trunk/WebKit/haiku/API/WebPage.h Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/API/WebPage.h Sat Feb 27 18:26:46 2010 (r240) @@ -159,9 +159,6 @@ void requestDownload(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response); void downloadCreated(BWebDownload* download); - void downloadFinished(WebCore::ResourceHandle* handle, BWebDownload* download, - uint32 status); - void cancelDownload(BWebDownload* download); void paint(BRect rect, bool contentChanged, bool immediate, bool repaintContentOnly); @@ -188,7 +185,6 @@ void handleChangeTextSize(BMessage* message); void handleFindString(BMessage* message); void handleResendNotifications(BMessage* message); - void handleCancelDownload(BMessage* message); status_t dispatchMessage(BMessage& message) const; Modified: webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp ============================================================================== --- webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Sat Feb 27 15:56:06 2010 (r239) +++ webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Sat Feb 27 18:26:46 2010 (r240) @@ -272,6 +272,12 @@ // TOAST! return; } + case B_DOWNLOAD_REMOVED: + // TODO: This is a bit asymetric. The removed notification + // arrives here, but it would be nicer if it arrived + // at the window... + Window()->PostMessage(message); + break; default: BGridView::MessageReceived(message); }