blob: e5f51d77e39e0df2953cecd2a41e3fe476b65a78 [file] [log] [blame]
// 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.View.OnCreateContextMenuListener;
import com.google.common.annotations.VisibleForTesting;
import org.chromium.base.CalledByNative;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewCore;
/**
* 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);
}