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
5package org.chromium.chrome.browser.contextmenu;
6
7import android.text.TextUtils;
8
9import org.chromium.base.CalledByNative;
10import org.chromium.base.JNINamespace;
11import org.chromium.content_public.common.Referrer;
12
13import java.util.ArrayList;
14
15/**
16 * A list of parameters that explain what kind of context menu to show the user.  This data is
17 * generated from content/public/common/context_menu_params.h.
18 */
19@JNINamespace("ContextMenuParamsAndroid")
20public class ContextMenuParams {
21    /** Must correspond to the MediaType enum in WebKit/chromium/public/WebContextMenuData.h */
22    @SuppressWarnings("unused")
23    private static interface MediaType {
24        public static final int MEDIA_TYPE_NONE = 0;
25        public static final int MEDIA_TYPE_IMAGE = 1;
26        public static final int MEDIA_TYPE_VIDEO = 2;
27        public static final int MEDIA_TYPE_AUDIO = 3;
28        public static final int MEDIA_TYPE_FILE = 4;
29        public static final int MEDIA_TYPE_PLUGIN = 5;
30    }
31
32    private static class CustomMenuItem {
33        public final String label;
34        public final int action;
35
36        public CustomMenuItem(String label, int action) {
37            this.label = label;
38            this.action = action;
39        }
40    }
41
42    private final String mLinkUrl;
43    private final String mLinkText;
44    private final String mUnfilteredLinkUrl;
45    private final String mSrcUrl;
46    private final boolean mIsEditable;
47    private final Referrer mReferrer;
48
49    private final boolean mIsAnchor;
50    private final boolean mIsSelectedText;
51    private final boolean mIsImage;
52    private final boolean mIsVideo;
53
54    private final ArrayList<CustomMenuItem> mCustomMenuItems = new ArrayList<CustomMenuItem>();
55
56    /**
57     * @return Whether or not the context menu should consist of custom items.
58     */
59    public boolean isCustomMenu() {
60        return !mCustomMenuItems.isEmpty();
61    }
62
63    /**
64     * @return The number of custom items in this context menu.
65     */
66    public int getCustomMenuSize() {
67        return mCustomMenuItems.size();
68    }
69
70    /**
71     * The label that should be shown for the custom menu item at {@code index}.
72     * @param index The index of the custom menu item.
73     * @return      The label to show.
74     */
75    public String getCustomLabelAt(int index) {
76        assert index >= 0 && index < mCustomMenuItems.size();
77        return mCustomMenuItems.get(index).label;
78    }
79
80    /**
81     * The action that should be returned for the custom menu item at {@code index}.
82     * @param index The index of the custom menu item.
83     * @return      The action to return.
84     */
85    public int getCustomActionAt(int index) {
86        assert index >= 0 && index < mCustomMenuItems.size();
87        return mCustomMenuItems.get(index).action;
88    }
89
90    /**
91     * @return The link URL, if any.
92     */
93    public String getLinkUrl() {
94        return mLinkUrl;
95    }
96
97    /**
98     * @return The link text, if any.
99     */
100    public String getLinkText() {
101        return mLinkText;
102    }
103
104    /**
105     * @return The unfiltered link URL, if any.
106     */
107    public String getUnfilteredLinkUrl() {
108        return mUnfilteredLinkUrl;
109    }
110
111    /**
112     * @return The source URL.
113     */
114    public String getSrcUrl() {
115        return mSrcUrl;
116    }
117
118    /**
119     * @return Whether or not the context menu is being shown for an editable piece of content.
120     */
121    public boolean isEditable() {
122        return mIsEditable;
123    }
124
125    /**
126     * @return the referrer associated with the frame on which the menu is invoked
127     */
128    public Referrer getReferrer() {
129        return mReferrer;
130    }
131
132    /**
133     * @return Whether or not the context menu is being shown for an anchor.
134     */
135    public boolean isAnchor() {
136        return mIsAnchor;
137    }
138
139    /**
140     * @return Whether or not the context menu is being shown for selected text.
141     */
142    public boolean isSelectedText() {
143        return mIsSelectedText;
144    }
145
146    /**
147     * @return Whether or not the context menu is being shown for an image.
148     */
149    public boolean isImage() {
150        return mIsImage;
151    }
152
153    /**
154     * @return Whether or not the context menu is being shown for a video.
155     */
156    public boolean isVideo() {
157        return mIsVideo;
158    }
159
160    private ContextMenuParams(int mediaType, String linkUrl, String linkText,
161            String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable,
162            Referrer referrer) {
163        mLinkUrl = linkUrl;
164        mLinkText = linkText;
165        mUnfilteredLinkUrl = unfilteredLinkUrl;
166        mSrcUrl = srcUrl;
167        mIsEditable = isEditable;
168        mReferrer = referrer;
169
170        mIsAnchor = !TextUtils.isEmpty(linkUrl);
171        mIsSelectedText = !TextUtils.isEmpty(selectionText);
172        mIsImage = mediaType == MediaType.MEDIA_TYPE_IMAGE;
173        mIsVideo = mediaType == MediaType.MEDIA_TYPE_VIDEO;
174    }
175
176    @CalledByNative
177    private static ContextMenuParams create(int mediaType, String linkUrl, String linkText,
178            String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable,
179            String sanitizedReferrer, int referrerPolicy) {
180        Referrer referrer = TextUtils.isEmpty(sanitizedReferrer) ?
181                null : new Referrer(sanitizedReferrer, referrerPolicy);
182        return new ContextMenuParams(mediaType, linkUrl, linkText, unfilteredLinkUrl, srcUrl,
183                selectionText, isEditable, referrer);
184    }
185
186    @CalledByNative
187    private void addCustomItem(String label, int action) {
188        mCustomMenuItems.add(new CustomMenuItem(label, action));
189    }
190}
191