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.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; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 * the appropriate TabRestoreType in a lookup table. | 69 * the appropriate TabRestoreType in a lookup table. |
| 70 */ | 70 */ |
| 71 private static final int BIT_ONLINE = 1; | 71 private static final int BIT_ONLINE = 1; |
| 72 private static final int BIT_CANT_SAVE_OFFLINE = 1 << 2; | 72 private static final int BIT_CANT_SAVE_OFFLINE = 1 << 2; |
| 73 private static final int BIT_OFFLINE_PAGE = 1 << 3; | 73 private static final int BIT_OFFLINE_PAGE = 1 << 3; |
| 74 private static final int BIT_LAST_N = 1 << 4; | 74 private static final int BIT_LAST_N = 1 << 4; |
| 75 | 75 |
| 76 // Used instead of the constant so tests can override the value. | 76 // Used instead of the constant so tests can override the value. |
| 77 private static int sSnackbarDurationMs = DEFAULT_SNACKBAR_DURATION_MS; | 77 private static int sSnackbarDurationMs = DEFAULT_SNACKBAR_DURATION_MS; |
| 78 | 78 |
| 79 private static OfflinePageUtils sInstance; | 79 /** Instance carrying actual implementation of utility methods. */ |
| 80 private static Internal sInstance; | |
| 80 | 81 |
| 81 private static File sOfflineSharingDirectory; | 82 private static File sOfflineSharingDirectory; |
| 82 | 83 |
| 83 /** | 84 /** |
| 84 * Tracks the observers of ChromeActivity's TabModelSelectors. This is weak so the activity can | 85 * Tracks the observers of ChromeActivity's TabModelSelectors. This is weak so the activity can |
| 85 * be garbage collected without worrying about this map. The RecentTabTrack er is held here so | 86 * be garbage collected without worrying about this map. The RecentTabTrack er is held here so |
| 86 * that it can be destroyed when the ChromeActivity gets a new TabModelSelec tor. | 87 * that it can be destroyed when the ChromeActivity gets a new TabModelSelec tor. |
| 87 */ | 88 */ |
| 88 private static Map<ChromeActivity, RecentTabTracker> sTabModelObservers = ne w HashMap<>(); | 89 private static Map<ChromeActivity, RecentTabTracker> sTabModelObservers = ne w HashMap<>(); |
| 89 | 90 |
| 90 /** | 91 /** |
| 92 * Interface for implementation of offline page utilities, that can be imple mented for testing. | |
| 93 * We are using an internal interface, so that instance methods can have the same names as | |
| 94 * static methods. | |
| 95 */ | |
|
dewittj
2017/04/27 17:29:14
@visiblefortest
fgorski
2017/05/08 21:41:24
Done.
| |
| 96 interface Internal { | |
| 97 /** Returns offline page bridge for specified profile. */ | |
| 98 OfflinePageBridge getOfflinePageBridge(Profile profile); | |
| 99 | |
| 100 /** Returns whether the network is connected. */ | |
| 101 boolean isConnected(); | |
| 102 | |
| 103 /** | |
| 104 * Checks if an offline page is shown for the tab. | |
| 105 * @param tab The tab to be reloaded. | |
| 106 * @return True if the offline page is opened. | |
| 107 */ | |
| 108 boolean isOfflinePage(Tab tab); | |
| 109 | |
| 110 /** | |
| 111 * Returns whether the tab is showing offline preview. | |
| 112 * @param tab The current tab. | |
| 113 */ | |
| 114 boolean isShowingOfflinePreview(Tab tab); | |
| 115 | |
| 116 /** | |
| 117 * Shows the "reload" snackbar for the given tab. | |
| 118 * @param context The application context. | |
| 119 * @param snackbarManager Class that shows the snackbar. | |
| 120 * @param snackbarController Class to control the snackbar. | |
| 121 * @param tabId Id of a tab that the snackbar is related to. | |
| 122 */ | |
| 123 void showReloadSnackbar(Context context, SnackbarManager snackbarManager , | |
| 124 final SnackbarController snackbarController, int tabId); | |
| 125 } | |
| 126 | |
| 127 private static class OfflinePageUtilsImpl implements Internal { | |
| 128 @Override | |
| 129 public OfflinePageBridge getOfflinePageBridge(Profile profile) { | |
| 130 return OfflinePageBridge.getForProfile(profile); | |
| 131 } | |
| 132 | |
| 133 @Override | |
| 134 public boolean isConnected() { | |
| 135 return NetworkChangeNotifier.isOnline(); | |
| 136 } | |
| 137 | |
| 138 @Override | |
| 139 public boolean isOfflinePage(Tab tab) { | |
| 140 OfflinePageBridge offlinePageBridge = getOfflinePageBridge(tab.getPr ofile()); | |
| 141 if (offlinePageBridge == null) return false; | |
| 142 return offlinePageBridge.isOfflinePage(tab.getWebContents()); | |
| 143 } | |
| 144 | |
| 145 @Override | |
| 146 public boolean isShowingOfflinePreview(Tab tab) { | |
| 147 OfflinePageBridge offlinePageBridge = getOfflinePageBridge(tab.getPr ofile()); | |
| 148 if (offlinePageBridge == null) return false; | |
| 149 return offlinePageBridge.isShowingOfflinePreview(tab.getWebContents( )); | |
| 150 } | |
| 151 | |
| 152 @Override | |
| 153 public void showReloadSnackbar(Context context, SnackbarManager snackbar Manager, | |
| 154 final SnackbarController snackbarController, int tabId) { | |
| 155 if (tabId == Tab.INVALID_TAB_ID) return; | |
| 156 | |
| 157 Log.d(TAG, "showReloadSnackbar called with controller " + snackbarCo ntroller); | |
| 158 Snackbar snackbar = | |
| 159 Snackbar.make(context.getString(R.string.offline_pages_viewi ng_offline_page), | |
| 160 snackbarController, Snackbar.TYPE_ACTION, | |
| 161 Snackbar.UMA_OFFLINE_PAGE_RELOAD) | |
| 162 .setSingleLine(false) | |
| 163 .setAction(context.getString(R.string.reload), tabId ); | |
| 164 snackbar.setDuration(sSnackbarDurationMs); | |
| 165 snackbarManager.showSnackbar(snackbar); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 /** | |
| 91 * Contains values from the histogram enum OfflinePagesTabRestoreType used f or reporting the | 170 * Contains values from the histogram enum OfflinePagesTabRestoreType used f or reporting the |
| 92 * OfflinePages.TabRestore metric. | 171 * OfflinePages.TabRestore metric. |
| 93 */ | 172 */ |
| 94 private static class TabRestoreType { | 173 private static class TabRestoreType { |
| 95 public static final int WHILE_ONLINE = 0; | 174 public static final int WHILE_ONLINE = 0; |
| 96 public static final int WHILE_ONLINE_CANT_SAVE_FOR_OFFLINE_USAGE = 1; | 175 public static final int WHILE_ONLINE_CANT_SAVE_FOR_OFFLINE_USAGE = 1; |
| 97 public static final int WHILE_ONLINE_TO_OFFLINE_PAGE = 2; | 176 public static final int WHILE_ONLINE_TO_OFFLINE_PAGE = 2; |
| 98 public static final int WHILE_ONLINE_TO_OFFLINE_PAGE_FROM_LAST_N = 3; | 177 public static final int WHILE_ONLINE_TO_OFFLINE_PAGE_FROM_LAST_N = 3; |
| 99 public static final int WHILE_OFFLINE = 4; | 178 public static final int WHILE_OFFLINE = 4; |
| 100 public static final int WHILE_OFFLINE_CANT_SAVE_FOR_OFFLINE_USAGE = 5; | 179 public static final int WHILE_OFFLINE_CANT_SAVE_FOR_OFFLINE_USAGE = 5; |
| 101 public static final int WHILE_OFFLINE_TO_OFFLINE_PAGE = 6; | 180 public static final int WHILE_OFFLINE_TO_OFFLINE_PAGE = 6; |
| 102 public static final int WHILE_OFFLINE_TO_OFFLINE_PAGE_FROM_LAST_N = 7; | 181 public static final int WHILE_OFFLINE_TO_OFFLINE_PAGE_FROM_LAST_N = 7; |
| 103 public static final int FAILED = 8; | 182 public static final int FAILED = 8; |
| 104 public static final int CRASHED = 9; | 183 public static final int CRASHED = 9; |
| 105 // NOTE: always keep this entry at the end. Add new result types only im mediately above this | 184 // NOTE: always keep this entry at the end. Add new result types only im mediately above this |
| 106 // line. Make sure to update the corresponding histogram enum accordingl y. | 185 // line. Make sure to update the corresponding histogram enum accordingl y. |
| 107 public static final int COUNT = 10; | 186 public static final int COUNT = 10; |
| 108 } | 187 } |
| 109 | 188 |
| 110 private static OfflinePageUtils getInstance() { | 189 private static Internal getInstance() { |
| 111 if (sInstance == null) { | 190 if (sInstance == null) { |
| 112 sInstance = new OfflinePageUtils(); | 191 sInstance = new OfflinePageUtilsImpl(); |
| 113 } | 192 } |
| 114 return sInstance; | 193 return sInstance; |
| 115 } | 194 } |
| 116 | 195 |
| 117 /** | 196 /** |
| 118 * Returns the number of free bytes on the storage. | 197 * Returns the number of free bytes on the storage. |
| 119 */ | 198 */ |
| 120 public static long getFreeSpaceInBytes() { | 199 public static long getFreeSpaceInBytes() { |
| 121 return Environment.getDataDirectory().getUsableSpace(); | 200 return Environment.getDataDirectory().getUsableSpace(); |
| 122 } | 201 } |
| 123 | 202 |
| 124 /** | 203 /** |
| 125 * Returns the number of total bytes on the storage. | 204 * Returns the number of total bytes on the storage. |
| 126 */ | 205 */ |
| 127 public static long getTotalSpaceInBytes() { | 206 public static long getTotalSpaceInBytes() { |
| 128 return Environment.getDataDirectory().getTotalSpace(); | 207 return Environment.getDataDirectory().getTotalSpace(); |
| 129 } | 208 } |
| 130 | 209 |
| 131 /** | 210 /** Returns whether the network is connected. */ |
| 132 * Returns true if the network is connected. | |
| 133 */ | |
| 134 public static boolean isConnected() { | 211 public static boolean isConnected() { |
| 135 return NetworkChangeNotifier.isOnline(); | 212 return getInstance().isConnected(); |
| 136 } | 213 } |
| 137 | 214 |
| 138 /* | 215 /* |
| 139 * Save an offline copy for the bookmarked page asynchronously. | 216 * Save an offline copy for the bookmarked page asynchronously. |
| 140 * | 217 * |
| 141 * @param bookmarkId The ID of the page to save an offline copy. | 218 * @param bookmarkId The ID of the page to save an offline copy. |
| 142 * @param tab A {@link Tab} object. | 219 * @param tab A {@link Tab} object. |
| 143 * @param callback The callback to be invoked when the offline copy is saved . | 220 * @param callback The callback to be invoked when the offline copy is saved . |
| 144 */ | 221 */ |
| 145 public static void saveBookmarkOffline(BookmarkId bookmarkId, Tab tab) { | 222 public static void saveBookmarkOffline(BookmarkId bookmarkId, Tab tab) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 /** | 273 /** |
| 197 * Shows the snackbar for the current tab to provide offline specific inform ation if needed. | 274 * Shows the snackbar for the current tab to provide offline specific inform ation if needed. |
| 198 * @param tab The current tab. | 275 * @param tab The current tab. |
| 199 */ | 276 */ |
| 200 public static void showOfflineSnackbarIfNecessary(Tab tab) { | 277 public static void showOfflineSnackbarIfNecessary(Tab tab) { |
| 201 // Set up the tab observer to watch for the tab being shown (not hidden) and a valid | 278 // Set up the tab observer to watch for the tab being shown (not hidden) and a valid |
| 202 // connection. When both conditions are met a snackbar is shown. | 279 // connection. When both conditions are met a snackbar is shown. |
| 203 OfflinePageTabObserver.addObserverForTab(tab); | 280 OfflinePageTabObserver.addObserverForTab(tab); |
| 204 } | 281 } |
| 205 | 282 |
| 283 protected void showReloadSnackbarInternal(Context context, SnackbarManager s nackbarManager, | |
| 284 final SnackbarController snackbarController, int tabId) {} | |
| 285 | |
| 206 /** | 286 /** |
| 207 * Shows the "reload" snackbar for the given tab. | 287 * Shows the "reload" snackbar for the given tab. |
| 208 * @param activity The activity owning the tab. | 288 * @param context The application context. |
| 209 * @param snackbarController Class to show the snackbar. | 289 * @param snackbarManager Class that shows the snackbar. |
| 290 * @param snackbarController Class to control the snackbar. | |
| 291 * @param tabId Id of a tab that the snackbar is related to. | |
| 210 */ | 292 */ |
| 211 public static void showReloadSnackbar(Context context, SnackbarManager snack barManager, | 293 public static void showReloadSnackbar(Context context, SnackbarManager snack barManager, |
| 212 final SnackbarController snackbarController, int tabId) { | 294 final SnackbarController snackbarController, int tabId) { |
| 213 if (tabId == Tab.INVALID_TAB_ID) return; | 295 getInstance().showReloadSnackbar(context, snackbarManager, snackbarContr oller, tabId); |
| 214 | |
| 215 Log.d(TAG, "showReloadSnackbar called with controller " + snackbarContro ller); | |
| 216 Snackbar snackbar = | |
| 217 Snackbar.make(context.getString(R.string.offline_pages_viewing_o ffline_page), | |
| 218 snackbarController, Snackbar.TYPE_ACTION, Snackbar.UMA_O FFLINE_PAGE_RELOAD) | |
| 219 .setSingleLine(false).setAction(context.getString(R.stri ng.reload), tabId); | |
| 220 snackbar.setDuration(sSnackbarDurationMs); | |
| 221 snackbarManager.showSnackbar(snackbar); | |
| 222 } | 296 } |
| 223 | 297 |
| 224 | |
| 225 /** | 298 /** |
| 226 * Records UMA data when the Offline Pages Background Load service awakens. | 299 * Records UMA data when the Offline Pages Background Load service awakens. |
| 227 * @param context android context | 300 * @param context android context |
| 228 */ | 301 */ |
| 229 public static void recordWakeupUMA(Context context, long taskScheduledTimeMi llis) { | 302 public static void recordWakeupUMA(Context context, long taskScheduledTimeMi llis) { |
| 230 DeviceConditions deviceConditions = DeviceConditions.getCurrentCondition s(context); | 303 DeviceConditions deviceConditions = DeviceConditions.getCurrentCondition s(context); |
| 231 if (deviceConditions == null) return; | 304 if (deviceConditions == null) return; |
| 232 | 305 |
| 233 // Report charging state. | 306 // Report charging state. |
| 234 RecordHistogram.recordBooleanHistogram( | 307 RecordHistogram.recordBooleanHistogram( |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 headers.put("X-Chrome-offline", "persist=1 reason=download id=" + Long.t oString(offlineId)); | 624 headers.put("X-Chrome-offline", "persist=1 reason=download id=" + Long.t oString(offlineId)); |
| 552 params.setExtraHeaders(headers); | 625 params.setExtraHeaders(headers); |
| 553 return params; | 626 return params; |
| 554 } | 627 } |
| 555 | 628 |
| 556 /** | 629 /** |
| 557 * @return True if an offline preview is being shown. | 630 * @return True if an offline preview is being shown. |
| 558 * @param tab The current tab. | 631 * @param tab The current tab. |
| 559 */ | 632 */ |
| 560 public static boolean isShowingOfflinePreview(Tab tab) { | 633 public static boolean isShowingOfflinePreview(Tab tab) { |
| 561 OfflinePageBridge offlinePageBridge = getInstance().getOfflinePageBridge (tab.getProfile()); | 634 return getInstance().isShowingOfflinePreview(tab); |
| 562 if (offlinePageBridge == null) return false; | |
| 563 return offlinePageBridge.isShowingOfflinePreview(tab.getWebContents()); | |
| 564 } | 635 } |
| 565 | 636 |
| 566 /** | 637 /** |
| 567 * Checks if an offline page is shown for the tab. | 638 * Checks if an offline page is shown for the tab. |
| 568 * @param tab The tab to be reloaded. | 639 * @param tab The tab to be reloaded. |
| 569 * @return True if the offline page is opened. | 640 * @return True if the offline page is opened. |
| 570 */ | 641 */ |
| 571 public static boolean isOfflinePage(Tab tab) { | 642 public static boolean isOfflinePage(Tab tab) { |
| 572 OfflinePageBridge offlinePageBridge = getInstance().getOfflinePageBridge (tab.getProfile()); | 643 return getInstance().isOfflinePage(tab); |
| 573 if (offlinePageBridge == null) return false; | |
| 574 return offlinePageBridge.isOfflinePage(tab.getWebContents()); | |
| 575 } | 644 } |
| 576 | 645 |
| 577 /** | 646 /** |
| 578 * Retrieves the offline page that is shown for the tab. | 647 * Retrieves the offline page that is shown for the tab. |
| 579 * @param tab The tab to be reloaded. | 648 * @param tab The tab to be reloaded. |
| 580 * @return The offline page if tab currently displays it, null otherwise. | 649 * @return The offline page if tab currently displays it, null otherwise. |
| 581 */ | 650 */ |
| 582 public static OfflinePageItem getOfflinePage(Tab tab) { | 651 public static OfflinePageItem getOfflinePage(Tab tab) { |
| 583 OfflinePageBridge offlinePageBridge = getInstance().getOfflinePageBridge (tab.getProfile()); | 652 OfflinePageBridge offlinePageBridge = getInstance().getOfflinePageBridge (tab.getProfile()); |
| 584 if (offlinePageBridge == null) return null; | 653 if (offlinePageBridge == null) return null; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 606 * @param tab The tab to navigate to the page. | 675 * @param tab The tab to navigate to the page. |
| 607 */ | 676 */ |
| 608 public static void openInExistingTab(String url, long offlineId, Tab tab) { | 677 public static void openInExistingTab(String url, long offlineId, Tab tab) { |
| 609 LoadUrlParams params = | 678 LoadUrlParams params = |
| 610 OfflinePageUtils.getLoadUrlParamsForOpeningOfflineVersion(url, o fflineId); | 679 OfflinePageUtils.getLoadUrlParamsForOpeningOfflineVersion(url, o fflineId); |
| 611 // Extra headers are not read in loadUrl, but verbatim headers are. | 680 // Extra headers are not read in loadUrl, but verbatim headers are. |
| 612 params.setVerbatimHeaders(params.getExtraHeadersString()); | 681 params.setVerbatimHeaders(params.getExtraHeadersString()); |
| 613 tab.loadUrl(params); | 682 tab.loadUrl(params); |
| 614 } | 683 } |
| 615 | 684 |
| 616 protected OfflinePageBridge getOfflinePageBridge(Profile profile) { | |
| 617 return OfflinePageBridge.getForProfile(profile); | |
| 618 } | |
| 619 | |
| 620 /** | 685 /** |
| 621 * Tracks tab creation and closure for the Recent Tabs feature. UI needs to stop showing | 686 * Tracks tab creation and closure for the Recent Tabs feature. UI needs to stop showing |
| 622 * recent offline pages as soon as the tab is closed. The TabModel is used to get profile | 687 * recent offline pages as soon as the tab is closed. The TabModel is used to get profile |
| 623 * information because Tab's profile is tied to the native WebContents, whic h may not exist at | 688 * information because Tab's profile is tied to the native WebContents, whic h may not exist at |
| 624 * tab adding or tab closing time. | 689 * tab adding or tab closing time. |
| 625 */ | 690 */ |
| 626 private static class RecentTabTracker extends TabModelSelectorTabModelObserv er { | 691 private static class RecentTabTracker extends TabModelSelectorTabModelObserv er { |
| 627 /** | 692 /** |
| 628 * The single, stateless TabRestoreTracker instance to monitor all tab r estores. | 693 * The single, stateless TabRestoreTracker instance to monitor all tab r estores. |
| 629 */ | 694 */ |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 } | 846 } |
| 782 } | 847 } |
| 783 | 848 |
| 784 private static void recordTabRestoreHistogram(int tabRestoreType, String url ) { | 849 private static void recordTabRestoreHistogram(int tabRestoreType, String url ) { |
| 785 Log.d(TAG, "Concluded tab restore: type=" + tabRestoreType + ", url=" + url); | 850 Log.d(TAG, "Concluded tab restore: type=" + tabRestoreType + ", url=" + url); |
| 786 RecordHistogram.recordEnumeratedHistogram( | 851 RecordHistogram.recordEnumeratedHistogram( |
| 787 "OfflinePages.TabRestore", tabRestoreType, TabRestoreType.COUNT) ; | 852 "OfflinePages.TabRestore", tabRestoreType, TabRestoreType.COUNT) ; |
| 788 } | 853 } |
| 789 | 854 |
| 790 @VisibleForTesting | 855 @VisibleForTesting |
| 791 static void setInstanceForTesting(OfflinePageUtils instance) { | 856 static void setInstanceForTesting(Internal instance) { |
| 792 sInstance = instance; | 857 sInstance = instance; |
| 793 } | 858 } |
| 794 | 859 |
| 795 @VisibleForTesting | 860 @VisibleForTesting |
| 796 public static void setSnackbarDurationForTesting(int durationMs) { | 861 public static void setSnackbarDurationForTesting(int durationMs) { |
| 797 sSnackbarDurationMs = durationMs; | 862 sSnackbarDurationMs = durationMs; |
| 798 } | 863 } |
| 799 } | 864 } |
| OLD | NEW |