1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.chrome.browser.contextmenu;
7 import android.view.ContextMenu;
8 import android.view.ContextMenu.ContextMenuInfo;
9 import android.view.HapticFeedbackConstants;
10 import android.view.Menu;
11 import android.view.MenuItem;
12 import android.view.MenuItem.OnMenuItemClickListener;
13 import android.view.View;
14 import android.view.View.OnCreateContextMenuListener;
16 import com.google.common.annotations.VisibleForTesting;
18 import org.chromium.base.CalledByNative;
19 import org.chromium.content.browser.ContentViewCore;
22 * A helper class that handles generating context menus for {@link ContentViewCore}s.
24 public class ContextMenuHelper implements OnCreateContextMenuListener, OnMenuItemClickListener {
25 private long mNativeContextMenuHelper;
27 private ContextMenuPopulator mPopulator;
28 private ContextMenuParams mCurrentContextMenuParams;
30 private ContextMenuHelper(long nativeContextMenuHelper) {
31 mNativeContextMenuHelper = nativeContextMenuHelper;
35 private static ContextMenuHelper create(long nativeContextMenuHelper) {
36 return new ContextMenuHelper(nativeContextMenuHelper);
40 private void destroy() {
41 mNativeContextMenuHelper = 0;
45 * @param populator A {@link ContextMenuPopulator} that is responsible for managing and showing
49 private void setPopulator(ContextMenuPopulator populator) {
50 mPopulator = populator;
54 * Starts showing a context menu for {@code view} based on {@code params}.
55 * @param contentViewCore The {@link ContentViewCore} to show the menu to.
56 * @param params The {@link ContextMenuParams} that indicate what menu items to show.
59 private void showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) {
60 final View view = contentViewCore.getContainerView();
62 if (!shouldShowMenu(params)
64 || view.getVisibility() != View.VISIBLE
65 || view.getParent() == null) {
69 mCurrentContextMenuParams = params;
71 view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
72 contentViewCore.setIgnoreRemainingTouchEvents();
73 view.setOnCreateContextMenuListener(this);
74 view.showContextMenu();
78 * Starts a download based on the current {@link ContextMenuParams}.
79 * @param isLink Whether or not the download target is a link.
81 public void startContextMenuDownload(boolean isLink) {
82 if (mNativeContextMenuHelper != 0) nativeOnStartDownload(mNativeContextMenuHelper, isLink);
86 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
87 if (!shouldShowMenu(mCurrentContextMenuParams)) return;
89 if (mCurrentContextMenuParams.isCustomMenu()) {
90 for (int i = 0; i < mCurrentContextMenuParams.getCustomMenuSize(); i++) {
91 menu.add(Menu.NONE, i, Menu.NONE, mCurrentContextMenuParams.getCustomLabelAt(i));
94 assert mPopulator != null;
95 mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContextMenuParams);
98 for (int i = 0; i < menu.size(); i++) {
99 menu.getItem(i).setOnMenuItemClickListener(this);
104 public boolean onMenuItemClick(MenuItem item) {
105 if (mCurrentContextMenuParams.isCustomMenu()) {
106 if (mNativeContextMenuHelper != 0) {
107 final int action = mCurrentContextMenuParams.getCustomActionAt(item.getItemId());
108 nativeOnCustomItemSelected(mNativeContextMenuHelper, action);
112 return mPopulator.onItemSelected(this, mCurrentContextMenuParams, item.getItemId());
117 * @return The {@link ContextMenuPopulator} responsible for populating the context menu.
120 public ContextMenuPopulator getPopulator() {
124 private boolean shouldShowMenu(ContextMenuParams params) {
125 // Custom menus are handled by this class and do not require a ContextMenuPopulator.
126 return params.isCustomMenu() ||
127 (mPopulator != null && mPopulator.shouldShowContextMenu(params));
130 private native void nativeOnStartDownload(long nativeContextMenuHelper, boolean isLink);
131 private native void nativeOnCustomItemSelected(long nativeContextMenuHelper, int action);