Commit 367bfa1d authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Video Tutorials : Replaced thumbnails to use AsyncImageView

This CL adds :
1- Replaces thumbnails to use AsyncImageView on IPH card, and list view.
2- Removes the dependency on LargeMediaPlayButton style from downloads.

Bug: 1134412
Change-Id: Ibd9e5dbaeddd47564406ce201e10ec207df785b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2444536
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarCalder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814764}
parent c1183175
...@@ -92,7 +92,6 @@ if (is_android) { ...@@ -92,7 +92,6 @@ if (is_android) {
] ]
deps = [ deps = [
"//chrome/browser/download/android:java_resources",
"//chrome/browser/ui/android/strings:ui_strings_grd", "//chrome/browser/ui/android/strings:ui_strings_grd",
"//components/browser_ui/widget/android:java_resources", "//components/browser_ui/widget/android:java_resources",
"//ui/android:ui_java_resources", "//ui/android:ui_java_resources",
......
...@@ -16,12 +16,14 @@ ...@@ -16,12 +16,14 @@
android:paddingEnd="@dimen/promo_compact_padding" android:paddingEnd="@dimen/promo_compact_padding"
android:paddingBottom="@dimen/promo_compact_padding"> android:paddingBottom="@dimen/promo_compact_padding">
<org.chromium.components.browser_ui.widget.RoundedCornerImageView <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
android:id="@+id/thumbnail" android:id="@+id/thumbnail"
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="58dp" android:layout_height="58dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:importantForAccessibility="no" android:importantForAccessibility="no"
app:unavailableSrc="@color/image_loading_color"
app:waitingSrc="@color/image_loading_color"
app:roundedfillColor="@color/modern_grey_300" app:roundedfillColor="@color/modern_grey_300"
app:cornerRadiusBottomStart="@dimen/default_rounded_corner_radius" app:cornerRadiusBottomStart="@dimen/default_rounded_corner_radius"
app:cornerRadiusBottomEnd="@dimen/default_rounded_corner_radius" app:cornerRadiusBottomEnd="@dimen/default_rounded_corner_radius"
......
...@@ -91,6 +91,7 @@ if (is_android) { ...@@ -91,6 +91,7 @@ if (is_android) {
"//chrome/browser/image_fetcher:java", "//chrome/browser/image_fetcher:java",
"//chrome/browser/profiles/android:java", "//chrome/browser/profiles/android:java",
"//chrome/browser/video_tutorials:java", "//chrome/browser/video_tutorials:java",
"//components/browser_ui/widget/android:java",
"//components/embedder_support/android:content_view_java", "//components/embedder_support/android:content_view_java",
"//components/embedder_support/android:web_contents_delegate_java", "//components/embedder_support/android:web_contents_delegate_java",
"//components/thin_webview:factory_java", "//components/thin_webview:factory_java",
...@@ -110,6 +111,7 @@ if (is_android) { ...@@ -110,6 +111,7 @@ if (is_android) {
android_resources("java_resources") { android_resources("java_resources") {
create_srcjar = false create_srcjar = false
sources = [ sources = [
"android/java/res/drawable/circular_media_button_background.xml",
"android/java/res/drawable/radio_button.xml", "android/java/res/drawable/radio_button.xml",
"android/java/res/drawable/radio_button_default.xml", "android/java/res/drawable/radio_button_default.xml",
"android/java/res/drawable/radio_button_selected.xml", "android/java/res/drawable/radio_button_selected.xml",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 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. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:shape="oval">
<solid android:color="@android:color/white" />
<size android:width="48dp"
android:height="48dp" />
</shape>
</item>
</layer-list>
\ No newline at end of file
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
app:columnCount="1" app:columnCount="1"
app:rowCount="2"> app:rowCount="2">
<org.chromium.ui.widget.ChromeImageView <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
android:id="@+id/thumbnail" android:id="@+id/thumbnail"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dp" android:layout_height="200dp"
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
android:layout_marginEnd="1dp" android:layout_marginEnd="1dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:importantForAccessibility="no"
app:unavailableSrc="@color/image_loading_color"
app:waitingSrc="@color/image_loading_color"
app:layout_column="0" app:layout_column="0"
app:layout_row="0" app:layout_row="0"
app:layout_gravity="center" app:layout_gravity="center"
...@@ -33,12 +36,16 @@ ...@@ -33,12 +36,16 @@
<org.chromium.ui.widget.ChromeImageButton <org.chromium.ui.widget.ChromeImageButton
android:id="@+id/action_button" android:id="@+id/action_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/ic_play_arrow_white_36dp"
android:tint="@color/modern_grey_800"
app:layout_column="0" app:layout_column="0"
app:layout_row="0" app:layout_row="0"
app:layout_gravity="center" app:layout_gravity="center"
android:elevation="2dp" android:elevation="2dp"
android:clickable="false" android:clickable="false"
style="@style/LargeMediaPlayButton"/> android:background="@drawable/circular_media_button_background" />
<TextView <TextView
android:id="@+id/video_length" android:id="@+id/video_length"
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
package org.chromium.chrome.browser.video_tutorials.iph; package org.chromium.chrome.browser.video_tutorials.iph;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.ViewStub; import android.view.ViewStub;
import org.chromium.base.Callback; import org.chromium.base.Callback;
...@@ -17,6 +20,7 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; ...@@ -17,6 +20,7 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
* inflate when the IPH is shown. * inflate when the IPH is shown.
*/ */
public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator { public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
private final Context mContext;
private final PropertyModel mModel; private final PropertyModel mModel;
private final VideoIPHView mView; private final VideoIPHView mView;
private final ImageFetcher mImageFetcher; private final ImageFetcher mImageFetcher;
...@@ -32,6 +36,7 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator { ...@@ -32,6 +36,7 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
*/ */
public VideoIPHCoordinatorImpl(ViewStub viewStub, ImageFetcher imageFetcher, public VideoIPHCoordinatorImpl(ViewStub viewStub, ImageFetcher imageFetcher,
Callback<Tutorial> onClickListener, Callback<Tutorial> onDismissListener) { Callback<Tutorial> onClickListener, Callback<Tutorial> onDismissListener) {
mContext = viewStub.getContext();
mImageFetcher = imageFetcher; mImageFetcher = imageFetcher;
mOnClickListener = onClickListener; mOnClickListener = onClickListener;
mOnDismissListener = onDismissListener; mOnDismissListener = onDismissListener;
...@@ -51,10 +56,17 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator { ...@@ -51,10 +56,17 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
mModel.set( mModel.set(
VideoIPHProperties.DISMISS_LISTENER, () -> mOnDismissListener.onResult(tutorial)); VideoIPHProperties.DISMISS_LISTENER, () -> mOnDismissListener.onResult(tutorial));
mModel.set(VideoIPHProperties.THUMBNAIL, null); mModel.set(VideoIPHProperties.THUMBNAIL_PROVIDER, (consumer, widthPx, heightPx) -> {
ImageFetcher.Params params = ImageFetcher.Params.create( return () -> {
tutorial.posterUrl, ImageFetcher.VIDEO_TUTORIALS_IPH_UMA_CLIENT_NAME); ImageFetcher.Params params = ImageFetcher.Params.create(tutorial.posterUrl,
mImageFetcher.fetchImage( ImageFetcher.VIDEO_TUTORIALS_IPH_UMA_CLIENT_NAME, widthPx, heightPx);
params, bitmap -> mModel.set(VideoIPHProperties.THUMBNAIL, bitmap)); mImageFetcher.fetchImage(params, bitmap -> {
Drawable drawable = bitmap == null
? null
: new BitmapDrawable(mContext.getResources(), bitmap);
consumer.onResult(drawable);
});
};
});
} }
} }
\ No newline at end of file
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
package org.chromium.chrome.browser.video_tutorials.iph; package org.chromium.chrome.browser.video_tutorials.iph;
import android.graphics.Bitmap; import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
...@@ -23,8 +22,8 @@ class VideoIPHProperties { ...@@ -23,8 +22,8 @@ class VideoIPHProperties {
public static final WritableObjectPropertyKey<String> VIDEO_LENGTH = public static final WritableObjectPropertyKey<String> VIDEO_LENGTH =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** The thumbnail associated with the tutorial. */ /** The thumbnail provider to supply thumbnail images. */
public static final WritableObjectPropertyKey<Bitmap> THUMBNAIL = public static final WritableObjectPropertyKey<AsyncImageView.Factory> THUMBNAIL_PROVIDER =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** The listener to be invoked when the IPH is clicked. */ /** The listener to be invoked when the IPH is clicked. */
...@@ -36,6 +35,6 @@ class VideoIPHProperties { ...@@ -36,6 +35,6 @@ class VideoIPHProperties {
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** All keys associated with the model. */ /** All keys associated with the model. */
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] { public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {VISIBILITY, DISPLAY_TITLE,
VISIBILITY, DISPLAY_TITLE, VIDEO_LENGTH, THUMBNAIL, CLICK_LISTENER, DISMISS_LISTENER}; VIDEO_LENGTH, THUMBNAIL_PROVIDER, CLICK_LISTENER, DISMISS_LISTENER};
} }
...@@ -4,16 +4,12 @@ ...@@ -4,16 +4,12 @@
package org.chromium.chrome.browser.video_tutorials.iph; package org.chromium.chrome.browser.video_tutorials.iph;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.view.View; import android.view.View;
import android.view.ViewStub; import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.Nullable;
import org.chromium.chrome.browser.video_tutorials.R; import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -46,14 +42,8 @@ class VideoIPHView { ...@@ -46,14 +42,8 @@ class VideoIPHView {
view.setText(videoLength); view.setText(videoLength);
} }
private void setThumbnail(@Nullable Bitmap bitmap) { private View getThumbnailView() {
ImageView view = mCardView.findViewById(R.id.thumbnail); return mCardView.findViewById(R.id.thumbnail);
if (bitmap == null) {
view.setImageDrawable(
new ColorDrawable(view.getResources().getColor(R.color.image_loading_color)));
} else {
view.setImageBitmap(bitmap);
}
} }
private void setClickListener(Runnable clickListener) { private void setClickListener(Runnable clickListener) {
...@@ -76,12 +66,14 @@ class VideoIPHView { ...@@ -76,12 +66,14 @@ class VideoIPHView {
view.setTitle(model.get(VideoIPHProperties.DISPLAY_TITLE)); view.setTitle(model.get(VideoIPHProperties.DISPLAY_TITLE));
} else if (propertyKey == VideoIPHProperties.VIDEO_LENGTH) { } else if (propertyKey == VideoIPHProperties.VIDEO_LENGTH) {
view.setVideoLength(model.get(VideoIPHProperties.VIDEO_LENGTH)); view.setVideoLength(model.get(VideoIPHProperties.VIDEO_LENGTH));
} else if (propertyKey == VideoIPHProperties.THUMBNAIL) {
view.setThumbnail(model.get(VideoIPHProperties.THUMBNAIL));
} else if (propertyKey == VideoIPHProperties.CLICK_LISTENER) { } else if (propertyKey == VideoIPHProperties.CLICK_LISTENER) {
view.setClickListener(model.get(VideoIPHProperties.CLICK_LISTENER)); view.setClickListener(model.get(VideoIPHProperties.CLICK_LISTENER));
} else if (propertyKey == VideoIPHProperties.DISMISS_LISTENER) { } else if (propertyKey == VideoIPHProperties.DISMISS_LISTENER) {
view.setDismissListener(model.get(VideoIPHProperties.DISMISS_LISTENER)); view.setDismissListener(model.get(VideoIPHProperties.DISMISS_LISTENER));
} else if (propertyKey == VideoIPHProperties.THUMBNAIL_PROVIDER) {
AsyncImageView thumbnailView = (AsyncImageView) view.getThumbnailView();
thumbnailView.setAsyncImageDrawable(
model.get(VideoIPHProperties.THUMBNAIL_PROVIDER), null);
} }
} }
} }
...@@ -4,9 +4,7 @@ ...@@ -4,9 +4,7 @@
package org.chromium.chrome.browser.video_tutorials.list; package org.chromium.chrome.browser.video_tutorials.list;
import android.graphics.drawable.Drawable; import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.base.Callback;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
...@@ -17,12 +15,6 @@ class TutorialCardProperties { ...@@ -17,12 +15,6 @@ class TutorialCardProperties {
/** The view type used by the recycler view to show the tutorial cards. */ /** The view type used by the recycler view to show the tutorial cards. */
public static final int VIDEO_TUTORIAL_CARD_VIEW_TYPE = 3; public static final int VIDEO_TUTORIAL_CARD_VIEW_TYPE = 3;
/** An interface to provide thumbnails for the videos. */
interface VisualsProvider {
/** Method to get visuals to display the thumbnail image. */
void getVisuals(Callback<Drawable> callback);
}
/** The title to be shown.*/ /** The title to be shown.*/
static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>(); static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>();
...@@ -33,8 +25,8 @@ class TutorialCardProperties { ...@@ -33,8 +25,8 @@ class TutorialCardProperties {
static final WritableObjectPropertyKey<Runnable> CLICK_CALLBACK = static final WritableObjectPropertyKey<Runnable> CLICK_CALLBACK =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** The provider to retrieve the visuals for the video thumbnail.*/ /** The thumbnail provider to supply thumbnail images. */
static final WritableObjectPropertyKey<VisualsProvider> VISUALS_PROVIDER = public static final WritableObjectPropertyKey<AsyncImageView.Factory> VISUALS_PROVIDER =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
static final PropertyKey[] ALL_KEYS = static final PropertyKey[] ALL_KEYS =
......
...@@ -4,14 +4,13 @@ ...@@ -4,14 +4,13 @@
package org.chromium.chrome.browser.video_tutorials.list; package org.chromium.chrome.browser.video_tutorials.list;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import org.chromium.chrome.browser.video_tutorials.R; import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -37,11 +36,9 @@ class TutorialCardViewBinder { ...@@ -37,11 +36,9 @@ class TutorialCardViewBinder {
view.setOnClickListener( view.setOnClickListener(
v -> { model.get(TutorialCardProperties.CLICK_CALLBACK).run(); }); v -> { model.get(TutorialCardProperties.CLICK_CALLBACK).run(); });
} else if (propertyKey == TutorialCardProperties.VISUALS_PROVIDER) { } else if (propertyKey == TutorialCardProperties.VISUALS_PROVIDER) {
final ImageView thumbnail = view.findViewById(R.id.thumbnail); AsyncImageView thumbnailView = (AsyncImageView) view.findViewById(R.id.thumbnail);
thumbnail.setImageDrawable(new ColorDrawable(thumbnail.getResources().getColor( thumbnailView.setAsyncImageDrawable(
org.chromium.components.browser_ui.widget.R.color.image_loading_color))); model.get(TutorialCardProperties.VISUALS_PROVIDER), null);
model.get(TutorialCardProperties.VISUALS_PROVIDER)
.getVisuals(thumbnail::setImageDrawable);
} else { } else {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Cannot update the view for propertyKey: " + propertyKey); "Cannot update the view for propertyKey: " + propertyKey);
......
...@@ -12,6 +12,7 @@ import org.chromium.base.Callback; ...@@ -12,6 +12,7 @@ import org.chromium.base.Callback;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher; import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.video_tutorials.Tutorial; import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService; import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.chrome.browser.video_tutorials.iph.VideoTutorialIPHUtils;
import org.chromium.ui.modelutil.MVCListAdapter; import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -54,23 +55,24 @@ public class TutorialListMediator { ...@@ -54,23 +55,24 @@ public class TutorialListMediator {
} }
private PropertyModel buildModelFromTutorial(Tutorial tutorial) { private PropertyModel buildModelFromTutorial(Tutorial tutorial) {
return new PropertyModel.Builder(TutorialCardProperties.ALL_KEYS) PropertyModel.Builder builder =
new PropertyModel.Builder(TutorialCardProperties.ALL_KEYS)
.with(TutorialCardProperties.TITLE, tutorial.displayTitle) .with(TutorialCardProperties.TITLE, tutorial.displayTitle)
// TODO(shaktisahu): Provide a string in mm:ss format. .with(TutorialCardProperties.VIDEO_LENGTH,
.with(TutorialCardProperties.VIDEO_LENGTH, Integer.toString(tutorial.videoLength)) VideoTutorialIPHUtils.getVideoLengthString(tutorial.videoLength))
.with(TutorialCardProperties.CLICK_CALLBACK, .with(TutorialCardProperties.CLICK_CALLBACK,
() -> mClickCallback.onResult(tutorial)) () -> mClickCallback.onResult(tutorial));
.with(TutorialCardProperties.VISUALS_PROVIDER,
callback -> getBitmap(tutorial, callback))
.build();
}
private void getBitmap(Tutorial tutorial, Callback<Drawable> callback) { builder.with(TutorialCardProperties.VISUALS_PROVIDER, (consumer, widthPx, heightPx) -> {
ImageFetcher.Params params = ImageFetcher.Params.create( return () -> {
tutorial.posterUrl, ImageFetcher.VIDEO_TUTORIALS_LIST_UMA_CLIENT_NAME); ImageFetcher.Params params = ImageFetcher.Params.create(tutorial.posterUrl,
ImageFetcher.VIDEO_TUTORIALS_LIST_UMA_CLIENT_NAME, widthPx, heightPx);
mImageFetcher.fetchImage(params, bitmap -> { mImageFetcher.fetchImage(params, bitmap -> {
Drawable drawable = new BitmapDrawable(mContext.getResources(), bitmap); Drawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
callback.onResult(drawable); consumer.onResult(drawable);
});
};
}); });
return builder.build();
} }
} }
\ No newline at end of file
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