@Override public void onConfirmInfoBarButtonClicked(ConfirmInfoBar infoBar, boolean confirm) { if (mPendingRequest.hasDownloadId()) { nativeDangerousDownloadValidated(mTab, mPendingRequest.getDownloadId(), confirm); if (confirm) { showDownloadStartNotification(); } closeBlankTab(); } else if (confirm) { // User confirmed the download. if (mPendingRequest.isGETRequest()) { enqueueDownloadManagerRequest(mPendingRequest); } else { DownloadInfo newDownloadInfo = DownloadInfo.Builder.fromDownloadInfo(mPendingRequest).setIsSuccessful(true).build(); DownloadManagerService.getDownloadManagerService(mContext) .onDownloadCompleted(newDownloadInfo); } } else { // User did not accept the download, discard the file if it is a POST download. if (!mPendingRequest.isGETRequest()) { discardFile(mPendingRequest.getFilePath()); } } mPendingRequest = null; infoBar.dismissJavaOnlyInfoBar(); }
private void deleteFileForOverwrite(DownloadInfo info) { File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (!dir.isDirectory()) return; final File file = new File(dir, info.getFileName()); if (!file.delete()) { Log.e(LOGTAG, "Failed to delete a file." + info.getFileName()); } }
private static void deleteFileForOverwrite(DownloadInfo info) { assert !ThreadUtils.runningOnUiThread(); File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (!dir.isDirectory()) return; final File file = new File(dir, info.getFileName()); if (!file.delete()) { Log.e(TAG, "Failed to delete a file: " + info.getFileName()); } }
@Override public void onInfoBarDismissed(InfoBar infoBar) { if (mPendingRequest != null) { if (mPendingRequest.hasDownloadId()) { nativeDangerousDownloadValidated(mTab, mPendingRequest.getDownloadId(), false); } else if (!mPendingRequest.isGETRequest()) { // Infobar was dismissed, discard the file if a POST download is pending. discardFile(mPendingRequest.getFilePath()); } } // Forget the pending request. mPendingRequest = null; }
@Override public void onConfirmInfoBarButtonClicked(ConfirmInfoBar infoBar, boolean confirm) { assert mTab != null; if (mPendingRequest.hasDownloadId()) { nativeDangerousDownloadValidated(mTab, mPendingRequest.getDownloadId(), confirm); if (confirm) { showDownloadStartNotification(); } closeBlankTab(); } else if (confirm) { // User confirmed the download. if (mPendingRequest.isGETRequest()) { final DownloadInfo info = mPendingRequest; new AsyncTask<Void, Void, Pair<String, String>>() { @Override protected Pair<String, String> doInBackground(Void... params) { Pair<String, String> result = getDownloadDirectoryNameAndFullPath(); String fullDirPath = result.second; return doesFileAlreadyExists(fullDirPath, info.getFileName()) ? result : null; } @Override protected void onPostExecute(Pair<String, String> result) { if (result != null) { // File already exists. String dirName = result.first; String fullDirPath = result.second; launchDownloadInfoBar(info, dirName, fullDirPath); } else { enqueueDownloadManagerRequest(info); } } }.execute(); } else { DownloadInfo newDownloadInfo = DownloadInfo.Builder.fromDownloadInfo(mPendingRequest).setIsSuccessful(true).build(); DownloadManagerService.getDownloadManagerService(mContext) .onDownloadCompleted(newDownloadInfo); } } else { // User did not accept the download, discard the file if it is a POST download. if (!mPendingRequest.isGETRequest()) { discardFile(mPendingRequest.getFilePath()); } } mPendingRequest = null; infoBar.dismissJavaOnlyInfoBar(); }
/** * Request a download from the given url, or if a streaming viewer is available stream the content * into the viewer. * * @param downloadInfo Information about the download. */ @Override public void requestHttpGetDownload(DownloadInfo downloadInfo) { // If we're dealing with A/V content that's not explicitly marked for download, check if it // is streamable. if (!DownloadManagerService.isAttachment(downloadInfo.getContentDisposition())) { // Query the package manager to see if there's a registered handler that matches. Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse(downloadInfo.getUrl()), downloadInfo.getMimeType()); // If the intent is resolved to ourselves, we don't want to attempt to load the url // only to try and download it again. if (DownloadManagerService.openIntent(mContext, intent, false)) { return; } } onDownloadStartNoStream(downloadInfo); }
/** * Notify the host application a download should be done, even if there is a streaming viewer * available for this type. * * @param downloadInfo Information about the download. */ protected void onDownloadStartNoStream(final DownloadInfo downloadInfo) { final String newMimeType = remapGenericMimeType( downloadInfo.getMimeType(), downloadInfo.getUrl(), downloadInfo.getFileName()); final String fileName = TextUtils.isEmpty(downloadInfo.getFileName()) ? fileName(downloadInfo.getUrl(), newMimeType, downloadInfo.getContentDisposition()) : downloadInfo.getFileName(); new AsyncTask<Void, Void, Object[]>() { @Override protected Object[] doInBackground(Void... params) { // Check to see if we have an SDCard. String status = Environment.getExternalStorageState(); Pair<String, String> result = getDownloadDirectoryNameAndFullPath(); String dirName = result.first; String fullDirPath = result.second; boolean fileExists = doesFileAlreadyExists(fullDirPath, fileName); return new Object[] {status, dirName, fullDirPath, fileExists}; } @Override protected void onPostExecute(Object[] result) { String externalStorageState = (String) result[0]; String dirName = (String) result[1]; String fullDirPath = (String) result[2]; Boolean fileExists = (Boolean) result[3]; if (!checkExternalStorageAndNotify(fileName, fullDirPath, externalStorageState)) { return; } String url = sanitizeDownloadUrl(downloadInfo); if (url == null) return; DownloadInfo newInfo = DownloadInfo.Builder.fromDownloadInfo(downloadInfo) .setUrl(url) .setMimeType(newMimeType) .setDescription(url) .setFileName(fileName) .setIsGETRequest(true) .build(); // TODO(acleung): This is a temp fix to disable auto downloading if flash files. // We want to avoid downloading flash files when it is linked as an iframe. // The proper fix would be to let chrome knows which frame originated the request. if ("application/x-shockwave-flash".equals(newInfo.getMimeType())) return; if (isDangerousFile(fileName, newMimeType)) { confirmDangerousDownload(newInfo); } else { // Not a dangerous file, proceed. if (fileExists) { launchDownloadInfoBar(newInfo, dirName, fullDirPath); } else { enqueueDownloadManagerRequest(newInfo); } } } }.execute(); }
/** * Launch an info bar if the file name already exists for the download. * * @param info The information of the file we are about to download. * @return Whether an info bar has been launched or not. */ private boolean launchInfoBarIfFileExists(final DownloadInfo info) { // Checks if file exists. final String fileName = info.getFileName(); File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (!dir.mkdir() && !dir.isDirectory()) return false; String dirName = dir.getName(); final File file = new File(dir, info.getFileName()); String fullDirPath = file.getParent(); if (!file.exists()) return false; if (TextUtils.isEmpty(fileName) || TextUtils.isEmpty(dirName) || TextUtils.isEmpty(fullDirPath)) { return false; } nativeLaunchDownloadOverwriteInfoBar( this, mTab, info, info.getFileName(), dirName, fullDirPath); return true; }
/** * Request user confirmation on a dangerous download. * * @param downloadInfo Information about the download. */ private void confirmDangerousDownload(DownloadInfo downloadInfo) { // A Dangerous file is already pending user confirmation, ignore the new download. if (mPendingRequest != null) return; mPendingRequest = downloadInfo; // TODO(dfalcantara): Ask ainslie@ for an icon to use for this InfoBar. int drawableId = 0; final String titleText = nativeGetDownloadWarningText(mPendingRequest.getFileName()); final String okButtonText = mContext.getResources().getString(R.string.ok); final String cancelButtonText = mContext.getResources().getString(R.string.cancel); mTab.getInfoBarContainer() .addInfoBar( new ConfirmInfoBar( this, drawableId, null, titleText, null, okButtonText, cancelButtonText)); }
/** * Notify the host application a download should be done, even if there is a streaming viewer * available for this type. * * @param downloadInfo Information about the download. */ protected void onDownloadStartNoStream(DownloadInfo downloadInfo) { final String newMimeType = remapGenericMimeType( downloadInfo.getMimeType(), downloadInfo.getUrl(), downloadInfo.getFileName()); final String path = TextUtils.isEmpty(downloadInfo.getFileName()) ? fileName(downloadInfo.getUrl(), newMimeType, downloadInfo.getContentDisposition()) : downloadInfo.getFileName(); final File file = new File(path); final String fileName = file.getName(); if (!checkExternalStorageAndNotify(downloadPath(fileName))) { return; } String url = sanitizeDownloadUrl(downloadInfo); if (url == null) return; DownloadInfo newInfo = DownloadInfo.Builder.fromDownloadInfo(downloadInfo) .setUrl(url) .setMimeType(newMimeType) .setDescription(url) .setFileName(fileName) .setIsGETRequest(true) .build(); // TODO(acleung): This is a temp fix to disable auto downloading if flash files. // We want to avoid downloading flash files when it is linked as an iframe. // The proper fix would be to let chrome knows which frame originated the request. if ("application/x-shockwave-flash".equals(newInfo.getMimeType())) return; if (isDangerousFile(fileName, newMimeType)) { confirmDangerousDownload(newInfo); } else { // Not a dangerous file, proceed. enqueueDownloadManagerRequest(newInfo); } }
private void launchDownloadInfoBar(DownloadInfo info, String dirName, String fullDirPath) { if (mTab == null) return; nativeLaunchDownloadOverwriteInfoBar( ChromeDownloadDelegate.this, mTab, info, info.getFileName(), dirName, fullDirPath); }
/** * Sanitize the URL for the download item. * * @param downloadInfo Information about the download. */ protected String sanitizeDownloadUrl(DownloadInfo downloadInfo) { return downloadInfo.getUrl(); }