Index: chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java |
index a11081c46e2c23f5c26074b4ae9e466a26bc1c08..8ab7675e978e3bf3aeaf49704012d48fda65adb9 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java |
@@ -13,6 +13,7 @@ import android.view.MenuInflater; |
import android.view.MenuItem; |
import android.webkit.MimeTypeMap; |
+import org.chromium.base.CollectionUtil; |
import org.chromium.base.metrics.RecordHistogram; |
import org.chromium.chrome.R; |
import org.chromium.chrome.browser.UrlConstants; |
@@ -24,7 +25,8 @@ import org.chromium.chrome.browser.util.UrlUtilities; |
import java.lang.annotation.Retention; |
import java.lang.annotation.RetentionPolicy; |
-import java.util.Arrays; |
+import java.util.HashSet; |
+import java.util.Set; |
/** |
* A {@link ContextMenuPopulator} used for showing the default Chrome context menu. |
@@ -49,41 +51,28 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { |
public static final int FULLSCREEN_TAB_MODE = 2; |
// Items that are included in all context menus. |
- private static final int[] BASE_WHITELIST = { |
- R.id.contextmenu_copy_link_address, |
- R.id.contextmenu_call, |
- R.id.contextmenu_send_message, |
- R.id.contextmenu_add_to_contacts, |
- R.id.contextmenu_copy, |
- R.id.contextmenu_copy_link_text, |
- R.id.contextmenu_load_original_image, |
- R.id.contextmenu_save_link_as, |
- R.id.contextmenu_save_image, |
- R.id.contextmenu_share_image, |
- R.id.contextmenu_save_video, |
- }; |
+ private static final Set<Integer> BASE_WHITELIST = CollectionUtil.newHashSet( |
+ R.id.contextmenu_copy_link_address, R.id.contextmenu_call, |
+ R.id.contextmenu_send_message, R.id.contextmenu_add_to_contacts, R.id.contextmenu_copy, |
+ R.id.contextmenu_copy_link_text, R.id.contextmenu_load_original_image, |
+ R.id.contextmenu_save_link_as, R.id.contextmenu_save_image, |
+ R.id.contextmenu_share_image, R.id.contextmenu_save_video); |
// Items that are included for normal Chrome browser mode. |
- private static final int[] NORMAL_MODE_WHITELIST = { |
- R.id.contextmenu_open_in_new_tab, |
- R.id.contextmenu_open_in_other_window, |
- R.id.contextmenu_open_in_incognito_tab, |
- R.id.contextmenu_save_link_as, |
- R.id.contextmenu_open_image_in_new_tab, |
- R.id.contextmenu_search_by_image, |
- }; |
+ private static final Set<Integer> NORMAL_MODE_WHITELIST = CollectionUtil.newHashSet( |
+ R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_other_window, |
+ R.id.contextmenu_open_in_incognito_tab, R.id.contextmenu_save_link_as, |
+ R.id.contextmenu_open_image_in_new_tab, R.id.contextmenu_search_by_image); |
// Additional items for custom tabs mode. |
- private static final int[] CUSTOM_TAB_MODE_WHITELIST = { |
+ private static final Set<Integer> CUSTOM_TAB_MODE_WHITELIST = CollectionUtil.newHashSet( |
R.id.contextmenu_open_image, R.id.contextmenu_search_by_image, |
R.id.contextmenu_open_in_new_chrome_tab, R.id.contextmenu_open_in_chrome_incognito_tab, |
- R.id.contextmenu_open_in_browser_id, |
- }; |
+ R.id.contextmenu_open_in_browser_id); |
// Additional items for fullscreen tabs mode. |
- private static final int[] FULLSCREEN_TAB_MODE_WHITELIST = { |
- R.id.menu_id_open_in_chrome |
- }; |
+ private static final Set<Integer> FULLSCREEN_TAB_MODE_WHITELIST = |
+ CollectionUtil.newHashSet(R.id.menu_id_open_in_chrome); |
private final ContextMenuItemDelegate mDelegate; |
private MenuInflater mMenuInflater; |
@@ -205,134 +194,155 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { |
menu.setGroupVisible(R.id.contextmenu_group_anchor, params.isAnchor()); |
menu.setGroupVisible(R.id.contextmenu_group_image, params.isImage()); |
menu.setGroupVisible(R.id.contextmenu_group_video, params.isVideo()); |
+ menu.setGroupVisible(R.id.contextmenu_group_message, |
+ MailTo.isMailTo(params.getLinkUrl()) |
+ || UrlUtilities.isTelScheme(params.getLinkUrl())); |
+ Set<Integer> supportedOptions = new HashSet<>(); |
+ supportedOptions.addAll(BASE_WHITELIST); |
+ if (mMode == FULLSCREEN_TAB_MODE) { |
+ supportedOptions.addAll(FULLSCREEN_TAB_MODE_WHITELIST); |
+ } else if (mMode == CUSTOM_TAB_MODE) { |
+ supportedOptions.addAll(CUSTOM_TAB_MODE_WHITELIST); |
+ if (!ChromePreferenceManager.getInstance().getCachedChromeDefaultBrowser()) { |
+ menu.findItem(R.id.contextmenu_open_in_browser_id) |
+ .setTitle(mDelegate.getTitleForOpenTabInExternalApp()); |
+ } |
+ } else { |
+ supportedOptions.addAll(NORMAL_MODE_WHITELIST); |
+ } |
+ |
+ Set<Integer> disabledOptions = getDisabledOptions(params); |
+ // Iterate through the entire menu list, if if doesn't exist in the map, don't show it. |
+ for (int i = 0; i < menu.size(); i++) { |
+ MenuItem item = menu.getItem(i); |
+ if (!item.isVisible()) continue; |
+ item.setVisible(supportedOptions.contains(item.getItemId()) |
+ && !disabledOptions.contains(item.getItemId())); |
+ } |
+ |
+ // Special case for searching by image element. |
+ if (supportedOptions.contains(R.id.contextmenu_search_by_image)) { |
+ menu.findItem(R.id.contextmenu_search_by_image) |
+ .setTitle(context.getString(R.string.contextmenu_search_web_for_image, |
+ TemplateUrlService.getInstance() |
+ .getDefaultSearchEngineTemplateUrl() |
+ .getShortName())); |
+ } |
+ } |
+ |
+ /** |
+ * Given a set of params. It creates a list of items that should not be accessible in specific |
+ * instances. Since it doesn't have access to the menu groups, they need to be filtered outside |
+ * of this method. |
+ * @param params The parameters used to create a list of items that should not be allowed. |
+ */ |
+ private Set<Integer> getDisabledOptions(ContextMenuParams params) { |
+ Set<Integer> disabledOptions = new HashSet<>(); |
if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) { |
- menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_in_other_window); |
} |
if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) { |
- menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_in_incognito_tab); |
} |
if (params.getLinkText().trim().isEmpty() || params.isImage()) { |
- menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_copy_link_text); |
} |
if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUrl())) { |
- menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_in_other_window); |
+ disabledOptions.add(R.id.contextmenu_open_in_new_tab); |
+ disabledOptions.add(R.id.contextmenu_open_in_incognito_tab); |
} |
if (MailTo.isMailTo(params.getLinkUrl())) { |
- menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); |
- menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); |
- menu.setGroupVisible(R.id.contextmenu_group_message, true); |
+ disabledOptions.add(R.id.contextmenu_copy_link_text); |
+ disabledOptions.add(R.id.contextmenu_copy_link_address); |
if (!mDelegate.supportsSendEmailMessage()) { |
- menu.findItem(R.id.contextmenu_send_message).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_send_message); |
} |
if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo()) |
|| !mDelegate.supportsAddToContacts()) { |
- menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_add_to_contacts); |
} |
- menu.findItem(R.id.contextmenu_call).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_call); |
} else if (UrlUtilities.isTelScheme(params.getLinkUrl())) { |
- menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); |
- menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); |
- menu.setGroupVisible(R.id.contextmenu_group_message, true); |
+ disabledOptions.add(R.id.contextmenu_copy_link_text); |
+ disabledOptions.add(R.id.contextmenu_copy_link_address); |
if (!mDelegate.supportsCall()) { |
- menu.findItem(R.id.contextmenu_call).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_call); |
} |
if (!mDelegate.supportsSendTextMessage()) { |
- menu.findItem(R.id.contextmenu_send_message).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_send_message); |
} |
if (!mDelegate.supportsAddToContacts()) { |
- menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_add_to_contacts); |
} |
- } else { |
- menu.setGroupVisible(R.id.contextmenu_group_message, false); |
} |
- menu.findItem(R.id.contextmenu_save_link_as).setVisible( |
- UrlUtilities.isDownloadableScheme(params.getLinkUrl())); |
+ if (!UrlUtilities.isDownloadableScheme(params.getLinkUrl())) { |
+ disabledOptions.add(R.id.contextmenu_save_link_as); |
+ } |
+ boolean isSrcDownloadableScheme = UrlUtilities.isDownloadableScheme(params.getSrcUrl()); |
if (params.isVideo()) { |
- menu.findItem(R.id.contextmenu_save_video).setVisible( |
- params.canSaveMedia() && UrlUtilities.isDownloadableScheme(params.getSrcUrl())); |
+ boolean saveableAndDownloadable = params.canSaveMedia() && isSrcDownloadableScheme; |
+ if (!saveableAndDownloadable) { |
+ disabledOptions.add(R.id.contextmenu_save_video); |
+ } |
} else if (params.isImage() && params.imageWasFetchedLoFi()) { |
DataReductionProxyUma.previewsLoFiContextMenuAction( |
DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SHOWN); |
// All image context menu items other than "Load image," "Open original image in |
// new tab," and "Copy image URL" should be disabled on Lo-Fi images. |
- menu.findItem(R.id.contextmenu_save_image).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_image).setVisible(false); |
- menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); |
- menu.findItem(R.id.contextmenu_share_image).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_save_image); |
+ disabledOptions.add(R.id.contextmenu_open_image); |
+ disabledOptions.add(R.id.contextmenu_search_by_image); |
+ disabledOptions.add(R.id.contextmenu_share_image); |
} else if (params.isImage() && !params.imageWasFetchedLoFi()) { |
- menu.findItem(R.id.contextmenu_load_original_image).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_load_original_image); |
- menu.findItem(R.id.contextmenu_save_image).setVisible( |
- UrlUtilities.isDownloadableScheme(params.getSrcUrl())); |
+ if (!isSrcDownloadableScheme) { |
+ disabledOptions.add(R.id.contextmenu_save_image); |
+ } |
// Avoid showing open image option for same image which is already opened. |
if (mDelegate.getPageUrl().equals(params.getSrcUrl())) { |
- menu.findItem(R.id.contextmenu_open_image).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_image); |
} |
final TemplateUrlService templateUrlServiceInstance = TemplateUrlService.getInstance(); |
- final boolean isSearchByImageAvailable = |
- UrlUtilities.isDownloadableScheme(params.getSrcUrl()) |
- && templateUrlServiceInstance.isLoaded() |
- && templateUrlServiceInstance.isSearchByImageAvailable() |
- && templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl() |
- != null; |
- |
- menu.findItem(R.id.contextmenu_search_by_image).setVisible(isSearchByImageAvailable); |
- if (isSearchByImageAvailable) { |
- menu.findItem(R.id.contextmenu_search_by_image).setTitle( |
- context.getString(R.string.contextmenu_search_web_for_image, |
- TemplateUrlService.getInstance() |
- .getDefaultSearchEngineTemplateUrl().getShortName())); |
+ final boolean isSearchByImageAvailable = isSrcDownloadableScheme |
+ && templateUrlServiceInstance.isLoaded() |
+ && templateUrlServiceInstance.isSearchByImageAvailable() |
+ && templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl() != null; |
+ |
+ if (!isSearchByImageAvailable) { |
+ disabledOptions.add(R.id.contextmenu_search_by_image); |
} |
} |
// Hide all items that could spawn additional tabs until FRE has been completed. |
if (!FirstRunStatus.getFirstRunFlowComplete()) { |
- menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false); |
- menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); |
- menu.findItem(R.id.menu_id_open_in_chrome).setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_image_in_new_tab); |
+ disabledOptions.add(R.id.contextmenu_open_in_other_window); |
+ disabledOptions.add(R.id.contextmenu_open_in_new_tab); |
+ disabledOptions.add(R.id.contextmenu_open_in_incognito_tab); |
+ disabledOptions.add(R.id.contextmenu_search_by_image); |
+ disabledOptions.add(R.id.menu_id_open_in_chrome); |
} |
- if (mMode == FULLSCREEN_TAB_MODE) { |
- removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST); |
- } else if (mMode == CUSTOM_TAB_MODE) { |
- removeUnsupportedItems(menu, CUSTOM_TAB_MODE_WHITELIST); |
- MenuItem defaultOpenMenuItem = menu.findItem(R.id.contextmenu_open_in_browser_id); |
+ if (mMode == CUSTOM_TAB_MODE) { |
if (ChromePreferenceManager.getInstance().getCachedChromeDefaultBrowser()) { |
- defaultOpenMenuItem.setVisible(false); |
+ disabledOptions.add(R.id.contextmenu_open_in_browser_id); |
} else { |
- menu.findItem(R.id.contextmenu_open_in_new_chrome_tab).setVisible(false); |
- menu.findItem(R.id.contextmenu_open_in_chrome_incognito_tab).setVisible(false); |
- defaultOpenMenuItem.setTitle(mDelegate.getTitleForOpenTabInExternalApp()); |
+ disabledOptions.add(R.id.contextmenu_open_in_new_chrome_tab); |
+ disabledOptions.add(R.id.contextmenu_open_in_chrome_incognito_tab); |
} |
- } else { |
- removeUnsupportedItems(menu, NORMAL_MODE_WHITELIST); |
} |
- } |
- private void removeUnsupportedItems(ContextMenu menu, int[] whitelist) { |
- Arrays.sort(BASE_WHITELIST); |
- Arrays.sort(whitelist); |
- for (int i = 0; i < menu.size(); i++) { |
- MenuItem item = menu.getItem(i); |
- if (Arrays.binarySearch(whitelist, item.getItemId()) < 0 |
- && Arrays.binarySearch(BASE_WHITELIST, item.getItemId()) < 0) { |
- menu.removeItem(item.getItemId()); |
- i--; |
- } |
- } |
+ return disabledOptions; |
} |
@Override |