1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/downloads/nsDownloadManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,440 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef downloadmanager___h___ 1.10 +#define downloadmanager___h___ 1.11 + 1.12 +#if defined(XP_WIN) 1.13 +#define DOWNLOAD_SCANNER 1.14 +#endif 1.15 + 1.16 +#include "nsIDownload.h" 1.17 +#include "nsIDownloadManager.h" 1.18 +#include "nsIDownloadProgressListener.h" 1.19 +#include "nsIFile.h" 1.20 +#include "nsIMIMEInfo.h" 1.21 +#include "nsINavHistoryService.h" 1.22 +#include "nsIObserver.h" 1.23 +#include "nsIObserverService.h" 1.24 +#include "nsIStringBundle.h" 1.25 +#include "nsISupportsPrimitives.h" 1.26 +#include "nsWeakReference.h" 1.27 +#include "nsITimer.h" 1.28 +#include "nsString.h" 1.29 + 1.30 +#include "mozStorageHelper.h" 1.31 +#include "nsAutoPtr.h" 1.32 +#include "nsCOMArray.h" 1.33 + 1.34 +typedef int16_t DownloadState; 1.35 +typedef int16_t DownloadType; 1.36 + 1.37 +class nsIArray; 1.38 +class nsDownload; 1.39 + 1.40 +#ifdef DOWNLOAD_SCANNER 1.41 +#include "nsDownloadScanner.h" 1.42 +#endif 1.43 + 1.44 +class nsDownloadManager : public nsIDownloadManager, 1.45 + public nsINavHistoryObserver, 1.46 + public nsIObserver, 1.47 + public nsSupportsWeakReference 1.48 +{ 1.49 +public: 1.50 + NS_DECL_ISUPPORTS 1.51 + NS_DECL_NSIDOWNLOADMANAGER 1.52 + NS_DECL_NSINAVHISTORYOBSERVER 1.53 + NS_DECL_NSIOBSERVER 1.54 + 1.55 + nsresult Init(); 1.56 + 1.57 + static nsDownloadManager *GetSingleton(); 1.58 + 1.59 + virtual ~nsDownloadManager(); 1.60 + nsDownloadManager() 1.61 +#ifdef DOWNLOAD_SCANNER 1.62 + : mScanner(nullptr) 1.63 +#endif 1.64 + { 1.65 + } 1.66 + 1.67 +protected: 1.68 + nsresult InitDB(); 1.69 + nsresult InitFileDB(); 1.70 + void CloseAllDBs(); 1.71 + void CloseDB(mozIStorageConnection* aDBConn, 1.72 + mozIStorageStatement* aUpdateStmt, 1.73 + mozIStorageStatement* aGetIdsStmt); 1.74 + nsresult InitPrivateDB(); 1.75 + already_AddRefed<mozIStorageConnection> GetFileDBConnection(nsIFile *dbFile) const; 1.76 + already_AddRefed<mozIStorageConnection> GetPrivateDBConnection() const; 1.77 + nsresult CreateTable(mozIStorageConnection* aDBConn); 1.78 + 1.79 + /** 1.80 + * Fix up the database after a crash such as dealing with previously-active 1.81 + * downloads. Call this before RestoreActiveDownloads to get the downloads 1.82 + * fixed here to be auto-resumed. 1.83 + */ 1.84 + nsresult RestoreDatabaseState(); 1.85 + 1.86 + /** 1.87 + * Paused downloads that survive across sessions are considered active, so 1.88 + * rebuild the list of these downloads. 1.89 + */ 1.90 + nsresult RestoreActiveDownloads(); 1.91 + 1.92 + nsresult GetDownloadFromDB(const nsACString& aGUID, nsDownload **retVal); 1.93 + nsresult GetDownloadFromDB(uint32_t aID, nsDownload **retVal); 1.94 + nsresult GetDownloadFromDB(mozIStorageConnection* aDBConn, 1.95 + mozIStorageStatement* stmt, 1.96 + nsDownload **retVal); 1.97 + 1.98 + /** 1.99 + * Specially track the active downloads so that we don't need to check 1.100 + * every download to see if they're in progress. 1.101 + */ 1.102 + nsresult AddToCurrentDownloads(nsDownload *aDl); 1.103 + 1.104 + void SendEvent(nsDownload *aDownload, const char *aTopic); 1.105 + 1.106 + /** 1.107 + * Adds a download with the specified information to the DB. 1.108 + * 1.109 + * @return The id of the download, or 0 if there was an error. 1.110 + */ 1.111 + int64_t AddDownloadToDB(const nsAString &aName, 1.112 + const nsACString &aSource, 1.113 + const nsACString &aTarget, 1.114 + const nsAString &aTempPath, 1.115 + int64_t aStartTime, 1.116 + int64_t aEndTime, 1.117 + const nsACString &aMimeType, 1.118 + const nsACString &aPreferredApp, 1.119 + nsHandlerInfoAction aPreferredAction, 1.120 + bool aPrivate, 1.121 + nsACString &aNewGUID); 1.122 + 1.123 + void NotifyListenersOnDownloadStateChange(int16_t aOldState, 1.124 + nsDownload *aDownload); 1.125 + void NotifyListenersOnProgressChange(nsIWebProgress *aProgress, 1.126 + nsIRequest *aRequest, 1.127 + int64_t aCurSelfProgress, 1.128 + int64_t aMaxSelfProgress, 1.129 + int64_t aCurTotalProgress, 1.130 + int64_t aMaxTotalProgress, 1.131 + nsDownload *aDownload); 1.132 + void NotifyListenersOnStateChange(nsIWebProgress *aProgress, 1.133 + nsIRequest *aRequest, 1.134 + uint32_t aStateFlags, 1.135 + nsresult aStatus, 1.136 + nsDownload *aDownload); 1.137 + 1.138 + nsDownload *FindDownload(const nsACString& aGUID); 1.139 + nsDownload *FindDownload(uint32_t aID); 1.140 + 1.141 + /** 1.142 + * First try to resume the download, and if that fails, retry it. 1.143 + * 1.144 + * @param aDl The download to resume and/or retry. 1.145 + */ 1.146 + nsresult ResumeRetry(nsDownload *aDl); 1.147 + 1.148 + /** 1.149 + * Pause all active downloads and remember if they should try to auto-resume 1.150 + * when the download manager starts again. 1.151 + * 1.152 + * @param aSetResume Indicate if the downloads that get paused should be set 1.153 + * as auto-resume. 1.154 + */ 1.155 + nsresult PauseAllDownloads(bool aSetResume); 1.156 + 1.157 + /** 1.158 + * Resume all paused downloads unless we're only supposed to do the automatic 1.159 + * ones; in that case, try to retry them as well if resuming doesn't work. 1.160 + * 1.161 + * @param aResumeAll If true, all downloads will be resumed; otherwise, only 1.162 + * those that are marked as auto-resume will resume. 1.163 + */ 1.164 + nsresult ResumeAllDownloads(bool aResumeAll); 1.165 + 1.166 + /** 1.167 + * Stop tracking the active downloads. Only use this when we're about to quit 1.168 + * the download manager because we destroy our list of active downloads to 1.169 + * break the dlmgr<->dl cycle. Active downloads that aren't real-paused will 1.170 + * be canceled. 1.171 + */ 1.172 + nsresult RemoveAllDownloads(); 1.173 + 1.174 + /** 1.175 + * Find all downloads from a source URI and delete them. 1.176 + * 1.177 + * @param aURI 1.178 + * The source URI to remove downloads 1.179 + */ 1.180 + nsresult RemoveDownloadsForURI(nsIURI *aURI); 1.181 + 1.182 + /** 1.183 + * Callback used for resuming downloads after getting a wake notification. 1.184 + * 1.185 + * @param aTimer 1.186 + * Timer object fired after some delay after a wake notification 1.187 + * @param aClosure 1.188 + * nsDownloadManager object used to resume downloads 1.189 + */ 1.190 + static void ResumeOnWakeCallback(nsITimer *aTimer, void *aClosure); 1.191 + nsCOMPtr<nsITimer> mResumeOnWakeTimer; 1.192 + 1.193 + void ConfirmCancelDownloads(int32_t aCount, 1.194 + nsISupportsPRBool *aCancelDownloads, 1.195 + const char16_t *aTitle, 1.196 + const char16_t *aCancelMessageMultiple, 1.197 + const char16_t *aCancelMessageSingle, 1.198 + const char16_t *aDontCancelButton); 1.199 + 1.200 + int32_t GetRetentionBehavior(); 1.201 + 1.202 + /** 1.203 + * Type to indicate possible behaviors for active downloads across sessions. 1.204 + * 1.205 + * Possible values are: 1.206 + * QUIT_AND_RESUME - downloads should be auto-resumed 1.207 + * QUIT_AND_PAUSE - downloads should be paused 1.208 + * QUIT_AND_CANCEL - downloads should be cancelled 1.209 + */ 1.210 + enum QuitBehavior { 1.211 + QUIT_AND_RESUME = 0, 1.212 + QUIT_AND_PAUSE = 1, 1.213 + QUIT_AND_CANCEL = 2 1.214 + }; 1.215 + 1.216 + /** 1.217 + * Indicates user-set behavior for active downloads across sessions, 1.218 + * 1.219 + * @return value of user-set pref for active download behavior 1.220 + */ 1.221 + enum QuitBehavior GetQuitBehavior(); 1.222 + 1.223 + void OnEnterPrivateBrowsingMode(); 1.224 + void OnLeavePrivateBrowsingMode(); 1.225 + 1.226 + nsresult RetryDownload(const nsACString& aGUID); 1.227 + nsresult RetryDownload(nsDownload* dl); 1.228 + 1.229 + nsresult RemoveDownload(const nsACString& aGUID); 1.230 + 1.231 + nsresult NotifyDownloadRemoval(nsDownload* aRemoved); 1.232 + 1.233 + // Virus scanner for windows 1.234 +#ifdef DOWNLOAD_SCANNER 1.235 +private: 1.236 + nsDownloadScanner* mScanner; 1.237 +#endif 1.238 + 1.239 +private: 1.240 + nsresult CleanUp(mozIStorageConnection* aDBConn); 1.241 + nsresult InitStatements(mozIStorageConnection* aDBConn, 1.242 + mozIStorageStatement** aUpdateStatement, 1.243 + mozIStorageStatement** aGetIdsStatement); 1.244 + nsresult RemoveAllDownloads(nsCOMArray<nsDownload>& aDownloads); 1.245 + nsresult PauseAllDownloads(nsCOMArray<nsDownload>& aDownloads, bool aSetResume); 1.246 + nsresult ResumeAllDownloads(nsCOMArray<nsDownload>& aDownloads, bool aResumeAll); 1.247 + nsresult RemoveDownloadsForURI(mozIStorageStatement* aStatement, nsIURI *aURI); 1.248 + 1.249 + bool mUseJSTransfer; 1.250 + nsCOMArray<nsIDownloadProgressListener> mListeners; 1.251 + nsCOMArray<nsIDownloadProgressListener> mPrivacyAwareListeners; 1.252 + nsCOMPtr<nsIStringBundle> mBundle; 1.253 + nsCOMPtr<mozIStorageConnection> mDBConn; 1.254 + nsCOMPtr<mozIStorageConnection> mPrivateDBConn; 1.255 + nsCOMArray<nsDownload> mCurrentDownloads; 1.256 + nsCOMArray<nsDownload> mCurrentPrivateDownloads; 1.257 + nsCOMPtr<nsIObserverService> mObserverService; 1.258 + nsCOMPtr<mozIStorageStatement> mUpdateDownloadStatement; 1.259 + nsCOMPtr<mozIStorageStatement> mUpdatePrivateDownloadStatement; 1.260 + nsCOMPtr<mozIStorageStatement> mGetIdsForURIStatement; 1.261 + nsCOMPtr<mozIStorageStatement> mGetPrivateIdsForURIStatement; 1.262 + nsAutoPtr<mozStorageTransaction> mHistoryTransaction; 1.263 + 1.264 + static nsDownloadManager *gDownloadManagerService; 1.265 + 1.266 + friend class nsDownload; 1.267 +}; 1.268 + 1.269 +class nsDownload : public nsIDownload 1.270 +{ 1.271 +public: 1.272 + NS_DECL_NSIWEBPROGRESSLISTENER 1.273 + NS_DECL_NSIWEBPROGRESSLISTENER2 1.274 + NS_DECL_NSITRANSFER 1.275 + NS_DECL_NSIDOWNLOAD 1.276 + NS_DECL_ISUPPORTS 1.277 + 1.278 + nsDownload(); 1.279 + virtual ~nsDownload(); 1.280 + 1.281 + /** 1.282 + * This method MUST be called when changing states on a download. It will 1.283 + * notify the download listener when a change happens. This also updates the 1.284 + * database, by calling UpdateDB(). 1.285 + */ 1.286 + nsresult SetState(DownloadState aState); 1.287 + 1.288 +protected: 1.289 + /** 1.290 + * Finish up the download by breaking reference cycles and clearing unneeded 1.291 + * data. Additionally, the download removes itself from the download 1.292 + * manager's list of current downloads. 1.293 + * 1.294 + * NOTE: This method removes the cycle created when starting the download, so 1.295 + * make sure to use kungFuDeathGrip if you want to access member variables. 1.296 + */ 1.297 + void Finalize(); 1.298 + 1.299 + /** 1.300 + * For finished resumed downloads that came in from exthandler, perform the 1.301 + * action that would have been done if the download wasn't resumed. 1.302 + */ 1.303 + nsresult ExecuteDesiredAction(); 1.304 + 1.305 + /** 1.306 + * Move the temporary file to the final destination by removing the existing 1.307 + * dummy target and renaming the temporary. 1.308 + */ 1.309 + nsresult MoveTempToTarget(); 1.310 + 1.311 + /** 1.312 + * Update the start time which also implies the last update time is the same. 1.313 + */ 1.314 + void SetStartTime(int64_t aStartTime); 1.315 + 1.316 + /** 1.317 + * Update the amount of bytes transferred and max bytes; and recalculate the 1.318 + * download percent. 1.319 + */ 1.320 + void SetProgressBytes(int64_t aCurrBytes, int64_t aMaxBytes); 1.321 + 1.322 + /** 1.323 + * All this does is cancel the connection that the download is using. It does 1.324 + * not remove it from the download manager. 1.325 + */ 1.326 + nsresult CancelTransfer(); 1.327 + 1.328 + /** 1.329 + * Download is not transferring? 1.330 + */ 1.331 + bool IsPaused(); 1.332 + 1.333 + /** 1.334 + * Download can continue from the middle of a transfer? 1.335 + */ 1.336 + bool IsResumable(); 1.337 + 1.338 + /** 1.339 + * Download was resumed? 1.340 + */ 1.341 + bool WasResumed(); 1.342 + 1.343 + /** 1.344 + * Indicates if the download should try to automatically resume or not. 1.345 + */ 1.346 + bool ShouldAutoResume(); 1.347 + 1.348 + /** 1.349 + * Download is in a state to stop and complete the download? 1.350 + */ 1.351 + bool IsFinishable(); 1.352 + 1.353 + /** 1.354 + * Download is totally done transferring and all? 1.355 + */ 1.356 + bool IsFinished(); 1.357 + 1.358 + /** 1.359 + * Update the DB with the current state of the download including time, 1.360 + * download state and other values not known when first creating the 1.361 + * download DB entry. 1.362 + */ 1.363 + nsresult UpdateDB(); 1.364 + 1.365 + /** 1.366 + * Fail a download because of a failure status and prompt the provided 1.367 + * message or use a generic download failure message if nullptr. 1.368 + */ 1.369 + nsresult FailDownload(nsresult aStatus, const char16_t *aMessage); 1.370 + 1.371 + /** 1.372 + * Opens the downloaded file with the appropriate application, which is 1.373 + * either the OS default, MIME type default, or the one selected by the user. 1.374 + * 1.375 + * This also adds the temporary file to the "To be deleted on Exit" list, if 1.376 + * the corresponding user preference is set (except on OS X). 1.377 + * 1.378 + * This function was adopted from nsExternalAppHandler::OpenWithApplication 1.379 + * (uriloader/exthandler/nsExternalHelperAppService.cpp). 1.380 + */ 1.381 + nsresult OpenWithApplication(); 1.382 + 1.383 + nsDownloadManager *mDownloadManager; 1.384 + nsCOMPtr<nsIURI> mTarget; 1.385 + 1.386 +private: 1.387 + nsString mDisplayName; 1.388 + nsCString mEntityID; 1.389 + nsCString mGUID; 1.390 + 1.391 + nsCOMPtr<nsIURI> mSource; 1.392 + nsCOMPtr<nsIURI> mReferrer; 1.393 + nsCOMPtr<nsICancelable> mCancelable; 1.394 + nsCOMPtr<nsIRequest> mRequest; 1.395 + nsCOMPtr<nsIFile> mTempFile; 1.396 + nsCOMPtr<nsIMIMEInfo> mMIMEInfo; 1.397 + 1.398 + DownloadState mDownloadState; 1.399 + 1.400 + uint32_t mID; 1.401 + int32_t mPercentComplete; 1.402 + 1.403 + /** 1.404 + * These bytes are based on the position of where the request started, so 0 1.405 + * doesn't necessarily mean we have nothing. Use GetAmountTransferred and 1.406 + * GetSize for the real transferred amount and size. 1.407 + */ 1.408 + int64_t mCurrBytes; 1.409 + int64_t mMaxBytes; 1.410 + 1.411 + PRTime mStartTime; 1.412 + PRTime mLastUpdate; 1.413 + int64_t mResumedAt; 1.414 + double mSpeed; 1.415 + 1.416 + bool mHasMultipleFiles; 1.417 + bool mPrivate; 1.418 + 1.419 + /** 1.420 + * Track various states of the download trying to auto-resume when starting 1.421 + * the download manager or restoring from a crash. 1.422 + * 1.423 + * DONT_RESUME: Don't automatically resume the download 1.424 + * AUTO_RESUME: Automaically resume the download 1.425 + */ 1.426 + enum AutoResume { DONT_RESUME, AUTO_RESUME }; 1.427 + AutoResume mAutoResume; 1.428 + 1.429 + /** 1.430 + * Stores the SHA-256 hash associated with the downloaded file. 1.431 + */ 1.432 + nsAutoCString mHash; 1.433 + 1.434 + /** 1.435 + * Stores the certificate chains in an nsIArray of nsIX509CertList of 1.436 + * nsIX509Cert, if this binary is signed. 1.437 + */ 1.438 + nsCOMPtr<nsIArray> mSignatureInfo; 1.439 + 1.440 + friend class nsDownloadManager; 1.441 +}; 1.442 + 1.443 +#endif