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