Commit 3308d51c authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Code cleanup for download home v1

Bug: 850608
Change-Id: Ia68fed867cea8c7d175b29dfaaa25f03579fec9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1804384
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700064}
parent f631bd72
...@@ -615,22 +615,8 @@ chrome_java_sources = [ ...@@ -615,22 +615,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiFactory.java", "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiFactory.java",
"java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java", "java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java",
"java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java", "java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java",
"java/src/org/chromium/chrome/browser/download/ui/BackendItems.java",
"java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java", "java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java",
"java/src/org/chromium/chrome/browser/download/ui/DeletedFileTracker.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadFilter.java", "java/src/org/chromium/chrome/browser/download/ui/DownloadFilter.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemViewHolder.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadItemSelectionDelegate.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadManagerToolbar.java",
"java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java",
"java/src/org/chromium/chrome/browser/download/ui/FilePathsToDownloadItemsMap.java",
"java/src/org/chromium/chrome/browser/download/ui/FilterAdapter.java",
"java/src/org/chromium/chrome/browser/download/ui/LoadingStateDelegate.java",
"java/src/org/chromium/chrome/browser/download/ui/OfflineGroupHeaderView.java",
"java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java",
"java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java", "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java",
"java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java", "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java",
"java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java", "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java",
......
...@@ -137,7 +137,6 @@ chrome_test_java_sources = [ ...@@ -137,7 +137,6 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java", "javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java",
"javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java", "javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java",
"javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java", "javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadFileProviderTest.java", "javatests/src/org/chromium/chrome/browser/download/DownloadFileProviderTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java", "javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceTest.java", "javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceTest.java",
...@@ -156,7 +155,6 @@ chrome_test_java_sources = [ ...@@ -156,7 +155,6 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/download/TestDownloadDirectoryProvider.java", "javatests/src/org/chromium/chrome/browser/download/TestDownloadDirectoryProvider.java",
"javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java", "javatests/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java",
"javatests/src/org/chromium/chrome/browser/download/home/StubbedOfflineContentProvider.java", "javatests/src/org/chromium/chrome/browser/download/home/StubbedOfflineContentProvider.java",
"javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java",
"javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java", "javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java",
"javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java", "javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java",
"javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimentalTest.java", "javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimentalTest.java",
......
...@@ -113,7 +113,6 @@ ...@@ -113,7 +113,6 @@
<color name="contextual_search_divider_line_color">@color/modern_secondary_color</color> <color name="contextual_search_divider_line_color">@color/modern_secondary_color</color>
<!-- Progress Bar colors --> <!-- Progress Bar colors -->
<color name="downloads_progress_bar_background_blue">#421A73E8</color>
<color name="progress_bar_foreground">@color/light_active_color</color> <color name="progress_bar_foreground">@color/light_active_color</color>
<color name="progress_bar_secondary">@color/modern_grey_600</color> <color name="progress_bar_secondary">@color/modern_grey_600</color>
<color name="progress_bar_background">#3D4386F7</color> <color name="progress_bar_background">#3D4386F7</color>
...@@ -183,7 +182,6 @@ ...@@ -183,7 +182,6 @@
<!-- Other colors --> <!-- Other colors -->
<color name="media_viewer_bg">#000000</color> <color name="media_viewer_bg">#000000</color>
<color name="image_viewer_bg">#0E0E0E</color> <color name="image_viewer_bg">#0E0E0E</color>
<color name="modern_blue_600_alpha_38_opaque">#A8CAF6</color>
<color name="bottom_system_nav_color">@android:color/white</color> <color name="bottom_system_nav_color">@android:color/white</color>
<color name="bottom_system_nav_divider_color">@color/black_alpha_12</color> <color name="bottom_system_nav_divider_color">@color/black_alpha_12</color>
<color name="search_box_hint">@color/default_text_color_secondary</color> <color name="search_box_hint">@color/default_text_color_secondary</color>
......
...@@ -591,10 +591,8 @@ ...@@ -591,10 +591,8 @@
<!-- Modern List Item dimensions --> <!-- Modern List Item dimensions -->
<dimen name="list_item_min_height">64dp</dimen> <dimen name="list_item_min_height">64dp</dimen>
<dimen name="list_item_default_margin">16dp</dimen> <dimen name="list_item_default_margin">16dp</dimen>
<dimen name="list_item_subsection_margin">40dp</dimen>
<dimen name="list_item_start_icon_right_margin">20dp</dimen> <dimen name="list_item_start_icon_right_margin">20dp</dimen>
<dimen name="list_item_start_icon_width">36dp</dimen> <dimen name="list_item_start_icon_width">36dp</dimen>
<dimen name="list_item_start_icon_corner_radius">18dp</dimen>
<dimen name="list_item_end_icon_width">56dp</dimen> <dimen name="list_item_end_icon_width">56dp</dimen>
<!-- SelectableListLayout dimensions --> <!-- SelectableListLayout dimensions -->
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<!-- Represents a single item in the DownloadHistoryAdapterView. -->
<view class="org.chromium.chrome.browser.download.ui.DownloadItemView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- The end margin is not assigned because the cancel button overlaps it. -->
<LinearLayout
android:id="@+id/layout_container"
style="@style/ListItemContainer" >
<org.chromium.ui.widget.ChromeImageView
android:id="@+id/icon_view"
style="@style/DownloadIconView"
app:tint="@color/standard_mode_tint" />
<!-- Shown for completed downloads. -->
<RelativeLayout
android:id="@+id/completed_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:id="@+id/filename_completed_view"
style="@style/DownloadTitleStyle"
android:layout_alignParentEnd="true" />
<TextView
android:id="@+id/description_view"
style="@style/DownloadDescriptionStyle"
android:layout_below="@+id/filename_completed_view" />
</RelativeLayout>
<include layout="@layout/list_menu_button" />
<!-- Shown for downloads that haven't been completed. -->
<RelativeLayout
android:id="@+id/progress_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
<TextView
android:id="@+id/filename_progress_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/pause_button"
android:minHeight="18dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.BlackTitle1" />
<org.chromium.chrome.browser.widget.MaterialProgressBar
android:id="@+id/download_progress_view"
android:layout_width="wrap_content"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginEnd="16dp"
android:layout_below="@+id/filename_progress_view"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/pause_button"
app:colorBackground="@color/downloads_progress_bar_background_blue"
app:colorProgress="@color/light_active_color"
app:colorSecondaryProgress="@color/modern_grey_600" />
<TextView
android:id="@+id/status_view"
style="@style/DownloadHomeStatusText"
android:layout_marginEnd="16dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/percentage_view"
android:layout_below="@+id/download_progress_view"
android:textAlignment="viewStart" />
<TextView
android:id="@+id/percentage_view"
style="@style/DownloadHomeStatusText"
android:layout_alignParentBottom="true"
android:layout_toStartOf="@+id/pause_button"
android:layout_below="@+id/download_progress_view"
android:textAlignment="viewEnd" />
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/pause_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_toStartOf="@+id/cancel_button"
android:padding="8dp"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/download_notification_pause_button"
android:src="@drawable/ic_pause_white_24dp"
app:tint="@color/default_icon_color" />
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/cancel_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:padding="8dp"
android:paddingEnd="@dimen/selectable_list_layout_row_padding"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/download_notification_cancel_button"
android:src="@drawable/btn_close"
app:tint="@color/default_icon_color" />
</RelativeLayout>
</LinearLayout>
</view>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<org.chromium.chrome.browser.widget.selection.SelectableListLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/selectable_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/modern_primary_color"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackHeadline" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:drawablePadding="16dp"
android:minWidth="176dp"
android:minHeight="48dp"
android:paddingStart="16dp"
android:textAppearance="@style/TextAppearance.BlackTitle1" />
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<org.chromium.chrome.browser.download.ui.DownloadManagerToolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/ModernToolbar" >
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/standard_mode_tint" />
</org.chromium.chrome.browser.download.ui.DownloadManagerToolbar>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="11dp"
android:paddingBottom="6dp"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/space_widget_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="@dimen/list_item_default_margin"
android:layout_marginEnd="@dimen/list_item_default_margin" >
<TextView
android:id="@+id/size_downloaded"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.BlueLink3" />
<!-- The progress bar uses 20dp of space, vertically, including spacing. -->
<org.chromium.chrome.browser.widget.MaterialProgressBar
android:id="@+id/space_bar"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:colorBackground="@color/modern_grey_300"
app:colorProgress="@color/modern_blue_600_alpha_38_opaque"
app:colorSecondaryProgress="@color/modern_blue_600" />
<TextView
android:id="@+id/size_free_and_other_apps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.BlackDisabledText2" />
</LinearLayout>
<View
style="@style/HorizontalDivider"
android:layout_marginTop="@dimen/list_item_default_margin" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<!-- Represents the suggested offline pages section header in the DownloadHistoryAdapter. -->
<view
class="org.chromium.chrome.browser.download.ui.OfflineGroupHeaderView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/layout_container"
style="@style/ListItemContainer" >
<org.chromium.ui.widget.ChromeImageView
android:id="@+id/icon_view"
style="@style/DownloadIconView"
android:src="@drawable/ic_chrome"
app:tint="@color/standard_mode_tint" />
<RelativeLayout
android:id="@+id/completed_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/filename_row"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/title"
style="@style/DownloadTitleStyle"
android:layout_weight="1"
android:text="@string/download_manager_offline_header_title" />
<!-- TODO(shaktisahu) : Add it back on when UX is determined. -->
<TextView
android:id="@+id/new_badge"
style="@style/DownloadNewBadgeStyle"
android:layout_weight="0"
android:visibility="gone" />
<org.chromium.ui.widget.ChromeImageView
android:id="@+id/expand_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_gravity="center_vertical|end"
android:paddingEnd="16dp"
tools:ignore="ContentDescription"
android:src="@drawable/ic_expand_more_black_24dp"
app:tint="@color/standard_mode_tint" />
</LinearLayout>
<TextView
android:id="@+id/description"
style="@style/DownloadDescriptionStyle"
android:layout_below="@+id/filename_row"
android:text="@string/download_manager_offline_header_description" />
</RelativeLayout>
</LinearLayout>
</view>
\ No newline at end of file
...@@ -5,59 +5,6 @@ ...@@ -5,59 +5,6 @@
<resources xmlns:tools="http://schemas.android.com/tools" <resources xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Download Home -->
<style name="DownloadHomeStatusText">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">0dp</item>
<item name="android:minHeight">18dp</item>
<item name="android:textAppearance">@style/TextAppearance.BlackBody</item>
<item name="android:ellipsize">start</item>
<item name="android:singleLine">true</item>
</style>
<style name="DownloadTitleStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_alignParentTop">true</item>
<item name="android:layout_alignParentStart">true</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:singleLine">true</item>
<item name="android:textAppearance">@style/TextAppearance.BlackTitle1</item>
</style>
<style name="DownloadDescriptionStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_alignParentBottom">true</item>
<item name="android:layout_alignParentStart">true</item>
<item name="android:layout_marginEnd">16dp</item>
<item name="android:layout_marginTop">0dp</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:ellipsize">start</item>
<item name="android:singleLine">true</item>
<item name="android:textAppearance">@style/TextAppearance.BlackBody</item>
</style>
<style name="DownloadIconView" parent="@style/ListItemStartIcon">
<item name="android:background">@color/light_active_color</item>
</style>
<style name="DownloadNewBadgeStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@color/light_active_color</item>
<item name="android:layout_marginStart">-8dp</item>
<item name="android:layout_marginTop">-2dp</item>
<item name="android:paddingStart">6dp</item>
<item name="android:paddingEnd">6dp</item>
<item name="android:singleLine">true</item>
<item name="android:text">@string/prefetch_badge_new</item>
<item name="android:textAppearance">@style/TextAppearance.DownloadNewBadge</item>
</style>
<style name="TextAppearance.DownloadNewBadge">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">@dimen/text_size_small</item>
<item name="android:textStyle">bold</item>
<item name="android:textAllCaps">true</item>
</style>
<!-- Download Home V2 --> <!-- Download Home V2 -->
<style name="DownloadItemText"> <style name="DownloadItemText">
<item name="android:layout_width">0dp</item> <item name="android:layout_width">0dp</item>
......
...@@ -8,14 +8,12 @@ import android.app.Activity; ...@@ -8,14 +8,12 @@ import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import android.os.Bundle; import android.os.Bundle;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.SnackbarActivity; import org.chromium.chrome.browser.SnackbarActivity;
import org.chromium.chrome.browser.download.home.DownloadManagerCoordinator; import org.chromium.chrome.browser.download.home.DownloadManagerCoordinator;
import org.chromium.chrome.browser.download.home.DownloadManagerCoordinatorFactory; import org.chromium.chrome.browser.download.home.DownloadManagerCoordinatorFactory;
import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig; import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig;
import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory;
import org.chromium.chrome.browser.download.ui.DownloadManagerUi;
import org.chromium.chrome.browser.modaldialog.AppModalPresenter; import org.chromium.chrome.browser.modaldialog.AppModalPresenter;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.util.UrlConstants; import org.chromium.chrome.browser.util.UrlConstants;
...@@ -111,15 +109,6 @@ public class DownloadActivity extends SnackbarActivity implements ModalDialogMan ...@@ -111,15 +109,6 @@ public class DownloadActivity extends SnackbarActivity implements ModalDialogMan
return mModalDialogManager; return mModalDialogManager;
} }
@VisibleForTesting
DownloadManagerUi getDownloadManagerUiForTests() {
// TODO(856383): Generalize/fix download home tests for the new DownloadManagerCoordinator.
if (mDownloadCoordinator instanceof DownloadManagerUi) {
return (DownloadManagerUi) mDownloadCoordinator;
}
return null;
}
public AndroidPermissionDelegate getAndroidPermissionDelegate() { public AndroidPermissionDelegate getAndroidPermissionDelegate() {
return mPermissionDelegate; return mPermissionDelegate;
} }
......
...@@ -7,8 +7,6 @@ package org.chromium.chrome.browser.download.home; ...@@ -7,8 +7,6 @@ package org.chromium.chrome.browser.download.home;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.download.ui.DownloadManagerUi;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager;
import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager;
...@@ -27,12 +25,7 @@ public class DownloadManagerCoordinatorFactory { ...@@ -27,12 +25,7 @@ public class DownloadManagerCoordinatorFactory {
public static DownloadManagerCoordinator create(Activity activity, public static DownloadManagerCoordinator create(Activity activity,
DownloadManagerUiConfig config, SnackbarManager snackbarManager, DownloadManagerUiConfig config, SnackbarManager snackbarManager,
ComponentName parentComponent, ModalDialogManager modalDialogManager) { ComponentName parentComponent, ModalDialogManager modalDialogManager) {
if (ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_HOME_V2)) { return new DownloadManagerCoordinatorImpl(Profile.getLastUsedProfile(), activity, config,
return new DownloadManagerCoordinatorImpl(Profile.getLastUsedProfile(), activity, snackbarManager, modalDialogManager);
config, snackbarManager, modalDialogManager);
} else {
return new DownloadManagerUi(activity, config.isOffTheRecord, parentComponent,
config.isSeparateActivity, snackbarManager);
}
} }
} }
...@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.download.DownloadDirectoryProvider; ...@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.download.DownloadDirectoryProvider;
import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterObserver; import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterObserver;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterSource; import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterSource;
import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter;
import org.chromium.components.offline_items_collection.OfflineItem; import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItemState; import org.chromium.components.offline_items_collection.OfflineItemState;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.text.TextUtils;
import org.chromium.chrome.browser.widget.DateDividedAdapter.TimedItem;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
/**
* Stores a List of DownloadHistoryItemWrappers for a particular download backend.
*/
public abstract class BackendItems extends ArrayList<DownloadHistoryItemWrapper> {
/** See {@link #findItemIndex}. */
public static final int INVALID_INDEX = -1;
/** Whether or not the list has been initialized. */
private boolean mIsInitialized;
/**
* Determines how many bytes are occupied by completed downloads.
* @return Total size of completed downloads in bytes.
*/
public long getTotalBytes() {
long totalSize = 0;
HashSet<String> filePaths = new HashSet<>();
for (DownloadHistoryItemWrapper item : this) {
String path = item.getFilePath();
if (item.isVisibleToUser(DownloadFilter.Type.ALL) && !filePaths.contains(path)) {
totalSize += item.getFileSize();
}
if (path != null && !path.isEmpty()) filePaths.add(path);
}
return totalSize;
}
/**
* TODO(shaktisahu) : Remove this when not needed.
* Filters out items that match the query and are displayed in this list for the current filter.
* @param filterType Filter to use.
* @param query The text to match.
* @param filteredItems List for appending items that match the filter.
*/
public void filter(int filterType, String query, List<TimedItem> filteredItems) {
if (TextUtils.isEmpty(query)) {
filter(filterType, filteredItems);
return;
}
for (DownloadHistoryItemWrapper item : this) {
query = query.toLowerCase(Locale.getDefault());
Locale locale = Locale.getDefault();
if (item.isVisibleToUser(filterType)
&& (item.getDisplayHostname().toLowerCase(locale).contains(query)
|| item.getDisplayFileName().toLowerCase(locale).contains(query))) {
filteredItems.add(item);
}
}
}
/**
* Search for an existing entry with the given ID.
* @param guid GUID of the entry.
* @return The index of the item, or INVALID_INDEX if it couldn't be found.
*/
public int findItemIndex(String guid) {
for (int i = 0; i < size(); i++) {
if (TextUtils.equals(get(i).getId(), guid)) return i;
}
return INVALID_INDEX;
}
/**
* Removes the item matching the given guid.
* @param guid GUID of the download to remove.
* @return Item that was removed, or null if the item wasn't found.
*/
public DownloadHistoryItemWrapper removeItem(String guid) {
int index = findItemIndex(guid);
if (index == INVALID_INDEX) return null;
return remove(index);
}
public boolean isInitialized() {
return mIsInitialized;
}
public void setIsInitialized() {
mIsInitialized = true;
}
/**
* Filters out items that are displayed in this list for the current filter.
*
* @param filterType Filter to use.
* @param filteredItems List for appending items that match the filter.
*/
private void filter(int filterType, List<TimedItem> filteredItems) {
for (DownloadHistoryItemWrapper item : this) {
if (item.isVisibleToUser(filterType)) filteredItems.add(item);
}
}
}
...@@ -8,10 +8,7 @@ import org.chromium.base.Callback; ...@@ -8,10 +8,7 @@ import org.chromium.base.Callback;
import org.chromium.chrome.browser.download.DownloadItem; import org.chromium.chrome.browser.download.DownloadItem;
import org.chromium.chrome.browser.download.DownloadManagerService; import org.chromium.chrome.browser.download.DownloadManagerService;
import org.chromium.chrome.browser.download.DownloadManagerService.DownloadObserver; import org.chromium.chrome.browser.download.DownloadManagerService.DownloadObserver;
import org.chromium.chrome.browser.widget.ThumbnailProvider;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.OfflineContentProvider;
/** /**
* Provides classes that need to be interacted with by the {@link DownloadHistoryAdapter}. * Provides classes that need to be interacted with by the {@link DownloadHistoryAdapter}.
...@@ -48,40 +45,4 @@ public interface BackendProvider { ...@@ -48,40 +45,4 @@ public interface BackendProvider {
void renameDownload(ContentId id, String name, Callback<Integer /*RenameResult*/> callback, void renameDownload(ContentId id, String name, Callback<Integer /*RenameResult*/> callback,
boolean isOffTheRecord); boolean isOffTheRecord);
} }
/**
* Processes actions from the UI that require front end management before hitting the backend.
* This should eventually get merged into a proper delegate with other UI actions, but currently
* that is not possible.
*/
public static interface UIDelegate {
/**
* Requests that {@code item} be deleted. This might not hit the backend quiet yet if the
* user can undo the action.
*/
void deleteItem(DownloadHistoryItemWrapper item);
/**
* Requests that {@code item} be shared.
*/
void shareItem(DownloadHistoryItemWrapper item);
}
/** Returns the {@link DownloadDelegate} that works with the Downloads backend. */
DownloadDelegate getDownloadDelegate();
/** Returns the associated {@link OfflineContentProvider}. */
OfflineContentProvider getOfflineContentProvider();
/** Returns the {@link ThumbnailProvider} that gets thumbnails for files. */
ThumbnailProvider getThumbnailProvider();
/** Returns the {@link SelectionDelegate} that tracks selected items. */
SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate();
/** Returns the {@link UIDelegate} responsible for handling download system UI events. */
UIDelegate getUIDelegate();
/** Destroys the BackendProvider. */
void destroy();
} }
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.DownloadItemWrapper;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Tracks items that have been removed from downloads history because they were deleted externally.
* For use solely by the {@link DownloadHistoryAdapter}.
*
* TODO(dfalcantara): Make this class unnecessary.
*/
class DeletedFileTracker {
private final Set<String> mRegularItems = new HashSet<>();
private final Set<String> mIncognitoItems = new HashSet<>();
private final AtomicInteger mNumInstances = new AtomicInteger();
/** Called when a new {@link DownloadHistoryAdapter} is tracking deleted downloads. */
void incrementInstanceCount() {
mNumInstances.getAndIncrement();
}
/** Called when a {@link DownloadHistoryAdapter} is no longer traking deleted downloads. */
void decrementInstanceCount() {
if (mNumInstances.decrementAndGet() == 0) {
// If there is no interest, clear out the maps so that they stop taking up space.
mRegularItems.clear();
mIncognitoItems.clear();
}
}
/** Add a new item to the tracker. */
void add(DownloadHistoryItemWrapper wrapper) {
if (!(wrapper instanceof DownloadItemWrapper)) return;
Set<String> items = wrapper.isOffTheRecord() ? mIncognitoItems : mRegularItems;
items.add(wrapper.getId());
}
/** Checks if an item is in the tracker. */
boolean contains(DownloadHistoryItemWrapper wrapper) {
if (!(wrapper instanceof DownloadItemWrapper)) return false;
Set<String> items = wrapper.isOffTheRecord() ? mIncognitoItems : mRegularItems;
return items.contains(wrapper.getId());
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.support.v7.widget.RecyclerView;
import org.chromium.base.VisibleForTesting;
/** Holds onto a View that displays information about a downloaded file. */
public class DownloadHistoryItemViewHolder extends RecyclerView.ViewHolder {
private final DownloadItemView mItemView;
public DownloadHistoryItemViewHolder(DownloadItemView itemView) {
super(itemView);
mItemView = itemView;
}
@VisibleForTesting
public DownloadItemView getItemView() {
return mItemView;
}
}
\ No newline at end of file
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import org.chromium.base.ObserverList;
import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter.SubsectionHeader;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Separately maintains the selected state of the {@link SubsectionHeader}s in addition to the other
* selected items. Notifies the {@link OfflineGroupHeaderView}s about any change in the selected
* state of the headers.
*/
public class DownloadItemSelectionDelegate extends SelectionDelegate<DownloadHistoryItemWrapper> {
/** Observer interface to be notified of selection changes for {@link SubsectionHeader}s. */
public interface SubsectionHeaderSelectionObserver {
/**
* Called when the set of selected subsection headers has changed.
* @param selectedHeaders The set of currently selected headers.
*/
public void onSubsectionHeaderSelectionStateChanged(Set<SubsectionHeader> selectedHeaders);
}
private final Set<SubsectionHeader> mSelectedHeaders = new HashSet<>();
private final ObserverList<SubsectionHeaderSelectionObserver> mObservers = new ObserverList<>();
private DownloadHistoryAdapter mAdapter;
/**
* Adds an observer to be notified of selection changes for subsection headers.
* @param observer The observer to add.
*/
public void addObserver(SubsectionHeaderSelectionObserver observer) {
mObservers.addObserver(observer);
}
/**
* Removes an observer.
* @param observer The observer to remove.
*/
public void removeObserver(SubsectionHeaderSelectionObserver observer) {
mObservers.removeObserver(observer);
}
/**
* Initializes the selection delegate with the required dependencies. Registers an observer to
* be notified of selection changes for the download items of the adapter.
* @param adapter The associated download history adapter.
*/
public void initialize(DownloadHistoryAdapter adapter) {
mAdapter = adapter;
addObserver(new SelectionObserver<DownloadHistoryItemWrapper>() {
@Override
public void onSelectionStateChange(List<DownloadHistoryItemWrapper> selectedItems) {
for (SubsectionHeader header : mAdapter.getSubsectionHeaders()) {
boolean isChecked = true;
// A header should get selected if all the associated items are selected
// irrespective of whether it is currently expanded or collapsed.
for (DownloadHistoryItemWrapper subItem : header.getItems()) {
if (!selectedItems.contains(subItem)) {
isChecked = false;
break;
}
}
setSelectionForHeader(header, isChecked);
}
notifySubsectionHeaderSelectionStateChanged();
}
});
}
/**
* True if the header is currently selected. False otherwise.
* @param header The given header.
* @return Whether the header is selected.
*/
public boolean isHeaderSelected(SubsectionHeader header) {
return mSelectedHeaders.contains(header);
}
/**
* Toggles selection for a given subsection and sets the associated items to the correct
* selection state.
* @param header The header for the subsection being toggled.
* @return True if the header is selected after the toggle, false otherwise.
*/
public boolean toggleSelectionForSubsection(SubsectionHeader header) {
boolean newSelectedState = !isHeaderSelected(header);
setSelectionForHeader(header, newSelectedState);
for (DownloadHistoryItemWrapper item : header.getItems()) {
if (newSelectedState != isItemSelected(item)) {
toggleSelectionForItem(item);
}
}
return isHeaderSelected(header);
}
/**
* Sets the selection state for a given header. Doesn't affect the associated items. This method
* is supposed to be called if the header needs to be toggled as a result of selecting or
* deselecting one of the associated items. In case of a long press on the header, don't call
* this method, call {@link #toggleSelectionForSubsection(SubsectionHeader)} instead directly.
* @param header The given {@link SubsectionHeader}.
* @param selected The new selected state.
*/
public void setSelectionForHeader(SubsectionHeader header, boolean selected) {
if (selected) {
mSelectedHeaders.add(header);
} else {
mSelectedHeaders.remove(header);
}
}
private void notifySubsectionHeaderSelectionStateChanged() {
for (SubsectionHeaderSelectionObserver observer : mObservers) {
observer.onSubsectionHeaderSelectionStateChanged(mSelectedHeaders);
}
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MenuItem;
import android.view.View;
import android.widget.Spinner;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
import org.chromium.chrome.download.R;
import java.util.List;
/**
* Handles toolbar functionality for the {@link DownloadManagerUi}.
*/
public class DownloadManagerToolbar extends SelectableListToolbar<DownloadHistoryItemWrapper> {
private Spinner mSpinner;
private DownloadManagerUi mManager;
private int mInfoMenuItemId;
public DownloadManagerToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
inflateMenu(R.menu.download_manager_menu);
}
/**
* @param manager The {@link DownloadManagerUi} associated with this toolbar.
*/
public void setManager(DownloadManagerUi manager) {
mManager = manager;
}
/**
* Initializes UI elements in download toolbar.
* @param adapter The adapter associated with the spinner.
*/
public void initialize(FilterAdapter adapter) {
// Initialize the spinner.
mSpinner = findViewById(R.id.spinner);
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(adapter);
}
/**
* Removes a menu item from the toolbar.
* @param menuItemId The menu item to be removed. Nothing happens if there is no menu item
* associated with this ID.
*/
public void removeMenuItem(int menuItemId) {
getMenu().removeItem(menuItemId);
}
/** Called whenever the selected filter on this adapter should change. */
public void onFilterChanged(int filter) {
mSpinner.setSelection(filter);
}
/** Called when this object should be destroyed. */
@Override
public void destroy() {
super.destroy();
mSpinner.setAdapter(null);
}
@Override
public void onSelectionStateChange(List<DownloadHistoryItemWrapper> selectedItems) {
boolean wasSelectionEnabled = mIsSelectionEnabled;
super.onSelectionStateChange(selectedItems);
mSpinner.setVisibility((mIsSelectionEnabled || isSearching()) ? GONE : VISIBLE);
if (mIsSelectionEnabled) {
int numSelected = mSelectionDelegate.getSelectedItems().size();
// If the share or delete menu items are shown in the overflow menu instead of as an
// action, there may not be views associated with them.
View shareButton = findViewById(R.id.selection_mode_share_menu_id);
if (shareButton != null) {
shareButton.setContentDescription(getResources().getQuantityString(
R.plurals.accessibility_share_selected_items,
numSelected, numSelected));
}
View deleteButton = findViewById(R.id.selection_mode_delete_menu_id);
if (deleteButton != null) {
deleteButton.setContentDescription(getResources().getQuantityString(
R.plurals.accessibility_remove_selected_items,
numSelected, numSelected));
}
if (!wasSelectionEnabled) {
RecordUserAction.record("Android.DownloadManager.SelectionEstablished");
}
}
}
@Override
public void setSearchEnabled(boolean searchEnabled) {
super.setSearchEnabled(searchEnabled);
MenuItem item = getMenu().findItem(mInfoMenuItemId);
if (item != null) item.setVisible(!isSearching() && !mIsSelectionEnabled && searchEnabled);
}
@Override
protected void showNormalView() {
super.showNormalView();
mManager.updateInfoButtonVisibility();
}
@Override
public void showSearchView() {
super.showSearchView();
mSpinner.setVisibility(GONE);
}
@Override
public void hideSearchView() {
super.hideSearchView();
mSpinner.setVisibility(VISIBLE);
}
@Override
public void setInfoMenuItem(int infoMenuItemId) {
super.setInfoMenuItem(infoMenuItemId);
mInfoMenuItemId = infoMenuItemId;
}
/** Returns the {@link Spinner}. */
@VisibleForTesting
public Spinner getSpinnerForTests() {
return mSpinner;
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Multiple download items may reference the same location on disk. This class maintains a mapping
* of file paths to download items that reference the file path.
* TODO(twellington): remove this class after the backend handles duplicate removal.
*/
class FilePathsToDownloadItemsMap {
private final Map<String, Set<DownloadHistoryItemWrapper>> mMap = new HashMap<>();
/**
* Adds a DownloadHistoryItemWrapper to the map if it has a valid path.
* @param wrapper The item to add to the map.
*/
void addItem(DownloadHistoryItemWrapper wrapper) {
if (TextUtils.isEmpty(wrapper.getFilePath())) return;
if (!mMap.containsKey(wrapper.getFilePath())) {
mMap.put(wrapper.getFilePath(), new HashSet<DownloadHistoryItemWrapper>());
}
mMap.get(wrapper.getFilePath()).add(wrapper);
}
/**
* Removes a DownloadHistoryItemWrapper from the map. Does nothing if the item does not exist in
* the map.
* @param wrapper The item to remove from the map.
*/
void removeItem(DownloadHistoryItemWrapper wrapper) {
Set<DownloadHistoryItemWrapper> matchingItems = mMap.get(wrapper.getFilePath());
if (matchingItems == null || !matchingItems.contains(wrapper)) return;
if (matchingItems.size() == 1) {
// If this is the only DownloadHistoryItemWrapper that references the file path,
// remove the file path from the map.
mMap.remove(wrapper.getFilePath());
} else {
matchingItems.remove(wrapper);
}
}
/**
* Gets all DownloadHistoryItemWrappers that point to the same path in the user's storage.
* @param filePath The file path used to retrieve items.
* @return DownloadHistoryItemWrappers associated with filePath.
*/
Set<DownloadHistoryItemWrapper> getItemsForFilePath(String filePath) {
return mMap.get(filePath);
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.content.res.Resources;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.download.R;
/** An adapter that allows selecting an item from a dropdown spinner. */
class FilterAdapter extends BaseAdapter implements AdapterView.OnItemSelectedListener {
private final int mIconColor;
private DownloadManagerUi mManagerUi;
/**
* @param resources The {@link Resources} used to retrieve resources.
*/
FilterAdapter(Resources resources) {
super();
mIconColor = ApiCompatibilityUtils.getColor(
resources, org.chromium.chrome.R.color.default_icon_color);
}
@Override
public int getCount() {
return DownloadFilter.getFilterCount();
}
@Override
public Object getItem(int position) {
return DownloadFilter.FILTER_LIST[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView labelView =
getTextViewFromResource(convertView, R.layout.download_manager_spinner_drop_down);
labelView.setText(DownloadFilter.getStringIdForFilter(position));
int iconId = DownloadFilter.getDrawableForFilter(position);
VectorDrawableCompat iconDrawable =
VectorDrawableCompat.create(mManagerUi.getActivity().getResources(), iconId,
mManagerUi.getActivity().getTheme());
DrawableCompat.setTint(iconDrawable, mIconColor);
labelView.setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null);
return labelView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView labelView =
getTextViewFromResource(convertView, R.layout.download_manager_spinner);
CharSequence title = mManagerUi.getActivity().getResources().getText(position == 0
? R.string.menu_downloads
: DownloadFilter.getStringIdForFilter(position));
labelView.setText(title);
return labelView;
}
private TextView getTextViewFromResource(View convertView, @LayoutRes int resId) {
TextView labelView = null;
if (convertView instanceof TextView) {
labelView = (TextView) convertView;
} else {
labelView =
(TextView) LayoutInflater.from(mManagerUi.getActivity()).inflate(resId, null);
}
return labelView;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mManagerUi.onFilterChanged(position);
}
public void initialize(DownloadManagerUi manager) {
mManagerUi = manager;
}
/** Called when this object should be destroyed. */
public void destroy() {
mManagerUi = null;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import org.chromium.chrome.browser.ChromeFeatureList;
/**
* Determines when the data from all of the backends has been loaded.
* <p>
* TODO(ianwen): add a timeout mechanism to either the DownloadLoadingDelegate or to the
* backend so that if it takes forever to load one of the backend, users are still able to see
* the other two.
*/
public class LoadingStateDelegate {
public static final int REGULAR_DOWNLOADS = 0b001;
public static final int INCOGNITO_DOWNLOADS = 0b010;
public static final int OFFLINE_ITEMS = 0b100;
private static final int ALL_LOADED = 0b111;
private int mLoadingState;
private @DownloadFilter.Type int mPendingFilter = DownloadFilter.Type.ALL;
/** @param offTheRecord Whether this delegate needs to consider incognito. */
public LoadingStateDelegate(boolean offTheRecord) {
// If we don't care about incognito, mark it as loaded.
mLoadingState = offTheRecord ? 0 : INCOGNITO_DOWNLOADS;
}
/**
* Tells this delegate one of the three backends has been loaded.
* @param backendFlag Which backend was loaded.
* @return Whether or not the backends are all loaded.
*/
public boolean updateLoadingState(int backendFlag) {
mLoadingState |= backendFlag;
return isLoaded();
}
/** @return Whether all backends are loaded. */
public boolean isLoaded() {
if (ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_OFFLINE_CONTENT_PROVIDER))
return true;
return mLoadingState == ALL_LOADED;
}
/** Caches a filter for when the backends have loaded. */
public void setPendingFilter(@DownloadFilter.Type int filter) {
mPendingFilter = filter;
}
/** @return The cached filter, or {@link DownloadFilter#FILTER_ALL} if none was set. */
public @DownloadFilter.Type int getPendingFilter() {
return mPendingFilter;
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.support.v7.content.res.AppCompatResources;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter.SubsectionHeader;
import org.chromium.chrome.browser.download.ui.DownloadItemSelectionDelegate.SubsectionHeaderSelectionObserver;
import org.chromium.chrome.browser.widget.DateDividedAdapter.TimedItem;
import org.chromium.chrome.browser.widget.selection.SelectableItemView;
import org.chromium.chrome.download.R;
import java.util.Set;
/**
* A header that presents users the option to view or hide the suggested offline pages.
*/
public class OfflineGroupHeaderView
extends SelectableItemView<TimedItem> implements SubsectionHeaderSelectionObserver {
private final int mIconBackgroundResId;
private final ColorStateList mIconForegroundColorList;
private final ColorStateList mCheckedIconForegroundColorList;
private SubsectionHeader mHeader;
private DownloadHistoryAdapter mAdapter;
private DownloadItemSelectionDelegate mSelectionDelegate;
private TextView mDescriptionTextView;
private ImageView mExpandImage;
private ImageView mIconImageView;
public OfflineGroupHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
mCheckedIconForegroundColorList = DownloadUtils.getIconForegroundColorList(context);
mIconBackgroundResId = R.drawable.list_item_icon_modern_bg;
mIconForegroundColorList =
AppCompatResources.getColorStateList(context, R.color.standard_mode_tint);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mIconImageView = findViewById(R.id.icon_view);
mDescriptionTextView = (TextView) findViewById(R.id.description);
mExpandImage = (ImageView) findViewById(R.id.expand_icon);
}
/**
* @param adapter The adapter associated with this header.
*/
public void setAdapter(DownloadHistoryAdapter adapter) {
mAdapter = adapter;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mSelectionDelegate != null) {
setChecked(mSelectionDelegate.isHeaderSelected(mHeader));
}
}
/**
* Updates the properties of this view.
* @param header The associated {@link SubsectionHeader}.
*/
@SuppressLint("StringFormatMatches")
public void displayHeader(SubsectionHeader header) {
this.mHeader = header;
// TODO(crbug.com/635567): Fix lint properly.
CharSequence timeSinceLastUpdate = DateUtils.getRelativeTimeSpanString(
header.getTimestamp(), System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);
String totalFileSize = Formatter.formatFileSize(getContext(), header.getTotalFileSize());
String description =
getContext().getString(R.string.download_manager_offline_header_description,
totalFileSize, timeSinceLastUpdate);
mDescriptionTextView.setText(description);
updateExpandIcon(header.isExpanded());
setChecked(mSelectionDelegate.isHeaderSelected(header));
}
private void updateExpandIcon(boolean expanded) {
mExpandImage.setImageResource(expanded ? R.drawable.ic_expand_less_black_24dp
: R.drawable.ic_expand_more_black_24dp);
mExpandImage.setContentDescription(
getResources().getString(expanded ? R.string.accessibility_collapse_section_header
: R.string.accessibility_expand_section_header));
}
@Override
protected void updateView(boolean animate) {
if (isChecked()) {
mIconImageView.setBackgroundResource(mIconBackgroundResId);
mIconImageView.getBackground().setLevel(
getResources().getInteger(R.integer.list_item_level_selected));
mIconImageView.setImageDrawable(mCheckDrawable);
ApiCompatibilityUtils.setImageTintList(mIconImageView, mCheckedIconForegroundColorList);
if (animate) mCheckDrawable.start();
} else {
mIconImageView.setBackgroundResource(mIconBackgroundResId);
mIconImageView.getBackground().setLevel(
getResources().getInteger(R.integer.list_item_level_default));
mIconImageView.setImageResource(R.drawable.ic_chrome);
ApiCompatibilityUtils.setImageTintList(mIconImageView, mIconForegroundColorList);
}
}
@Override
public void onClick() {
boolean newState = !mHeader.isExpanded();
mAdapter.setPrefetchSectionExpanded(newState);
}
@Override
protected boolean isSelectionModeActive() {
return mSelectionDelegate.isSelectionEnabled();
}
@Override
protected boolean toggleSelectionForItem(TimedItem item) {
return mSelectionDelegate.toggleSelectionForSubsection(mHeader);
}
/**
* Sets the selection delegate and registers |this| as
* an observer. The delegate must be set before the item can respond to click events.
* {@link SelectionDelegate} expects all the views to be of same type i.e.
* SelectableItemView<DownloadHistoryItemWrapper>, whereas DownloadItemSelectionDelegate can
* handle multiple types. This view being of type SelectableItemView<TimedItem>, we need
* to use a DownloadItemSelectionDelegate instead of SelectionDelegate.
* @param delegate The selection delegate that will inform this item of selection changes.
*/
public void setSelectionDelegate(DownloadItemSelectionDelegate delegate) {
if (mSelectionDelegate == delegate) return;
if (mSelectionDelegate != null) {
mSelectionDelegate.removeObserver(this);
}
mSelectionDelegate = delegate;
mSelectionDelegate.addObserver(this);
}
@Override
public void onSubsectionHeaderSelectionStateChanged(Set<SubsectionHeader> selectedHeaders) {
boolean isChecked = selectedHeaders.contains(mHeader);
setChecked(isChecked);
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.ui;
import android.content.Context;
import android.os.StatFs;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.base.Callback;
import org.chromium.base.Log;
import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.download.DownloadDirectoryProvider;
import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.widget.MaterialProgressBar;
import org.chromium.chrome.download.R;
import java.io.File;
import java.util.concurrent.RejectedExecutionException;
/** A View that manages the display of space used by the downloads. */
public class SpaceDisplay extends RecyclerView.AdapterDataObserver {
/** Observes changes to the SpaceDisplay. */
public static interface Observer {
/** Called when the display has had its values updated. */
void onSpaceDisplayUpdated(SpaceDisplay spaceDisplay);
}
private static final String TAG = "download_ui";
private static final int[] USED_STRINGS = {
R.string.download_manager_ui_space_used_kb,
R.string.download_manager_ui_space_used_mb,
R.string.download_manager_ui_space_used_gb
};
private static final int[] OTHER_STRINGS = {
R.string.download_manager_ui_space_other_kb,
R.string.download_manager_ui_space_other_mb,
R.string.download_manager_ui_space_other_gb
};
private static class StorageSizeTask extends AsyncTask<Long> {
/**
* If true, the task gets the total size of storage. If false, it fetches how much
* space is free.
*/
private boolean mFetchTotalSize;
private Callback<Long> mOnTaskCompleteCallback;
StorageSizeTask(boolean fetchTotalSize, Callback<Long> onTaskCompleteCallback) {
mFetchTotalSize = fetchTotalSize;
mOnTaskCompleteCallback = onTaskCompleteCallback;
}
@Override
protected Long doInBackground() {
File downloadDirectory = DownloadDirectoryProvider.getPrimaryDownloadDirectory();
// Determine how much space is available on the storage device where downloads
// reside. If the downloads directory doesn't exist, it is likely that the user
// doesn't have an SD card installed.
long blocks = 0;
if (downloadDirectory.exists()) {
StatFs statFs = new StatFs(downloadDirectory.getPath());
if (mFetchTotalSize) {
blocks = statFs.getBlockCountLong();
} else {
blocks = statFs.getAvailableBlocksLong();
}
return blocks * statFs.getBlockSizeLong();
} else {
Log.e(TAG, "Download directory doesn't exist.");
return 0L;
}
}
@Override
protected void onPostExecute(Long bytes) {
mOnTaskCompleteCallback.onResult(bytes);
}
};
private final ObserverList<Observer> mObservers = new ObserverList<>();
private AsyncTask<Long> mFreeBytesTask;
private DownloadHistoryAdapter mHistoryAdapter;
private View mView;
private View mViewContainer;
private TextView mSpaceUsedByDownloadsTextView;
private TextView mSpaceFreeAndOtherAppsTextView;
private MaterialProgressBar mSpaceBar;
private long mFreeBytes;
private long mFileSystemBytes;
SpaceDisplay(Context context, final ViewGroup parent, DownloadHistoryAdapter historyAdapter) {
mHistoryAdapter = historyAdapter;
mViewContainer = LayoutInflater.from(context).inflate(
R.layout.download_manager_ui_space_widget, parent, false);
mView = mViewContainer.findViewById(R.id.space_widget_content);
mSpaceUsedByDownloadsTextView = (TextView) mView.findViewById(R.id.size_downloaded);
mSpaceFreeAndOtherAppsTextView =
(TextView) mView.findViewById(R.id.size_free_and_other_apps);
mSpaceBar = (MaterialProgressBar) mView.findViewById(R.id.space_bar);
new StorageSizeTask(true, this ::onFileSystemBytesTaskFinished)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void onFileSystemBytesTaskFinished(Long bytes) {
mFileSystemBytes = bytes;
long bytesUsedByDownloads = Math.max(0, mHistoryAdapter.getTotalDownloadSize());
RecordHistogram.recordPercentageHistogram("Android.DownloadManager.SpaceUsed",
computePercentage(bytesUsedByDownloads, bytes));
updateSpaceDisplay();
}
private void onFreeBytesTaskFinished(Long bytes) {
mFreeBytes = bytes;
mFreeBytesTask = null;
updateSpaceDisplay();
}
/** @return The view container of space display view. */
public View getViewContainer() {
return mViewContainer;
}
/** Returns the view. */
public View getView() {
return mView;
}
@Override
public void onChanged() {
// Determine how much space is free now, then update the display.
if (mFreeBytesTask == null) {
mFreeBytesTask = new StorageSizeTask(false, this ::onFreeBytesTaskFinished);
try {
mFreeBytesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (RejectedExecutionException e) {
mFreeBytesTask = null;
}
}
}
@VisibleForTesting
public void addObserverForTests(Observer observer) {
mObservers.addObserver(observer);
}
private void updateSpaceDisplay() {
// Indicate how much space has been used by everything on the device via the progress bar.
long bytesUsedTotal = Math.max(0, mFileSystemBytes - mFreeBytes);
long bytesUsedByDownloads = Math.max(0, mHistoryAdapter.getTotalDownloadSize());
long bytesUsedByOtherApps = Math.max(0, bytesUsedTotal - bytesUsedByDownloads);
// Describe how much space has been used by downloads in text.
Context context = mSpaceUsedByDownloadsTextView.getContext();
mSpaceUsedByDownloadsTextView.setText(
DownloadUtils.getStringForBytes(context, USED_STRINGS, bytesUsedByDownloads));
String spaceFree = DownloadUtils.getStringForAvailableBytes(context, mFreeBytes);
String spaceUsedByOtherApps =
DownloadUtils.getStringForBytes(context, OTHER_STRINGS, bytesUsedByOtherApps);
mSpaceFreeAndOtherAppsTextView.setText(
context.getResources().getString(R.string.download_manager_ui_space_free_and_other,
spaceFree, spaceUsedByOtherApps));
// Set a minimum size for the download size so that it shows up in the progress bar.
long threePercentOfSystem = mFileSystemBytes == 0 ? 0 : mFileSystemBytes / 100 * 3;
long fudgedBytesUsedByDownloads = Math.max(bytesUsedByDownloads, threePercentOfSystem);
long fudgedBytesUsedByOtherApps = Math.max(bytesUsedByOtherApps, threePercentOfSystem);
// Indicate how much space has been used as a progress bar. The percentage used by
// downloads is shown by the non-overlapped area of the primary and secondary progressbar.
int percentageUsedTotal = computePercentage(
fudgedBytesUsedByDownloads + fudgedBytesUsedByOtherApps, mFileSystemBytes);
int percentageDownloaded = computePercentage(fudgedBytesUsedByDownloads, mFileSystemBytes);
mSpaceBar.setProgress(percentageUsedTotal);
mSpaceBar.setSecondaryProgress(percentageDownloaded);
for (Observer observer : mObservers) observer.onSpaceDisplayUpdated(this);
}
private int computePercentage(long numerator, long denominator) {
if (denominator == 0) return 0;
return (int) Math.min(100.0f, Math.max(0.0f, 100.0f * numerator / denominator));
}
}
...@@ -2388,9 +2388,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p ...@@ -2388,9 +2388,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_DOWNLOAD_UI_DETERMINATE_BYTES" desc="Appears in a notification when a user starts downloading a file. Indicates the number of bytes downloaded out of the total file size. E.g. 3/7 MB [downloaded]. As appropriate for your language, use '/' or 'of'; and change word order as needed."> <message name="IDS_DOWNLOAD_UI_DETERMINATE_BYTES" desc="Appears in a notification when a user starts downloading a file. Indicates the number of bytes downloaded out of the total file size. E.g. 3/7 MB [downloaded]. As appropriate for your language, use '/' or 'of'; and change word order as needed.">
<ph name="BYTES_DOWNLOADED_WITH_UNITS">%1$s<ex>12.2 MB</ex></ph> / <ph name="FILE_SIZE_WITH_UNITS">%2$s<ex>20.3 GB</ex></ph> <ph name="BYTES_DOWNLOADED_WITH_UNITS">%1$s<ex>12.2 MB</ex></ph> / <ph name="FILE_SIZE_WITH_UNITS">%2$s<ex>20.3 GB</ex></ph>
</message> </message>
<message name="IDS_PREFETCH_BADGE_NEW" desc="Message on download home to show that there are new prefetched contents">
New
</message>
<message name="IDS_FILE_SIZE_DOWNLOADED_KB" desc="Notification message showing how many KBs have been downloaded."> <message name="IDS_FILE_SIZE_DOWNLOADED_KB" desc="Notification message showing how many KBs have been downloaded.">
Downloaded <ph name="KBS">%1$.1f<ex>10.1</ex></ph> KB Downloaded <ph name="KBS">%1$.1f<ex>10.1</ex></ph> KB
</message> </message>
...@@ -2468,9 +2465,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p ...@@ -2468,9 +2465,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_OPEN_DOWNLOADED_LABEL" desc="A text label on the snackbar widget to open the downloaded file."> <message name="IDS_OPEN_DOWNLOADED_LABEL" desc="A text label on the snackbar widget to open the downloaded file.">
Open Open
</message> </message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_FREE_AND_OTHER" desc="Formatted string indicating how much storage is available to use on this device and how much storage space on this device has been used by other apps.">
<ph name="SPACE_FREE">%1$s<ex>4.8 GB available</ex></ph> (<ph name="SPACE_OTHER">%2$s<ex>5.22 GB other apps</ex></ph>)
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_FREE_KB" desc="String indicating how much storage is available to use on the device, in kilobytes."> <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_FREE_KB" desc="String indicating how much storage is available to use on the device, in kilobytes.">
<ph name="kilobytes">%1$3.2f<ex>12.5</ex></ph> KB available <ph name="kilobytes">%1$3.2f<ex>12.5</ex></ph> KB available
</message> </message>
...@@ -2480,24 +2474,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p ...@@ -2480,24 +2474,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_FREE_GB" desc="String indicating how much storage is available to use on the device, in gigabytes."> <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_FREE_GB" desc="String indicating how much storage is available to use on the device, in gigabytes.">
<ph name="gigabytes">%1$3.2f<ex>12.5</ex></ph> GB available <ph name="gigabytes">%1$3.2f<ex>12.5</ex></ph> GB available
</message> </message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_OTHER_KB" desc="String indicating that some amount of storage space on the device has been used by other apps, in kilobytes.">
<ph name="kilobytes">%1$3.2f<ex>0.3</ex></ph> KB other apps
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_OTHER_MB" desc="String indicating that some amount of storage space on the device has been used by other apps, in megabytes.">
<ph name="megabytes">%1$3.2f<ex>0.3</ex></ph> MB other apps
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_OTHER_GB" desc="String indicating that some amount of storage space on the device has been used by other apps, in gigabytes.">
<ph name="gigabytes">%1$3.2f<ex>0.3</ex></ph> GB other apps
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USED_KB" desc="String indicating that some amount of storage space on the device has been used by downloads, in kilobytes.">
<ph name="kilobytes">%1$3.2f<ex>0.3</ex></ph> KB downloaded
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USED_MB" desc="String indicating that some amount of storage space on the device has been used by downloads, in megabytes.">
<ph name="megabytes">%1$3.2f<ex>0.3</ex></ph> MB downloaded
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USED_GB" desc="String indicating that some amount of storage space on the device has been used by downloads, in gigabytes.">
<ph name="gigabytes">%1$3.2f<ex>0.3</ex></ph> GB downloaded
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USING" desc="String indicating the amount of storage space used by downloads out of total available storage."> <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USING" desc="String indicating the amount of storage space used by downloads out of total available storage.">
Using <ph name="SPACE_USED">%1$s<ex>0.3MB</ex></ph> of <ph name="SPACE_AVAILABLE">%2$s<ex>3 GB</ex></ph> Using <ph name="SPACE_USED">%1$s<ex>0.3MB</ex></ph> of <ph name="SPACE_AVAILABLE">%2$s<ex>3 GB</ex></ph>
</message> </message>
...@@ -2549,15 +2525,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p ...@@ -2549,15 +2525,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_DOWNLOAD_MANAGER_SEARCH" desc="Placeholder text for the input field that allows users to search downloads."> <message name="IDS_DOWNLOAD_MANAGER_SEARCH" desc="Placeholder text for the input field that allows users to search downloads.">
Search your downloads Search your downloads
</message> </message>
<message name="IDS_DOWNLOAD_MANAGER_NO_RESULTS" desc="Text explaining that no download items matched a search query.">
No downloads found
</message>
<message name="IDS_DOWNLOAD_MANAGER_OFFLINE_HEADER_TITLE" desc="The title for suggested offline pages header.">
Popular pages from Chrome
</message>
<message name="IDS_DOWNLOAD_MANAGER_OFFLINE_HEADER_DESCRIPTION" desc="Text containing the offline pages description.">
<ph name="FILE_SIZE">%1$s<ex>1.56 MB</ex></ph> - Updated <ph name="TIME_SINCE_UPDATE">%2$s<ex>4 minutes ago</ex></ph>
</message>
<message name="IDS_DOWNLOAD_MANAGER_LIST_ITEM_DESCRIPTION" desc="Text containing the download list item description."> <message name="IDS_DOWNLOAD_MANAGER_LIST_ITEM_DESCRIPTION" desc="Text containing the download list item description.">
<ph name="FILE_SIZE">%1$s<ex>1.56 MB</ex></ph> <ph name="SEPARATOR"></ph> <ph name="DESCRIPTION">%2$s<ex>www.example.com</ex></ph> <ph name="FILE_SIZE">%1$s<ex>1.56 MB</ex></ph> <ph name="SEPARATOR"></ph> <ph name="DESCRIPTION">%2$s<ex>www.example.com</ex></ph>
</message> </message>
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
package org.chromium.chrome.browser.download; package org.chromium.chrome.browser.download;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.text.format.DateUtils; import android.text.format.DateUtils;
...@@ -18,20 +16,13 @@ import org.junit.Test; ...@@ -18,20 +16,13 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper;
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflineItemWrapper;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItem.Progress; import org.chromium.components.offline_items_collection.OfflineItem.Progress;
import org.chromium.components.offline_items_collection.OfflineItemProgressUnit; import org.chromium.components.offline_items_collection.OfflineItemProgressUnit;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Tests of {@link DownloadUtils}. * Tests of {@link DownloadUtils}.
...@@ -142,66 +133,4 @@ public class DownloadUtilsTest { ...@@ -142,66 +133,4 @@ public class DownloadUtilsTest {
Assert.assertEquals(100, progress.getPercentage()); Assert.assertEquals(100, progress.getPercentage());
Assert.assertEquals("0 files left", DownloadUtils.formatRemainingFiles(context, progress)); Assert.assertEquals("0 files left", DownloadUtils.formatRemainingFiles(context, progress));
} }
@Test
@SmallTest
@Feature({"Download"})
public void testCreateShareIntentHasTitle() {
// Create an item list with a single item.
List<DownloadHistoryItemWrapper> items = new ArrayList<DownloadHistoryItemWrapper>();
OfflineItem offlineItem = new OfflineItem();
offlineItem.title = OFFLINE_ITEM_TITLE;
offlineItem.description = OFFLINE_ITEM_DESCRIPTION;
offlineItem.filePath = FILE_PATH;
offlineItem.mimeType = MULTIPART_RELATED;
OfflineItemWrapper itemWrapper =
OfflineItemWrapper.createOfflineItemWrapperForTest(offlineItem);
items.add(itemWrapper);
// Create a map matching the id to a filename.
Map<String, String> offlineFilePathMap = new HashMap<String, String>();
offlineFilePathMap.put(ITEM_ID, FILE_PATH);
// Call the share function.
Intent shareIntent = DownloadUtils.createShareIntent(items, offlineFilePathMap);
// Check the resulting share intent.
Assert.assertEquals("multipart/related", shareIntent.getType());
Assert.assertEquals(Intent.ACTION_SEND, shareIntent.getAction());
// Check that the resulting share intent has extra subject set for the title.
Bundle extras = shareIntent.getExtras();
Assert.assertNotNull(extras);
String subject = extras.getString(Intent.EXTRA_SUBJECT);
Assert.assertEquals(OFFLINE_ITEM_TITLE, subject);
}
@Test
@SmallTest
@Feature({"Download"})
@CommandLineFlags.Add({"enable-features=OfflinePagesSharing"})
public void testCreateShareIntentOfflinePageWithContentUri() {
// Create an item list with a single item representing an offline page.
List<DownloadHistoryItemWrapper> items = new ArrayList<DownloadHistoryItemWrapper>();
// OfflineItem represents an offline page.
OfflineItem offlineItem = new OfflineItem();
offlineItem.title = OFFLINE_ITEM_TITLE;
offlineItem.description = OFFLINE_ITEM_DESCRIPTION;
offlineItem.filePath = TEMP_FILE_PATH;
offlineItem.mimeType = MULTIPART_RELATED;
offlineItem.isSuggested = true;
OfflineItemWrapper itemWrapper =
OfflineItemWrapper.createOfflineItemWrapperForTest(offlineItem);
items.add(itemWrapper);
// Create a map matching the id to a filename.
Map<String, String> offlineFilePathMap = new HashMap<String, String>();
// Call the share function.
Intent shareIntent = DownloadUtils.createShareIntent(items, offlineFilePathMap);
// Check the resulting share intent.
Assert.assertEquals("multipart/related", shareIntent.getType());
Assert.assertEquals(Intent.ACTION_SEND, shareIntent.getAction());
}
} }
...@@ -16,8 +16,6 @@ import org.chromium.base.test.util.CallbackHelper; ...@@ -16,8 +16,6 @@ import org.chromium.base.test.util.CallbackHelper;
import org.chromium.chrome.browser.download.DownloadInfo; import org.chromium.chrome.browser.download.DownloadInfo;
import org.chromium.chrome.browser.download.DownloadItem; import org.chromium.chrome.browser.download.DownloadItem;
import org.chromium.chrome.browser.download.DownloadManagerService.DownloadObserver; import org.chromium.chrome.browser.download.DownloadManagerService.DownloadObserver;
import org.chromium.chrome.browser.widget.ThumbnailProvider;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.download.DownloadState; import org.chromium.components.download.DownloadState;
import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.LaunchLocation; import org.chromium.components.offline_items_collection.LaunchLocation;
...@@ -184,82 +182,18 @@ public class StubbedProvider implements BackendProvider { ...@@ -184,82 +182,18 @@ public class StubbedProvider implements BackendProvider {
} }
} }
/** Stubs out all attempts to get thumbnails for files. */
public static class StubbedThumbnailProvider implements ThumbnailProvider {
@Override
public void destroy() {}
@Override
public void getThumbnail(ThumbnailRequest request) {}
@Override
public void removeThumbnailsFromDisk(String contentId) {}
@Override
public void cancelRetrieval(ThumbnailRequest request) {}
}
/** Stubs out the UIDelegate. */
public class StubbedUIDelegate implements UIDelegate {
@Override
public void deleteItem(DownloadHistoryItemWrapper item) {
mHandler.post(() -> item.removePermanently());
}
@Override
public void shareItem(DownloadHistoryItemWrapper item) {}
}
private static final long ONE_GIGABYTE = 1024L * 1024L * 1024L; private static final long ONE_GIGABYTE = 1024L * 1024L * 1024L;
private final Handler mHandler; private final Handler mHandler;
private final StubbedDownloadDelegate mDownloadDelegate; private final StubbedDownloadDelegate mDownloadDelegate;
private final StubbedOfflineContentProvider mOfflineContentProvider; private final StubbedOfflineContentProvider mOfflineContentProvider;
private final SelectionDelegate<DownloadHistoryItemWrapper> mSelectionDelegate;
private final StubbedThumbnailProvider mStubbedThumbnailProvider;
private UIDelegate mUIDelegate;
public StubbedProvider() { public StubbedProvider() {
mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper());
mDownloadDelegate = new StubbedDownloadDelegate(); mDownloadDelegate = new StubbedDownloadDelegate();
mOfflineContentProvider = new StubbedOfflineContentProvider(); mOfflineContentProvider = new StubbedOfflineContentProvider();
mSelectionDelegate = new DownloadItemSelectionDelegate();
mStubbedThumbnailProvider = new StubbedThumbnailProvider();
mUIDelegate = new StubbedUIDelegate();
}
public void setUIDelegate(UIDelegate delegate) {
mUIDelegate = delegate;
}
@Override
public StubbedDownloadDelegate getDownloadDelegate() {
return mDownloadDelegate;
}
@Override
public StubbedOfflineContentProvider getOfflineContentProvider() {
return mOfflineContentProvider;
} }
@Override
public SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate() {
return mSelectionDelegate;
}
@Override
public StubbedThumbnailProvider getThumbnailProvider() {
return mStubbedThumbnailProvider;
}
@Override
public UIDelegate getUIDelegate() {
return mUIDelegate;
}
@Override
public void destroy() {}
/** See {@link #createDownloadItem(int, String, boolean, int, int)}. */ /** See {@link #createDownloadItem(int, String, boolean, int, int)}. */
public static DownloadItem createDownloadItem(int which, String date) throws Exception { public static DownloadItem createDownloadItem(int which, String date) throws Exception {
return createDownloadItem(which, date, false, DownloadState.COMPLETE, 100); return createDownloadItem(which, date, false, DownloadState.COMPLETE, 100);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment