Upstream version 5.34.97.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / client / XWalkDefaultDownloadListener.java
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.xwalk.core.client;
6
7 import android.app.DownloadManager;
8 import android.app.DownloadManager.Request;
9 import android.content.pm.PackageManager;
10 import android.content.Context;
11 import android.net.Uri;
12 import android.os.AsyncTask;
13 import android.os.Environment;
14 import android.webkit.MimeTypeMap;
15 import android.webkit.URLUtil;
16 import android.widget.Toast;
17 import android.Manifest;
18
19 import java.io.File;
20 import java.io.FileOutputStream;
21 import java.io.InputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24
25 import org.xwalk.core.AndroidProtocolHandler;
26 import org.xwalk.core.DownloadListener;
27 import org.xwalk.core.R;
28
29 public class XWalkDefaultDownloadListener implements DownloadListener {
30     private static String DOWNLOAD_START_TOAST;
31     private static String DOWNLOAD_NO_PERMISSION_TOAST;
32     private static String DOWNLOAD_ALREADY_EXISTS_TOAST;
33     private static String DOWNLOAD_FAILED_TOAST;
34     private static String DOWNLOAD_FINISHED_TOAST;
35
36     private Context mContext;
37
38     public XWalkDefaultDownloadListener(Context context) {
39         mContext = context;
40
41         DOWNLOAD_START_TOAST = mContext.getString(R.string.download_start_toast);
42         DOWNLOAD_NO_PERMISSION_TOAST =
43                 mContext.getString(R.string.download_no_permission_toast);
44         DOWNLOAD_ALREADY_EXISTS_TOAST =
45                 mContext.getString(R.string.download_already_exists_toast);
46         DOWNLOAD_FAILED_TOAST =
47                 mContext.getString(R.string.download_failed_toast);
48         DOWNLOAD_FINISHED_TOAST =
49                 mContext.getString(R.string.download_finished_toast);
50     }
51
52     @Override
53     public void onDownloadStart(String url, String userAgent,
54             String contentDisposition, String mimetype, long contentLength) {
55         String fileName = getFileName(url, contentDisposition, mimetype);
56
57         // Check whether we have permission to write file to external storage.
58         // We only start download request if we have permission.
59         if (!checkWriteExternalPermission()) return;
60
61         Uri src = Uri.parse(url);
62         if (src.getScheme().equals("http") || src.getScheme().equals("https")) {
63             Request request = new Request(Uri.parse(url));
64             request.setDestinationInExternalPublicDir(
65                     Environment.DIRECTORY_DOWNLOADS, fileName);
66             getDownloadManager().enqueue(request);
67             popupMessages(DOWNLOAD_START_TOAST + fileName);
68         } else {
69             new FileTransfer(url, fileName).execute();
70         }
71     }
72
73     private String getFileName(String url, String contentDisposition, String mimetype) {
74         String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
75         int extensionIndex = fileName.lastIndexOf(".");
76         String extension = null;
77         if ((extensionIndex > 1) && (extensionIndex < fileName.length())) {
78             extension = fileName.substring(extensionIndex + 1);
79         }
80
81         // If the file name does not have a file extension, append extension based on MIME type.
82         if (extension == null) {
83             extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimetype);
84             if (extension != null) fileName = fileName + "." + extension;
85         }
86         return fileName;
87     }
88
89     private DownloadManager getDownloadManager() {
90         DownloadManager downloadManager =
91                 (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
92         return downloadManager;
93     }
94
95     private boolean checkWriteExternalPermission() {
96         int result = mContext.checkCallingOrSelfPermission(
97                 Manifest.permission.WRITE_EXTERNAL_STORAGE);
98         if (result == PackageManager.PERMISSION_GRANTED) return true;
99
100         popupMessages(DOWNLOAD_NO_PERMISSION_TOAST);
101         return false;
102     }
103
104     private void popupMessages(String message) {
105         Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
106     }
107
108     private class FileTransfer extends AsyncTask<Void, Void, String> {
109         String url;
110         String fileName;
111
112         public FileTransfer(String url, String fileName) {
113             this.url = url;
114             this.fileName = fileName;
115         }
116
117         @Override
118         protected String doInBackground(Void... params) {
119             OutputStream dstStream = null;
120             InputStream srcStream = null;
121             File dir = Environment.getExternalStoragePublicDirectory(
122                     Environment.DIRECTORY_DOWNLOADS);
123             File dst = new File(dir, fileName);
124             if (dst.exists()) {
125                 return "Existed";
126             }
127             try {
128                 dstStream = new FileOutputStream(dst);
129                 srcStream = AndroidProtocolHandler.open(mContext, url);
130                 if (dstStream != null && srcStream != null) {
131                     streamTransfer(srcStream, dstStream);
132                 }
133             } catch (IOException e) {
134                 e.printStackTrace();
135             } finally {
136                 try {
137                     if (srcStream != null) srcStream.close();
138                     if (dstStream != null) dstStream.close();
139                 } catch (IOException e) {
140                     e.printStackTrace();
141                     return "Failed";
142                 }
143             }
144             return "Finished";
145         }
146
147         @Override
148         protected void onPostExecute(String result) {
149             if (result.equals("Failed")) {
150                 popupMessages(DOWNLOAD_FAILED_TOAST);
151             } else if (result.equals("Existed")) {
152                 popupMessages(DOWNLOAD_ALREADY_EXISTS_TOAST);
153             } else if (result.equals("Finished")) {
154                 popupMessages(DOWNLOAD_FINISHED_TOAST);
155             }
156         }
157
158         private void streamTransfer(InputStream src, OutputStream dst) throws IOException {
159             // Transfer bytes from src to dst.
160             byte[] buf = new byte[1024];
161             int length = 0;
162             while ((length = src.read(buf)) > 0) {
163                 dst.write(buf, 0, length);
164             }
165         }
166     }
167 }