1 // Copyright 2013 The Chromium Authors. 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.chromium.chrome.browser.download; 6 7 import android.graphics.Bitmap; 8 9 import org.chromium.base.annotations.CalledByNative; 10 import org.chromium.components.download.DownloadState; 11 import org.chromium.components.offline_items_collection.ContentId; 12 import org.chromium.components.offline_items_collection.FailState; 13 import org.chromium.components.offline_items_collection.LegacyHelpers; 14 import org.chromium.components.offline_items_collection.OfflineItem; 15 import org.chromium.components.offline_items_collection.OfflineItem.Progress; 16 import org.chromium.components.offline_items_collection.OfflineItemProgressUnit; 17 import org.chromium.components.offline_items_collection.OfflineItemSchedule; 18 import org.chromium.components.offline_items_collection.OfflineItemState; 19 import org.chromium.components.offline_items_collection.OfflineItemVisuals; 20 import org.chromium.components.offline_items_collection.PendingState; 21 22 /** 23 * Class representing the state of a single download. 24 */ 25 public final class DownloadInfo { 26 private final String mUrl; 27 private final String mUserAgent; 28 private final String mMimeType; 29 private final String mCookie; 30 private final String mFileName; 31 private final String mDescription; 32 private final String mFilePath; 33 private final String mReferrer; 34 private final String mOriginalUrl; 35 private final long mBytesReceived; 36 private final long mBytesTotalSize; 37 private final String mDownloadGuid; 38 private final boolean mHasUserGesture; 39 private final String mContentDisposition; 40 private final boolean mIsGETRequest; 41 private final Progress mProgress; 42 private final long mTimeRemainingInMillis; 43 private final boolean mIsResumable; 44 private final boolean mIsPaused; 45 private final boolean mIsOffTheRecord; 46 private final boolean mIsOfflinePage; 47 private final int mState; 48 private final long mLastAccessTime; 49 private final boolean mIsDangerous; 50 51 // New variables to assist with the migration to OfflineItems. 52 private final ContentId mContentId; 53 private final boolean mIsOpenable; 54 private final boolean mIsTransient; 55 private final boolean mIsParallelDownload; 56 private final Bitmap mIcon; 57 @PendingState 58 private final int mPendingState; 59 @FailState 60 private final int mFailState; 61 private final boolean mShouldPromoteOrigin; 62 private final OfflineItemSchedule mSchedule; 63 DownloadInfo(Builder builder)64 private DownloadInfo(Builder builder) { 65 mUrl = builder.mUrl; 66 mUserAgent = builder.mUserAgent; 67 mMimeType = builder.mMimeType; 68 mCookie = builder.mCookie; 69 mFileName = builder.mFileName; 70 mDescription = builder.mDescription; 71 mFilePath = builder.mFilePath; 72 mReferrer = builder.mReferrer; 73 mOriginalUrl = builder.mOriginalUrl; 74 mBytesReceived = builder.mBytesReceived; 75 mBytesTotalSize = builder.mBytesTotalSize; 76 mDownloadGuid = builder.mDownloadGuid; 77 mHasUserGesture = builder.mHasUserGesture; 78 mIsGETRequest = builder.mIsGETRequest; 79 mContentDisposition = builder.mContentDisposition; 80 mProgress = builder.mProgress; 81 mTimeRemainingInMillis = builder.mTimeRemainingInMillis; 82 mIsResumable = builder.mIsResumable; 83 mIsPaused = builder.mIsPaused; 84 mIsOffTheRecord = builder.mIsOffTheRecord; 85 mIsOfflinePage = builder.mIsOfflinePage; 86 mState = builder.mState; 87 mLastAccessTime = builder.mLastAccessTime; 88 mIsDangerous = builder.mIsDangerous; 89 90 if (builder.mContentId != null) { 91 mContentId = builder.mContentId; 92 } else { 93 mContentId = LegacyHelpers.buildLegacyContentId(mIsOfflinePage, mDownloadGuid); 94 } 95 mIsOpenable = builder.mIsOpenable; 96 mIsTransient = builder.mIsTransient; 97 mIsParallelDownload = builder.mIsParallelDownload; 98 mIcon = builder.mIcon; 99 mPendingState = builder.mPendingState; 100 mFailState = builder.mFailState; 101 mShouldPromoteOrigin = builder.mShouldPromoteOrigin; 102 mSchedule = builder.mSchedule; 103 } 104 getUrl()105 public String getUrl() { 106 return mUrl; 107 } 108 getUserAgent()109 public String getUserAgent() { 110 return mUserAgent; 111 } 112 getMimeType()113 public String getMimeType() { 114 return mMimeType; 115 } 116 getCookie()117 public String getCookie() { 118 return mCookie; 119 } 120 getFileName()121 public String getFileName() { 122 return mFileName; 123 } 124 getDescription()125 public String getDescription() { 126 return mDescription; 127 } 128 getFilePath()129 public String getFilePath() { 130 return mFilePath; 131 } 132 getReferrer()133 public String getReferrer() { 134 return mReferrer; 135 } 136 getOriginalUrl()137 public String getOriginalUrl() { 138 return mOriginalUrl; 139 } 140 getBytesReceived()141 public long getBytesReceived() { 142 return mBytesReceived; 143 } 144 getBytesTotalSize()145 public long getBytesTotalSize() { 146 return mBytesTotalSize; 147 } 148 isGETRequest()149 public boolean isGETRequest() { 150 return mIsGETRequest; 151 } 152 getDownloadGuid()153 public String getDownloadGuid() { 154 return mDownloadGuid; 155 } 156 hasUserGesture()157 public boolean hasUserGesture() { 158 return mHasUserGesture; 159 } 160 getContentDisposition()161 public String getContentDisposition() { 162 return mContentDisposition; 163 } 164 getProgress()165 public Progress getProgress() { 166 return mProgress; 167 } 168 169 /** 170 * @return Remaining download time in milliseconds or -1 if it is unknown. 171 */ getTimeRemainingInMillis()172 public long getTimeRemainingInMillis() { 173 return mTimeRemainingInMillis; 174 } 175 isResumable()176 public boolean isResumable() { 177 return mIsResumable; 178 } 179 isPaused()180 public boolean isPaused() { 181 return mIsPaused; 182 } 183 isOffTheRecord()184 public boolean isOffTheRecord() { 185 return mIsOffTheRecord; 186 } 187 isOfflinePage()188 public boolean isOfflinePage() { 189 return mIsOfflinePage; 190 } 191 state()192 public int state() { 193 return mState; 194 } 195 getLastAccessTime()196 public long getLastAccessTime() { 197 return mLastAccessTime; 198 } 199 getIsDangerous()200 public boolean getIsDangerous() { 201 return mIsDangerous; 202 } 203 getContentId()204 public ContentId getContentId() { 205 return mContentId; 206 } 207 getIsOpenable()208 public boolean getIsOpenable() { 209 return mIsOpenable; 210 } 211 getIsTransient()212 public boolean getIsTransient() { 213 return mIsTransient; 214 } 215 getIsParallelDownload()216 public boolean getIsParallelDownload() { 217 return mIsParallelDownload; 218 } 219 getIcon()220 public Bitmap getIcon() { 221 return mIcon; 222 } 223 getPendingState()224 public @PendingState int getPendingState() { 225 return mPendingState; 226 } 227 getFailState()228 public @FailState int getFailState() { 229 return mFailState; 230 } 231 getShouldPromoteOrigin()232 public boolean getShouldPromoteOrigin() { 233 return mShouldPromoteOrigin; 234 } 235 getOfflineItemSchedule()236 public OfflineItemSchedule getOfflineItemSchedule() { 237 return mSchedule; 238 } 239 240 /** 241 * Helper method to build a {@link DownloadInfo} from an {@link OfflineItem}. 242 * @param item The {@link OfflineItem} to mimic. 243 * @param visuals The {@link OfflineItemVisuals} to mimic. 244 * @return A {@link DownloadInfo} containing the relevant fields from {@code item}. 245 */ fromOfflineItem(OfflineItem item, OfflineItemVisuals visuals)246 public static DownloadInfo fromOfflineItem(OfflineItem item, OfflineItemVisuals visuals) { 247 return builderFromOfflineItem(item, visuals).build(); 248 } 249 250 /** 251 * Helper method to build a {@link DownloadInfo.Builder} from an {@link OfflineItem}. 252 * @param item The {@link OfflineItem} to mimic. 253 * @param visuals The {@link OfflineItemVisuals} to mimic. 254 * @return A {@link DownloadInfo.Builder} containing the relevant fields from 255 * {@code item}. 256 */ builderFromOfflineItem( OfflineItem item, OfflineItemVisuals visuals)257 public static DownloadInfo.Builder builderFromOfflineItem( 258 OfflineItem item, OfflineItemVisuals visuals) { 259 int state; 260 switch (item.state) { 261 case OfflineItemState.COMPLETE: 262 state = DownloadState.COMPLETE; 263 break; 264 case OfflineItemState.CANCELLED: 265 state = DownloadState.CANCELLED; 266 break; 267 case OfflineItemState.INTERRUPTED: 268 state = DownloadState.INTERRUPTED; 269 break; 270 case OfflineItemState.FAILED: 271 state = DownloadState.INTERRUPTED; // TODO(dtrainor): Validate what this state is. 272 break; 273 case OfflineItemState.PENDING: // TODO(dtrainor): Validate what this state is. 274 case OfflineItemState.IN_PROGRESS: 275 case OfflineItemState.PAUSED: // TODO(dtrainor): Validate what this state is. 276 default: 277 state = DownloadState.IN_PROGRESS; 278 break; 279 } 280 281 return new DownloadInfo.Builder() 282 .setContentId(item.id) 283 .setDownloadGuid(item.id.id) 284 .setFileName(item.title) 285 .setFilePath(item.filePath) 286 .setDescription(item.description) 287 .setIsTransient(item.isTransient) 288 .setLastAccessTime(item.lastAccessedTimeMs) 289 .setIsOpenable(item.isOpenable) 290 .setMimeType(item.mimeType) 291 .setUrl(item.pageUrl) 292 .setOriginalUrl(item.originalUrl) 293 .setIsOffTheRecord(item.isOffTheRecord) 294 .setState(state) 295 .setIsPaused(item.state == OfflineItemState.PAUSED) 296 .setIsResumable(item.isResumable) 297 .setBytesReceived(item.receivedBytes) 298 .setBytesTotalSize(item.totalSizeBytes) 299 .setProgress(item.progress) 300 .setTimeRemainingInMillis(item.timeRemainingMs) 301 .setIsDangerous(item.isDangerous) 302 .setIsParallelDownload(item.isAccelerated) 303 .setIcon(visuals == null ? null : visuals.icon) 304 .setPendingState(item.pendingState) 305 .setFailState(item.failState) 306 .setShouldPromoteOrigin(item.promoteOrigin) 307 .setOfflineItemSchedule(item.schedule); 308 } 309 310 /** 311 * Helper class for building the DownloadInfo object. 312 */ 313 public static class Builder { 314 private String mUrl; 315 private String mUserAgent; 316 private String mMimeType; 317 private String mCookie; 318 private String mFileName; 319 private String mDescription; 320 private String mFilePath; 321 private String mReferrer; 322 private String mOriginalUrl; 323 private long mBytesReceived; 324 private long mBytesTotalSize; 325 private boolean mIsGETRequest; 326 private String mDownloadGuid; 327 private boolean mHasUserGesture; 328 private String mContentDisposition; 329 private Progress mProgress = Progress.createIndeterminateProgress(); 330 private long mTimeRemainingInMillis; 331 private boolean mIsResumable = true; 332 private boolean mIsPaused; 333 private boolean mIsOffTheRecord; 334 private boolean mIsOfflinePage; 335 private int mState = DownloadState.IN_PROGRESS; 336 private long mLastAccessTime; 337 private boolean mIsDangerous; 338 private ContentId mContentId; 339 private boolean mIsOpenable = true; 340 private boolean mIsTransient; 341 private boolean mIsParallelDownload; 342 private Bitmap mIcon; 343 @PendingState 344 private int mPendingState; 345 @FailState 346 private int mFailState; 347 private boolean mShouldPromoteOrigin; 348 private OfflineItemSchedule mSchedule; 349 setUrl(String url)350 public Builder setUrl(String url) { 351 mUrl = url; 352 return this; 353 } 354 setUserAgent(String userAgent)355 public Builder setUserAgent(String userAgent) { 356 mUserAgent = userAgent; 357 return this; 358 } 359 setMimeType(String mimeType)360 public Builder setMimeType(String mimeType) { 361 mMimeType = mimeType; 362 return this; 363 } 364 setCookie(String cookie)365 public Builder setCookie(String cookie) { 366 mCookie = cookie; 367 return this; 368 } 369 setFileName(String fileName)370 public Builder setFileName(String fileName) { 371 mFileName = fileName; 372 return this; 373 } 374 setDescription(String description)375 public Builder setDescription(String description) { 376 mDescription = description; 377 return this; 378 } 379 setFilePath(String filePath)380 public Builder setFilePath(String filePath) { 381 mFilePath = filePath; 382 return this; 383 } 384 setReferrer(String referer)385 public Builder setReferrer(String referer) { 386 mReferrer = referer; 387 return this; 388 } 389 setOriginalUrl(String originalUrl)390 public Builder setOriginalUrl(String originalUrl) { 391 mOriginalUrl = originalUrl; 392 return this; 393 } 394 setBytesReceived(long bytesReceived)395 public Builder setBytesReceived(long bytesReceived) { 396 mBytesReceived = bytesReceived; 397 return this; 398 } 399 setBytesTotalSize(long bytesTotalSize)400 public Builder setBytesTotalSize(long bytesTotalSize) { 401 mBytesTotalSize = bytesTotalSize; 402 return this; 403 } 404 setIsGETRequest(boolean isGETRequest)405 public Builder setIsGETRequest(boolean isGETRequest) { 406 mIsGETRequest = isGETRequest; 407 return this; 408 } 409 setDownloadGuid(String downloadGuid)410 public Builder setDownloadGuid(String downloadGuid) { 411 mDownloadGuid = downloadGuid; 412 return this; 413 } 414 setHasUserGesture(boolean hasUserGesture)415 public Builder setHasUserGesture(boolean hasUserGesture) { 416 mHasUserGesture = hasUserGesture; 417 return this; 418 } 419 setContentDisposition(String contentDisposition)420 public Builder setContentDisposition(String contentDisposition) { 421 mContentDisposition = contentDisposition; 422 return this; 423 } 424 setProgress(OfflineItem.Progress progress)425 public Builder setProgress(OfflineItem.Progress progress) { 426 mProgress = progress; 427 return this; 428 } 429 setTimeRemainingInMillis(long timeRemainingInMillis)430 public Builder setTimeRemainingInMillis(long timeRemainingInMillis) { 431 mTimeRemainingInMillis = timeRemainingInMillis; 432 return this; 433 } 434 setIsResumable(boolean isResumable)435 public Builder setIsResumable(boolean isResumable) { 436 mIsResumable = isResumable; 437 return this; 438 } 439 setIsPaused(boolean isPaused)440 public Builder setIsPaused(boolean isPaused) { 441 mIsPaused = isPaused; 442 return this; 443 } 444 setIsOffTheRecord(boolean isOffTheRecord)445 public Builder setIsOffTheRecord(boolean isOffTheRecord) { 446 mIsOffTheRecord = isOffTheRecord; 447 return this; 448 } 449 setIsOfflinePage(boolean isOfflinePage)450 public Builder setIsOfflinePage(boolean isOfflinePage) { 451 mIsOfflinePage = isOfflinePage; 452 return this; 453 } 454 setState(int downloadState)455 public Builder setState(int downloadState) { 456 mState = downloadState; 457 return this; 458 } 459 setLastAccessTime(long lastAccessTime)460 public Builder setLastAccessTime(long lastAccessTime) { 461 mLastAccessTime = lastAccessTime; 462 return this; 463 } 464 setIsDangerous(boolean isDangerous)465 public Builder setIsDangerous(boolean isDangerous) { 466 mIsDangerous = isDangerous; 467 return this; 468 } 469 setContentId(ContentId contentId)470 public Builder setContentId(ContentId contentId) { 471 mContentId = contentId; 472 return this; 473 } 474 setIsOpenable(boolean isOpenable)475 public Builder setIsOpenable(boolean isOpenable) { 476 mIsOpenable = isOpenable; 477 return this; 478 } 479 setIsTransient(boolean isTransient)480 public Builder setIsTransient(boolean isTransient) { 481 mIsTransient = isTransient; 482 return this; 483 } 484 setIsParallelDownload(boolean isParallelDownload)485 public Builder setIsParallelDownload(boolean isParallelDownload) { 486 mIsParallelDownload = isParallelDownload; 487 return this; 488 } 489 setIcon(Bitmap icon)490 public Builder setIcon(Bitmap icon) { 491 mIcon = icon; 492 return this; 493 } 494 setPendingState(@endingState int pendingState)495 public Builder setPendingState(@PendingState int pendingState) { 496 mPendingState = pendingState; 497 return this; 498 } 499 setFailState(@ailState int failState)500 public Builder setFailState(@FailState int failState) { 501 mFailState = failState; 502 return this; 503 } 504 setShouldPromoteOrigin(boolean shouldPromoteOrigin)505 public Builder setShouldPromoteOrigin(boolean shouldPromoteOrigin) { 506 mShouldPromoteOrigin = shouldPromoteOrigin; 507 return this; 508 } 509 setOfflineItemSchedule(OfflineItemSchedule schedule)510 public Builder setOfflineItemSchedule(OfflineItemSchedule schedule) { 511 mSchedule = schedule; 512 return this; 513 } 514 build()515 public DownloadInfo build() { 516 return new DownloadInfo(this); 517 } 518 519 /** 520 * Create a builder from the DownloadInfo object. 521 * @param downloadInfo DownloadInfo object from which builder fields are populated. 522 * @return A builder initialized with fields from downloadInfo object. 523 */ fromDownloadInfo(final DownloadInfo downloadInfo)524 public static Builder fromDownloadInfo(final DownloadInfo downloadInfo) { 525 Builder builder = new Builder(); 526 builder.setUrl(downloadInfo.getUrl()) 527 .setUserAgent(downloadInfo.getUserAgent()) 528 .setMimeType(downloadInfo.getMimeType()) 529 .setCookie(downloadInfo.getCookie()) 530 .setFileName(downloadInfo.getFileName()) 531 .setDescription(downloadInfo.getDescription()) 532 .setFilePath(downloadInfo.getFilePath()) 533 .setReferrer(downloadInfo.getReferrer()) 534 .setOriginalUrl(downloadInfo.getOriginalUrl()) 535 .setBytesReceived(downloadInfo.getBytesReceived()) 536 .setBytesTotalSize(downloadInfo.getBytesTotalSize()) 537 .setDownloadGuid(downloadInfo.getDownloadGuid()) 538 .setHasUserGesture(downloadInfo.hasUserGesture()) 539 .setContentDisposition(downloadInfo.getContentDisposition()) 540 .setIsGETRequest(downloadInfo.isGETRequest()) 541 .setProgress(downloadInfo.getProgress()) 542 .setTimeRemainingInMillis(downloadInfo.getTimeRemainingInMillis()) 543 .setIsDangerous(downloadInfo.getIsDangerous()) 544 .setIsResumable(downloadInfo.isResumable()) 545 .setIsPaused(downloadInfo.isPaused()) 546 .setIsOffTheRecord(downloadInfo.isOffTheRecord()) 547 .setIsOfflinePage(downloadInfo.isOfflinePage()) 548 .setState(downloadInfo.state()) 549 .setLastAccessTime(downloadInfo.getLastAccessTime()) 550 .setIsTransient(downloadInfo.getIsTransient()) 551 .setIsParallelDownload(downloadInfo.getIsParallelDownload()) 552 .setIcon(downloadInfo.getIcon()) 553 .setPendingState(downloadInfo.getPendingState()) 554 .setFailState(downloadInfo.getFailState()) 555 .setShouldPromoteOrigin(downloadInfo.getShouldPromoteOrigin()) 556 .setOfflineItemSchedule(downloadInfo.getOfflineItemSchedule()); 557 return builder; 558 } 559 } 560 561 @CalledByNative createDownloadInfo(String downloadGuid, String fileName, String filePath, String url, String mimeType, long bytesReceived, long bytesTotalSize, boolean isIncognito, int state, int percentCompleted, boolean isPaused, boolean hasUserGesture, boolean isResumable, boolean isParallelDownload, String originalUrl, String referrerUrl, long timeRemainingInMs, long lastAccessTime, boolean isDangerous, @FailState int failState, OfflineItemSchedule schedule)562 private static DownloadInfo createDownloadInfo(String downloadGuid, String fileName, 563 String filePath, String url, String mimeType, long bytesReceived, long bytesTotalSize, 564 boolean isIncognito, int state, int percentCompleted, boolean isPaused, 565 boolean hasUserGesture, boolean isResumable, boolean isParallelDownload, 566 String originalUrl, String referrerUrl, long timeRemainingInMs, long lastAccessTime, 567 boolean isDangerous, @FailState int failState, OfflineItemSchedule schedule) { 568 String remappedMimeType = MimeUtils.remapGenericMimeType(mimeType, url, fileName); 569 570 Progress progress = new Progress(bytesReceived, 571 percentCompleted == -1 ? null : bytesTotalSize, OfflineItemProgressUnit.BYTES); 572 573 return new DownloadInfo.Builder() 574 .setBytesReceived(bytesReceived) 575 .setBytesTotalSize(bytesTotalSize) 576 .setDescription(fileName) 577 .setDownloadGuid(downloadGuid) 578 .setFileName(fileName) 579 .setFilePath(filePath) 580 .setHasUserGesture(hasUserGesture) 581 .setIsOffTheRecord(isIncognito) 582 .setIsPaused(isPaused) 583 .setIsResumable(isResumable) 584 .setIsParallelDownload(isParallelDownload) 585 .setMimeType(remappedMimeType) 586 .setOriginalUrl(originalUrl) 587 .setProgress(progress) 588 .setReferrer(referrerUrl) 589 .setState(state) 590 .setTimeRemainingInMillis(timeRemainingInMs) 591 .setLastAccessTime(lastAccessTime) 592 .setIsDangerous(isDangerous) 593 .setUrl(url) 594 .setFailState(failState) 595 .setOfflineItemSchedule(schedule) 596 .build(); 597 } 598 } 599