/**
   * 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();
  }
 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());
   }
 }
  /**
   * 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;
  }
  /**
   * 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);
    }
  }
  /**
   * 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));
  }
 private void launchDownloadInfoBar(DownloadInfo info, String dirName, String fullDirPath) {
   if (mTab == null) return;
   nativeLaunchDownloadOverwriteInfoBar(
       ChromeDownloadDelegate.this, mTab, info, info.getFileName(), dirName, fullDirPath);
 }