| 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.offlinepages; | 5 package org.chromium.chrome.browser.offlinepages; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.net.Uri; | 9 import android.net.Uri; |
| 10 import android.os.AsyncTask; | 10 import android.os.AsyncTask; |
| 11 import android.os.Environment; | 11 import android.os.Environment; |
| 12 | 12 |
| 13 import org.chromium.base.ActivityState; | 13 import org.chromium.base.ActivityState; |
| 14 import org.chromium.base.ApplicationStatus; | 14 import org.chromium.base.ApplicationStatus; |
| 15 import org.chromium.base.Callback; | 15 import org.chromium.base.Callback; |
| 16 import org.chromium.base.ContextUtils; |
| 16 import org.chromium.base.FileUtils; | 17 import org.chromium.base.FileUtils; |
| 17 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
| 18 import org.chromium.base.StreamUtil; | 19 import org.chromium.base.StreamUtil; |
| 19 import org.chromium.base.VisibleForTesting; | 20 import org.chromium.base.VisibleForTesting; |
| 20 import org.chromium.base.metrics.RecordHistogram; | 21 import org.chromium.base.metrics.RecordHistogram; |
| 21 import org.chromium.chrome.R; | 22 import org.chromium.chrome.R; |
| 22 import org.chromium.chrome.browser.ChromeActivity; | 23 import org.chromium.chrome.browser.ChromeActivity; |
| 23 import org.chromium.chrome.browser.UrlConstants; | 24 import org.chromium.chrome.browser.UrlConstants; |
| 24 import org.chromium.chrome.browser.profiles.Profile; | 25 import org.chromium.chrome.browser.profiles.Profile; |
| 25 import org.chromium.chrome.browser.share.ShareHelper; | 26 import org.chromium.chrome.browser.share.ShareHelper; |
| 27 import org.chromium.chrome.browser.share.ShareParams; |
| 26 import org.chromium.chrome.browser.snackbar.Snackbar; | 28 import org.chromium.chrome.browser.snackbar.Snackbar; |
| 27 import org.chromium.chrome.browser.snackbar.SnackbarManager; | 29 import org.chromium.chrome.browser.snackbar.SnackbarManager; |
| 28 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; | 30 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; |
| 29 import org.chromium.chrome.browser.tab.EmptyTabObserver; | 31 import org.chromium.chrome.browser.tab.EmptyTabObserver; |
| 30 import org.chromium.chrome.browser.tab.Tab; | 32 import org.chromium.chrome.browser.tab.Tab; |
| 31 import org.chromium.chrome.browser.tabmodel.TabModel; | 33 import org.chromium.chrome.browser.tabmodel.TabModel; |
| 32 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 34 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
| 33 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; | 35 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; |
| 34 import org.chromium.components.bookmarks.BookmarkId; | 36 import org.chromium.components.bookmarks.BookmarkId; |
| 35 import org.chromium.components.offlinepages.SavePageResult; | 37 import org.chromium.components.offlinepages.SavePageResult; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 return; | 330 return; |
| 329 } | 331 } |
| 330 RecordHistogram.recordLongTimesHistogram( | 332 RecordHistogram.recordLongTimesHistogram( |
| 331 "OfflinePages.Wakeup.DelayTime", | 333 "OfflinePages.Wakeup.DelayTime", |
| 332 delayInMilliseconds, | 334 delayInMilliseconds, |
| 333 TimeUnit.MILLISECONDS); | 335 TimeUnit.MILLISECONDS); |
| 334 } | 336 } |
| 335 | 337 |
| 336 /** | 338 /** |
| 337 * Share an offline copy of the current page. | 339 * Share an offline copy of the current page. |
| 338 * @param shareDirectly Whether it should share directly with the activity t
hat was most | 340 * @param builder The builder to construct {@link ShareParams} for holding s
hare parameters. |
| 339 * recently used to share. | |
| 340 * @param saveLastUsed Whether to save the chosen activity for future direct
sharing. | |
| 341 * @param mainActivity Activity that is used to access package manager. | |
| 342 * @param text Text to be shared. If both |text| and |url| are supplied, the
y are concatenated | |
| 343 * with a space. | |
| 344 * @param screenshotUri Screenshot of the page to be shared. | |
| 345 * @param callback Optional callback to be called when user makes a choice.
Will not be called | |
| 346 * if receiving a response when the user makes a choice is n
ot supported (see | |
| 347 * TargetChosenReceiver#isSupported()). | |
| 348 * @param currentTab The current tab for which sharing is being done. | 341 * @param currentTab The current tab for which sharing is being done. |
| 349 */ | 342 */ |
| 350 public static void shareOfflinePage(final boolean shareDirectly, final boole
an saveLastUsed, | 343 public static void shareOfflinePage(ShareParams.Builder builder, final Tab c
urrentTab) { |
| 351 final Activity mainActivity, final String text, final Uri screenshot
Uri, | |
| 352 final ShareHelper.TargetChosenCallback callback, final Tab currentTa
b) { | |
| 353 final String url = currentTab.getUrl(); | |
| 354 final String title = currentTab.getTitle(); | |
| 355 final OfflinePageBridge offlinePageBridge = | 344 final OfflinePageBridge offlinePageBridge = |
| 356 OfflinePageBridge.getForProfile(currentTab.getProfile()); | 345 OfflinePageBridge.getForProfile(currentTab.getProfile()); |
| 357 | 346 |
| 358 if (offlinePageBridge == null) { | 347 if (offlinePageBridge == null) { |
| 359 Log.e(TAG, "Unable to perform sharing on current tab."); | 348 Log.e(TAG, "Unable to perform sharing on current tab."); |
| 360 return; | 349 return; |
| 361 } | 350 } |
| 362 | 351 |
| 363 OfflinePageItem offlinePage = offlinePageBridge.getOfflinePage(currentTa
b.getWebContents()); | 352 OfflinePageItem offlinePage = offlinePageBridge.getOfflinePage(currentTa
b.getWebContents()); |
| 364 if (offlinePage != null) { | 353 if (offlinePage != null) { |
| 365 // If we're currently on offline page get the saved file directly. | 354 // If we're currently on offline page get the saved file directly. |
| 366 prepareFileAndShare(shareDirectly, saveLastUsed, mainActivity, title
, text, | 355 prepareFileAndShare(builder, offlinePage.getFilePath()); |
| 367 url, screenshotUri, callback, offlinePage.getFil
ePath()); | |
| 368 return; | 356 return; |
| 369 } | 357 } |
| 370 | 358 |
| 371 // If this is an online page, share the offline copy of it. | 359 // If this is an online page, share the offline copy of it. |
| 372 Callback<OfflinePageItem> prepareForSharing = onGotOfflinePageItemToShar
e(shareDirectly, | 360 Callback<OfflinePageItem> prepareForSharing = onGotOfflinePageItemToShar
e(builder); |
| 373 saveLastUsed, mainActivity, title, text, url, screenshotUri, cal
lback); | 361 offlinePageBridge.selectPageForOnlineUrl(currentTab.getUrl(), currentTab
.getId(), |
| 374 offlinePageBridge.selectPageForOnlineUrl(url, currentTab.getId(), | 362 selectPageForOnlineUrlCallback( |
| 375 selectPageForOnlineUrlCallback(currentTab.getWebContents(), offl
inePageBridge, | 363 currentTab.getWebContents(), offlinePageBridge, prepareF
orSharing)); |
| 376 prepareForSharing)); | |
| 377 } | 364 } |
| 378 | 365 |
| 379 /** | 366 /** |
| 380 * Callback for receiving the OfflinePageItem and use it to call prepareForS
haring. | 367 * Callback for receiving the OfflinePageItem and use it to call prepareForS
haring. |
| 381 * @param shareDirectly Whether it should share directly with the activity t
hat was most | 368 * @param builder The builder to construct {@link ShareParams} for holding s
hare parameters. |
| 382 * recently used to share. | |
| 383 * @param mainActivity Activity that is used to access package manager | |
| 384 * @param title Title of the page. | |
| 385 * @param onlineUrl Online URL associated with the offline page that is used
to access the | |
| 386 * offline page file path. | |
| 387 * @param screenshotUri Screenshot of the page to be shared. | |
| 388 * @param mContext The application context. | |
| 389 * @return a callback of OfflinePageItem | |
| 390 */ | 369 */ |
| 391 private static Callback<OfflinePageItem> onGotOfflinePageItemToShare( | 370 private static Callback<OfflinePageItem> onGotOfflinePageItemToShare( |
| 392 final boolean shareDirectly, final boolean saveLastUsed, final Activ
ity mainActivity, | 371 final ShareParams.Builder builder) { |
| 393 final String title, final String text, final String onlineUrl, final
Uri screenshotUri, | |
| 394 final ShareHelper.TargetChosenCallback callback) { | |
| 395 return new Callback<OfflinePageItem>() { | 372 return new Callback<OfflinePageItem>() { |
| 396 @Override | 373 @Override |
| 397 public void onResult(OfflinePageItem item) { | 374 public void onResult(OfflinePageItem item) { |
| 398 String offlineFilePath = (item == null) ? null : item.getFilePat
h(); | 375 String offlineFilePath = (item == null) ? null : item.getFilePat
h(); |
| 399 prepareFileAndShare(shareDirectly, saveLastUsed, mainActivity, t
itle, text, | 376 prepareFileAndShare(builder, offlineFilePath); |
| 400 onlineUrl, screenshotUri, callback, offlineFilePath); | |
| 401 } | 377 } |
| 402 }; | 378 }; |
| 403 } | 379 } |
| 404 | 380 |
| 405 /** | 381 /** |
| 406 * Takes the offline page item from selectPageForOnlineURL. If it exists, in
vokes | 382 * Takes the offline page item from selectPageForOnlineURL. If it exists, in
vokes |
| 407 * |prepareForSharing| with it. Otherwise, saves a page for the online URL
and invokes | 383 * |prepareForSharing| with it. Otherwise, saves a page for the online URL
and invokes |
| 408 * |prepareForSharing| with the result when it's ready. | 384 * |prepareForSharing| with the result when it's ready. |
| 409 * @param webContents Contents of the page to save. | 385 * @param webContents Contents of the page to save. |
| 410 * @param offlinePageBridge A static copy of the offlinePageBridge. | 386 * @param offlinePageBridge A static copy of the offlinePageBridge. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 } | 430 } |
| 455 | 431 |
| 456 offlinePageBridge.getPageByOfflineId(offlineId, prepareForSharin
g); | 432 offlinePageBridge.getPageByOfflineId(offlineId, prepareForSharin
g); |
| 457 } | 433 } |
| 458 }; | 434 }; |
| 459 } | 435 } |
| 460 | 436 |
| 461 /** | 437 /** |
| 462 * If file path of offline page is not null, do file operations needed for t
he page to be | 438 * If file path of offline page is not null, do file operations needed for t
he page to be |
| 463 * shared. Otherwise, only share the online url. | 439 * shared. Otherwise, only share the online url. |
| 464 * @param shareDirectly Whether it should share directly with the activity t
hat was most | 440 * @param builder The builder to construct {@link ShareParams} for holding s
hare parameters. |
| 465 * recently used to share. | |
| 466 * @param saveLastUsed Whether to save the chosen activity for future direct
sharing. | |
| 467 * @param activity Activity that is used to access package manager | |
| 468 * @param title Title of the page. | |
| 469 * @param text Text to be shared. If both |text| and |url| are supplied, the
y are concatenated | |
| 470 * with a space. | |
| 471 * @param onlineUrl Online URL associated with the offline page that is used
to access the | |
| 472 * offline page file path. | |
| 473 * @param screenshotUri Screenshot of the page to be shared. | |
| 474 * @param callback Optional callback to be called when user makes a choice.
Will not be called | |
| 475 * if receiving a response when the user makes a choice is n
ot supported (on | |
| 476 * older Android versions). | |
| 477 * @param filePath File path of the offline page. | 441 * @param filePath File path of the offline page. |
| 478 */ | 442 */ |
| 479 private static void prepareFileAndShare(final boolean shareDirectly, final b
oolean saveLastUsed, | 443 private static void prepareFileAndShare( |
| 480 final Activity activity, final String title, final String text, fina
l String onlineUrl, | 444 final ShareParams.Builder builder, final String filePath) { |
| 481 final Uri screenshotUri, final ShareHelper.TargetChosenCallback call
back, | |
| 482 final String filePath) { | |
| 483 new AsyncTask<Void, Void, File>() { | 445 new AsyncTask<Void, Void, File>() { |
| 484 @Override | 446 @Override |
| 485 protected File doInBackground(Void... params) { | 447 protected File doInBackground(Void... params) { |
| 486 if (filePath == null) return null; | 448 if (filePath == null) return null; |
| 487 | 449 |
| 488 File offlinePageOriginal = new File(filePath); | 450 File offlinePageOriginal = new File(filePath); |
| 489 File shareableDir = getDirectoryForOfflineSharing(activity); | 451 File shareableDir = |
| 452 getDirectoryForOfflineSharing(ContextUtils.getApplicatio
nContext()); |
| 490 | 453 |
| 491 if (shareableDir == null) { | 454 if (shareableDir == null) { |
| 492 Log.e(TAG, "Unable to create subdirectory in shareable direc
tory"); | 455 Log.e(TAG, "Unable to create subdirectory in shareable direc
tory"); |
| 493 return null; | 456 return null; |
| 494 } | 457 } |
| 495 | 458 |
| 496 String fileName = rewriteOfflineFileName(offlinePageOriginal.get
Name()); | 459 String fileName = rewriteOfflineFileName(offlinePageOriginal.get
Name()); |
| 497 File offlinePageShareable = new File(shareableDir, fileName); | 460 File offlinePageShareable = new File(shareableDir, fileName); |
| 498 | 461 |
| 499 if (offlinePageShareable.exists()) { | 462 if (offlinePageShareable.exists()) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 515 | 478 |
| 516 return null; | 479 return null; |
| 517 } | 480 } |
| 518 | 481 |
| 519 @Override | 482 @Override |
| 520 protected void onPostExecute(File offlinePageShareable) { | 483 protected void onPostExecute(File offlinePageShareable) { |
| 521 Uri offlineUri = null; | 484 Uri offlineUri = null; |
| 522 if (offlinePageShareable != null) { | 485 if (offlinePageShareable != null) { |
| 523 offlineUri = Uri.fromFile(offlinePageShareable); | 486 offlineUri = Uri.fromFile(offlinePageShareable); |
| 524 } | 487 } |
| 525 ShareHelper.share(shareDirectly, saveLastUsed, activity, title,
text, onlineUrl, | 488 builder.setOfflineUri(offlineUri); |
| 526 offlineUri, screenshotUri, callback); | 489 ShareHelper.share(builder.build()); |
| 527 } | 490 } |
| 528 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); | 491 }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); |
| 529 } | 492 } |
| 530 | 493 |
| 531 /** | 494 /** |
| 532 * Copies the file from internal storage to a sharable directory. | 495 * Copies the file from internal storage to a sharable directory. |
| 533 * @param src The original file to be copied. | 496 * @param src The original file to be copied. |
| 534 * @param dst The destination file. | 497 * @param dst The destination file. |
| 535 */ | 498 */ |
| 536 @VisibleForTesting | 499 @VisibleForTesting |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 @VisibleForTesting | 824 @VisibleForTesting |
| 862 static void setInstanceForTesting(Internal instance) { | 825 static void setInstanceForTesting(Internal instance) { |
| 863 sInstance = instance; | 826 sInstance = instance; |
| 864 } | 827 } |
| 865 | 828 |
| 866 @VisibleForTesting | 829 @VisibleForTesting |
| 867 public static void setSnackbarDurationForTesting(int durationMs) { | 830 public static void setSnackbarDurationForTesting(int durationMs) { |
| 868 sSnackbarDurationMs = durationMs; | 831 sSnackbarDurationMs = durationMs; |
| 869 } | 832 } |
| 870 } | 833 } |
| OLD | NEW |