Home | History | Annotate | Download | only in android_scripting
      1 /*
      2  * Copyright (C) 2016 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.googlecode.android_scripting;
     18 
     19 import android.app.ProgressDialog;
     20 import android.content.Context;
     21 import android.content.DialogInterface;
     22 import android.os.AsyncTask;
     23 
     24 
     25 import com.googlecode.android_scripting.IoUtils;
     26 import com.googlecode.android_scripting.Log;
     27 import com.googlecode.android_scripting.exception.Sl4aException;
     28 
     29 import java.io.File;
     30 import java.io.FileNotFoundException;
     31 import java.io.FileOutputStream;
     32 import java.io.IOException;
     33 import java.io.OutputStream;
     34 import java.net.MalformedURLException;
     35 import java.net.URL;
     36 import java.net.URLConnection;
     37 
     38 /**
     39  * AsyncTask for extracting ZIP files.
     40  *
     41  */
     42 public class UrlDownloaderTask extends AsyncTask<Void, Integer, Long> {
     43 
     44   private final URL mUrl;
     45   private final File mFile;
     46   private final ProgressDialog mDialog;
     47 
     48   private Throwable mException;
     49   private OutputStream mProgressReportingOutputStream;
     50 
     51   private final class ProgressReportingOutputStream extends FileOutputStream {
     52     private int mProgress = 0;
     53 
     54     private ProgressReportingOutputStream(File f) throws FileNotFoundException {
     55       super(f);
     56     }
     57 
     58     @Override
     59     public void write(byte[] buffer, int offset, int count) throws IOException {
     60       super.write(buffer, offset, count);
     61       mProgress += count;
     62       publishProgress(mProgress);
     63     }
     64   }
     65 
     66   public UrlDownloaderTask(String url, String out, Context context) throws MalformedURLException {
     67     super();
     68     if (context != null) {
     69       mDialog = new ProgressDialog(context);
     70     } else {
     71       mDialog = null;
     72     }
     73     mUrl = new URL(url);
     74     String fileName = new File(mUrl.getFile()).getName();
     75     mFile = new File(out, fileName);
     76   }
     77 
     78   @Override
     79   protected void onPreExecute() {
     80     Log.v("Downloading " + mUrl);
     81     if (mDialog != null) {
     82       mDialog.setTitle("Downloading");
     83       mDialog.setMessage(mFile.getName());
     84       // mDialog.setIndeterminate(true);
     85       mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
     86       mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
     87         @Override
     88         public void onCancel(DialogInterface dialog) {
     89           cancel(true);
     90         }
     91       });
     92       mDialog.show();
     93     }
     94   }
     95 
     96   @Override
     97   protected Long doInBackground(Void... params) {
     98     try {
     99       return download();
    100     } catch (Exception e) {
    101       if (mFile.exists()) {
    102         // Clean up bad downloads.
    103         mFile.delete();
    104       }
    105       mException = e;
    106       return null;
    107     }
    108   }
    109 
    110   @Override
    111   protected void onProgressUpdate(Integer... progress) {
    112     if (mDialog == null) {
    113       return;
    114     }
    115     if (progress.length > 1) {
    116       int contentLength = progress[1];
    117       if (contentLength == -1) {
    118         mDialog.setIndeterminate(true);
    119       } else {
    120         mDialog.setMax(contentLength);
    121       }
    122     } else {
    123       mDialog.setProgress(progress[0].intValue());
    124     }
    125   }
    126 
    127   @Override
    128   protected void onPostExecute(Long result) {
    129     if (mDialog != null && mDialog.isShowing()) {
    130       mDialog.dismiss();
    131     }
    132     if (isCancelled()) {
    133       return;
    134     }
    135     if (mException != null) {
    136       Log.e("Download failed.", mException);
    137     }
    138   }
    139 
    140   @Override
    141   protected void onCancelled() {
    142     if (mDialog != null) {
    143       mDialog.setTitle("Download cancelled.");
    144     }
    145   }
    146 
    147   private long download() throws Exception {
    148     URLConnection connection = null;
    149     try {
    150       connection = mUrl.openConnection();
    151     } catch (IOException e) {
    152       throw new Sl4aException("Cannot open URL: " + mUrl, e);
    153     }
    154 
    155     int contentLength = connection.getContentLength();
    156 
    157     if (mFile.exists() && contentLength == mFile.length()) {
    158       Log.v("Output file already exists. Skipping download.");
    159       return 0l;
    160     }
    161 
    162     try {
    163       mProgressReportingOutputStream = new ProgressReportingOutputStream(mFile);
    164     } catch (FileNotFoundException e) {
    165       throw new Sl4aException(e);
    166     }
    167 
    168     publishProgress(0, contentLength);
    169 
    170     int bytesCopied = IoUtils.copy(connection.getInputStream(), mProgressReportingOutputStream);
    171     if (bytesCopied != contentLength && contentLength != -1) {
    172       throw new IOException("Download incomplete: " + bytesCopied + " != " + contentLength);
    173     }
    174     mProgressReportingOutputStream.close();
    175     Log.v("Download completed successfully.");
    176     return bytesCopied;
    177   }
    178 }
    179