blob: 175f5f980c9aeeec1d07ff51d5f649d4fe96b064 [file] [log] [blame]
luxiaol62677b02013-07-22 07:54:49 +08001/*
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -07002 * Copyright (c) 2013,2014, The Linux Foundation. All rights reserved.
luxiaol62677b02013-07-22 07:54:49 +08003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
Bijan Amirzada41242f22014-03-21 12:12:18 -070030package com.android.browser;
luxiaol62677b02013-07-22 07:54:49 +080031
32import java.io.File;
33
34import android.app.Activity;
35import android.content.Intent;
36import java.lang.Thread;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080037
Bijan Amirzada41242f22014-03-21 12:12:18 -070038import com.android.browser.R;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080039
luxiaol62677b02013-07-22 07:54:49 +080040import android.net.Uri;
41import android.os.Bundle;
kaiyizf1a66762013-09-16 16:59:43 +080042import android.os.Environment;
luxiaol62677b02013-07-22 07:54:49 +080043import android.text.format.*;
44import android.util.Log;
45import android.view.View;
46import android.view.View.OnClickListener;
47import android.widget.Button;
48import android.widget.EditText;
49import android.widget.TextView;
50import android.view.Window;
51import android.widget.Toast;
52import android.text.TextUtils;
53
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -070054import com.android.browser.reflect.ReflectHelper;
55
luxiaol62677b02013-07-22 07:54:49 +080056public class DownloadSettings extends Activity {
57
58 private EditText downloadFilenameET;
59 private EditText downloadPathET;
60 private TextView downloadEstimateSize;
61 private TextView downloadEstimateTime;
62 private Button downloadStart;
63 private Button downloadCancel;
64 private String url;
65 private String userAgent;
66 private String contentDisposition;
67 private String mimetype;
68 private String referer;
69 private String filenameBase;
70 private String filename;
71 private String filenameExtension;
72 private boolean privateBrowsing;
73 private long contentLength;
74 private String downloadPath;
75 private String downloadPathForUser;
76 private static final int downloadRate = (1024 * 100 * 60);// Download Rate
77 // 100KB/s
78 private final static String LOGTAG = "DownloadSettings";
79 private final static int DOWNLOAD_PATH = 0;
80 private boolean isDownloadStarted = false;
81
82 private static final String ENV_EMULATED_STORAGE_TARGET = "EMULATED_STORAGE_TARGET";
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -070083 private static final String APK_TYPE="apk";
84 private static final String OCTET_STREAM = "application/octet-stream";
luxiaol62677b02013-07-22 07:54:49 +080085
86 protected void onCreate(Bundle savedInstanceState) {
87 super.onCreate(savedInstanceState);
88 // initial the DownloadSettings view
89 requestWindowFeature(Window.FEATURE_NO_TITLE);
90 setContentView(R.layout.download_settings);
91 downloadFilenameET = (EditText) findViewById(R.id.download_filename_edit);
92 downloadPathET = (EditText) findViewById(R.id.download_filepath_selected);
93 downloadEstimateSize = (TextView) findViewById(R.id.download_estimate_size_content);
94 downloadEstimateTime = (TextView) findViewById(R.id.download_estimate_time_content);
95 downloadStart = (Button) findViewById(R.id.download_start);
96 downloadCancel = (Button) findViewById(R.id.download_cancle);
97 downloadPathET.setOnClickListener(downloadPathListener);
98 downloadStart.setOnClickListener(downloadStartListener);
99 downloadCancel.setOnClickListener(downloadCancelListener);
100
101 // get the bundle from Intent
102 Intent intent = getIntent();
103 Bundle fileInfo = intent.getExtras();
104 url = fileInfo.getString("url");
105 userAgent = fileInfo.getString("userAgent");
106 contentDisposition = fileInfo.getString("contentDisposition");
107 mimetype = fileInfo.getString("mimetype");
108 referer = fileInfo.getString("referer");
109 contentLength = fileInfo.getLong("contentLength");
110 privateBrowsing = fileInfo.getBoolean("privateBrowsing");
111 filename = fileInfo.getString("filename");
112
113 // download filenamebase's length is depended on filenameLength's values
114 // if filenamebase.length >= flienameLength, destroy the last string!
115
116 filenameBase = DownloadHandler.getFilenameBase(filename);
117 if (filenameBase.length() >= (BrowserUtils.FILENAME_MAX_LENGTH)) {
118 filenameBase = filenameBase.substring(0, BrowserUtils.FILENAME_MAX_LENGTH);
119 }
120
121 // warring when user enter more over letters into the EditText
122 BrowserUtils.maxLengthFilter(DownloadSettings.this, downloadFilenameET,
123 BrowserUtils.FILENAME_MAX_LENGTH);
124
125 downloadFilenameET.setText(filenameBase);
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -0700126
127 String filenameExtension = DownloadHandler.getFilenameExtension(filename);
128
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700129 // introspect for octet stream mimetype what type of file extension it has
130 // and reassign mimetype
131 if (mimetype == null || mimetype.isEmpty() || mimetype.equals(OCTET_STREAM)) {
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -0700132
133 String updatedFileName = filenameBase + "." + filenameExtension;
134 Object[] params = {updatedFileName};
135 Class[] type = new Class[] {String.class};
Bijan Amirzada58383e72014-04-01 14:45:22 -0700136 mimetype = (String) ReflectHelper.invokeMethod("android.media.MediaFile",
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -0700137 "getMimeTypeForFile", type, params);
138 }
139
140 //Add special check for .apk files with octet-stream mimetype
Axesh R. Ajmera77258982014-04-02 14:39:09 -0700141 if (filenameExtension.equals(APK_TYPE) && mimetype != null && mimetype.equals(OCTET_STREAM)) {
Axesh R. Ajmera7cfd7a72014-04-01 16:03:42 -0700142 mimetype = "application/vnd.android.package-archive";
143 }
144
kaiyizf1a66762013-09-16 16:59:43 +0800145 downloadPath = chooseFolderFromMimeType(BrowserSettings.getInstance().getDownloadPath(),
146 mimetype);
luxiaol62677b02013-07-22 07:54:49 +0800147 downloadPathForUser = DownloadHandler.getDownloadPathForUser(DownloadSettings.this,
148 downloadPath);
149 setDownloadPathForUserText(downloadPathForUser);
150 setDownloadFileSizeText();
151 setDownloadFileTimeText();
luxiaol62677b02013-07-22 07:54:49 +0800152 }
153
154 private OnClickListener downloadPathListener = new OnClickListener() {
155
156 @Override
157 public void onClick(View v) {
158
Vivek Sekharefefe6b2015-01-05 16:01:07 -0800159 final String filemanagerIntent =
160 getResources().getString(R.string.def_intent_file_manager);
161 if (!TextUtils.isEmpty(filemanagerIntent)) {
162 // start filemanager for getting download path
163 try {
164 Intent downloadPathIntent = new Intent(filemanagerIntent);
165 DownloadSettings.this.startActivityForResult(downloadPathIntent, DOWNLOAD_PATH);
166 } catch (Exception e) {
167 String err_msg = getString(R.string.activity_not_found,
168 filemanagerIntent);
169 Toast.makeText(DownloadSettings.this, err_msg, Toast.LENGTH_LONG).show();
170 }
171 } else {
172 Log.e(LOGTAG, "File Manager intent not defined !!");
luxiaol62677b02013-07-22 07:54:49 +0800173 }
174
175 }
176 };
177
178 private OnClickListener downloadStartListener = new OnClickListener() {
179
180 @Override
181 public void onClick(View v) {
182 filenameBase = getFilenameBaseFromUserEnter();
183 // check the filename user enter is null or not
184 if (filenameBase.length() <= 0) {
185 DownloadHandler.showFilenameEmptyDialog(DownloadSettings.this);
186 return;
187 }
188
189 filenameExtension = DownloadHandler.getFilenameExtension(filename);
190 filename = filenameBase + "." + filenameExtension;
191
192 // check the storage status
193 if (!DownloadHandler.isStorageStatusOK(DownloadSettings.this, filename, downloadPath)) {
194 return;
195 }
196
197 // check the storage memory enough or not
198 try {
199 DownloadHandler.setAppointedFolder(downloadPath);
200 } catch (Exception e) {
201 DownloadHandler.showNoEnoughMemoryDialog(DownloadSettings.this);
202 return;
203 }
kaiyize6a27d02013-08-22 15:08:19 +0800204 boolean isNoEnoughMemory = DownloadHandler.manageNoEnoughMemory(contentLength,
205 downloadPath);
luxiaol62677b02013-07-22 07:54:49 +0800206 if (isNoEnoughMemory) {
kaiyize6a27d02013-08-22 15:08:19 +0800207 DownloadHandler.showNoEnoughMemoryDialog(DownloadSettings.this);
luxiaol62677b02013-07-22 07:54:49 +0800208 return;
209 }
210
211 // check the download file is exist or not
212 String fullFilename = downloadPath + "/" + filename;
213 if (mimetype != null && new File(fullFilename).exists()) {
214 DownloadHandler.fileExistQueryDialog(DownloadSettings.this);
215 return;
216 }
217
218 // staring downloading
219 DownloadHandler.startingDownload(DownloadSettings.this,
220 url, userAgent, contentDisposition,
221 mimetype, referer, privateBrowsing, contentLength,
222 Uri.encode(filename), downloadPath);
223 isDownloadStarted = true;
224 }
225 };
226
227 private OnClickListener downloadCancelListener = new OnClickListener() {
luxiaol62677b02013-07-22 07:54:49 +0800228 @Override
229 public void onClick(View v) {
230 finish();
231 }
232 };
233
234 protected void onDestroy() {
235 super.onDestroy();
236 }
237
238 protected void onPause() {
239 super.onPause();
240 if (isDownloadStarted) {
241 finish();
242 }
243 }
244
245 protected void onResume() {
246 super.onResume();
247 }
248
249 @Override
250 protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
Vivek Sekharefefe6b2015-01-05 16:01:07 -0800251
luxiaol62677b02013-07-22 07:54:49 +0800252 if (DOWNLOAD_PATH == requestCode) {
Vivek Sekharefefe6b2015-01-05 16:01:07 -0800253 if (resultCode == Activity.RESULT_OK && intent != null) {
254 final String result_dir_sel =
255 getResources().getString(R.string.def_file_manager_result_dir);
256 downloadPath = intent.getStringExtra(result_dir_sel);
Vivek Sekhar76074ac2014-06-27 16:33:13 -0700257 // Fallback logic to stock browser
258 if (downloadPath == null) {
259 Uri uri = intent.getData();
260 if(uri != null)
261 downloadPath = uri.getPath();
262 }
luxiaol62677b02013-07-22 07:54:49 +0800263 if (downloadPath != null) {
264 String rawEmulatedStorageTarget = System.getenv(ENV_EMULATED_STORAGE_TARGET);
265 if (!TextUtils.isEmpty(rawEmulatedStorageTarget)) {
266 if (downloadPath.startsWith("/storage/sdcard0"))
267 downloadPath = downloadPath.replace("/storage/sdcard0",
268 "/storage/emulated/0");
269 if (downloadPath.startsWith("/storage/emulated/legacy"))
270 downloadPath = downloadPath.replace("/storage/emulated/legacy",
271 "/storage/emulated/0");
272 }
273 downloadPathForUser = DownloadHandler.getDownloadPathForUser(
274 DownloadSettings.this, downloadPath);
275 setDownloadPathForUserText(downloadPathForUser);
276 }
277 }
278 }
279 }
280
kaiyizf1a66762013-09-16 16:59:43 +0800281 // Add for carrier feature - download to related folders by mimetype.
282 private static String chooseFolderFromMimeType(String path, String mimeType) {
283 String destinationFolder = null;
284 if (!path.contains(Environment.DIRECTORY_DOWNLOADS) || null == mimeType)
285 return path;
286 if (mimeType.startsWith("audio"))
287 destinationFolder = Environment.DIRECTORY_MUSIC;
288 else if (mimeType.startsWith("video"))
289 destinationFolder = Environment.DIRECTORY_MOVIES;
290 else if (mimeType.startsWith("image"))
291 destinationFolder = Environment.DIRECTORY_PICTURES;
292 if (null != destinationFolder)
293 path = path.replace(Environment.DIRECTORY_DOWNLOADS, destinationFolder);
294 return path;
295 }
296
luxiaol62677b02013-07-22 07:54:49 +0800297 /**
298 * show download path for user
299 *
300 * @param downloadPath the download path user can see
301 */
302 private void setDownloadPathForUserText(String downloadPathForUser) {
303 downloadPathET.setText(downloadPathForUser);
304 }
305
306 /**
307 * get the filename from user select the download path
308 *
309 * @return String the filename from user selected
310 */
311 private String getFilenameBaseFromUserEnter() {
312 return downloadFilenameET.getText().toString();
313 }
314
315 /**
316 * set the download file size for user to be known
317 */
318 private void setDownloadFileSizeText() {
319 String sizeText;
320 if (contentLength <= 0) {
321 sizeText = getString(R.string.unknow_length);
322 } else {
323 sizeText = getDownloadFileSize();
324 }
325 downloadEstimateSize.setText(sizeText);
326
327 }
328
329 /**
330 * set the time which downloaded this file will be estimately use;
331 */
332 private void setDownloadFileTimeText() {
333 String neededTimeText;
334 if (contentLength <= 0) {
335 neededTimeText = getString(R.string.unknow_length);
336 } else {
337 neededTimeText = getNeededTime() + getString(R.string.time_min);
338 }
339 downloadEstimateTime.setText(neededTimeText);
340 }
341
342 /**
343 * count the download file's size and format the values
344 *
345 * @return String the format values
346 */
347 private String getDownloadFileSize() {
348 String currentSizeText = "";
349 if (contentLength > 0) {
350 currentSizeText = Formatter.formatFileSize(DownloadSettings.this, contentLength);
351 }
352 return currentSizeText;
353 }
354
355 /**
356 * get the time download this file will be use,and format this time values
357 *
358 * @return long the valses of time which download this file will be use
359 */
360 private long getNeededTime() {
361 long timeNeeded = contentLength / downloadRate;
362 if (timeNeeded < 1) {
363 timeNeeded = 1;
364 }
365 Log.e(LOGTAG, "TimeNeeded:" + timeNeeded + "min");
366 // return the time like 5 min, not 5 s;
367 return timeNeeded;
368 }
369}