diff --git a/mozilla/camino/src/download/SaveHeaderSniffer.mm b/mozilla/camino/src/download/SaveHeaderSniffer.mm index 9b11afbb68b..b20f0aee8e8 100644 --- a/mozilla/camino/src/download/SaveHeaderSniffer.mm +++ b/mozilla/camino/src/download/SaveHeaderSniffer.mm @@ -371,11 +371,13 @@ nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString& nsCOMPtr downloader = do_CreateInstance(NS_TRANSFER_CONTRACTID); // dlListener attaches to its progress dialog here, which gains ownership - rv = downloader->Init(inOriginalURI, destURI, inFileName.get(), nsnull, timeNow, webPersist); + rv = downloader->Init(inOriginalURI, destURI, inFileName, nsnull, timeNow, webPersist); if (NS_FAILED(rv)) return rv; PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES; webPersist->SetPersistFlags(flags); + + webPersist->SetProgressListener(downloader); if (sourceURI) { diff --git a/mozilla/camino/src/download/nsDownloadListener.h b/mozilla/camino/src/download/nsDownloadListener.h index e66051cbef5..46ed6a2a233 100644 --- a/mozilla/camino/src/download/nsDownloadListener.h +++ b/mozilla/camino/src/download/nsDownloadListener.h @@ -80,10 +80,8 @@ public: private: - // These two are mutually exclusive - nsCOMPtr mWebPersist; // Our web persist object. - nsCOMPtr mHelperAppLauncher; // If we're talking to uriloader - + nsCOMPtr mCancelable; // Object to cancel the download + nsCOMPtr mURI; // The URI of our source file. Null if we're saving a complete document. nsCOMPtr mDestination; // Our destination URL. nsCOMPtr mDestinationFile; // Our destination file. diff --git a/mozilla/camino/src/download/nsDownloadListener.mm b/mozilla/camino/src/download/nsDownloadListener.mm index 6c2b197f667..17ec8047d2b 100644 --- a/mozilla/camino/src/download/nsDownloadListener.mm +++ b/mozilla/camino/src/download/nsDownloadListener.mm @@ -40,7 +40,6 @@ #import "NSString+Utils.h" #include "nsDownloadListener.h" -#include "nsIObserver.h" #include "nsIWebProgress.h" #include "nsIRequest.h" @@ -69,10 +68,10 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsDownloadListener, CHDownloader, nsIDownload, #pragma mark - -/* void init (in nsIURI aSource, in nsIURI aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */ +/* void init (in nsIURI aSource, in nsIURI aTarget, in AString aDisplayName, in wstring openingWith, in long long startTime, in nsICancelable aCancelable); */ NS_IMETHODIMP -nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const PRUnichar *aDisplayName, - nsIMIMEInfo* aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist) +nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const nsAString &aDisplayName, + nsIMIMEInfo* aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable) { // get the local file corresponding to the given target URI nsCOMPtr targetFile; @@ -89,23 +88,19 @@ nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const PRUnichar *aDis NS_ENSURE_TRUE(targetFile, NS_ERROR_INVALID_ARG); CreateDownloadDisplay(); // call the base class to make the download UI - - if (aPersist) // only true for File->Save As. - { - mWebPersist = aPersist; - mWebPersist->SetProgressListener(this); // we form a cycle here, since we're a listener. - // we'll break this cycle in DownloadDone() - } - - SetIsFileSave(aPersist != NULL); + + // Note: This forms a cycle, which will be broken in DownloadDone + mCancelable = aCancelable; + + // This is a file save if the cancelable object is a webbrowserpersist + nsCOMPtr persist(do_QueryInterface(aCancelable)); + SetIsFileSave(persist != NULL); mDestination = aTarget; mDestinationFile = targetFile; mURI = aSource; mStartTime = startTime; - mHelperAppLauncher = nsnull; - InitDialog(); return NS_OK; } @@ -128,12 +123,12 @@ nsDownloadListener::GetTarget(nsIURI * *aTarget) return NS_OK; } -/* readonly attribute nsIWebBrowserPersist persist; */ +/* readonly attribute nsICancelable cancelable; */ NS_IMETHODIMP -nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist) +nsDownloadListener::GetCancelable(nsICancelable * *aCancelable) { - NS_ENSURE_ARG_POINTER(aPersist); - NS_IF_ADDREF(*aPersist = mWebPersist); + NS_ENSURE_ARG_POINTER(aCancelable); + NS_IF_ADDREF(*aCancelable = mCancelable); return NS_OK; } @@ -182,21 +177,6 @@ nsDownloadListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) return NS_ERROR_NOT_IMPLEMENTED; } -/* attribute nsIObserver observer; */ -NS_IMETHODIMP -nsDownloadListener::GetObserver(nsIObserver * *aObserver) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDownloadListener::SetObserver(nsIObserver * aObserver) -{ - if (aObserver) - mHelperAppLauncher = do_QueryInterface(aObserver); - return NS_OK; -} - NS_IMETHODIMP nsDownloadListener::GetTargetFile(nsILocalFile ** aTargetFile) { @@ -344,10 +324,8 @@ nsDownloadListener::CancelDownload() if (!mSentCancel) { - if (mWebPersist) - mWebPersist->CancelSave(); - else if (mHelperAppLauncher) - mHelperAppLauncher->Cancel(NS_BINDING_ABORTED); + if (mCancelable) + mCancelable->Cancel(NS_BINDING_ABORTED); mSentCancel = PR_TRUE; } @@ -361,12 +339,8 @@ nsDownloadListener::CancelDownload() void nsDownloadListener::DownloadDone(nsresult aStatus) { - // break the reference cycle by removing ourselves as a listener - if (mWebPersist) - { - mWebPersist->SetProgressListener(nsnull); - mWebPersist = nsnull; - } + // break the reference cycle + mCancelable = nsnull; mHelperAppLauncher = nsnull; mDownloadStatus = aStatus; diff --git a/mozilla/embedding/browser/cocoa/src/SaveHeaderSniffer.mm b/mozilla/embedding/browser/cocoa/src/SaveHeaderSniffer.mm index 8950721219a..73222739800 100644 --- a/mozilla/embedding/browser/cocoa/src/SaveHeaderSniffer.mm +++ b/mozilla/embedding/browser/cocoa/src/SaveHeaderSniffer.mm @@ -341,8 +341,10 @@ nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString& nsCOMPtr downloader = do_CreateInstance(NS_TRANSFER_CONTRACTID); // dlListener attaches to its progress dialog here, which gains ownership - rv = downloader->Init(inOriginalURI, destFile, inFileName.get(), nsnull, timeNow, webPersist); + rv = downloader->Init(inOriginalURI, destFile, inFileName, nsnull, timeNow, webPersist); if (NS_FAILED(rv)) return rv; + + webPersist->SetProgressListener(downloader); PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION | nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES; diff --git a/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm b/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm index 84bd5dcdeb0..2c0ecfc731f 100644 --- a/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm +++ b/mozilla/embedding/browser/cocoa/src/nsDownloadListener.mm @@ -64,21 +64,19 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsDownloadListener, CHDownloader, nsIDownload, #pragma mark - -/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */ +/* void init (in nsIURI aSource, in nsILocalFile aTarget, in AString aDisplayName, in wstring openingWith, in long long startTime, in nsICancelable aCancelable); */ NS_IMETHODIMP -nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, - nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist) +nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const nsAString &aDisplayName, + nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable) { CreateDownloadDisplay(); // call the base class to make the download UI - - if (aPersist) // only true for File->Save As. - { - mWebPersist = aPersist; - mWebPersist->SetProgressListener(this); // we form a cycle here, since we're a listener. - // we'll break this cycle in DownloadDone() - } - - SetIsFileSave(aPersist != NULL); + + // Note: This forms a cycle, which will be broken in DownloadDone + mCancelable = aCancelable; + + // This is a file save if the cancelable object is a webbrowserpersist + nsCOMPtr persist(do_QueryInterface(aCancelable)); + SetIsFileSave(persist != NULL); mDestination = aTarget; mURI = aSource; @@ -106,12 +104,12 @@ nsDownloadListener::GetTarget(nsILocalFile * *aTarget) return NS_OK; } -/* readonly attribute nsIWebBrowserPersist persist; */ +/* readonly attribute nsICancelable cancelable; */ NS_IMETHODIMP -nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist) +nsDownloadListener::GetCancelable(nsICancelable * *aCancelable) { - NS_ENSURE_ARG_POINTER(aPersist); - NS_IF_ADDREF(*aPersist = mWebPersist); + NS_ENSURE_ARG_POINTER(aCancelable); + NS_IF_ADDREF(*aCancelable = mCancelable); return NS_OK; } @@ -174,19 +172,6 @@ nsDownloadListener::SetListener(nsIWebProgressListener * aListener) return NS_ERROR_NOT_IMPLEMENTED; } -/* attribute nsIObserver observer; */ -NS_IMETHODIMP -nsDownloadListener::GetObserver(nsIObserver * *aObserver) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDownloadListener::SetObserver(nsIObserver * aObserver) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - #pragma mark - /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ diff --git a/mozilla/embedding/browser/powerplant/source/UDownload.cpp b/mozilla/embedding/browser/powerplant/source/UDownload.cpp index 78f453356b3..097540bec09 100644 --- a/mozilla/embedding/browser/powerplant/source/UDownload.cpp +++ b/mozilla/embedding/browser/powerplant/source/UDownload.cpp @@ -44,7 +44,6 @@ #include "nsDirectoryServiceUtils.h" #include "nsIRequest.h" #include "netCore.h" -#include "nsIObserver.h" #include "UDownloadDisplay.h" #include "UMacUnicode.h" @@ -76,20 +75,16 @@ NS_IMPL_ISUPPORTS4(CDownload, nsIDownload, nsITransfer, #pragma mark - #pragma mark [CDownload::nsIDownload] -/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsIWebBrowserPersist aPersist); */ -NS_IMETHODIMP CDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist) +/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsICancelable aCancelable); */ +NS_IMETHODIMP CDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable) { try { mSource = aSource; mDestination = aTarget; mStartTime = startTime; mPercentComplete = 0; - if (aPersist) { - mWebPersist = aPersist; - // We have to break this circular ref when the download is done - - // until nsIWebBrowserPersist supports weak refs - bug #163889. - aPersist->SetProgressListener(this); - } + // We have to break this circular ref when the download is done + mCancelable = aCancelable; EnsureProgressView(); sProgressView->AddDownloadItem(this); } @@ -115,11 +110,11 @@ NS_IMETHODIMP CDownload::GetTarget(nsILocalFile * *aTarget) return NS_OK; } -/* readonly attribute nsIWebBrowserPersist persist; */ -NS_IMETHODIMP CDownload::GetPersist(nsIWebBrowserPersist * *aPersist) +/* readonly attribute nsICancelable cancelable; */ +NS_IMETHODIMP CDownload::GetCancelable(nsIWebBrowserCancelable * *aCancelable) { - NS_ENSURE_ARG_POINTER(aPersist); - NS_IF_ADDREF(*aPersist = mWebPersist); + NS_ENSURE_ARG_POINTER(aCancelable); + NS_IF_ADDREF(*aCancelable = mCancelable); return NS_OK; } @@ -151,19 +146,6 @@ NS_IMETHODIMP CDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) return NS_ERROR_NOT_IMPLEMENTED; } -/* attribute nsIObserver observer; */ -NS_IMETHODIMP CDownload::GetObserver(nsIObserver * *aObserver) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP CDownload::SetObserver(nsIObserver * aObserver) -{ - if (aObserver) - aObserver->QueryInterface(NS_GET_IID(nsIHelperAppLauncher), getter_AddRefs(mHelperAppLauncher)); - return NS_OK; -} - #pragma mark - #pragma mark [CDownload::nsIWebProgressListener] @@ -183,11 +165,7 @@ NS_IMETHODIMP CDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest // We will get this even in the event of a cancel, if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) { - if (mWebPersist) { - mWebPersist->SetProgressListener(nsnull); - mWebPersist = nsnull; - } - mHelperAppLauncher = nsnull; + mCancelable = nsnull; BroadcastMessage(msg_OnDLComplete, this); } @@ -198,10 +176,7 @@ NS_IMETHODIMP CDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest NS_IMETHODIMP CDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) { if (mUserCanceled) { - if (mHelperAppLauncher) - mHelperAppLauncher->Cancel(NS_BINDING_ABORTED); - else if (aRequest) - aRequest->Cancel(NS_BINDING_ABORTED); + mCancelable->Cancel(NS_BINDING_ABORTED); mUserCanceled = false; } if (aMaxTotalProgress == -1) @@ -251,8 +226,7 @@ void CDownload::Cancel() mUserCanceled = true; // nsWebBrowserPersist does the right thing: After canceling, next time through // OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService. - if (!mWebPersist) - mStatus = NS_ERROR_ABORT; + mStatus = NS_ERROR_ABORT; } void CDownload::CreateProgressView() diff --git a/mozilla/embedding/browser/powerplant/source/UDownload.h b/mozilla/embedding/browser/powerplant/source/UDownload.h index f93e9a232cb..02de3b91daf 100644 --- a/mozilla/embedding/browser/powerplant/source/UDownload.h +++ b/mozilla/embedding/browser/powerplant/source/UDownload.h @@ -117,9 +117,7 @@ protected: bool mUserCanceled; nsresult mStatus; - // These two are mutually exclusive. - nsCOMPtr mWebPersist; - nsCOMPtr mHelperAppLauncher; + nsCOMPtr mCancelable; static ADownloadProgressView *sProgressView; }; diff --git a/mozilla/embedding/components/ui/progressDlg/nsIProgressDialog.idl b/mozilla/embedding/components/ui/progressDlg/nsIProgressDialog.idl index a8eff831016..1b2d08bc605 100644 --- a/mozilla/embedding/components/ui/progressDlg/nsIProgressDialog.idl +++ b/mozilla/embedding/components/ui/progressDlg/nsIProgressDialog.idl @@ -40,6 +40,7 @@ #include "nsIDownload.idl" interface nsIDOMWindow; +interface nsIObserver; /* nsIProgressDialog * @@ -62,7 +63,7 @@ interface nsIDOMWindow; * not need to hold a reference to it. */ -[scriptable, uuid(80183bd3-b9e8-45a6-a2ee-1449bc0d4253)] +[scriptable, uuid(20e790a2-76c6-462d-851a-22ab6cbbe48b)] interface nsIProgressDialog : nsIDownload { /** * Open the dialog @@ -80,6 +81,15 @@ interface nsIProgressDialog : nsIDownload { */ attribute PRBool cancelDownloadOnClose; + /** + * Observer for this dialog. If set, receives the following topics: + * oncancel - observer should cancel the transfer + * onpause - observer should suspend the transfer + * onresume - observer should resume the suspended transfer + * For each of those, the subject will be the nsIProgressDialog. + */ + attribute nsIObserver observer; + /** * The dialog object itself. This might be null if the dialog isn't * open yet, or has been closed. diff --git a/mozilla/embedding/components/ui/progressDlg/nsProgressDialog.js b/mozilla/embedding/components/ui/progressDlg/nsProgressDialog.js index c2af028eb52..f283b1fc66a 100644 --- a/mozilla/embedding/components/ui/progressDlg/nsProgressDialog.js +++ b/mozilla/embedding/components/ui/progressDlg/nsProgressDialog.js @@ -498,7 +498,8 @@ nsProgressDialog.prototype = { // Cancel the download, if not completed. if ( !this.completed ) { if ( this.operation ) { - this.operation.cancelSave(); + const NS_BINDING_ABORTED = 0x804b0002; + this.operation.cancel(NS_BINDING_ABORTED); // XXX We're supposed to clean up files/directories. } if ( this.observer ) { diff --git a/mozilla/mailnews/base/src/nsMessenger.cpp b/mozilla/mailnews/base/src/nsMessenger.cpp index 6690bcdeccc..3204e957c8a 100644 --- a/mozilla/mailnews/base/src/nsMessenger.cpp +++ b/mozilla/mailnews/base/src/nsMessenger.cpp @@ -253,7 +253,7 @@ class nsSaveAllAttachmentsState; class nsSaveMsgListener : public nsIUrlListener, public nsIMsgCopyServiceListener, public nsIStreamListener, - public nsIObserver + public nsICancelable { public: nsSaveMsgListener(nsIFileSpec* fileSpec, nsMessenger* aMessenger); @@ -265,7 +265,7 @@ public: NS_DECL_NSIMSGCOPYSERVICELISTENER NS_DECL_NSISTREAMLISTENER NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSIOBSERVER + NS_DECL_NSICANCELABLE nsCOMPtr m_fileSpec; nsCOMPtr m_outputStream; @@ -1714,15 +1714,13 @@ nsSaveMsgListener::~nsSaveMsgListener() // // nsISupports // -NS_IMPL_ISUPPORTS4(nsSaveMsgListener, nsIUrlListener, nsIMsgCopyServiceListener, nsIStreamListener, nsIObserver) +NS_IMPL_ISUPPORTS4(nsSaveMsgListener, nsIUrlListener, nsIMsgCopyServiceListener, nsIStreamListener, nsICancelable) NS_IMETHODIMP -nsSaveMsgListener::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) +nsSaveMsgListener::Cancel(nsresult status) { - if (!nsCRT::strcmp(aTopic, "oncancel")) - mCanceled = PR_TRUE; - + mCanceled = PR_TRUE; return NS_OK; } @@ -1862,9 +1860,8 @@ nsresult nsSaveMsgListener::InitializeDownload(nsIRequest * aRequest, PRInt32 aB nsCOMPtr url; channel->GetURI(getter_AddRefs(url)); - rv = tr->Init(url, outputURI, nsnull, mimeinfo, timeDownloadStarted, nsnull); + rv = tr->Init(url, outputURI, EmptyString(), mimeinfo, timeDownloadStarted, this); - tr->SetObserver(this); // now store the web progresslistener mTransfer = tr; } diff --git a/mozilla/toolkit/components/downloads/public/nsIDownloadManager.idl b/mozilla/toolkit/components/downloads/public/nsIDownloadManager.idl index 77f8fe7894c..df66605af9f 100644 --- a/mozilla/toolkit/components/downloads/public/nsIDownloadManager.idl +++ b/mozilla/toolkit/components/downloads/public/nsIDownloadManager.idl @@ -45,13 +45,13 @@ interface nsIDOMWindow; interface nsIURI; interface nsILocalFile; interface nsIDownload; -interface nsIWebBrowserPersist; +interface nsICancelable; interface nsIMIMEInfo; interface nsIRDFDataSource; interface nsIDownloadProgressListener; interface nsISupportsArray; -[scriptable, uuid(9be66cc0-1dd1-11b2-8617-e3a3ed26e3b0)] +[scriptable, uuid(31e8cfdc-52c7-4a36-b1c2-8038a12c271d)] interface nsIDownloadManager : nsISupports { // Download States const short DOWNLOAD_NOTSTARTED = -1; @@ -68,30 +68,32 @@ interface nsIDownloadManager : nsISupports { /** * Creates an nsIDownload and adds it to be managed by the download manager. * - * @param aSource The source (nsIURI) of the download. + * @param aSource The source URI of the transfer. Must not be null. * - * @param aTarget The local file to which the download is being saved. + * @param aTarget The target URI of the transfer. Must not be null. * - * @param aDisplayName The user-readable description of the download. + * @param aDisplayName The user-readable description of the transfer. + * Can be empty. * - * @param aPersist The "persist" used to transfer the download. If set, - * the manager will set its listener to the download item - * and use it for cancellation. If not set, the client - * is expected to set the download item as the listener on - * whatever transfer component is being used, and to - * set an observer on the download item that listens for - * the "oncancel" topic and cancels the download. + * @param aMIMEInfo The MIME info associated with the target, + * including MIME type and helper app when appropriate. + * This parameter is optional. + * + * @param startTime Time when the download started + * + * @param aCancelable An object that can be used to abort the download. + * Must not be null. * * @return The newly created download item with the passed-in properties. */ nsIDownload addDownload(in short aDownloadType, in nsIURI aSource, in nsIURI aTarget, - in wstring aDisplayName, - in wstring aIconURL, + in AString aDisplayName, + in AString aIconURL, in nsIMIMEInfo aMIMEInfo, - in long long aStartTime, - in nsIWebBrowserPersist aPersist); + in PRTime aStartTime, + in nsICancelable aCancelable); /** * Retrieves an in-progress download managed by the download manager. @@ -108,11 +110,8 @@ interface nsIDownloadManager : nsISupports { /** * Cancels the download with the specified persistent descriptor if it's - * currently in progress. If a "persist" was specified for the download, - * nsIWebBrowserPersist::CancelSave will be called. If an observer was set - * on the nsIDownload, it will be notified with the "oncancel" topic. Clients - * that don't provide a "persist" must listen for this topic and cancel the - * download. + * currently in progress. This calls cancel(NS_BINDING_ABORTED) on the + * nsICancelable provided for the download. * * @param aPersistentDescriptor The persistent descriptor of the download to * be cancelled. diff --git a/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp b/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp index 0a153b981ed..f5c68043cd4 100644 --- a/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp +++ b/mozilla/toolkit/components/downloads/src/nsDownloadManager.cpp @@ -495,11 +495,11 @@ NS_IMETHODIMP nsDownloadManager::AddDownload(DownloadType aDownloadType, nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, - const PRUnichar* aIconURL, + const nsAString& aDisplayName, + const nsAString& aIconURL, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist, + PRTime aStartTime, + nsICancelable* aCancelable, nsIDownload** aDownload) { NS_ENSURE_ARG_POINTER(aSource); @@ -610,10 +610,9 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType, } // Assert icon information - if (aIconURL) { + if (!aIconURL.IsEmpty()) { nsCOMPtr iconURIRes; - nsDependentString iconURL(aIconURL); - gRDFService->GetUnicodeResource(iconURL, getter_AddRefs(iconURIRes)); + gRDFService->GetUnicodeResource(aIconURL, getter_AddRefs(iconURIRes)); mDataSource->GetTarget(downloadRes, gNC_IconURL, PR_TRUE, getter_AddRefs(node)); if (node) rv = mDataSource->Change(downloadRes, gNC_IconURL, node, iconURIRes); @@ -655,13 +654,8 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType, return rv; } - // if a persist object was specified, set the download item as the progress listener // this will create a cycle that will be broken in nsDownload::OnStateChange - if (aPersist) { - internalDownload->SetPersist(aPersist); - nsCOMPtr listener = do_QueryInterface(*aDownload); - aPersist->SetProgressListener(listener); - } + internalDownload->SetCancelable(aCancelable); // If this is an install operation, ensure we have a progress listener for the // install and track this download separately. @@ -717,23 +711,11 @@ nsDownloadManager::CancelDownload(const PRUnichar* aPath) internalDownload->SetDownloadState(nsIDownloadManager::DOWNLOAD_CANCELED); - // if a persist was provided, we can do the cancel ourselves. - nsCOMPtr persist; - internalDownload->GetPersist(getter_AddRefs(persist)); - if (persist) { - rv = persist->CancelSave(); - if (NS_FAILED(rv)) return rv; - } - - // if an observer was provided, notify that the download was cancelled. - // if no persist was provided, this is necessary so that whatever transfer - // component being used can cancel the download itself. - nsCOMPtr observer; - internalDownload->GetObserver(getter_AddRefs(observer)); - if (observer) { - rv = observer->Observe(internalDownload, "oncancel", nsnull); - if (NS_FAILED(rv)) return rv; - } + // Cancel using the provided object + nsCOMPtr cancelable; + internalDownload->GetCancelable(getter_AddRefs(cancelable)); + if (cancelable) + cancelable->Cancel(NS_BINDING_ABORTED); DownloadEnded(aPath, nsnull); @@ -744,7 +726,7 @@ nsDownloadManager::CancelDownload(const PRUnichar* aPath) nsCOMPtr dialog; internalDownload->GetDialog(getter_AddRefs(dialog)); if (dialog) { - observer = do_QueryInterface(dialog); + nsCOMPtr observer = do_QueryInterface(dialog); rv = observer->Observe(internalDownload, "oncancel", nsnull); if (NS_FAILED(rv)) return rv; } @@ -1878,9 +1860,9 @@ nsDownload::SetDownloadType(DownloadType aType) } nsresult -nsDownload::SetPersist(nsIWebBrowserPersist* aPersist) +nsDownload::SetCancelable(nsICancelable* aCancelable) { - mPersist = aPersist; + mCancelable = aCancelable; return NS_OK; } @@ -2066,7 +2048,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress, if (aStateFlags & STATE_START) mStartTime = PR_Now(); - // When we break the ref cycle with mPersist, we don't want to lose + // When we break the ref cycle with mCancelable, we don't want to lose // access to out member vars! nsCOMPtr kungFuDeathGrip; CallQueryInterface(this, NS_STATIC_CAST(nsIDownload**, @@ -2141,8 +2123,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress, gObserverService->NotifyObservers(NS_STATIC_CAST(nsIDownload *, this), "dl-done", nsnull); // break the cycle we created in AddDownload - if (mPersist) - mPersist->SetProgressListener(nsnull); + mCancelable = nsnull; // Now remove the download if the user's retention policy is "Remove when Done" if (mDownloadManager->GetRetentionBehavior() == 0) { @@ -2177,10 +2158,10 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress, NS_IMETHODIMP nsDownload::Init(nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, + const nsAString& aDisplayName, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist) + PRTime aStartTime, + nsICancelable* aCancelable) { NS_WARNING("Huh...how did we get here?!"); return NS_OK; @@ -2193,6 +2174,14 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName) return NS_OK; } +NS_IMETHODIMP +nsDownload::GetCancelable(nsICancelable** aCancelable) +{ + *aCancelable = mCancelable; + NS_IF_ADDREF(*aCancelable); + return NS_OK; +} + NS_IMETHODIMP nsDownload::GetTarget(nsIURI** aTarget) { @@ -2209,14 +2198,6 @@ nsDownload::GetSource(nsIURI** aSource) return NS_OK; } -NS_IMETHODIMP -nsDownload::GetPersist(nsIWebBrowserPersist** aPersist) -{ - *aPersist = mPersist; - NS_IF_ADDREF(*aPersist); - return NS_OK; -} - NS_IMETHODIMP nsDownload::GetStartTime(PRInt64* aStartTime) { @@ -2245,21 +2226,6 @@ nsDownload::GetSize(PRUint64* aSize) return NS_OK; } -NS_IMETHODIMP -nsDownload::SetObserver(nsIObserver* aObserver) -{ - mObserver = aObserver; - return NS_OK; -} - -NS_IMETHODIMP -nsDownload::GetObserver(nsIObserver** aObserver) -{ - *aObserver = mObserver; - NS_IF_ADDREF(*aObserver); - return NS_OK; -} - NS_IMETHODIMP nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo) { diff --git a/mozilla/toolkit/components/downloads/src/nsDownloadManager.h b/mozilla/toolkit/components/downloads/src/nsDownloadManager.h index dda3fa384d1..c0b50309f17 100644 --- a/mozilla/toolkit/components/downloads/src/nsDownloadManager.h +++ b/mozilla/toolkit/components/downloads/src/nsDownloadManager.h @@ -219,7 +219,7 @@ protected: nsresult GetDialogListener(nsIWebProgressListener** aInternalListener); nsresult SetDialog(nsIProgressDialog* aDialog); nsresult GetDialog(nsIProgressDialog** aDialog); - nsresult SetPersist(nsIWebBrowserPersist* aPersist); + nsresult SetCancelable(nsICancelable* aCancelable); nsresult SetTarget(nsIURI* aTarget); nsresult SetDisplayName(const PRUnichar* aDisplayName); nsresult SetSource(nsIURI* aSource); @@ -238,10 +238,9 @@ private: nsCOMPtr mSource; nsCOMPtr mDialogListener; - nsCOMPtr mPersist; + nsCOMPtr mCancelable; nsCOMPtr mRequest; nsCOMPtr mDialog; - nsCOMPtr mObserver; nsCOMPtr mMIMEInfo; DownloadState mDownloadState; diff --git a/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h b/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h index f0c8fb361c4..4c7e406f52d 100644 --- a/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h +++ b/mozilla/toolkit/components/downloads/src/nsDownloadProxy.h @@ -60,18 +60,18 @@ public: NS_IMETHODIMP Init(nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, + const nsAString& aDisplayName, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist) { + PRTime aStartTime, + nsICancelable* aCancelable) { nsresult rv; nsCOMPtr dm = do_GetService("@mozilla.org/download-manager;1", &rv); if (NS_FAILED(rv)) return rv; - rv = dm->AddDownload(nsIDownloadManager::DOWNLOAD_TYPE_DOWNLOAD, aSource, aTarget, - aDisplayName, nsnull, aMIMEInfo, aStartTime, aPersist, - getter_AddRefs(mInner)); + rv = dm->AddDownload(nsIDownloadManager::DOWNLOAD_TYPE_DOWNLOAD, aSource, + aTarget, aDisplayName, EmptyString(), aMIMEInfo, + aStartTime, aCancelable, getter_AddRefs(mInner)); if (NS_FAILED(rv)) return rv; nsCOMPtr prefs = do_GetService("@mozilla.org/preferences-service;1", &rv); @@ -142,19 +142,9 @@ public: return mInner->GetSize(aSize); } - NS_IMETHODIMP GetObserver(nsIObserver** aObserver) + NS_IMETHODIMP GetCancelable(nsICancelable** aCancelable) { - return mInner->GetObserver(aObserver); - } - - NS_IMETHODIMP SetObserver(nsIObserver* aObserver) - { - return mInner->SetObserver(aObserver); - } - - NS_IMETHODIMP GetPersist(nsIWebBrowserPersist** aPersist) - { - return mInner->GetPersist(aPersist); + return mInner->GetCancelable(aCancelable); } NS_IMETHODIMP GetTargetFile(nsILocalFile** aTargetFile) diff --git a/mozilla/toolkit/content/contentAreaUtils.js b/mozilla/toolkit/content/contentAreaUtils.js index 18cf60be940..8f08c75ce51 100644 --- a/mozilla/toolkit/content/contentAreaUtils.js +++ b/mozilla/toolkit/content/contentAreaUtils.js @@ -353,11 +353,13 @@ function foundHeaderInfo(aSniffer, aData, aSkipPrompt) } const kWrapColumn = 80; - tr.init(aSniffer.uri, persistArgs.target, null, null, null, persist); + tr.init(aSniffer.uri, persistArgs.target, "", null, null, persist); + persist.progressListener = tr; persist.saveDocument(persistArgs.source, persistArgs.target, filesFolder, persistArgs.contentType, encodingFlags, kWrapColumn); } else { - tr.init(source, persistArgs.target, null, null, null, persist); + tr.init(source, persistArgs.target, null, "", null, persist); + persist.progressListener = tr; var referrer = aData.referrer || getReferrer(document) persist.saveURI(source, null, referrer, persistArgs.postData, null, persistArgs.target); } diff --git a/mozilla/uriloader/base/nsIDownload.idl b/mozilla/uriloader/base/nsIDownload.idl index b63b56204bb..013ad711806 100644 --- a/mozilla/uriloader/base/nsIDownload.idl +++ b/mozilla/uriloader/base/nsIDownload.idl @@ -41,11 +41,11 @@ interface nsIURI; interface nsILocalFile; interface nsIObserver; -interface nsIWebBrowserPersist; +interface nsICancelable; interface nsIWebProgressListener; interface nsIMIMEInfo; -[scriptable, uuid(4584178b-ebbd-4d5e-91d3-aa676c2291d2)] +[scriptable, uuid(1cb42fb4-f092-4a0e-8930-6c06a524da07)] interface nsIDownload : nsITransfer { /** @@ -81,13 +81,10 @@ interface nsIDownload : nsITransfer { readonly attribute nsIURI target; /** - * Optional. If set, it will be used for cancellation, and the transfer - * will be set as its listener. If not, |observer| should be set to listen - * and respond accordingly to topics like oncancel, and the client promises - * to set the transfer item as the listener for whatever transfer component - * is being used. + * Object that can be used to cancel the download. + * Will be null after the download is finished. */ - readonly attribute nsIWebBrowserPersist persist; + readonly attribute nsICancelable cancelable; /** * The user-readable description of the transfer. diff --git a/mozilla/uriloader/base/nsITransfer.idl b/mozilla/uriloader/base/nsITransfer.idl index 564395bfbdf..8d3b173339d 100644 --- a/mozilla/uriloader/base/nsITransfer.idl +++ b/mozilla/uriloader/base/nsITransfer.idl @@ -39,47 +39,44 @@ #include "nsIWebProgressListener2.idl" interface nsIURI; -interface nsIObserver; -interface nsIWebBrowserPersist; +interface nsICancelable; interface nsIMIMEInfo; -[scriptable, uuid(4af66079-938d-4093-9cc4-561dac709c7b)] +[scriptable, uuid(0721AAF2-28AC-46cd-BCFA-5F8CA2A8B99B)] interface nsITransfer : nsIWebProgressListener2 { /** * Initializes the transfer with certain properties. This function must * be called prior to accessing any properties on this interface. * - * @param aSource The source URI of the transfer. + * @param aSource The source URI of the transfer. Must not be null. * - * @param aTarget The target URI of the transfer. + * @param aTarget The target URI of the transfer. Must not be null. * * @param aDisplayName The user-readable description of the transfer. + * Can be empty. * * @param aMIMEInfo The MIME info associated with the target, * including MIME type and helper app when appropriate. * This parameter is optional. * - * @param aPersist The "persist" used for this transfer. If set, - * the manager will set its listener to the transfer item - * and use it for cancellation. If not set, the client - * is expected to set the transfer item as the listener on - * whatever transfer component is being used, and to - * set an observer on the transfer item that listens for - * the "oncancel" topic and cancels the transfer. + * @param startTime Time when the download started (ie, when the first + * response from the server was received) + * XXX presumably wbp and exthandler do this differently + * + * @param aCancelable An object that can be used to abort the download. + * Must not be null. + * Implementations are expected to hold a strong + * reference to this object until the download is + * finished, at which point they should release the + * reference. */ void init(in nsIURI aSource, in nsIURI aTarget, - in wstring aDisplayName, + in AString aDisplayName, in nsIMIMEInfo aMIMEInfo, - in long long startTime, - in nsIWebBrowserPersist aPersist); - - /** - * If set, receives notifications of events like cancel ("oncancel"). - * Must be set if no persist object is specified (see above). - */ - attribute nsIObserver observer; + in PRTime startTime, + in nsICancelable aCancelable); }; %{C++ @@ -88,7 +85,7 @@ interface nsITransfer : nsIWebProgressListener2 { * started, and nsITransfer::Init will be called on it and an observer will be set. * * Notifications of the download progress will happen via - * nsIWebProgressListener. + * nsIWebProgressListener/nsIWebProgressListener2. * * If nsIObserver is implemented, the component may get a notification with * topic "temp-file" and an nsILocalFile instance as subject, which indicates @@ -98,9 +95,13 @@ interface nsITransfer : nsIWebProgressListener2 { * INTERFACES THAT MUST BE IMPLEMENTED: * nsITransfer * nsIWebProgressListener + * nsIWebProgressListener2 * * INTERFACES THAT MAY BE IMPLEMENTED: * nsIObserver + * + * XXX move this to nsEmbedCID.h once the interfaces (and the contract ID) are + * frozen. */ #define NS_TRANSFER_CONTRACTID "@mozilla.org/transfer;1" %} diff --git a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp index c1ee44d4bcb..10a107b68d1 100644 --- a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -1348,7 +1348,6 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler) NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher) NS_INTERFACE_MAP_ENTRY(nsICancelable) - NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_END_THREADSAFE nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, @@ -1390,17 +1389,6 @@ nsExternalAppHandler::~nsExternalAppHandler() sSrv->Release(); } -NS_IMETHODIMP nsExternalAppHandler::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData ) -{ - if (strcmp(aTopic, "oncancel") == 0) - { - // User pressed cancel button on dialog. - return Cancel(NS_BINDING_ABORTED); - } - return NS_OK; -} - - NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener2 * aWebProgressListener) { // this call back means we've succesfully brought up the @@ -2013,9 +2001,6 @@ NS_IMETHODIMP nsExternalAppHandler::OnStopRequest(nsIRequest *request, nsISuppor // This nsITransfer object holds a reference to us (we are its observer), so // we need to release the reference to break a reference cycle (and therefore // to prevent leaking) - nsCOMPtr tr(do_QueryInterface(mWebProgressListener)); - if (tr) - tr->SetObserver(nsnull); mWebProgressListener = nsnull; return NS_OK; @@ -2100,11 +2085,9 @@ nsresult nsExternalAppHandler::InitializeDownload(nsITransfer* aTransfer) rv = NS_NewFileURI(getter_AddRefs(target), mFinalFileDestination); if (NS_FAILED(rv)) return rv; - rv = aTransfer->Init(mSourceUrl, target, nsnull, - mMimeInfo, mTimeDownloadStarted, nsnull); + rv = aTransfer->Init(mSourceUrl, target, EmptyString(), + mMimeInfo, mTimeDownloadStarted, this); if (NS_FAILED(rv)) return rv; - - rv = aTransfer->SetObserver(this); // Tell the listener about the location of the target file nsCOMPtr obs(do_QueryInterface(aTransfer)); @@ -2457,9 +2440,6 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) // Release the listener, to break the reference cycle with it (we are the // observer of the listener). - nsCOMPtr tr(do_QueryInterface(mWebProgressListener)); - if (tr) - tr->SetObserver(nsnull); mWebProgressListener = nsnull; return NS_OK; diff --git a/mozilla/uriloader/exthandler/nsExternalHelperAppService.h b/mozilla/uriloader/exthandler/nsExternalHelperAppService.h index 40a2fc415f4..f706a9a4386 100644 --- a/mozilla/uriloader/exthandler/nsExternalHelperAppService.h +++ b/mozilla/uriloader/exthandler/nsExternalHelperAppService.h @@ -321,8 +321,7 @@ protected: * data using a helper app. */ class nsExternalAppHandler : public nsIStreamListener, - public nsIHelperAppLauncher, - public nsIObserver + public nsIHelperAppLauncher { public: NS_DECL_ISUPPORTS @@ -330,7 +329,6 @@ public: NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIHELPERAPPLAUNCHER NS_DECL_NSICANCELABLE - NS_DECL_NSIOBSERVER /** * @param aMIMEInfo MIMEInfo object, representing the type of the diff --git a/mozilla/xpfe/communicator/resources/content/contentAreaUtils.js b/mozilla/xpfe/communicator/resources/content/contentAreaUtils.js index 06ffc230da0..47ed4d908d2 100644 --- a/mozilla/xpfe/communicator/resources/content/contentAreaUtils.js +++ b/mozilla/xpfe/communicator/resources/content/contentAreaUtils.js @@ -416,12 +416,14 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition, const kWrapColumn = 80; tr.init((aChosenData ? aChosenData.uri : fileInfo.uri), - persistArgs.target, null, null, null, persist); + persistArgs.target, "", null, null, persist); + persist.progressListener = tr; persist.saveDocument(persistArgs.source, persistArgs.target, filesFolder, persistArgs.contentType, encodingFlags, kWrapColumn); } else { tr.init((aChosenData ? aChosenData.uri : source), - persistArgs.target, null, null, null, persist); + persistArgs.target, "", null, null, persist); + persist.progressListener = tr; var referer = aReferrer || getReferrer(document); persist.saveURI((aChosenData ? aChosenData.uri : source), null, referer, persistArgs.postData, null, persistArgs.target); diff --git a/mozilla/xpfe/components/download-manager/public/nsIDownloadManager.idl b/mozilla/xpfe/components/download-manager/public/nsIDownloadManager.idl index a915a9cc4ea..b075bdf0450 100644 --- a/mozilla/xpfe/components/download-manager/public/nsIDownloadManager.idl +++ b/mozilla/xpfe/components/download-manager/public/nsIDownloadManager.idl @@ -46,10 +46,10 @@ interface nsIDOMWindow; interface nsIURI; interface nsILocalFile; interface nsIDownload; -interface nsIWebBrowserPersist; +interface nsICancelable; interface nsIMIMEInfo; -[scriptable, uuid(17d403cc-364a-482c-b77e-914a0ecbf7a1)] +[scriptable, uuid(db2eb695-ebb3-4296-9f52-41ddcfce4ca3)] interface nsIDownloadManager : nsISupports { // Methods called by clients to carry out various managing functions @@ -57,28 +57,31 @@ interface nsIDownloadManager : nsISupports { /** * Creates an nsIDownload and adds it to be managed by the download manager. * - * @param aSource The source (nsIURI) of the download. + * @param aSource The source URI of the transfer. Must not be null. * - * @param aTarget The local file to which the download is being saved. + * @param aTarget The target URI of the transfer. Must not be null. * - * @param aDisplayName The user-readable description of the download. + * @param aDisplayName The user-readable description of the transfer. + * Can be empty. * - * @param aPersist The "persist" used to transfer the download. If set, - * the manager will set its listener to the download item - * and use it for cancellation. If not set, the client - * is expected to set the download item as the listener on - * whatever transfer component is being used, and to - * set an observer on the download item that listens for - * the "oncancel" topic and cancels the download. + * @param aMIMEInfo The MIME info associated with the target, + * including MIME type and helper app when appropriate. + * This parameter is optional. * + * @param startTime Time when the download started (ie, when the first + * response from the server was received) + * + * @param aCancelable An object that can be used to abort the download. + * Must not be null. + * @return The newly created download item with the passed-in properties. */ nsIDownload addDownload(in nsIURI aSource, in nsIURI aTarget, - in wstring aDisplayName, + in AString aDisplayName, in nsIMIMEInfo aMIMEInfo, - in long long startTime, - in nsIWebBrowserPersist aPersist); + in PRTime startTime, + in nsICancelable aCancelable); /** * Retrieves an in-progress download managed by the download manager. diff --git a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp index 4922105922c..c147ab4874b 100644 --- a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp +++ b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.cpp @@ -432,10 +432,10 @@ nsDownloadManager::AssertProgressInfoFor(const nsACString& aTargetPath) NS_IMETHODIMP nsDownloadManager::AddDownload(nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, + const nsAString& aDisplayName, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist, + PRTime aStartTime, + nsICancelable* aCancelable, nsIDownload** aDownload) { NS_ENSURE_ARG_POINTER(aSource); @@ -446,7 +446,8 @@ nsDownloadManager::AddDownload(nsIURI* aSource, nsresult rv = GetDownloadsContainer(getter_AddRefs(downloads)); if (NS_FAILED(rv)) return rv; - nsDownload* internalDownload = new nsDownload(this, aTarget, aSource); + // this will create a cycle that will be broken in nsDownload::OnStateChange + nsDownload* internalDownload = new nsDownload(this, aTarget, aSource, aCancelable); if (!internalDownload) return NS_ERROR_OUT_OF_MEMORY; @@ -528,13 +529,6 @@ nsDownloadManager::AddDownload(nsIURI* aSource, rv = remote->Flush(); if (NS_FAILED(rv)) return rv; - // if a persist object was specified, set the download item as the progress listener - // this will create a cycle that will be broken in nsDownload::OnStateChange - if (aPersist) { - internalDownload->SetPersist(aPersist); - aPersist->SetProgressListener(internalDownload); - } - mCurrDownloads.Put(utf8Path, internalDownload); return rv; @@ -555,45 +549,11 @@ nsDownloadManager::GetDownload(const nsACString & aTargetPath, nsIDownload** aDo NS_IMETHODIMP nsDownloadManager::CancelDownload(const nsACString & aTargetPath) { - nsresult rv = NS_OK; nsRefPtr internalDownload = mCurrDownloads.GetWeak(aTargetPath); if (!internalDownload) return NS_ERROR_FAILURE; - // Don't cancel if download is already finished - if (internalDownload->GetDownloadState() == FINISHED) - return NS_OK; - - internalDownload->SetDownloadState(CANCELED); - - // if a persist was provided, we can do the cancel ourselves. - nsCOMPtr persist; - internalDownload->GetPersist(getter_AddRefs(persist)); - if (persist) { - rv = persist->CancelSave(); - if (NS_FAILED(rv)) return rv; - } - - // if an observer was provided, notify that the download was cancelled. - // if no persist was provided, this is necessary so that whatever transfer - // component being used can cancel the download itself. - nsCOMPtr observer; - internalDownload->GetObserver(getter_AddRefs(observer)); - if (observer) { - rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, internalDownload), "oncancel", nsnull); - if (NS_FAILED(rv)) return rv; - } - - DownloadEnded(aTargetPath, nsnull); - - // if there's a progress dialog open for the item, - // we have to notify it that we're cancelling - observer = do_QueryInterface(internalDownload->GetDialog()); - if (observer) { - rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, internalDownload), "oncancel", nsnull); - } - - return rv; + return internalDownload->Cancel(); } NS_IMETHODIMP @@ -801,7 +761,7 @@ nsDownloadManager::OpenProgressDialogFor(nsIDownload* aDownload, nsIDOMWindow* a nsCOMPtr mimeInfo; aDownload->GetMIMEInfo(getter_AddRefs(mimeInfo)); - dialog->Init(source, target, nsnull, mimeInfo, startTime, nsnull); + dialog->Init(source, target, EmptyString(), mimeInfo, startTime, nsnull); dialog->SetObserver(internalDownload); // now set the listener so we forward notifications to the dialog @@ -927,10 +887,12 @@ NS_IMPL_ISUPPORTS5(nsDownload, nsIDownload, nsITransfer, nsIWebProgressListener, nsDownload::nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, - nsIURI* aSource) : + nsIURI* aSource, + nsICancelable* aCancelable) : mDownloadManager(aManager), mTarget(aTarget), mSource(aSource), + mCancelable(aCancelable), mDownloadState(NOTSTARTED), mPercentComplete(0), mCurrBytes(0), @@ -957,6 +919,35 @@ nsDownload::Suspend() return mRequest->Suspend(); } +nsresult +nsDownload::Cancel() +{ + // Don't cancel if download is already finished or canceled + if (GetDownloadState() == FINISHED || GetDownloadState() == CANCELED) + return NS_OK; + + nsresult rv = mCancelable->Cancel(NS_BINDING_ABORTED); + if (NS_FAILED(rv)) + return rv; + + SetDownloadState(CANCELED); + + nsCAutoString path; + rv = GetFilePathUTF8(mTarget, path); + if (NS_FAILED(rv)) + return rv; + mDownloadManager->DownloadEnded(path, nsnull); + + // if there's a progress dialog open for the item, + // we have to notify it that we're cancelling + nsCOMPtr observer = do_QueryInterface(GetDialog()); + if (observer) { + rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, this), "oncancel", nsnull); + } + + return rv; +} + nsresult nsDownload::SetDisplayName(const PRUnichar* aDisplayName) { @@ -1001,11 +992,7 @@ nsDownload::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* if (strcmp(aTopic, "oncancel") == 0) { SetDialog(nsnull); - nsCAutoString path; - nsresult rv = GetFilePathUTF8(mTarget, path); - // XXX why can't nsDownload cancel itself without help from the dl manager? - if (NS_SUCCEEDED(rv)) - mDownloadManager->CancelDownload(path); + Cancel(); // Ignoring return value; this function will get called twice, // and bad things happen if we return a failure code the second time. return NS_OK; @@ -1268,8 +1255,12 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress, } // break the cycle we created in AddDownload - if (mPersist) - mPersist->SetProgressListener(nsnull); + mCancelable = nsnull; + // and the one with the progress dialog + if (mDialog) { + mDialog->SetObserver(nsnull); + mDialog = nsnull; + } } if (mDownloadManager->MustUpdateUI()) { @@ -1279,8 +1270,13 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress, internalListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus, this); } - if (mDialogListener) + if (mDialogListener) { mDialogListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); + if (aStateFlags & STATE_STOP) { + // Break this cycle, too + mDialogListener = nsnull; + } + } return rv; } @@ -1308,12 +1304,12 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress, NS_IMETHODIMP nsDownload::Init(nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, + const nsAString& aDisplayName, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist) + PRTime aStartTime, + nsICancelable* aCancelable) { - NS_WARNING("Huh...how did we get here?!"); + NS_NOTREACHED("Huh...how did we get here?!"); return NS_OK; } @@ -1324,6 +1320,14 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName) return NS_OK; } +NS_IMETHODIMP +nsDownload::GetCancelable(nsICancelable** aCancelable) +{ + *aCancelable = mCancelable; + NS_IF_ADDREF(*aCancelable); + return NS_OK; +} + NS_IMETHODIMP nsDownload::GetTarget(nsIURI** aTarget) { @@ -1340,14 +1344,6 @@ nsDownload::GetSource(nsIURI** aSource) return NS_OK; } -NS_IMETHODIMP -nsDownload::GetPersist(nsIWebBrowserPersist** aPersist) -{ - *aPersist = mPersist; - NS_IF_ADDREF(*aPersist); - return NS_OK; -} - NS_IMETHODIMP nsDownload::GetStartTime(PRInt64* aStartTime) { @@ -1376,21 +1372,6 @@ nsDownload::GetSize(PRUint64* aSize) return NS_OK; } -NS_IMETHODIMP -nsDownload::SetObserver(nsIObserver* aObserver) -{ - mObserver = aObserver; - return NS_OK; -} - -NS_IMETHODIMP -nsDownload::GetObserver(nsIObserver** aObserver) -{ - *aObserver = mObserver; - NS_IF_ADDREF(*aObserver); - return NS_OK; -} - NS_IMETHODIMP nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo) { diff --git a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.h b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.h index 923ab67c2f1..4a14637baf0 100644 --- a/mozilla/xpfe/components/download-manager/src/nsDownloadManager.h +++ b/mozilla/xpfe/components/download-manager/src/nsDownloadManager.h @@ -51,7 +51,6 @@ #include "nsIRDFContainerUtils.h" #include "nsIWebProgressListener.h" #include "nsIURI.h" -#include "nsIWebBrowserPersist.h" #include "nsILocalFile.h" #include "nsRefPtrHashtable.h" #include "nsIRequest.h" @@ -114,9 +113,11 @@ public: NS_DECL_NSIOBSERVER NS_DECL_ISUPPORTS - nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, nsIURI* aSource); + nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, nsIURI* aSource, + nsICancelable* aCancelable); ~nsDownload(); + nsresult Cancel(); nsresult Suspend(); nsresult SetDisplayName(const PRUnichar* aDisplayName); nsresult Resume(); @@ -132,9 +133,6 @@ public: nsIProgressDialog* GetDialog() { return mDialog; } - void SetPersist(nsIWebBrowserPersist* aPersist) { - mPersist = aPersist; - } struct TransferInformation { PRInt32 mCurrBytes, mMaxBytes; @@ -167,10 +165,9 @@ private: nsCOMPtr mTarget; nsCOMPtr mSource; nsCOMPtr mDialogListener; - nsCOMPtr mPersist; + nsCOMPtr mCancelable; nsCOMPtr mRequest; nsCOMPtr mDialog; - nsCOMPtr mObserver; nsCOMPtr mMIMEInfo; DownloadState mDownloadState; diff --git a/mozilla/xpfe/components/download-manager/src/nsDownloadProxy.h b/mozilla/xpfe/components/download-manager/src/nsDownloadProxy.h index 9cde6c2c6a5..acab0ba12a0 100644 --- a/mozilla/xpfe/components/download-manager/src/nsDownloadProxy.h +++ b/mozilla/xpfe/components/download-manager/src/nsDownloadProxy.h @@ -39,6 +39,7 @@ #ifndef downloadproxy___h___ #define downloadproxy___h___ +#include "nsCOMPtr.h" #include "nsIDownload.h" #include "nsIDownloadManager.h" #include "nsIPrefBranch.h" @@ -47,7 +48,7 @@ #define DOWNLOAD_MANAGER_BEHAVIOR_PREF "browser.downloadmanager.behavior" -class nsDownloadProxy : public nsIDownload +class nsDownloadProxy : public nsITransfer { public: @@ -55,19 +56,21 @@ public: virtual ~nsDownloadProxy() { } NS_DECL_ISUPPORTS + NS_FORWARD_SAFE_NSIWEBPROGRESSLISTENER(mInner) + NS_FORWARD_SAFE_NSIWEBPROGRESSLISTENER2(mInner) NS_IMETHODIMP Init(nsIURI* aSource, nsIURI* aTarget, - const PRUnichar* aDisplayName, + const nsAString& aDisplayName, nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist* aPersist) { + PRTime aStartTime, + nsICancelable* aCancelable) { nsresult rv; nsCOMPtr dm = do_GetService("@mozilla.org/download-manager;1", &rv); if (NS_FAILED(rv)) return rv; - rv = dm->AddDownload(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime, aPersist, getter_AddRefs(mInner)); + rv = dm->AddDownload(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime, aCancelable, getter_AddRefs(mInner)); if (NS_FAILED(rv)) return rv; @@ -79,171 +82,16 @@ public: behavior = 0; if (behavior == 0) - rv = dm->Open(nsnull, this); + rv = dm->Open(nsnull, mInner); else if (behavior == 1) rv = dm->OpenProgressDialogFor(mInner, nsnull, PR_TRUE); return rv; } - - - NS_IMETHODIMP GetDisplayName(PRUnichar** aDisplayName) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetDisplayName(aDisplayName); - } - - NS_IMETHODIMP GetMIMEInfo(nsIMIMEInfo** aMIMEInfo) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetMIMEInfo(aMIMEInfo); - } - - NS_IMETHODIMP GetSource(nsIURI** aSource) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetSource(aSource); - } - - NS_IMETHODIMP GetTarget(nsIURI** aTarget) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetTarget(aTarget); - } - - NS_IMETHODIMP GetStartTime(PRInt64* aStartTime) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetStartTime(aStartTime); - } - - NS_IMETHODIMP GetPercentComplete(PRInt32* aPercentComplete) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetPercentComplete(aPercentComplete); - } - - NS_IMETHODIMP GetAmountTransferred(PRUint64* aAmountTransferred) - { - return mInner->GetAmountTransferred(aAmountTransferred); - } - - NS_IMETHODIMP GetSize(PRUint64* aSize) - { - return mInner->GetSize(aSize); - } - - NS_IMETHODIMP GetObserver(nsIObserver** aObserver) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetObserver(aObserver); - } - - NS_IMETHODIMP SetObserver(nsIObserver* aObserver) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->SetObserver(aObserver); - } - - NS_IMETHODIMP GetPersist(nsIWebBrowserPersist** aPersist) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetPersist(aPersist); - } - - NS_IMETHODIMP GetTargetFile(nsILocalFile** aTargetFile) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->GetTargetFile(aTargetFile); - } - - NS_IMETHODIMP OnStateChange(nsIWebProgress* aWebProgress, - nsIRequest* aRequest, PRUint32 aStateFlags, - PRUint32 aStatus) - { - nsCOMPtr listener = do_QueryInterface(mInner); - if (listener) - return listener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); - return NS_OK; - } - - NS_IMETHODIMP OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsresult aStatus, - const PRUnichar *aMessage) - { - nsCOMPtr listener = do_QueryInterface(mInner); - if (listener) - return listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); - return NS_OK; - } - - NS_IMETHODIMP OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *aLocation) - { - nsCOMPtr listener = do_QueryInterface(mInner); - if (listener) - return listener->OnLocationChange(aWebProgress, aRequest, aLocation); - return NS_OK; - } - - NS_IMETHODIMP OnProgressChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aCurSelfProgress, - PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, - PRInt32 aMaxTotalProgress) - { - nsCOMPtr listener = do_QueryInterface(mInner); - if (listener) - return listener->OnProgressChange(aWebProgress, aRequest, - aCurSelfProgress, - aMaxSelfProgress, - aCurTotalProgress, - aMaxTotalProgress); - return NS_OK; - } - - NS_IMETHODIMP OnProgressChange64(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt64 aCurSelfProgress, - PRInt64 aMaxSelfProgress, - PRInt64 aCurTotalProgress, - PRInt64 aMaxTotalProgress) - { - if (!mInner) - return NS_ERROR_NOT_INITIALIZED; - return mInner->OnProgressChange64(aWebProgress, aRequest, - aCurSelfProgress, - aMaxSelfProgress, - aCurTotalProgress, - aMaxTotalProgress); - } - - - - NS_IMETHODIMP OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, PRUint32 aState) - { - nsCOMPtr listener = do_QueryInterface(mInner); - if (listener) - return listener->OnSecurityChange(aWebProgress, aRequest, aState); - return NS_OK; - } - private: nsCOMPtr mInner; }; -NS_IMPL_ISUPPORTS4(nsDownloadProxy, nsIDownload, nsITransfer, +NS_IMPL_ISUPPORTS3(nsDownloadProxy, nsITransfer, nsIWebProgressListener, nsIWebProgressListener2) #endif