Commit febcd854 authored by Pavel Yatsuk's avatar Pavel Yatsuk Committed by Commit Bot

Cleanup touchless context menu

In this change:
- Remove getActivity() from TouchlessContextMenuManager.Delegate and
  adjust consumers. Implementation of handleMenuItemClick should supply
  context
- Remove TouchlessExploreSitesSiteViewBinder and optimize code around
  it.

BUG=959317
R=dewittj@chromium.org,dominickn@chromium.org

Change-Id: Ie30ee4a5448fb67fc7d01b4ae2f9322fbfc556ed
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1615832Reviewed-by: default avatarJustin DeWitt <dewittj@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Commit-Queue: Pavel Yatsuk <pavely@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660978}
parent 7bac3179
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.explore_sites;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
......@@ -40,6 +39,7 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
private static final int MAX_TILE_COUNT = 8;
private static final int MAX_ROWS = 2;
private final ExploreSitesSiteViewBinder mSiteViewBinder;
private TextView mTitleView;
private TileGridLayout mTileView;
private RoundedIconGenerator mIconGenerator;
......@@ -148,6 +148,11 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
}
}
protected CategoryCardInteractionDelegate createInteractionDelegate(PropertyModel model) {
return new CategoryCardInteractionDelegate(
model.get(ExploreSitesSite.URL_KEY), model.get(ExploreSitesSite.TILE_INDEX_KEY));
}
// We use the MVC paradigm for the site tiles inside the category card. We don't use the MVC
// paradigm for the category card view itself since it is mismatched to the needs of the
// recycler view that we use for category cards. The controller for MVC is actually here, the
......@@ -172,16 +177,12 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
view.setOnFocusChangeListener(interactionDelegate);
}
}
protected CategoryCardInteractionDelegate createInteractionDelegate(PropertyModel model) {
return new CategoryCardInteractionDelegate(model.get(ExploreSitesSite.URL_KEY),
model.get(ExploreSitesSite.TILE_INDEX_KEY));
}
}
public ExploreSitesCategoryCardView(Context context, AttributeSet attrs) {
super(context, attrs);
mModelChangeProcessors = new ArrayList<>(MAX_TILE_COUNT);
mSiteViewBinder = new ExploreSitesSiteViewBinder();
}
@Override
......@@ -254,8 +255,8 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
siteModel.set(ExploreSitesSite.TILE_INDEX_KEY, tileIndex);
mModelChangeProcessors.add(PropertyModelChangeProcessor.create(
siteModel, tileView, createViewBinder((Activity) getContext())));
mModelChangeProcessors.add(
PropertyModelChangeProcessor.create(siteModel, tileView, mSiteViewBinder));
// Fetch icon if not present already.
if (siteModel.get(ExploreSitesSite.ICON_KEY) == null) {
......@@ -286,8 +287,4 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
RecordHistogram.recordLinearCountHistogram("ExploreSites.SiteTilesClickIndex",
cardIndex * MAX_TILE_COUNT + tileIndex, 1, 100, 100);
}
protected ExploreSitesSiteViewBinder createViewBinder(Activity activity) {
return new ExploreSitesSiteViewBinder();
}
}
......@@ -5,7 +5,7 @@
package org.chromium.chrome.browser.webapps;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
......@@ -14,6 +14,7 @@ import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
......@@ -72,13 +73,13 @@ public class AddToHomescreenDialog implements View.OnClickListener {
private RatingBar mAppRatingBar;
private ImageView mPlayLogoView;
private Activity mActivity;
private Context mContext;
private Delegate mDelegate;
private boolean mHasIcon;
public AddToHomescreenDialog(Activity activity, Delegate delegate) {
mActivity = activity;
public AddToHomescreenDialog(Context context, Delegate delegate) {
mContext = context;
mDelegate = delegate;
}
......@@ -89,12 +90,11 @@ public class AddToHomescreenDialog implements View.OnClickListener {
/**
* Shows the dialog for adding a shortcut to the home screen.
* @param activity The current activity in which to create the dialog.
*/
public void show() {
View view = mActivity.getLayoutInflater().inflate(R.layout.add_to_homescreen_dialog, null);
View view = LayoutInflater.from(mContext).inflate(R.layout.add_to_homescreen_dialog, null);
AlertDialog.Builder builder =
new AlertDialog.Builder(mActivity, R.style.Theme_Chromium_AlertDialog)
new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog)
.setTitle(AppBannerManager.getHomescreenLanguageOption())
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
......@@ -154,7 +154,7 @@ public class AddToHomescreenDialog implements View.OnClickListener {
mDialog.setView(view);
mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
mActivity.getResources().getString(R.string.add),
mContext.getResources().getString(R.string.add),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
......@@ -222,7 +222,7 @@ public class AddToHomescreenDialog implements View.OnClickListener {
// Update the text on the primary button.
Button button = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
button.setText(installText);
button.setContentDescription(mActivity.getString(
button.setContentDescription(mContext.getString(
R.string.app_banner_view_native_app_install_accessibility, installText));
// Clicking on the app title or the icon will open the Play Store for more details.
......
......@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.touchless;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import org.chromium.chrome.browser.ShortcutHelper;
......@@ -14,16 +14,14 @@ import org.chromium.chrome.browser.webapps.AddToHomescreenDialog;
* Add to homescreen manager specifically for touchless devices.
*/
class TouchlessAddToHomescreenManager implements AddToHomescreenDialog.Delegate {
protected final Activity mActivity;
private final Context mContext;
private final String mUrl;
private final String mTitle;
private final Bitmap mIconBitmap;
protected AddToHomescreenDialog mDialog;
public TouchlessAddToHomescreenManager(
Activity activity, String url, String title, Bitmap iconBitmap) {
mActivity = activity;
Context context, String url, String title, Bitmap iconBitmap) {
mContext = context;
mUrl = url;
mTitle = title;
mIconBitmap = iconBitmap;
......@@ -31,10 +29,10 @@ class TouchlessAddToHomescreenManager implements AddToHomescreenDialog.Delegate
// Starts the process of showing the dialog and adding the shortcut.
public void start() {
mDialog = new AddToHomescreenDialog(mActivity, this);
mDialog.show();
mDialog.onUserTitleAvailable(mTitle, mUrl, false);
mDialog.onIconAvailable(mIconBitmap);
AddToHomescreenDialog dialog = new AddToHomescreenDialog(mContext, this);
dialog.show();
dialog.onUserTitleAvailable(mTitle, mUrl, false);
dialog.onIconAvailable(mIconBitmap);
}
@Override
......@@ -43,12 +41,8 @@ class TouchlessAddToHomescreenManager implements AddToHomescreenDialog.Delegate
}
@Override
public void onNativeAppDetailsRequested() {
return;
}
public void onNativeAppDetailsRequested() {}
@Override
public void onDialogDismissed() {
mDialog = null;
}
public void onDialogDismissed() {}
}
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.touchless;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.DrawableRes;
......@@ -33,11 +32,6 @@ public class TouchlessContextMenuManager extends ContextMenuManager {
* Delegate for touchless-specific context menu items.
*/
public interface Delegate extends ContextMenuManager.Delegate {
/**
* @return Activity associated with this delegate. Used to display prompts.
*/
Activity getActivity();
/**
* @return Title associated with this delegate.
*/
......@@ -49,41 +43,42 @@ public class TouchlessContextMenuManager extends ContextMenuManager {
Bitmap getIconBitmap();
}
private final Context mContext;
private PropertyModel mTouchlessMenuModel;
private ModalDialogManager mModalDialogManager;
public TouchlessContextMenuManager(NativePageNavigationDelegate navigationDelegate,
public TouchlessContextMenuManager(Context context,
NativePageNavigationDelegate navigationDelegate,
TouchEnabledDelegate touchEnabledDelegate, Runnable closeContextMenuCallback,
String userActionPrefix) {
super(navigationDelegate, touchEnabledDelegate, closeContextMenuCallback, userActionPrefix);
mContext = context;
}
/**
* Creates PropertyModel for touchless context menu and displays it through modalDialogManager.
*
* @param modalDialogManager The ModalDialogManager to display context menu.
* @param context The Context used for loading resources (strings, drawables).
* @param delegate Delegate defines filter for displayed menu items and behavior for selects
* item.
*/
public void showTouchlessContextMenu(ModalDialogManager modalDialogManager, Context context,
ContextMenuManager.Delegate delegate) {
public void showTouchlessContextMenu(
ModalDialogManager modalDialogManager, ContextMenuManager.Delegate delegate) {
ArrayList<PropertyModel> menuItems = new ArrayList();
for (@ContextMenuItemId int itemId = 0; itemId < ContextMenuItemId.NUM_ENTRIES; itemId++) {
if (!shouldShowItem(itemId, delegate)) continue;
// Each menu item is assigned its own instance of TouchlessItemClickListener where
// itemId of this item is maintained.
PropertyModel menuItem = buildMenuItem(
context, itemId, new TouchlessItemClickListener(delegate, itemId));
PropertyModel menuItem =
buildMenuItem(itemId, new TouchlessItemClickListener(delegate, itemId));
menuItems.add(menuItem);
}
if (menuItems.size() == 0) return;
PropertyModel[] menuItemsArray = new PropertyModel[menuItems.size()];
menuItemsArray = menuItems.toArray(menuItemsArray);
mTouchlessMenuModel =
buildMenuModel(context, delegate.getContextMenuTitle(), menuItemsArray);
mTouchlessMenuModel = buildMenuModel(delegate.getContextMenuTitle(), menuItemsArray);
mModalDialogManager = modalDialogManager;
mModalDialogManager.showDialog(mTouchlessMenuModel, ModalDialogManager.ModalDialogType.APP);
......@@ -105,9 +100,8 @@ public class TouchlessContextMenuManager extends ContextMenuManager {
if (itemId == ContextMenuItemId.ADD_TO_MY_APPS) {
Delegate touchlessDelegate = (Delegate) delegate;
TouchlessAddToHomescreenManager touchlessAddToHomescreenManager =
new TouchlessAddToHomescreenManager(touchlessDelegate.getActivity(),
touchlessDelegate.getUrl(), touchlessDelegate.getTitle(),
touchlessDelegate.getIconBitmap());
new TouchlessAddToHomescreenManager(mContext, touchlessDelegate.getUrl(),
touchlessDelegate.getTitle(), touchlessDelegate.getIconBitmap());
touchlessAddToHomescreenManager.start();
return false;
}
......@@ -143,18 +137,17 @@ public class TouchlessContextMenuManager extends ContextMenuManager {
* Builds PropertyModel for individual menu item. String for item's label is loaded from
* resources by PropertyModel.Builder.
*/
private PropertyModel buildMenuItem(
Context context, @ContextMenuItemId int itemId, OnClickListener listener) {
private PropertyModel buildMenuItem(@ContextMenuItemId int itemId, OnClickListener listener) {
return new PropertyModel.Builder(DialogListItemProperties.ALL_KEYS)
.with(DialogListItemProperties.TEXT, context.getResources(),
.with(DialogListItemProperties.TEXT, mContext.getResources(),
getResourceIdForMenuItem(itemId))
.with(DialogListItemProperties.ICON, context, getIconIdForMenuItem(itemId))
.with(DialogListItemProperties.ICON, mContext, getIconIdForMenuItem(itemId))
.with(DialogListItemProperties.CLICK_LISTENER, listener)
.build();
}
/** Builds PropertyModel for context menu from list of PropertyModels for individual items. */
private PropertyModel buildMenuModel(Context context, String title, PropertyModel[] menuItems) {
private PropertyModel buildMenuModel(String title, PropertyModel[] menuItems) {
PropertyModel.Builder builder =
new PropertyModel.Builder(TouchlessDialogProperties.ALL_DIALOG_KEYS);
ActionNames names = new ActionNames();
......
......@@ -4,56 +4,29 @@
package org.chromium.chrome.browser.touchless;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.explore_sites.ExploreSitesCategoryCardView;
import org.chromium.chrome.browser.explore_sites.ExploreSitesSite;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.ui.modelutil.PropertyModel;
class TouchlessExploreSitesCategoryCardView extends ExploreSitesCategoryCardView {
public TouchlessExploreSitesCategoryCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected class TouchlessExploreSitesSiteViewBinder
extends ExploreSitesCategoryCardView.ExploreSitesSiteViewBinder {
Activity mActivity;
public TouchlessExploreSitesSiteViewBinder(Activity activity) {
mActivity = activity;
}
@Override
protected ExploreSitesCategoryCardView.CategoryCardInteractionDelegate
createInteractionDelegate(PropertyModel model) {
return new TouchlessCategoryCardInteractionDelegate((ChromeActivity) mActivity, model);
}
}
/**
* Delegate that's aware of fields necessary for the touchless context menu.
*/
protected class TouchlessCategoryCardInteractionDelegate
extends ExploreSitesCategoryCardView.CategoryCardInteractionDelegate
protected class TouchlessCategoryCardInteractionDelegate extends CategoryCardInteractionDelegate
implements TouchlessContextMenuManager.Delegate {
private ChromeActivity mActivity;
private PropertyModel mModel;
TouchlessCategoryCardInteractionDelegate(ChromeActivity activity, PropertyModel model) {
TouchlessCategoryCardInteractionDelegate(PropertyModel model) {
super(model.get(ExploreSitesSite.URL_KEY), model.get(ExploreSitesSite.TILE_INDEX_KEY));
mActivity = activity;
mModel = model;
}
@Override
public Activity getActivity() {
return mActivity;
}
@Override
public String getTitle() {
return mModel.get(ExploreSitesSite.TITLE_KEY);
......@@ -76,8 +49,12 @@ class TouchlessExploreSitesCategoryCardView extends ExploreSitesCategoryCardView
}
}
public TouchlessExploreSitesCategoryCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected ExploreSitesSiteViewBinder createViewBinder(Activity activity) {
return new TouchlessExploreSitesSiteViewBinder(activity);
protected CategoryCardInteractionDelegate createInteractionDelegate(PropertyModel model) {
return new TouchlessCategoryCardInteractionDelegate(model);
}
}
......@@ -19,23 +19,28 @@ import org.chromium.ui.modaldialog.ModalDialogManager;
* A variant of {@see ExploreSitesPage} that handles touchless context menus.
*/
public class TouchlessExploreSitesPage extends ExploreSitesPage {
private TouchlessContextMenuManager mTouchlessContextMenuManager;
private final ModalDialogManager mModalDialogManager;
private Context mContext;
private ModalDialogManager mModalDialogManager;
private TouchlessContextMenuManager mTouchlessContextMenuManager;
/**
* Create a new instance of the explore sites page.
*/
public TouchlessExploreSitesPage(ChromeActivity activity, NativePageHost host) {
super(activity, host);
mContext = activity;
mModalDialogManager = activity.getModalDialogManager();
}
@Override
protected void initialize(ChromeActivity activity, final NativePageHost host) {
mContext = activity;
super.initialize(activity, host);
}
@Override
protected ContextMenuManager createContextMenuManager(NativePageNavigationDelegate navDelegate,
Runnable closeContextMenuCallback, String contextMenuUserActionPrefix) {
mTouchlessContextMenuManager = new TouchlessContextMenuManager(navDelegate,
mTouchlessContextMenuManager = new TouchlessContextMenuManager(mContext, navDelegate,
(enabled) -> {}, closeContextMenuCallback, contextMenuUserActionPrefix);
return mTouchlessContextMenuManager;
}
......@@ -47,8 +52,7 @@ public class TouchlessExploreSitesPage extends ExploreSitesPage {
ContextMenuManager.Delegate delegate =
ContextMenuManager.getDelegateFromFocusedView(focusedView);
if (delegate == null) return;
mTouchlessContextMenuManager.showTouchlessContextMenu(
mModalDialogManager, mContext, delegate);
mTouchlessContextMenuManager.showTouchlessContextMenu(mModalDialogManager, delegate);
}
@Override
......
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.touchless;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.view.LayoutInflater;
import android.view.View;
......@@ -45,7 +44,6 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
public class TouchlessNewTabPage extends BasicNativePage {
private static final String TAG = "TouchlessNewTabPage";
private Context mContext;
private ModalDialogManager mModalDialogManager;
private String mTitle;
private int mBackgroundColor;
......@@ -68,7 +66,6 @@ public class TouchlessNewTabPage extends BasicNativePage {
protected void initialize(ChromeActivity activity, NativePageHost nativePageHost) {
TraceEvent.begin(TAG);
mContext = activity;
mModalDialogManager = activity.getModalDialogManager();
mTab = activity.getActivityTab();
Profile profile = mTab.getProfile();
......@@ -127,7 +124,7 @@ public class TouchlessNewTabPage extends BasicNativePage {
// Don't store a direct reference to the activity, because it might change later if the tab
// is reparented.
Runnable closeContextMenuCallback = () -> mTab.getActivity().closeContextMenu();
mContextMenuManager = new TouchlessContextMenuManager(
mContextMenuManager = new TouchlessContextMenuManager(activity,
suggestionsUiDelegate.getNavigationDelegate(), mRecyclerView::setTouchEnabled,
closeContextMenuCallback, NewTabPage.CONTEXT_MENU_USER_ACTION_PREFIX);
mTab.getWindowAndroid().addContextMenuCloseListener(mContextMenuManager);
......@@ -198,6 +195,6 @@ public class TouchlessNewTabPage extends BasicNativePage {
ContextMenuManager.Delegate delegate =
ContextMenuManager.getDelegateFromFocusedView(focusedView);
if (delegate == null) return;
mContextMenuManager.showTouchlessContextMenu(mModalDialogManager, mContext, delegate);
mContextMenuManager.showTouchlessContextMenu(mModalDialogManager, delegate);
}
}
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