mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 982006 - Make GetDownloadDirectory return error for both SD card missing and SD card busy. r=bz
This commit is contained in:
parent
eb43826f40
commit
4574a13528
@ -319,7 +319,8 @@ DOMDownloadImpl.prototype = {
|
||||
});
|
||||
|
||||
if (aDownload.error) {
|
||||
this.error = new this._window.DOMError("DownloadError", aDownload.error);
|
||||
this.error =
|
||||
new this._window.DOMError("DownloadError", aDownload.error.result);
|
||||
} else {
|
||||
this.error = null;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ let DownloadsAPI = {
|
||||
};
|
||||
|
||||
if (aDownload.error) {
|
||||
res.error = aDownload.error.name;
|
||||
res.error = aDownload.error;
|
||||
}
|
||||
|
||||
res.id = this.downloadId(aDownload);
|
||||
|
@ -8,7 +8,8 @@ launchError=%S could not be opened, because an unknown error occurred.\n\nTry sa
|
||||
diskFull=There is not enough room on the disk to save %S.\n\nRemove unnecessary files from the disk and try again, or try saving in a different location.
|
||||
readOnly=%S could not be saved, because the disk, folder, or file is write-protected.\n\nWrite-enable the disk and try again, or try saving in a different location.
|
||||
accessError=%S could not be saved, because you cannot change the contents of that folder.\n\nChange the folder properties and try again, or try saving in a different location.
|
||||
accessErrorSD=No SD card.\n\nAn SD card is required to download %S.
|
||||
SDAccessErrorCardReadOnly=Cannot download file because the SD card is in use.
|
||||
SDAccessErrorCardMissing=Cannot download file because the SD card is missing.
|
||||
helperAppNotFound=%S could not be opened, because the associated helper application does not exist. Change the association in your preferences.
|
||||
noMemory=There is not sufficient memory to complete the action you requested.\n\nQuit some applications and try again.
|
||||
title=Downloading %S
|
||||
|
@ -87,11 +87,7 @@
|
||||
#include "nsIDownloadHistory.h" // to mark downloads as visited
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "nsLocalHandlerApp.h"
|
||||
|
||||
#include "nsIRandomGenerator.h"
|
||||
@ -292,8 +288,11 @@ static bool GetFilenameAndExtensionFromChannel(nsIChannel* aChannel,
|
||||
* needs to be consistent throughout our codepaths. For platforms where
|
||||
* helper apps use the downloads directory, this should be kept in
|
||||
* sync with nsDownloadManager.cpp
|
||||
*
|
||||
* Optionally skip availability of the directory and storage.
|
||||
*/
|
||||
static nsresult GetDownloadDirectory(nsIFile **_directory)
|
||||
static nsresult GetDownloadDirectory(nsIFile **_directory,
|
||||
bool aSkipChecks = false)
|
||||
{
|
||||
nsCOMPtr<nsIFile> dir;
|
||||
#ifdef XP_MACOSX
|
||||
@ -309,6 +308,12 @@ static nsresult GetDownloadDirectory(nsIFile **_directory)
|
||||
getter_AddRefs(dir));
|
||||
if (!dir) break;
|
||||
|
||||
// If we're not checking for availability we're done.
|
||||
if (aSkipChecks) {
|
||||
dir.forget(_directory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We have the directory, and now we need to make sure it exists
|
||||
bool dirExists = false;
|
||||
(void) dir->Exists(&dirExists);
|
||||
@ -342,13 +347,35 @@ static nsresult GetDownloadDirectory(nsIFile **_directory)
|
||||
nsString storageName;
|
||||
nsDOMDeviceStorage::GetDefaultStorageName(NS_LITERAL_STRING("sdcard"),
|
||||
storageName);
|
||||
NS_ENSURE_TRUE(!storageName.IsEmpty(), NS_ERROR_FAILURE);
|
||||
|
||||
DeviceStorageFile dsf(NS_LITERAL_STRING("sdcard"),
|
||||
storageName,
|
||||
NS_LITERAL_STRING("downloads"));
|
||||
NS_ENSURE_TRUE(dsf.mFile, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
NS_ENSURE_TRUE(dsf.IsAvailable(), NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
// If we're not checking for availability we're done.
|
||||
if (aSkipChecks) {
|
||||
dsf.mFile.forget(_directory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check device storage status before continuing.
|
||||
nsString storageStatus;
|
||||
dsf.GetStatus(storageStatus);
|
||||
|
||||
// If we get an "unavailable" status, it means the sd card is not present.
|
||||
// We'll also catch internal errors by looking for an empty string and assume
|
||||
// the SD card isn't present when this occurs.
|
||||
if (storageStatus.EqualsLiteral("unavailable") ||
|
||||
storageStatus.IsEmpty()) {
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
// If we get a status other than 'available' here it means the card is busy
|
||||
// because it's mounted via USB or it is being formatted.
|
||||
if (!storageStatus.EqualsLiteral("available")) {
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
bool alreadyThere;
|
||||
nsresult rv = dsf.mFile->Exists(&alreadyThere);
|
||||
@ -366,11 +393,17 @@ static nsresult GetDownloadDirectory(nsIFile **_directory)
|
||||
char* downloadDir = getenv("DOWNLOADS_DIRECTORY");
|
||||
nsresult rv;
|
||||
if (downloadDir) {
|
||||
nsCOMPtr<nsIFile> ldir;
|
||||
nsCOMPtr<nsIFile> ldir;
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(downloadDir),
|
||||
true, getter_AddRefs(ldir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
dir = do_QueryInterface(ldir);
|
||||
|
||||
// If we're not checking for availability we're done.
|
||||
if (aSkipChecks) {
|
||||
dir.forget(_directory);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -1621,12 +1654,25 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest *request, nsISuppo
|
||||
|
||||
rv = SetUpTempFile(aChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsresult transferError = rv;
|
||||
|
||||
rv = CreateFailedTransfer(aChannel && NS_UsePrivateBrowsing(aChannel));
|
||||
#ifdef PR_LOGGING
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Failed to create transfer to report failure."
|
||||
"Will fallback to prompter!"));
|
||||
}
|
||||
#endif
|
||||
|
||||
mCanceled = true;
|
||||
request->Cancel(rv);
|
||||
request->Cancel(transferError);
|
||||
|
||||
nsAutoString path;
|
||||
if (mTempFile)
|
||||
mTempFile->GetPath(path);
|
||||
SendStatusChange(kWriteError, rv, request, path);
|
||||
|
||||
SendStatusChange(kWriteError, transferError, request, path);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1786,8 +1832,9 @@ void nsExternalAppHandler::SendStatusChange(ErrorType type, nsresult rv, nsIRequ
|
||||
if (type == kWriteError) {
|
||||
// Attempt to write without sufficient permissions.
|
||||
#if defined(ANDROID)
|
||||
// On Android, assume the SD card is missing or read-only
|
||||
msgId.AssignLiteral("accessErrorSD");
|
||||
// On Android (and Gonk), this means the SD card is present but
|
||||
// unavailable (read-only).
|
||||
msgId.AssignLiteral("SDAccessErrorCardReadOnly");
|
||||
#else
|
||||
msgId.AssignLiteral("accessError");
|
||||
#endif
|
||||
@ -1806,6 +1853,14 @@ void nsExternalAppHandler::SendStatusChange(ErrorType type, nsresult rv, nsIRequ
|
||||
msgId.AssignLiteral("helperAppNotFound");
|
||||
break;
|
||||
}
|
||||
#if defined(ANDROID)
|
||||
else if (type == kWriteError) {
|
||||
// On Android (and Gonk), this means the SD card is missing (not in
|
||||
// SD slot).
|
||||
msgId.AssignLiteral("SDAccessErrorCardMissing");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through
|
||||
|
||||
default:
|
||||
@ -2137,6 +2192,39 @@ nsresult nsExternalAppHandler::CreateTransfer()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsExternalAppHandler::CreateFailedTransfer(bool aIsPrivateBrowsing)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsITransfer> transfer =
|
||||
do_CreateInstance(NS_TRANSFER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we don't have a download directory we're kinda screwed but it's OK
|
||||
// we'll still report the error via the prompter.
|
||||
nsCOMPtr<nsIFile> pseudoFile;
|
||||
rv = GetDownloadDirectory(getter_AddRefs(pseudoFile), true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Append the default suggested filename. If the user restarts the transfer
|
||||
// we will re-trigger a filename check anyway to ensure that it is unique.
|
||||
rv = pseudoFile->Append(mSuggestedFileName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> pseudoTarget;
|
||||
rv = NS_NewFileURI(getter_AddRefs(pseudoTarget), pseudoFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transfer->Init(mSourceUrl, pseudoTarget, EmptyString(),
|
||||
mMimeInfo, mTimeDownloadStarted, nullptr, this,
|
||||
aIsPrivateBrowsing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Our failed transfer is ready.
|
||||
mTransfer = transfer.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsExternalAppHandler::SaveDestinationAvailable(nsIFile * aFile)
|
||||
{
|
||||
if (aFile)
|
||||
|
@ -356,6 +356,12 @@ protected:
|
||||
*/
|
||||
nsresult CreateTransfer();
|
||||
|
||||
/**
|
||||
* If we fail to create the necessary temporary file to initiate a transfer
|
||||
* we will report the failure by creating a failed nsITransfer.
|
||||
*/
|
||||
nsresult CreateFailedTransfer(bool aIsPrivateBrowsing);
|
||||
|
||||
/*
|
||||
* The following two functions are part of the split of SaveToDisk
|
||||
* to make it async, and works as following:
|
||||
|
Loading…
Reference in New Issue
Block a user