Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(717)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java

Issue 2710833002: Refactor ChromeContextMenuPopulator population (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.contextmenu; 5 package org.chromium.chrome.browser.contextmenu;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.net.MailTo; 8 import android.net.MailTo;
9 import android.support.annotation.IntDef; 9 import android.support.annotation.IntDef;
10 import android.text.TextUtils; 10 import android.text.TextUtils;
11 import android.view.ContextMenu; 11 import android.view.ContextMenu;
12 import android.view.MenuInflater; 12 import android.view.MenuInflater;
13 import android.view.MenuItem;
14 import android.webkit.MimeTypeMap; 13 import android.webkit.MimeTypeMap;
15 14
16 import org.chromium.base.metrics.RecordHistogram; 15 import org.chromium.base.metrics.RecordHistogram;
17 import org.chromium.chrome.R; 16 import org.chromium.chrome.R;
18 import org.chromium.chrome.browser.UrlConstants; 17 import org.chromium.chrome.browser.UrlConstants;
19 import org.chromium.chrome.browser.firstrun.FirstRunStatus; 18 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
20 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; 19 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
21 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU ma; 20 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU ma;
22 import org.chromium.chrome.browser.search_engines.TemplateUrlService; 21 import org.chromium.chrome.browser.search_engines.TemplateUrlService;
23 import org.chromium.chrome.browser.util.UrlUtilities; 22 import org.chromium.chrome.browser.util.UrlUtilities;
24 23
25 import java.lang.annotation.Retention; 24 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy; 25 import java.lang.annotation.RetentionPolicy;
26 import java.util.ArrayList;
27 import java.util.Arrays; 27 import java.util.Arrays;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
28 31
29 /** 32 /**
30 * A {@link ContextMenuPopulator} used for showing the default Chrome context me nu. 33 * A {@link ContextMenuPopulator} used for showing the default Chrome context me nu.
31 */ 34 */
32 public class ChromeContextMenuPopulator implements ContextMenuPopulator { 35 public class ChromeContextMenuPopulator implements ContextMenuPopulator {
33 36
34 private static final String TAG = "CCMenuPopulator"; 37 private static final String TAG = "CCMenuPopulator";
35 38
36 /** 39 /**
37 * Defines the context menu modes 40 * Defines the context menu modes
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 198 }
196 199
197 if (mMenuInflater == null) mMenuInflater = new MenuInflater(context); 200 if (mMenuInflater == null) mMenuInflater = new MenuInflater(context);
198 201
199 mMenuInflater.inflate(R.menu.chrome_context_menu, menu); 202 mMenuInflater.inflate(R.menu.chrome_context_menu, menu);
200 203
201 menu.setGroupVisible(R.id.contextmenu_group_anchor, params.isAnchor()); 204 menu.setGroupVisible(R.id.contextmenu_group_anchor, params.isAnchor());
202 menu.setGroupVisible(R.id.contextmenu_group_image, params.isImage()); 205 menu.setGroupVisible(R.id.contextmenu_group_image, params.isImage());
203 menu.setGroupVisible(R.id.contextmenu_group_video, params.isVideo()); 206 menu.setGroupVisible(R.id.contextmenu_group_video, params.isVideo());
204 207
208 boolean isGroupMessage = MailTo.isMailTo(params.getLinkUrl())
David Trainor- moved to gerrit 2017/02/22 05:36:33 Looks like we call these methods below too. Can w
JJ 2017/02/23 03:29:14 Sorry, missed this. Pushed it inside of the url.
209 || UrlUtilities.isTelScheme(params.getLinkUrl());
210 menu.setGroupVisible(R.id.contextmenu_group_message, isGroupMessage);
211
212 Map<Integer, String> menuIdMap = new HashMap<>(menu.size());
Ted C 2017/02/22 06:10:54 Take a look at https://developer.android.com/refe
JJ 2017/02/22 19:09:39 So I did look at this before I put it up thinking
213 for (int i = 0; i < menu.size(); i++) {
214 if (menu.getItem(i).isVisible()) {
David Trainor- moved to gerrit 2017/02/22 05:36:33 Can we pull out menu.getItem(i) to a local?
JJ 2017/02/22 19:09:39 Done.
215 menuIdMap.put(menu.getItem(i).getItemId(), (String) menu.getItem (i).getTitle());
216 }
217 }
218 menuIdMap = getListOfOptions(params, context, menuIdMap);
David Trainor- moved to gerrit 2017/02/22 05:36:33 Do we have to return menuIdMap here? Might make i
Ted C 2017/02/22 06:10:54 looks like dtrainor@ left comments, but I'll put t
JJ 2017/02/22 19:09:39 No we don't need to return it at all! I'm hesitati
JJ 2017/02/22 19:09:39 I actually was thinking about this heavily when lo
219
220 // Iterate through the entire menu list, if if doesn't exist in the map, don't show it.
221 for (int i = 0; i < menu.size(); i++) {
222 boolean inMenuList = menuIdMap.containsKey(menu.getItem(i).getItemId ());
David Trainor- moved to gerrit 2017/02/22 05:36:33 Pull out menu.getItem(i) again imo
JJ 2017/02/22 19:09:39 Done.
223 menu.getItem(i).setVisible(inMenuList);
224 if (inMenuList) {
225 menu.getItem(i).setTitle(menuIdMap.get(menu.getItem(i).getItemId ()));
226 }
227 }
228 }
229
230 /**
231 * Given a set of params and context, and a list of all the items, it'll ret urn a list of items
David Trainor- moved to gerrit 2017/02/22 05:36:33 remove it'll?
JJ 2017/02/22 19:09:38 Done.
232 * that should be displayed. This method never adds items, only removes or e dits them from the
233 * list.
234 * @param params The parameters used for filtering out the the list of items .
David Trainor- moved to gerrit 2017/02/22 05:36:33 Do we need @param context in here (even with no de
JJ 2017/02/22 19:09:38 Question for the future: Is it alright to have a p
235 * @param allItems A list, with all the possible options for a link. Items w ill be removed based
David Trainor- moved to gerrit 2017/02/22 05:36:33 Can we describe what the format of the map is?
JJ 2017/02/22 19:09:38 Done.
236 * off the parameters.
237 * @return Returns a map containing the id and string of all the items that are allowed to be
238 * on the menu.
239 */
240 private Map<Integer, String> getListOfOptions(
241 ContextMenuParams params, Context context, Map<Integer, String> allI tems) {
205 if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) { 242 if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) {
206 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); 243 allItems.remove(R.id.contextmenu_open_in_other_window);
207 } 244 }
208 245
209 if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) { 246 if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) {
210 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); 247 allItems.remove(R.id.contextmenu_open_in_incognito_tab);
211 } 248 }
212 249
213 if (params.getLinkText().trim().isEmpty() || params.isImage()) { 250 if (params.getLinkText().trim().isEmpty() || params.isImage()) {
214 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); 251 allItems.remove(R.id.contextmenu_copy_link_text);
215 } 252 }
216 253
217 if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUr l())) { 254 if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUr l())) {
218 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); 255 allItems.remove(R.id.contextmenu_open_in_other_window);
219 menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); 256 allItems.remove(R.id.contextmenu_open_in_new_tab);
220 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); 257 allItems.remove(R.id.contextmenu_open_in_incognito_tab);
221 } 258 }
222 259
223 if (MailTo.isMailTo(params.getLinkUrl())) { 260 if (MailTo.isMailTo(params.getLinkUrl())) {
224 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); 261 allItems.remove(R.id.contextmenu_copy_link_text);
225 menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); 262 allItems.remove(R.id.contextmenu_copy_link_address);
226 menu.setGroupVisible(R.id.contextmenu_group_message, true);
227 if (!mDelegate.supportsSendEmailMessage()) { 263 if (!mDelegate.supportsSendEmailMessage()) {
228 menu.findItem(R.id.contextmenu_send_message).setVisible(false); 264 allItems.remove(R.id.contextmenu_send_message);
229 } 265 }
230 if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo()) 266 if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo())
231 || !mDelegate.supportsAddToContacts()) { 267 || !mDelegate.supportsAddToContacts()) {
232 menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false ); 268 allItems.remove(R.id.contextmenu_add_to_contacts);
233 } 269 }
234 menu.findItem(R.id.contextmenu_call).setVisible(false); 270 allItems.remove(R.id.contextmenu_call);
235 } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) { 271 } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) {
236 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); 272 allItems.remove(R.id.contextmenu_copy_link_text);
237 menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); 273 allItems.remove(R.id.contextmenu_copy_link_address);
238 menu.setGroupVisible(R.id.contextmenu_group_message, true);
239 if (!mDelegate.supportsCall()) { 274 if (!mDelegate.supportsCall()) {
240 menu.findItem(R.id.contextmenu_call).setVisible(false); 275 allItems.remove(R.id.contextmenu_call);
241 } 276 }
242 if (!mDelegate.supportsSendTextMessage()) { 277 if (!mDelegate.supportsSendTextMessage()) {
243 menu.findItem(R.id.contextmenu_send_message).setVisible(false); 278 allItems.remove(R.id.contextmenu_send_message);
244 } 279 }
245 if (!mDelegate.supportsAddToContacts()) { 280 if (!mDelegate.supportsAddToContacts()) {
246 menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false ); 281 allItems.remove(R.id.contextmenu_add_to_contacts);
247 } 282 }
248 } else {
249 menu.setGroupVisible(R.id.contextmenu_group_message, false);
250 } 283 }
251 284
252 menu.findItem(R.id.contextmenu_save_link_as).setVisible( 285 if (!UrlUtilities.isDownloadableScheme(params.getLinkUrl())) {
253 UrlUtilities.isDownloadableScheme(params.getLinkUrl())); 286 allItems.remove(R.id.contextmenu_save_link_as);
287 }
254 288
255 if (params.imageWasFetchedLoFi() 289 if (params.imageWasFetchedLoFi()
256 || !DataReductionProxySettings.getInstance().wasLoFiModeActiveOn MainFrame() 290 || !DataReductionProxySettings.getInstance().wasLoFiModeActiveOn MainFrame()
257 || !DataReductionProxySettings.getInstance().canUseDataReduction Proxy( 291 || !DataReductionProxySettings.getInstance().canUseDataReduction Proxy(
258 params.getPageUrl())) { 292 params.getPageUrl())) {
259 menu.findItem(R.id.contextmenu_load_images).setVisible(false); 293 allItems.remove(R.id.contextmenu_load_images);
260 } else { 294 } else {
261 // Links can have images as backgrounds that aren't recognized here as images. CSS 295 // Links can have images as backgrounds that aren't recognized here as images. CSS
262 // properties can also prevent an image underlying a link from being clickable. 296 // properties can also prevent an image underlying a link from being clickable.
263 // When Lo-Fi is active, provide the user with a "Load images" optio n on links 297 // When Lo-Fi is active, provide the user with a "Load images" optio n on links
264 // to get the images in these cases. 298 // to get the images in these cases.
265 DataReductionProxyUma.previewsLoFiContextMenuAction( 299 DataReductionProxyUma.previewsLoFiContextMenuAction(
266 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGES_CONTEXT_MENU_S HOWN); 300 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGES_CONTEXT_MENU_S HOWN);
267 } 301 }
268 302
269 if (params.isVideo()) { 303 if (params.isVideo()) {
270 menu.findItem(R.id.contextmenu_save_video).setVisible( 304 boolean saveableAndDownloadable =
271 params.canSaveMedia() && UrlUtilities.isDownloadableScheme(p arams.getSrcUrl())); 305 params.canSaveMedia() && UrlUtilities.isDownloadableScheme(p arams.getSrcUrl());
David Trainor- moved to gerrit 2017/02/22 05:36:33 pull out isDownloadableScheme(params.getSrcUrl())
JJ 2017/02/23 03:29:14 Done.
306 if (!saveableAndDownloadable) {
307 allItems.remove(R.id.contextmenu_save_video);
308 }
272 } else if (params.isImage() && params.imageWasFetchedLoFi()) { 309 } else if (params.isImage() && params.imageWasFetchedLoFi()) {
273 DataReductionProxyUma.previewsLoFiContextMenuAction( 310 DataReductionProxyUma.previewsLoFiContextMenuAction(
274 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SH OWN); 311 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SH OWN);
275 // All image context menu items other than "Load image," "Open origi nal image in 312 // All image context menu items other than "Load image," "Open origi nal image in
276 // new tab," and "Copy image URL" should be disabled on Lo-Fi images . 313 // new tab," and "Copy image URL" should be disabled on Lo-Fi images .
277 menu.findItem(R.id.contextmenu_save_image).setVisible(false); 314 allItems.remove(R.id.contextmenu_save_image);
278 menu.findItem(R.id.contextmenu_open_image).setVisible(false); 315 allItems.remove(R.id.contextmenu_open_image);
279 menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); 316 allItems.remove(R.id.contextmenu_search_by_image);
280 menu.findItem(R.id.contextmenu_share_image).setVisible(false); 317 allItems.remove(R.id.contextmenu_share_image);
281 } else if (params.isImage() && !params.imageWasFetchedLoFi()) { 318 } else if (params.isImage() && !params.imageWasFetchedLoFi()) {
282 menu.findItem(R.id.contextmenu_load_original_image).setVisible(false ); 319 allItems.remove(R.id.contextmenu_load_original_image);
283 320
284 menu.findItem(R.id.contextmenu_save_image).setVisible( 321 if (!UrlUtilities.isDownloadableScheme(params.getSrcUrl())) {
285 UrlUtilities.isDownloadableScheme(params.getSrcUrl())); 322 allItems.remove(R.id.contextmenu_save_image);
323 }
286 324
287 // Avoid showing open image option for same image which is already o pened. 325 // Avoid showing open image option for same image which is already o pened.
288 if (mDelegate.getPageUrl().equals(params.getSrcUrl())) { 326 if (mDelegate.getPageUrl().equals(params.getSrcUrl())) {
289 menu.findItem(R.id.contextmenu_open_image).setVisible(false); 327 allItems.remove(R.id.contextmenu_open_image);
290 } 328 }
291 final TemplateUrlService templateUrlServiceInstance = TemplateUrlSer vice.getInstance(); 329 final TemplateUrlService templateUrlServiceInstance = TemplateUrlSer vice.getInstance();
292 final boolean isSearchByImageAvailable = 330 final boolean isSearchByImageAvailable =
293 UrlUtilities.isDownloadableScheme(params.getSrcUrl()) 331 UrlUtilities.isDownloadableScheme(params.getSrcUrl())
294 && templateUrlServiceInstance.isLoaded() 332 && templateUrlServiceInstance.isLoaded()
295 && templateUrlServiceInstance.isSearchByImageAvailab le() 333 && templateUrlServiceInstance.isSearchByImageAvailab le()
296 && templateUrlServiceInstance.getDefaultSearchEngine TemplateUrl() 334 && templateUrlServiceInstance.getDefaultSearchEngine TemplateUrl()
297 != null; 335 != null;
298 336
299 menu.findItem(R.id.contextmenu_search_by_image).setVisible(isSearchB yImageAvailable);
300 if (isSearchByImageAvailable) { 337 if (isSearchByImageAvailable) {
301 menu.findItem(R.id.contextmenu_search_by_image).setTitle( 338 allItems.put(R.id.contextmenu_search_by_image,
David Trainor- moved to gerrit 2017/02/22 05:36:32 Does this break the rule? Seems like this adds th
JJ 2017/02/22 19:09:39 So the initial idea was to set up this method as a
302 context.getString(R.string.contextmenu_search_web_for_im age, 339 context.getString(R.string.contextmenu_search_web_for_im age,
303 TemplateUrlService.getInstance() 340 TemplateUrlService.getInstance()
304 .getDefaultSearchEngineTemplateUrl().get ShortName())); 341 .getDefaultSearchEngineTemplateUrl()
342 .getShortName()));
343 } else {
344 allItems.remove(R.id.contextmenu_search_by_image);
305 } 345 }
306 } 346 }
307 347
308 // Hide all items that could spawn additional tabs until FRE has been co mpleted. 348 // Hide all items that could spawn additional tabs until FRE has been co mpleted.
309 if (!FirstRunStatus.getFirstRunFlowComplete()) { 349 if (!FirstRunStatus.getFirstRunFlowComplete()) {
310 menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(fal se); 350 allItems.remove(R.id.contextmenu_open_image_in_new_tab);
311 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); 351 allItems.remove(R.id.contextmenu_open_in_other_window);
312 menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); 352 allItems.remove(R.id.contextmenu_open_in_new_tab);
313 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); 353 allItems.remove(R.id.contextmenu_open_in_incognito_tab);
314 menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); 354 allItems.remove(R.id.contextmenu_search_by_image);
315 menu.findItem(R.id.menu_id_open_in_chrome).setVisible(false); 355 allItems.remove(R.id.menu_id_open_in_chrome);
316 } 356 }
317 357
318 if (mMode == FULLSCREEN_TAB_MODE) { 358 if (mMode == FULLSCREEN_TAB_MODE) {
319 removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST); 359 removeUnsupportedItems(allItems, FULLSCREEN_TAB_MODE_WHITELIST);
320 } else if (mMode == CUSTOM_TAB_MODE) { 360 } else if (mMode == CUSTOM_TAB_MODE) {
321 removeUnsupportedItems(menu, CUSTOM_TAB_MODE_WHITELIST); 361 removeUnsupportedItems(allItems, CUSTOM_TAB_MODE_WHITELIST);
322 } else { 362 } else {
323 removeUnsupportedItems(menu, NORMAL_MODE_WHITELIST); 363 removeUnsupportedItems(allItems, NORMAL_MODE_WHITELIST);
324 } 364 }
365
366 return allItems;
325 } 367 }
326 368
327 private void removeUnsupportedItems(ContextMenu menu, int[] whitelist) { 369 private void removeUnsupportedItems(Map<Integer, String> itemList, int[] whi telist) {
328 Arrays.sort(BASE_WHITELIST); 370 Arrays.sort(BASE_WHITELIST);
329 Arrays.sort(whitelist); 371 Arrays.sort(whitelist);
330 for (int i = 0; i < menu.size(); i++) { 372 List<Integer> keyList = new ArrayList<>(itemList.keySet());
331 MenuItem item = menu.getItem(i); 373 for (int i = 0; i < keyList.size(); i++) {
332 if (Arrays.binarySearch(whitelist, item.getItemId()) < 0 374 int itemId = keyList.get(i);
333 && Arrays.binarySearch(BASE_WHITELIST, item.getItemId()) < 0 ) { 375 if (Arrays.binarySearch(whitelist, itemId) < 0
334 menu.removeItem(item.getItemId()); 376 && Arrays.binarySearch(BASE_WHITELIST, itemId) < 0) {
335 i--; 377 itemList.remove(itemId);
336 } 378 }
337 } 379 }
338 } 380 }
339 381
340 @Override 382 @Override
341 public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams pa rams, int itemId) { 383 public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams pa rams, int itemId) {
342 if (itemId == R.id.contextmenu_open_in_other_window) { 384 if (itemId == R.id.contextmenu_open_in_other_window) {
343 ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_OTHER_WI NDOW); 385 ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_OTHER_WI NDOW);
344 mDelegate.onOpenInOtherWindow(params.getLinkUrl(), params.getReferre r()); 386 mDelegate.onOpenInOtherWindow(params.getLinkUrl(), params.getReferre r());
345 } else if (itemId == R.id.contextmenu_open_in_new_tab) { 387 } else if (itemId == R.id.contextmenu_open_in_new_tab) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 474 }
433 475
434 return true; 476 return true;
435 } 477 }
436 478
437 private void setHeaderText(Context context, ContextMenu menu, String text) { 479 private void setHeaderText(Context context, ContextMenu menu, String text) {
438 ContextMenuTitleView title = new ContextMenuTitleView(context, text); 480 ContextMenuTitleView title = new ContextMenuTitleView(context, text);
439 menu.setHeaderView(title); 481 menu.setHeaderView(title);
440 } 482 }
441 } 483 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698