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.ContentView;
20 import org.chromium.content.browser.ContentViewCore;
23 * A helper class that handles generating context menus for {@link ContentView}s.
25 public class ContextMenuHelper implements OnCreateContextMenuListener, OnMenuItemClickListener {
26 private long mNativeContextMenuHelper;
28 private ContextMenuPopulator mPopulator;
29 private ContextMenuParams mCurrentContextMenuParams;
31 private ContextMenuHelper(long nativeContextMenuHelper) {
32 mNativeContextMenuHelper = nativeContextMenuHelper;
36 private static ContextMenuHelper create(long nativeContextMenuHelper) {
37 return new ContextMenuHelper(nativeContextMenuHelper);
41 private void destroy() {
42 mNativeContextMenuHelper = 0;
46 * @param populator A {@link ContextMenuPopulator} that is responsible for managing and showing
50 private void setPopulator(ContextMenuPopulator populator) {
51 mPopulator = populator;
55 * Starts showing a context menu for {@code view} based on {@code params}.
56 * @param contentViewCore The {@link ContentViewCore} to show the menu to.
57 * @param params The {@link ContextMenuParams} that indicate what menu items to show.
60 private void showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) {
61 final View view = contentViewCore.getContainerView();
63 if (!shouldShowMenu(params)
65 || view.getVisibility() != View.VISIBLE
66 || view.getParent() == null) {
70 mCurrentContextMenuParams = params;
72 view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
73 contentViewCore.setIgnoreRemainingTouchEvents();
74 view.setOnCreateContextMenuListener(this);
75 view.showContextMenu();
79 * Starts a download based on the current {@link ContextMenuParams}.
80 * @param isLink Whether or not the download target is a link.
82 public void startContextMenuDownload(boolean isLink) {
83 if (mNativeContextMenuHelper != 0) nativeOnStartDownload(mNativeContextMenuHelper, isLink);
87 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
88 if (!shouldShowMenu(mCurrentContextMenuParams)) return;
90 if (mCurrentContextMenuParams.isCustomMenu()) {
91 for (int i = 0; i < mCurrentContextMenuParams.getCustomMenuSize(); i++) {
92 menu.add(Menu.NONE, i, Menu.NONE, mCurrentContextMenuParams.getCustomLabelAt(i));
95 assert mPopulator != null;
96 mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContextMenuParams);
99 for (int i = 0; i < menu.size(); i++) {
100 menu.getItem(i).setOnMenuItemClickListener(this);
105 public boolean onMenuItemClick(MenuItem item) {
106 if (mCurrentContextMenuParams.isCustomMenu()) {
107 if (mNativeContextMenuHelper != 0) {
108 final int action = mCurrentContextMenuParams.getCustomActionAt(item.getItemId());
109 nativeOnCustomItemSelected(mNativeContextMenuHelper, action);
113 return mPopulator.onItemSelected(this, mCurrentContextMenuParams, item.getItemId());
118 * @return The {@link ContextMenuPopulator} responsible for populating the context menu.
121 public ContextMenuPopulator getPopulator() {
125 private boolean shouldShowMenu(ContextMenuParams params) {
126 // Custom menus are handled by this class and do not require a ContextMenuPopulator.
127 return params.isCustomMenu() ||
128 (mPopulator != null && mPopulator.shouldShowContextMenu(params));
131 private native void nativeOnStartDownload(long nativeContextMenuHelper, boolean isLink);
132 private native void nativeOnCustomItemSelected(long nativeContextMenuHelper, int action);