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