Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / contextmenu / ContextMenuHelper.java
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.
4
5 package org.chromium.chrome.browser.contextmenu;
6
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;
15
16 import com.google.common.annotations.VisibleForTesting;
17
18 import org.chromium.base.CalledByNative;
19 import org.chromium.content.browser.ContentViewCore;
20
21 /**
22  * A helper class that handles generating context menus for {@link ContentViewCore}s.
23  */
24 public class ContextMenuHelper implements OnCreateContextMenuListener, OnMenuItemClickListener {
25     private long mNativeContextMenuHelper;
26
27     private ContextMenuPopulator mPopulator;
28     private ContextMenuParams mCurrentContextMenuParams;
29
30     private ContextMenuHelper(long nativeContextMenuHelper) {
31         mNativeContextMenuHelper = nativeContextMenuHelper;
32     }
33
34     @CalledByNative
35     private static ContextMenuHelper create(long nativeContextMenuHelper) {
36         return new ContextMenuHelper(nativeContextMenuHelper);
37     }
38
39     @CalledByNative
40     private void destroy() {
41         mNativeContextMenuHelper = 0;
42     }
43
44     /**
45      * @param populator A {@link ContextMenuPopulator} that is responsible for managing and showing
46      *                  context menus.
47      */
48     @CalledByNative
49     private void setPopulator(ContextMenuPopulator populator) {
50         mPopulator = populator;
51     }
52
53     /**
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.
57      */
58     @CalledByNative
59     private void showContextMenu(ContentViewCore contentViewCore, ContextMenuParams params) {
60         final View view = contentViewCore.getContainerView();
61
62         if (!shouldShowMenu(params)
63                 || view == null
64                 || view.getVisibility() != View.VISIBLE
65                 || view.getParent() == null) {
66             return;
67         }
68
69         mCurrentContextMenuParams = params;
70
71         view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
72         contentViewCore.setIgnoreRemainingTouchEvents();
73         view.setOnCreateContextMenuListener(this);
74         view.showContextMenu();
75     }
76
77     /**
78      * Starts a download based on the current {@link ContextMenuParams}.
79      * @param isLink Whether or not the download target is a link.
80      */
81     public void startContextMenuDownload(boolean isLink) {
82         if (mNativeContextMenuHelper != 0) nativeOnStartDownload(mNativeContextMenuHelper, isLink);
83     }
84
85     @Override
86     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
87         if (!shouldShowMenu(mCurrentContextMenuParams)) return;
88
89         if (mCurrentContextMenuParams.isCustomMenu()) {
90             for (int i = 0; i < mCurrentContextMenuParams.getCustomMenuSize(); i++) {
91                 menu.add(Menu.NONE, i, Menu.NONE, mCurrentContextMenuParams.getCustomLabelAt(i));
92             }
93         } else {
94             assert mPopulator != null;
95             mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContextMenuParams);
96         }
97
98         for (int i = 0; i < menu.size(); i++) {
99             menu.getItem(i).setOnMenuItemClickListener(this);
100         }
101     }
102
103     @Override
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);
109             }
110             return true;
111         } else {
112             return mPopulator.onItemSelected(this, mCurrentContextMenuParams, item.getItemId());
113         }
114     }
115
116     /**
117      * @return The {@link ContextMenuPopulator} responsible for populating the context menu.
118      */
119     @VisibleForTesting
120     public ContextMenuPopulator getPopulator() {
121         return mPopulator;
122     }
123
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));
128     }
129
130     private native void nativeOnStartDownload(long nativeContextMenuHelper, boolean isLink);
131     private native void nativeOnCustomItemSelected(long nativeContextMenuHelper, int action);
132 }