Index: chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..992740def07ecaff026f454b72494dab99bbd265 |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java |
@@ -0,0 +1,129 @@ |
+// Copyright 2013 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.contextmenu; |
+ |
+import android.view.ContextMenu; |
+import android.view.ContextMenu.ContextMenuInfo; |
+import android.view.HapticFeedbackConstants; |
+import android.view.Menu; |
+import android.view.MenuItem; |
+import android.view.MenuItem.OnMenuItemClickListener; |
+import android.view.View; |
+import android.view.ViewTreeObserver; |
+ |
+import org.chromium.base.CalledByNative; |
+import org.chromium.content.browser.ContentView; |
+import org.chromium.content.browser.ContentViewCore; |
+ |
+import android.view.View.OnCreateContextMenuListener; |
+ |
+import com.google.common.annotations.VisibleForTesting; |
+ |
+/** |
+ * A helper class that handles generating context menus for {@link ContentView}s. |
+ */ |
+public class ContextMenuHelper implements OnCreateContextMenuListener, OnMenuItemClickListener { |
+ private long mNativeContextMenuHelper; |
+ |
+ private ContextMenuPopulator mPopulator; |
+ private ContextMenuParams mCurrentContextMenuParams; |
+ |
+ private ContextMenuHelper(long nativeContextMenuHelper) { |
+ mNativeContextMenuHelper = nativeContextMenuHelper; |
+ } |
+ |
+ @CalledByNative |
+ private static ContextMenuHelper create(long nativeContextMenuHelper) { |
+ return new ContextMenuHelper(nativeContextMenuHelper); |
+ } |
+ |
+ @CalledByNative |
+ private void destroy() { |
+ mNativeContextMenuHelper = 0; |
+ } |
+ |
+ /** |
+ * @param populator A {@link ContextMenuPopulator} that is responsible for managing and showing |
+ * context menus. |
+ */ |
+ @CalledByNative |
+ private void setPopulator(ContextMenuPopulator populator) { |
+ mPopulator = populator; |
+ } |
+ |
+ /** |
+ * Starts showing a context menu for {@code view} based on {@code params}. |
+ * @param contentViewCore The {@link ContentViewCore} to show the menu to. |
+ * @param params The {@link ContextMenuParams} that indicate what menu items to show. |
+ */ |
+ @CalledByNative |
+ private void showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) { |
+ if (!shouldShowMenu(params)) return; |
+ |
+ mCurrentContextMenuParams = params; |
+ |
+ View view = contentViewCore.getContainerView(); |
+ view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
+ if (view instanceof ContentView) ((ContentView) view).setIgnoreRemainingTouchEvents(); |
+ view.setOnCreateContextMenuListener(this); |
+ view.showContextMenu(); |
+ } |
+ |
+ /** |
+ * Starts a download based on the current {@link ContextMenuParams}. |
+ * @param isLink Whether or not the download target is a link. |
+ */ |
+ public void startContextMenuDownload(boolean isLink) { |
+ if (mNativeContextMenuHelper != 0) nativeOnStartDownload(mNativeContextMenuHelper, isLink); |
+ } |
+ |
+ @Override |
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { |
+ if (!shouldShowMenu(mCurrentContextMenuParams)) return; |
+ |
+ if (mCurrentContextMenuParams.isCustomMenu()) { |
+ for (int i = 0; i < mCurrentContextMenuParams.getCustomMenuSize(); i++) { |
+ menu.add(Menu.NONE, i, Menu.NONE, mCurrentContextMenuParams.getCustomLabelAt(i)); |
+ } |
+ } else { |
+ assert mPopulator != null; |
+ mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContextMenuParams); |
+ } |
+ |
+ for (int i = 0; i < menu.size(); i++) { |
+ menu.getItem(i).setOnMenuItemClickListener(this); |
+ } |
+ } |
+ |
+ @Override |
+ public boolean onMenuItemClick(MenuItem item) { |
+ if (mCurrentContextMenuParams.isCustomMenu()) { |
+ if (mNativeContextMenuHelper != 0) { |
+ final int action = mCurrentContextMenuParams.getCustomActionAt(item.getItemId()); |
+ nativeOnCustomItemSelected(mNativeContextMenuHelper, action); |
+ } |
+ return true; |
+ } else { |
+ return mPopulator.onItemSelected(this, mCurrentContextMenuParams, item.getItemId()); |
+ } |
+ } |
+ |
+ /** |
+ * @return The {@link ContextMenuPopulator} responsible for populating the context menu. |
+ */ |
+ @VisibleForTesting |
+ public ContextMenuPopulator getPopulator() { |
+ return mPopulator; |
+ } |
+ |
+ private boolean shouldShowMenu(ContextMenuParams params) { |
+ // Custom menus are handled by this class and do not require a ContextMenuPopulator. |
+ return params.isCustomMenu() || |
+ (mPopulator != null && mPopulator.shouldShowContextMenu(params)); |
+ } |
+ |
+ private native void nativeOnStartDownload(long nativeContextMenuHelper, boolean isLink); |
+ private native void nativeOnCustomItemSelected(long nativeContextMenuHelper, int action); |
+} |