Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.download; | 5 package org.chromium.chrome.browser.download; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.app.DownloadManager; | 8 import android.app.DownloadManager; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.content.DialogInterface; | 10 import android.content.DialogInterface; |
| 11 import android.content.Intent; | 11 import android.content.Intent; |
| 12 import android.content.SharedPreferences; | |
| 12 import android.content.pm.PackageManager; | 13 import android.content.pm.PackageManager; |
| 14 import android.database.Cursor; | |
| 13 import android.net.Uri; | 15 import android.net.Uri; |
| 14 import android.os.AsyncTask; | 16 import android.os.AsyncTask; |
| 15 import android.os.Environment; | 17 import android.os.Environment; |
| 16 import android.os.ParcelFileDescriptor; | 18 import android.os.ParcelFileDescriptor; |
| 17 import android.provider.Browser; | 19 import android.provider.Browser; |
| 18 import android.support.v7.app.AlertDialog; | 20 import android.support.v7.app.AlertDialog; |
| 19 import android.text.TextUtils; | 21 import android.text.TextUtils; |
| 20 import android.util.Log; | 22 import android.util.Log; |
| 21 import android.util.LongSparseArray; | 23 import android.util.LongSparseArray; |
| 24 import android.util.Pair; | |
| 22 import android.view.LayoutInflater; | 25 import android.view.LayoutInflater; |
| 23 import android.view.View; | 26 import android.view.View; |
| 24 import android.webkit.URLUtil; | 27 import android.webkit.URLUtil; |
| 25 import android.widget.TextView; | 28 import android.widget.TextView; |
| 26 | 29 |
| 27 import org.xmlpull.v1.XmlPullParser; | 30 import org.xmlpull.v1.XmlPullParser; |
| 28 import org.xmlpull.v1.XmlPullParserException; | 31 import org.xmlpull.v1.XmlPullParserException; |
| 29 import org.xmlpull.v1.XmlPullParserFactory; | 32 import org.xmlpull.v1.XmlPullParserFactory; |
| 30 | 33 |
| 31 import org.chromium.base.ApplicationStatus; | 34 import org.chromium.base.ApplicationStatus; |
| 35 import org.chromium.base.ContextUtils; | |
| 32 import org.chromium.base.VisibleForTesting; | 36 import org.chromium.base.VisibleForTesting; |
| 33 import org.chromium.chrome.R; | 37 import org.chromium.chrome.R; |
| 34 import org.chromium.chrome.browser.ChromeApplication; | 38 import org.chromium.chrome.browser.ChromeApplication; |
| 35 | 39 |
| 36 import java.io.DataOutputStream; | 40 import java.io.DataOutputStream; |
| 37 import java.io.File; | 41 import java.io.File; |
| 38 import java.io.FileInputStream; | 42 import java.io.FileInputStream; |
| 39 import java.io.FileNotFoundException; | 43 import java.io.FileNotFoundException; |
| 40 import java.io.IOException; | 44 import java.io.IOException; |
| 41 import java.io.InputStream; | 45 import java.io.InputStream; |
| 42 import java.net.HttpURLConnection; | 46 import java.net.HttpURLConnection; |
| 43 import java.net.MalformedURLException; | 47 import java.net.MalformedURLException; |
| 44 import java.net.URL; | 48 import java.net.URL; |
| 45 import java.util.ArrayList; | 49 import java.util.ArrayList; |
| 46 import java.util.Arrays; | 50 import java.util.Arrays; |
| 47 import java.util.HashMap; | 51 import java.util.HashMap; |
| 48 import java.util.List; | 52 import java.util.List; |
| 49 import java.util.Map; | 53 import java.util.Map; |
| 54 import java.util.Set; | |
| 50 | 55 |
| 51 /** | 56 /** |
| 52 * This class handles OMA downloads according to the steps described in | 57 * This class handles OMA downloads according to the steps described in |
| 53 * http://xml.coverpages.org/OMA-Download-OTA-V10-20020620.pdf: | 58 * http://xml.coverpages.org/OMA-Download-OTA-V10-20020620.pdf: |
| 54 * 1. Receives a download descriptor xml file. | 59 * 1. Receives a download descriptor xml file. |
| 55 * 2. Parses all the contents. | 60 * 2. Parses all the contents. |
| 56 * 3. Checks device capability to see if it is able to handle the content. | 61 * 3. Checks device capability to see if it is able to handle the content. |
| 57 * 4. Find the objectURI value from the download descriptor and prompt user with | 62 * 4. Find the objectURI value from the download descriptor and prompt user with |
| 58 * a dialog to proceed with the download. | 63 * a dialog to proceed with the download. |
| 59 * 5. On positive confirmation, sends a request to the download manager. | 64 * 5. On positive confirmation, sends a request to the download manager. |
| 60 * 6. Once the download is completed, sends a message to the server if installNo tifyURI | 65 * 6. Once the download is completed, sends a message to the server if installNo tifyURI |
| 61 * is present in the download descriptor. | 66 * is present in the download descriptor. |
| 62 * 7. Prompts user with a dialog to open the NextURL specified in the download d escriptor. | 67 * 7. Prompts user with a dialog to open the NextURL specified in the download d escriptor. |
| 63 * If steps 2 - 6 fails, a warning dialog will be prompted to the user to let th em | 68 * If steps 2 - 6 fails, a warning dialog will be prompted to the user to let th em |
| 64 * know the error. Steps 6-7 will be executed afterwards. | 69 * know the error. Steps 6-7 will be executed afterwards. |
| 65 * If installNotifyURI is present in the download descriptor, the downloaded con tent will | 70 * If installNotifyURI is present in the download descriptor, the downloaded con tent will |
| 66 * be saved to the app directory first. If step 6 completes successfully, the co ntent will | 71 * be saved to the app directory first. If step 6 completes successfully, the co ntent will |
| 67 * be moved to the public external storage. Otherwise, it will be removed from t he device. | 72 * be moved to the public external storage. Otherwise, it will be removed from t he device. |
| 68 */ | 73 */ |
| 69 public class OMADownloadHandler { | 74 public class OMADownloadHandler implements DownloadManagerDelegate.EnqueueDownlo adRequestCallback { |
| 70 private static final String TAG = "OMADownloadHandler"; | 75 private static final String TAG = "OMADownloadHandler"; |
| 76 private static final String PENDING_OMA_DOWNLOADS = "PendingOMADownloads"; | |
| 71 | 77 |
| 72 // MIME types for OMA downloads. | 78 // MIME types for OMA downloads. |
| 73 public static final String OMA_DOWNLOAD_DESCRIPTOR_MIME = "application/vnd.o ma.dd+xml"; | 79 public static final String OMA_DOWNLOAD_DESCRIPTOR_MIME = "application/vnd.o ma.dd+xml"; |
| 74 public static final String OMA_DRM_MESSAGE_MIME = "application/vnd.oma.drm.m essage"; | 80 public static final String OMA_DRM_MESSAGE_MIME = "application/vnd.oma.drm.m essage"; |
| 75 public static final String OMA_DRM_CONTENT_MIME = "application/vnd.oma.drm.c ontent"; | 81 public static final String OMA_DRM_CONTENT_MIME = "application/vnd.oma.drm.c ontent"; |
| 76 public static final String OMA_DRM_RIGHTS_MIME = "application/vnd.oma.drm.ri ghts+wbxml"; | 82 public static final String OMA_DRM_RIGHTS_MIME = "application/vnd.oma.drm.ri ghts+wbxml"; |
| 77 | 83 |
| 78 // Valid download descriptor attributes. | 84 // Valid download descriptor attributes. |
| 79 protected static final String OMA_TYPE = "type"; | 85 protected static final String OMA_TYPE = "type"; |
| 80 protected static final String OMA_SIZE = "size"; | 86 protected static final String OMA_SIZE = "size"; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 97 private static final String DOWNLOAD_STATUS_LOSS_OF_SERVICE = "903 Loss of S ervice \n\r"; | 103 private static final String DOWNLOAD_STATUS_LOSS_OF_SERVICE = "903 Loss of S ervice \n\r"; |
| 98 private static final String DOWNLOAD_STATUS_ATTRIBUTE_MISMATCH = "905 Attrib ute mismatch \n\r"; | 104 private static final String DOWNLOAD_STATUS_ATTRIBUTE_MISMATCH = "905 Attrib ute mismatch \n\r"; |
| 99 private static final String DOWNLOAD_STATUS_INVALID_DESCRIPTOR = "906 Invali d descriptor \n\r"; | 105 private static final String DOWNLOAD_STATUS_INVALID_DESCRIPTOR = "906 Invali d descriptor \n\r"; |
| 100 private static final String DOWNLOAD_STATUS_INVALID_DDVERSION = "951 Invalid DDVersion \n\r"; | 106 private static final String DOWNLOAD_STATUS_INVALID_DDVERSION = "951 Invalid DDVersion \n\r"; |
| 101 private static final String DOWNLOAD_STATUS_DEVICE_ABORTED = "952 Device Abo rted \n\r"; | 107 private static final String DOWNLOAD_STATUS_DEVICE_ABORTED = "952 Device Abo rted \n\r"; |
| 102 private static final String DOWNLOAD_STATUS_NON_ACCEPTABLE_CONTENT = | 108 private static final String DOWNLOAD_STATUS_NON_ACCEPTABLE_CONTENT = |
| 103 "953 Non-Acceptable Content \n\r"; | 109 "953 Non-Acceptable Content \n\r"; |
| 104 private static final String DOWNLOAD_STATUS_LOADER_ERROR = "954 Loader Error \n\r"; | 110 private static final String DOWNLOAD_STATUS_LOADER_ERROR = "954 Loader Error \n\r"; |
| 105 | 111 |
| 106 private final Context mContext; | 112 private final Context mContext; |
| 113 private final SharedPreferences mSharedPrefs; | |
| 107 private final LongSparseArray<OMAInfo> mPendingOMADownloads = | 114 private final LongSparseArray<OMAInfo> mPendingOMADownloads = |
| 108 new LongSparseArray<OMAInfo>(); | 115 new LongSparseArray<OMAInfo>(); |
| 116 private final DownloadSnackbarController mDownloadSnackbarController; | |
| 117 private final DownloadManagerDelegate mDownloadManagerDelegate; | |
| 109 | 118 |
| 110 /** | 119 /** |
| 111 * Information about the OMA content. The object is parsed from the download | 120 * Information about the OMA content. The object is parsed from the download |
| 112 * descriptor. There can be multiple MIME types for the object. | 121 * descriptor. There can be multiple MIME types for the object. |
| 113 */ | 122 */ |
| 114 @VisibleForTesting | 123 @VisibleForTesting |
| 115 protected static class OMAInfo { | 124 protected static class OMAInfo { |
| 116 private final Map<String, String> mDescription; | 125 private final Map<String, String> mDescription; |
| 117 private final List<String> mTypes; | 126 private final List<String> mTypes; |
| 118 | 127 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 for (String type : mTypes) { | 194 for (String type : mTypes) { |
| 186 if (type.equalsIgnoreCase(OMA_DRM_MESSAGE_MIME) | 195 if (type.equalsIgnoreCase(OMA_DRM_MESSAGE_MIME) |
| 187 || type.equalsIgnoreCase(OMA_DRM_CONTENT_MIME)) { | 196 || type.equalsIgnoreCase(OMA_DRM_CONTENT_MIME)) { |
| 188 return type; | 197 return type; |
| 189 } | 198 } |
| 190 } | 199 } |
| 191 return null; | 200 return null; |
| 192 } | 201 } |
| 193 } | 202 } |
| 194 | 203 |
| 195 public OMADownloadHandler(Context context) { | 204 /** |
| 205 * Class representing an OMA download entry to be stored in SharedPrefs. | |
| 206 */ | |
| 207 @VisibleForTesting | |
| 208 protected static class OMAEntry { | |
| 209 final long mDownloadId; | |
| 210 final String mInstallNotifyURI; | |
| 211 | |
| 212 OMAEntry(long downloadId, String installNotifyURI) { | |
| 213 mDownloadId = downloadId; | |
| 214 mInstallNotifyURI = installNotifyURI; | |
| 215 } | |
| 216 | |
| 217 /** | |
| 218 * Parse OMA entry from the SharedPrefs String | |
| 219 * TODO(qinmin): use a file instead of SharedPrefs to store the OMA entr y. | |
| 220 * | |
| 221 * @param entry String contains the OMA information. | |
| 222 * @return an OMAEntry object. | |
| 223 */ | |
| 224 @VisibleForTesting | |
| 225 static OMAEntry parseOMAEntry(String entry) { | |
| 226 int index = entry.indexOf(","); | |
| 227 long downloadId = Long.parseLong(entry.substring(0, index)); | |
| 228 return new OMAEntry(downloadId, entry.substring(index + 1)); | |
| 229 } | |
| 230 | |
| 231 /** | |
| 232 * Generates a string for an OMA entry to be inserted into the SharedPre fs. | |
| 233 * TODO(qinmin): use a file instead of SharedPrefs to store the OMA entr y. | |
| 234 * | |
| 235 * @return a String representing the download entry. | |
| 236 */ | |
| 237 String generateSharedPrefsString() { | |
| 238 return String.valueOf(mDownloadId) + "," + mInstallNotifyURI; | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 public OMADownloadHandler(Context context, DownloadManagerDelegate delegate, | |
| 243 DownloadSnackbarController downloadSnackbarController) { | |
| 196 mContext = context; | 244 mContext = context; |
| 245 mSharedPrefs = ContextUtils.getAppSharedPreferences(); | |
| 246 mDownloadManagerDelegate = delegate; | |
| 247 mDownloadManagerDelegate.setOMADownloadHandler(this); | |
| 248 mDownloadSnackbarController = downloadSnackbarController; | |
| 197 } | 249 } |
| 198 | 250 |
| 199 /** | 251 /** |
| 200 * Starts handling the OMA download. | 252 * Starts handling the OMA download. |
| 201 * | 253 * |
| 202 * @param downloadInfo The information about the download. | 254 * @param downloadInfo The information about the download. |
| 203 * @param downloadId The unique identifier maintained by the Android Downloa dManager. | 255 * @param downloadId The unique identifier maintained by the Android Downloa dManager. |
| 204 */ | 256 */ |
| 205 public void handleOMADownload(DownloadInfo downloadInfo, long downloadId) { | 257 public void handleOMADownload(DownloadInfo downloadInfo, long downloadId) { |
| 206 OMAParserTask task = new OMAParserTask(downloadInfo, downloadId); | 258 OMAParserTask task = new OMAParserTask(downloadInfo, downloadId); |
| 207 task.execute(); | 259 task.execute(); |
| 208 } | 260 } |
| 209 | 261 |
| 210 /** | 262 /** |
| 211 * Async task to parse an OMA download descriptor. | 263 * Async task to parse an OMA download descriptor. |
| 212 */ | 264 */ |
| 213 private class OMAParserTask extends AsyncTask<Void, Void, OMAInfo> { | 265 private class OMAParserTask extends AsyncTask<Void, Void, OMAInfo> { |
| 214 private final DownloadInfo mDownloadInfo; | 266 private final DownloadInfo mDownloadInfo; |
| 215 private final long mDownloadId; | 267 private final long mDownloadId; |
| 268 private long mFreeSpace; | |
| 216 public OMAParserTask(DownloadInfo downloadInfo, long downloadId) { | 269 public OMAParserTask(DownloadInfo downloadInfo, long downloadId) { |
| 217 mDownloadInfo = downloadInfo; | 270 mDownloadInfo = downloadInfo; |
| 218 mDownloadId = downloadId; | 271 mDownloadId = downloadId; |
| 219 } | 272 } |
| 220 | 273 |
| 221 @Override | 274 @Override |
| 222 public OMAInfo doInBackground(Void...voids) { | 275 public OMAInfo doInBackground(Void...voids) { |
| 223 OMAInfo omaInfo = null; | 276 OMAInfo omaInfo = null; |
| 224 final DownloadManager manager = | 277 final DownloadManager manager = |
| 225 (DownloadManager) mContext.getSystemService(Context.DOWNLOAD _SERVICE); | 278 (DownloadManager) mContext.getSystemService(Context.DOWNLOAD _SERVICE); |
| 226 try { | 279 try { |
| 227 ParcelFileDescriptor fd = manager.openDownloadedFile(mDownloadId ); | 280 ParcelFileDescriptor fd = manager.openDownloadedFile(mDownloadId ); |
| 228 if (fd != null) { | 281 if (fd != null) { |
| 229 omaInfo = parseDownloadDescriptor(new FileInputStream(fd.get FileDescriptor())); | 282 omaInfo = parseDownloadDescriptor(new FileInputStream(fd.get FileDescriptor())); |
| 230 fd.close(); | 283 fd.close(); |
| 231 } | 284 } |
| 232 } catch (FileNotFoundException e) { | 285 } catch (FileNotFoundException e) { |
| 233 Log.w(TAG, "File not found.", e); | 286 Log.w(TAG, "File not found.", e); |
| 234 } catch (IOException e) { | 287 } catch (IOException e) { |
| 235 Log.w(TAG, "Cannot read file.", e); | 288 Log.w(TAG, "Cannot read file.", e); |
| 236 } | 289 } |
| 237 manager.remove(mDownloadId); | 290 manager.remove(mDownloadId); |
| 291 mFreeSpace = Environment.getExternalStorageDirectory().getUsableSpac e(); | |
| 238 return omaInfo; | 292 return omaInfo; |
| 239 } | 293 } |
| 240 | 294 |
| 241 @Override | 295 @Override |
| 242 protected void onPostExecute(OMAInfo omaInfo) { | 296 protected void onPostExecute(OMAInfo omaInfo) { |
| 243 if (omaInfo == null) return; | 297 if (omaInfo == null) return; |
| 244 // Send notification if required attributes are missing. | 298 // Send notification if required attributes are missing. |
| 245 if (omaInfo.getTypes().isEmpty() || getSize(omaInfo) <= 0 | 299 if (omaInfo.getTypes().isEmpty() || getSize(omaInfo) <= 0 |
| 246 || omaInfo.isValueEmpty(OMA_OBJECT_URI)) { | 300 || omaInfo.isValueEmpty(OMA_OBJECT_URI)) { |
| 247 sendNotification(omaInfo, mDownloadInfo, DownloadItem.INVALID_DO WNLOAD_ID, | 301 sendNotification(omaInfo, mDownloadInfo, DownloadItem.INVALID_DO WNLOAD_ID, |
| 248 DOWNLOAD_STATUS_INVALID_DESCRIPTOR); | 302 DOWNLOAD_STATUS_INVALID_DESCRIPTOR); |
| 249 return; | 303 return; |
| 250 } | 304 } |
| 251 // Check version. Null version are treated as 1.0. | 305 // Check version. Null version are treated as 1.0. |
| 252 String version = omaInfo.getValue(OMA_DD_VERSION); | 306 String version = omaInfo.getValue(OMA_DD_VERSION); |
| 253 if (version != null && !version.startsWith("1.")) { | 307 if (version != null && !version.startsWith("1.")) { |
| 254 sendNotification(omaInfo, mDownloadInfo, DownloadItem.INVALID_DO WNLOAD_ID, | 308 sendNotification(omaInfo, mDownloadInfo, DownloadItem.INVALID_DO WNLOAD_ID, |
| 255 DOWNLOAD_STATUS_INVALID_DDVERSION); | 309 DOWNLOAD_STATUS_INVALID_DDVERSION); |
| 256 return; | 310 return; |
| 257 } | 311 } |
| 258 // Check device capabilities. | 312 // Check device capabilities. |
| 259 if (Environment.getExternalStorageDirectory().getUsableSpace() < get Size(omaInfo)) { | 313 if (mFreeSpace < getSize(omaInfo)) { |
| 260 showDownloadWarningDialog( | 314 showDownloadWarningDialog( |
| 261 R.string.oma_download_insufficient_memory, | 315 R.string.oma_download_insufficient_memory, |
| 262 omaInfo, mDownloadInfo, DOWNLOAD_STATUS_INSUFFICIENT_MEM ORY); | 316 omaInfo, mDownloadInfo, DOWNLOAD_STATUS_INSUFFICIENT_MEM ORY); |
| 263 return; | 317 return; |
| 264 } | 318 } |
| 265 if (getOpennableType(mContext.getPackageManager(), omaInfo) == null) { | 319 if (getOpennableType(mContext.getPackageManager(), omaInfo) == null) { |
| 266 showDownloadWarningDialog( | 320 showDownloadWarningDialog( |
| 267 R.string.oma_download_non_acceptable_content, | 321 R.string.oma_download_non_acceptable_content, |
| 268 omaInfo, mDownloadInfo, DOWNLOAD_STATUS_NON_ACCEPTABLE_C ONTENT); | 322 omaInfo, mDownloadInfo, DOWNLOAD_STATUS_NON_ACCEPTABLE_C ONTENT); |
| 269 return; | 323 return; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 .setUrl(url) | 656 .setUrl(url) |
| 603 .setMimeType(mimeType) | 657 .setMimeType(mimeType) |
| 604 .setDescription(omaInfo.getValue(OMA_DESCRIPTION)) | 658 .setDescription(omaInfo.getValue(OMA_DESCRIPTION)) |
| 605 .setBytesReceived(getSize(omaInfo)) | 659 .setBytesReceived(getSize(omaInfo)) |
| 606 .build(); | 660 .build(); |
| 607 // If installNotifyURI is not empty, the downloaded content cannot | 661 // If installNotifyURI is not empty, the downloaded content cannot |
| 608 // be used until the PostStatusTask gets a 200-series response. | 662 // be used until the PostStatusTask gets a 200-series response. |
| 609 // Don't show complete notification until that happens. | 663 // Don't show complete notification until that happens. |
| 610 DownloadItem item = new DownloadItem(true, newInfo); | 664 DownloadItem item = new DownloadItem(true, newInfo); |
| 611 item.setSystemDownloadId(downloadId); | 665 item.setSystemDownloadId(downloadId); |
| 612 DownloadManagerService.getDownloadManagerService().enqueueDownloadManage rRequest( | 666 mDownloadManagerDelegate.enqueueDownloadManagerRequest( |
| 613 item, omaInfo.isValueEmpty(OMA_INSTALL_NOTIFY_URI)); | 667 item, omaInfo.isValueEmpty(OMA_INSTALL_NOTIFY_URI), this); |
| 614 mPendingOMADownloads.put(downloadId, omaInfo); | 668 mPendingOMADownloads.put(downloadId, omaInfo); |
| 615 } | 669 } |
| 616 | 670 |
| 617 /** | 671 /** |
| 618 * Checks if an OMA download is currently pending. | 672 * Checks if an OMA download is currently pending. |
| 619 * | 673 * |
| 620 * @param downloadId Download identifier. | 674 * @param downloadId Download identifier. |
| 621 * @return true if the download is in progress, or false otherwise. | 675 * @return true if the download is in progress, or false otherwise. |
| 622 */ | 676 */ |
| 623 public boolean isPendingOMADownload(long downloadId) { | 677 public boolean isPendingOMADownload(long downloadId) { |
| 624 return mPendingOMADownloads.get(downloadId) != null; | 678 return mPendingOMADownloads.get(downloadId) != null; |
| 625 } | 679 } |
| 626 | 680 |
| 627 /** | 681 /** |
| 628 * Updates the download information with the new download Id. | 682 * Updates the download information with the new download Id. |
| 629 * | 683 * |
| 630 * @param oldDownloadId Old download Id from the DownloadManager. | 684 * @param oldDownloadId Old download Id from the DownloadManager. |
| 631 * @param newDownloadId New download Id from the DownloadManager. | 685 * @param newDownloadId New download Id from the DownloadManager. |
| 632 */ | 686 */ |
| 633 public void updateDownloadInfo(long oldDownloadId, long newDownloadId) { | 687 public void updateDownloadInfo(long oldDownloadId, long newDownloadId) { |
| 634 OMAInfo omaInfo = mPendingOMADownloads.get(oldDownloadId); | 688 OMAInfo omaInfo = mPendingOMADownloads.get(oldDownloadId); |
| 635 mPendingOMADownloads.remove(oldDownloadId); | 689 mPendingOMADownloads.remove(oldDownloadId); |
| 636 mPendingOMADownloads.put(newDownloadId, omaInfo); | 690 mPendingOMADownloads.put(newDownloadId, omaInfo); |
| 637 } | 691 } |
| 638 | 692 |
| 639 /** | 693 /** |
| 694 * Handles broadcasts from android DownloadManager. Clears the entry from Do wnloadManager, if | |
| 695 * the |downloadId| corresponds to a pending OMA download. | |
| 696 * @param downloadId The download Id in the broadcast intent. | |
| 697 * @return True if the download was handled by OMADownloadHandler, false oth erwise. | |
| 698 */ | |
| 699 public boolean handleDownloadManagerBroadcast(long downloadId) { | |
| 700 boolean isPendingOMADownload = isPendingOMADownload(downloadId); | |
| 701 boolean isInOMASharedPrefs = isDownloadIdInOMASharedPrefs(downloadId); | |
| 702 if (isPendingOMADownload || isInOMASharedPrefs) { | |
| 703 clearPendingOMADownload(downloadId, null); | |
| 704 System.out.println("shakti, clearPendingOMADownload"); | |
|
David Trainor- moved to gerrit
2017/05/09 05:49:49
Remove :)
| |
| 705 return true; | |
| 706 } | |
| 707 | |
| 708 return false; | |
| 709 } | |
| 710 | |
| 711 @Override | |
| 712 public void onDownloadEnqueued( | |
| 713 boolean result, int failureReason, DownloadItem downloadItem, long d ownloadId) { | |
| 714 boolean isPendingOMADownload = isPendingOMADownload(downloadItem.getSyst emDownloadId()); | |
| 715 if (!result) { | |
| 716 if (isPendingOMADownload) { | |
| 717 onDownloadFailed(downloadItem.getDownloadInfo(), downloadItem.ge tSystemDownloadId(), | |
| 718 DownloadManager.ERROR_UNKNOWN, null); | |
| 719 } | |
| 720 return; | |
| 721 } | |
| 722 if (isPendingOMADownload) { | |
| 723 // A new downloadId is generated, needs to update the OMADownloadHan dler | |
| 724 // about this. | |
| 725 updateDownloadInfo(downloadItem.getSystemDownloadId(), downloadId); | |
| 726 // TODO(qinmin): use a file instead of shared prefs to save the | |
| 727 // OMA information in case chrome is killed. This will allow us to | |
| 728 // save more information like cookies and user agent. | |
| 729 String notifyUri = getInstallNotifyInfo(downloadId); | |
| 730 if (!TextUtils.isEmpty(notifyUri)) { | |
| 731 OMAEntry entry = new OMAEntry(downloadId, notifyUri); | |
| 732 addOMADownloadToSharedPrefs(entry.generateSharedPrefsString()); | |
| 733 } | |
| 734 } | |
| 735 DownloadManagerService.getDownloadManagerService().onDownloadEnqueued( | |
| 736 result, failureReason, downloadItem, downloadId); | |
| 737 } | |
| 738 | |
| 739 /** | |
| 740 * Async task to clear the pending OMA download from SharedPrefs and inform | |
| 741 * the OMADownloadHandler about download status. | |
| 742 */ | |
| 743 protected class ClearPendingOMADownloadTask | |
| 744 extends AsyncTask<Void, Void, Pair<Integer, Boolean>> { | |
| 745 private final DownloadItem mDownloadItem; | |
| 746 private final String mInstallNotifyURI; | |
| 747 private DownloadInfo mDownloadInfo; | |
| 748 private int mFailureReason; | |
| 749 | |
| 750 public ClearPendingOMADownloadTask(DownloadItem downloadItem, String ins tallNotifyURI) { | |
| 751 mDownloadItem = downloadItem; | |
| 752 mInstallNotifyURI = installNotifyURI; | |
| 753 mDownloadInfo = downloadItem.getDownloadInfo(); | |
| 754 } | |
| 755 | |
| 756 @Override | |
| 757 public Pair<Integer, Boolean> doInBackground(Void... voids) { | |
| 758 DownloadManager manager = | |
| 759 (DownloadManager) mContext.getSystemService(Context.DOWNLOAD _SERVICE); | |
| 760 Cursor c = manager.query( | |
| 761 new DownloadManager.Query().setFilterById(mDownloadItem.getS ystemDownloadId())); | |
| 762 int statusIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); | |
| 763 int reasonIndex = c.getColumnIndex(DownloadManager.COLUMN_REASON); | |
| 764 int titleIndex = c.getColumnIndex(DownloadManager.COLUMN_TITLE); | |
| 765 int status = DownloadManager.STATUS_FAILED; | |
| 766 Boolean canResolve = false; | |
| 767 if (c.moveToNext()) { | |
| 768 status = c.getInt(statusIndex); | |
| 769 String title = c.getString(titleIndex); | |
| 770 if (mDownloadInfo == null) { | |
| 771 // Chrome has been killed, reconstruct a DownloadInfo. | |
| 772 mDownloadInfo = | |
| 773 new DownloadInfo.Builder() | |
| 774 .setFileName(title) | |
| 775 .setDescription(c.getString( | |
| 776 c.getColumnIndex(DownloadManager.COL UMN_DESCRIPTION))) | |
| 777 .setMimeType(c.getString( | |
| 778 c.getColumnIndex(DownloadManager.COL UMN_MEDIA_TYPE))) | |
| 779 .setBytesReceived(Long.parseLong(c.getString (c.getColumnIndex( | |
| 780 DownloadManager.COLUMN_TOTAL_SIZE_BY TES)))) | |
| 781 .build(); | |
| 782 } | |
| 783 if (status == DownloadManager.STATUS_SUCCESSFUL) { | |
| 784 mDownloadInfo = DownloadInfo.Builder.fromDownloadInfo(mDownl oadInfo) | |
| 785 .setFileName(title) | |
| 786 .build(); | |
| 787 mDownloadItem.setDownloadInfo(mDownloadInfo); | |
| 788 canResolve = DownloadManagerService.canResolveDownloadItem( | |
| 789 mContext, mDownloadItem, false); | |
| 790 } else if (status == DownloadManager.STATUS_FAILED) { | |
| 791 mFailureReason = c.getInt(reasonIndex); | |
| 792 manager.remove(mDownloadItem.getSystemDownloadId()); | |
| 793 } | |
| 794 } | |
| 795 c.close(); | |
| 796 return Pair.create(status, canResolve); | |
| 797 } | |
| 798 | |
| 799 @Override | |
| 800 protected void onPostExecute(Pair<Integer, Boolean> result) { | |
| 801 long downloadId = mDownloadItem.getSystemDownloadId(); | |
| 802 if (result.first == DownloadManager.STATUS_SUCCESSFUL) { | |
| 803 onDownloadCompleted(mDownloadInfo, downloadId, mInstallNotifyURI ); | |
| 804 removeOMADownloadFromSharedPrefs(downloadId); | |
| 805 mDownloadSnackbarController.onDownloadSucceeded(mDownloadInfo, | |
| 806 DownloadSnackbarController.INVALID_NOTIFICATION_ID, down loadId, | |
| 807 result.second, true); | |
| 808 } else if (result.first == DownloadManager.STATUS_FAILED) { | |
| 809 onDownloadFailed(mDownloadInfo, downloadId, mFailureReason, mIns tallNotifyURI); | |
| 810 removeOMADownloadFromSharedPrefs(downloadId); | |
| 811 if (mDownloadInfo != null) { | |
| 812 String fileName = mDownloadInfo.getFileName(); | |
| 813 DownloadManagerService.getDownloadManagerService().onDownloa dFailed( | |
| 814 fileName, mFailureReason); | |
| 815 } | |
| 816 } | |
| 817 } | |
| 818 } | |
| 819 | |
| 820 /** | |
| 821 * Clear pending OMA downloads for a particular download ID. | |
| 822 * | |
| 823 * @param downloadId Download identifier from Android DownloadManager. | |
| 824 * @param installNotifyURI URI to notify after installation. | |
| 825 */ | |
| 826 protected void clearPendingOMADownload(long downloadId, String installNotify URI) { | |
| 827 DownloadItem item = mDownloadManagerDelegate.findDownloadItem(downloadId ); | |
| 828 if (item == null) { | |
| 829 item = new DownloadItem(true, null); | |
| 830 item.setSystemDownloadId(downloadId); | |
| 831 } | |
| 832 ClearPendingOMADownloadTask task = new ClearPendingOMADownloadTask(item, installNotifyURI); | |
| 833 task.execute(); | |
| 834 } | |
| 835 | |
| 836 /** | |
| 837 * Clear any pending OMA downloads by reading them from shared prefs. | |
| 838 */ | |
| 839 public void clearPendingOMADownloads() { | |
| 840 if (mSharedPrefs.contains(PENDING_OMA_DOWNLOADS)) { | |
| 841 Set<String> omaDownloads = getStoredDownloadInfo(mSharedPrefs, PENDI NG_OMA_DOWNLOADS); | |
| 842 for (String omaDownload : omaDownloads) { | |
| 843 OMAEntry entry = OMAEntry.parseOMAEntry(omaDownload); | |
| 844 clearPendingOMADownload(entry.mDownloadId, entry.mInstallNotifyU RI); | |
| 845 } | |
| 846 } | |
| 847 } | |
| 848 | |
| 849 /** | |
| 850 * Gets download information from SharedPreferences. | |
| 851 * @param sharedPrefs The SharedPreferences object to parse. | |
| 852 * @param type Type of the information to retrieve. | |
| 853 * @return download information saved to the SharedPrefs for the given type. | |
| 854 */ | |
| 855 @VisibleForTesting | |
| 856 protected static Set<String> getStoredDownloadInfo(SharedPreferences sharedP refs, String type) { | |
| 857 return DownloadManagerService.getStoredDownloadInfo(sharedPrefs, type); | |
| 858 } | |
| 859 | |
| 860 /** | |
| 861 * Stores download information to shared preferences. The information can be | |
| 862 * either pending download IDs, or pending OMA downloads. | |
| 863 * | |
| 864 * @param sharedPrefs SharedPreferences to update. | |
| 865 * @param type Type of the information. | |
| 866 * @param downloadInfo Information to be saved. | |
| 867 */ | |
| 868 static void storeDownloadInfo( | |
| 869 SharedPreferences sharedPrefs, String type, Set<String> downloadInfo ) { | |
| 870 DownloadManagerService.storeDownloadInfo(sharedPrefs, type, downloadInfo ); | |
| 871 } | |
| 872 | |
| 873 /** | |
| 640 * Returns the installation notification URI for the OMA download. | 874 * Returns the installation notification URI for the OMA download. |
| 641 * | 875 * |
| 642 * @param downloadId Download Identifier. | 876 * @param downloadId Download Identifier. |
| 643 * @return String containing the installNotifyURI. | 877 * @return String containing the installNotifyURI. |
| 644 */ | 878 */ |
| 645 public String getInstallNotifyInfo(long downloadId) { | 879 public String getInstallNotifyInfo(long downloadId) { |
| 646 OMAInfo omaInfo = mPendingOMADownloads.get(downloadId); | 880 OMAInfo omaInfo = mPendingOMADownloads.get(downloadId); |
| 647 return omaInfo.getValue(OMA_INSTALL_NOTIFY_URI); | 881 return omaInfo.getValue(OMA_INSTALL_NOTIFY_URI); |
| 648 } | 882 } |
| 649 | 883 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 731 Log.w(TAG, "Failed to rename and delete the file."); | 965 Log.w(TAG, "Failed to rename and delete the file."); |
| 732 } | 966 } |
| 733 } | 967 } |
| 734 showNextUrlDialog(mOMAInfo); | 968 showNextUrlDialog(mOMAInfo); |
| 735 } else if (mDownloadId != DownloadItem.INVALID_DOWNLOAD_ID) { | 969 } else if (mDownloadId != DownloadItem.INVALID_DOWNLOAD_ID) { |
| 736 // Remove the downloaded content. | 970 // Remove the downloaded content. |
| 737 manager.remove(mDownloadId); | 971 manager.remove(mDownloadId); |
| 738 } | 972 } |
| 739 } | 973 } |
| 740 } | 974 } |
| 975 | |
| 976 /** | |
| 977 * Add OMA download info to SharedPrefs. | |
| 978 * @param omaInfo OMA download information to save. | |
| 979 */ | |
| 980 @VisibleForTesting | |
| 981 protected void addOMADownloadToSharedPrefs(String omaInfo) { | |
| 982 Set<String> omaDownloads = getStoredDownloadInfo(mSharedPrefs, PENDING_O MA_DOWNLOADS); | |
| 983 omaDownloads.add(omaInfo); | |
| 984 storeDownloadInfo(mSharedPrefs, PENDING_OMA_DOWNLOADS, omaDownloads); | |
| 985 } | |
| 986 | |
| 987 /** | |
| 988 * Remove OMA download info from SharedPrefs. | |
| 989 * @param downloadId ID to be removed. | |
| 990 */ | |
| 991 private void removeOMADownloadFromSharedPrefs(long downloadId) { | |
| 992 Set<String> omaDownloads = getStoredDownloadInfo(mSharedPrefs, PENDING_O MA_DOWNLOADS); | |
| 993 for (String omaDownload : omaDownloads) { | |
| 994 OMAEntry entry = OMAEntry.parseOMAEntry(omaDownload); | |
| 995 if (entry.mDownloadId == downloadId) { | |
| 996 omaDownloads.remove(omaDownload); | |
| 997 storeDownloadInfo(mSharedPrefs, PENDING_OMA_DOWNLOADS, omaDownlo ads); | |
| 998 return; | |
| 999 } | |
| 1000 } | |
| 1001 } | |
| 1002 | |
| 1003 /** | |
| 1004 * Check if a download ID is in OMA SharedPrefs. | |
| 1005 * @param downloadId Download identifier to check. | |
| 1006 * @param true if it is in the SharedPrefs, or false otherwise. | |
| 1007 */ | |
| 1008 protected boolean isDownloadIdInOMASharedPrefs(long downloadId) { | |
| 1009 Set<String> omaDownloads = getStoredDownloadInfo(mSharedPrefs, PENDING_O MA_DOWNLOADS); | |
| 1010 for (String omaDownload : omaDownloads) { | |
| 1011 OMAEntry entry = OMAEntry.parseOMAEntry(omaDownload); | |
| 1012 if (entry.mDownloadId == downloadId) return true; | |
| 1013 } | |
| 1014 return false; | |
| 1015 } | |
| 741 } | 1016 } |
| OLD | NEW |