OLD | NEW |
---|---|
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; | 13 import android.view.MenuItem; |
14 import android.webkit.MimeTypeMap; | 14 import android.webkit.MimeTypeMap; |
15 | 15 |
16 import org.chromium.base.metrics.RecordHistogram; | 16 import org.chromium.base.metrics.RecordHistogram; |
17 import org.chromium.chrome.R; | 17 import org.chromium.chrome.R; |
18 import org.chromium.chrome.browser.UrlConstants; | 18 import org.chromium.chrome.browser.UrlConstants; |
19 import org.chromium.chrome.browser.firstrun.FirstRunStatus; | 19 import org.chromium.chrome.browser.firstrun.FirstRunStatus; |
20 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; | 20 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; |
21 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU ma; | 21 import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyU ma; |
22 import org.chromium.chrome.browser.search_engines.TemplateUrlService; | 22 import org.chromium.chrome.browser.search_engines.TemplateUrlService; |
23 import org.chromium.chrome.browser.util.UrlUtilities; | 23 import org.chromium.chrome.browser.util.UrlUtilities; |
24 | 24 |
25 import java.lang.annotation.Retention; | 25 import java.lang.annotation.Retention; |
26 import java.lang.annotation.RetentionPolicy; | 26 import java.lang.annotation.RetentionPolicy; |
27 import java.util.Arrays; | 27 import java.util.Arrays; |
28 import java.util.HashSet; | |
29 import java.util.Iterator; | |
30 import java.util.Set; | |
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 Loading... | |
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 menu.setGroupVisible(R.id.contextmenu_group_message, MailTo.isMailTo(par ams.getLinkUrl()) | |
209 || UrlUtilities.isTelScheme(params.getLinkUrl())); | |
Ted C
2017/02/28 06:10:13
this looks to be indented too much...is this what
JJ
2017/03/01 01:41:04
Yup! Sorry about that, it was yelling at me each t
| |
210 | |
211 Set<Integer> menuIdSet = new HashSet<>(menu.size()); | |
212 for (int i = 0; i < menu.size(); i++) { | |
213 MenuItem item = menu.getItem(i); | |
214 if (item.isVisible()) { | |
215 menuIdSet.add(item.getItemId()); | |
216 } | |
217 } | |
218 trimMenuOptions(params, menuIdSet); | |
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 MenuItem item = menu.getItem(i); | |
223 item.setVisible(menuIdSet.contains(item.getItemId())); | |
224 } | |
225 | |
226 // Special case for searching by image element. | |
227 if (menuIdSet.contains(R.id.contextmenu_search_by_image)) { | |
228 menu.findItem(R.id.contextmenu_search_by_image) | |
229 .setTitle(context.getString(R.string.contextmenu_search_web_ for_image, | |
230 TemplateUrlService.getInstance() | |
231 .getDefaultSearchEngineTemplateUrl() | |
232 .getShortName())); | |
233 } | |
234 } | |
235 | |
236 /** | |
237 * Given a set of params and context, and a list of all the items. This meth od never adds items, | |
238 * only removes or edits them from the | |
239 * list. | |
240 * @param params The parameters used for filtering out the the list of items . | |
241 * @param allItems A set, with all the possible options for a link represent ed as ids Items will | |
242 * be removed based off the parameters. | |
243 */ | |
244 private void trimMenuOptions(ContextMenuParams params, Set<Integer> allItems ) { | |
Ted C
2017/02/28 06:10:13
Instead of this getting the full list of items, wh
JJ
2017/03/01 01:41:04
Alright, take a look at what I did. While it does
| |
205 if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) { | 245 if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) { |
206 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); | 246 allItems.remove(R.id.contextmenu_open_in_other_window); |
207 } | 247 } |
208 | 248 |
209 if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) { | 249 if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) { |
210 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); | 250 allItems.remove(R.id.contextmenu_open_in_incognito_tab); |
211 } | 251 } |
212 | 252 |
213 if (params.getLinkText().trim().isEmpty() || params.isImage()) { | 253 if (params.getLinkText().trim().isEmpty() || params.isImage()) { |
214 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); | 254 allItems.remove(R.id.contextmenu_copy_link_text); |
215 } | 255 } |
216 | 256 |
217 if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUr l())) { | 257 if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUr l())) { |
218 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); | 258 allItems.remove(R.id.contextmenu_open_in_other_window); |
219 menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); | 259 allItems.remove(R.id.contextmenu_open_in_new_tab); |
220 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); | 260 allItems.remove(R.id.contextmenu_open_in_incognito_tab); |
221 } | 261 } |
222 | 262 |
223 if (MailTo.isMailTo(params.getLinkUrl())) { | 263 if (MailTo.isMailTo(params.getLinkUrl())) { |
224 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); | 264 allItems.remove(R.id.contextmenu_copy_link_text); |
225 menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); | 265 allItems.remove(R.id.contextmenu_copy_link_address); |
226 menu.setGroupVisible(R.id.contextmenu_group_message, true); | |
227 if (!mDelegate.supportsSendEmailMessage()) { | 266 if (!mDelegate.supportsSendEmailMessage()) { |
228 menu.findItem(R.id.contextmenu_send_message).setVisible(false); | 267 allItems.remove(R.id.contextmenu_send_message); |
229 } | 268 } |
230 if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo()) | 269 if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo()) |
231 || !mDelegate.supportsAddToContacts()) { | 270 || !mDelegate.supportsAddToContacts()) { |
232 menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false ); | 271 allItems.remove(R.id.contextmenu_add_to_contacts); |
233 } | 272 } |
234 menu.findItem(R.id.contextmenu_call).setVisible(false); | 273 allItems.remove(R.id.contextmenu_call); |
235 } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) { | 274 } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) { |
236 menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false); | 275 allItems.remove(R.id.contextmenu_copy_link_text); |
237 menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false); | 276 allItems.remove(R.id.contextmenu_copy_link_address); |
238 menu.setGroupVisible(R.id.contextmenu_group_message, true); | |
239 if (!mDelegate.supportsCall()) { | 277 if (!mDelegate.supportsCall()) { |
240 menu.findItem(R.id.contextmenu_call).setVisible(false); | 278 allItems.remove(R.id.contextmenu_call); |
241 } | 279 } |
242 if (!mDelegate.supportsSendTextMessage()) { | 280 if (!mDelegate.supportsSendTextMessage()) { |
243 menu.findItem(R.id.contextmenu_send_message).setVisible(false); | 281 allItems.remove(R.id.contextmenu_send_message); |
244 } | 282 } |
245 if (!mDelegate.supportsAddToContacts()) { | 283 if (!mDelegate.supportsAddToContacts()) { |
246 menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false ); | 284 allItems.remove(R.id.contextmenu_add_to_contacts); |
247 } | 285 } |
248 } else { | |
249 menu.setGroupVisible(R.id.contextmenu_group_message, false); | |
250 } | 286 } |
251 | 287 |
252 menu.findItem(R.id.contextmenu_save_link_as).setVisible( | 288 if (!UrlUtilities.isDownloadableScheme(params.getLinkUrl())) { |
253 UrlUtilities.isDownloadableScheme(params.getLinkUrl())); | 289 allItems.remove(R.id.contextmenu_save_link_as); |
290 } | |
254 | 291 |
255 if (params.imageWasFetchedLoFi() | 292 if (params.imageWasFetchedLoFi() |
256 || !DataReductionProxySettings.getInstance().wasLoFiModeActiveOn MainFrame() | 293 || !DataReductionProxySettings.getInstance().wasLoFiModeActiveOn MainFrame() |
257 || !DataReductionProxySettings.getInstance().canUseDataReduction Proxy( | 294 || !DataReductionProxySettings.getInstance().canUseDataReduction Proxy( |
258 params.getPageUrl())) { | 295 params.getPageUrl())) { |
259 menu.findItem(R.id.contextmenu_load_images).setVisible(false); | 296 allItems.remove(R.id.contextmenu_load_images); |
260 } else { | 297 } else { |
261 // Links can have images as backgrounds that aren't recognized here as images. CSS | 298 // 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. | 299 // 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 | 300 // When Lo-Fi is active, provide the user with a "Load images" optio n on links |
264 // to get the images in these cases. | 301 // to get the images in these cases. |
265 DataReductionProxyUma.previewsLoFiContextMenuAction( | 302 DataReductionProxyUma.previewsLoFiContextMenuAction( |
266 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGES_CONTEXT_MENU_S HOWN); | 303 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGES_CONTEXT_MENU_S HOWN); |
267 } | 304 } |
268 | 305 |
306 boolean isSrcDownloadableScheme = UrlUtilities.isDownloadableScheme(para ms.getSrcUrl()); | |
269 if (params.isVideo()) { | 307 if (params.isVideo()) { |
270 menu.findItem(R.id.contextmenu_save_video).setVisible( | 308 boolean saveableAndDownloadable = params.canSaveMedia() && isSrcDown loadableScheme; |
271 params.canSaveMedia() && UrlUtilities.isDownloadableScheme(p arams.getSrcUrl())); | 309 if (!saveableAndDownloadable) { |
310 allItems.remove(R.id.contextmenu_save_video); | |
311 } | |
272 } else if (params.isImage() && params.imageWasFetchedLoFi()) { | 312 } else if (params.isImage() && params.imageWasFetchedLoFi()) { |
273 DataReductionProxyUma.previewsLoFiContextMenuAction( | 313 DataReductionProxyUma.previewsLoFiContextMenuAction( |
274 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SH OWN); | 314 DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SH OWN); |
275 // All image context menu items other than "Load image," "Open origi nal image in | 315 // 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 . | 316 // new tab," and "Copy image URL" should be disabled on Lo-Fi images . |
277 menu.findItem(R.id.contextmenu_save_image).setVisible(false); | 317 allItems.remove(R.id.contextmenu_save_image); |
278 menu.findItem(R.id.contextmenu_open_image).setVisible(false); | 318 allItems.remove(R.id.contextmenu_open_image); |
279 menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); | 319 allItems.remove(R.id.contextmenu_search_by_image); |
280 menu.findItem(R.id.contextmenu_share_image).setVisible(false); | 320 allItems.remove(R.id.contextmenu_share_image); |
281 } else if (params.isImage() && !params.imageWasFetchedLoFi()) { | 321 } else if (params.isImage() && !params.imageWasFetchedLoFi()) { |
282 menu.findItem(R.id.contextmenu_load_original_image).setVisible(false ); | 322 allItems.remove(R.id.contextmenu_load_original_image); |
283 | 323 |
284 menu.findItem(R.id.contextmenu_save_image).setVisible( | 324 if (!isSrcDownloadableScheme) { |
285 UrlUtilities.isDownloadableScheme(params.getSrcUrl())); | 325 allItems.remove(R.id.contextmenu_save_image); |
326 } | |
286 | 327 |
287 // Avoid showing open image option for same image which is already o pened. | 328 // Avoid showing open image option for same image which is already o pened. |
288 if (mDelegate.getPageUrl().equals(params.getSrcUrl())) { | 329 if (mDelegate.getPageUrl().equals(params.getSrcUrl())) { |
289 menu.findItem(R.id.contextmenu_open_image).setVisible(false); | 330 allItems.remove(R.id.contextmenu_open_image); |
290 } | 331 } |
291 final TemplateUrlService templateUrlServiceInstance = TemplateUrlSer vice.getInstance(); | 332 final TemplateUrlService templateUrlServiceInstance = TemplateUrlSer vice.getInstance(); |
292 final boolean isSearchByImageAvailable = | 333 final boolean isSearchByImageAvailable = isSrcDownloadableScheme |
293 UrlUtilities.isDownloadableScheme(params.getSrcUrl()) | 334 && templateUrlServiceInstance.isLoaded() |
294 && templateUrlServiceInstance.isLoaded() | 335 && templateUrlServiceInstance.isSearchByImageAvailable() |
295 && templateUrlServiceInstance.isSearchByImageAvailab le() | 336 && templateUrlServiceInstance.getDefaultSearchEngineTemplate Url() != null; |
296 && templateUrlServiceInstance.getDefaultSearchEngine TemplateUrl() | |
297 != null; | |
298 | 337 |
299 menu.findItem(R.id.contextmenu_search_by_image).setVisible(isSearchB yImageAvailable); | 338 if (!isSearchByImageAvailable) { |
300 if (isSearchByImageAvailable) { | 339 allItems.remove(R.id.contextmenu_search_by_image); |
301 menu.findItem(R.id.contextmenu_search_by_image).setTitle( | |
302 context.getString(R.string.contextmenu_search_web_for_im age, | |
303 TemplateUrlService.getInstance() | |
304 .getDefaultSearchEngineTemplateUrl().get ShortName())); | |
305 } | 340 } |
306 } | 341 } |
307 | 342 |
308 // Hide all items that could spawn additional tabs until FRE has been co mpleted. | 343 // Hide all items that could spawn additional tabs until FRE has been co mpleted. |
309 if (!FirstRunStatus.getFirstRunFlowComplete()) { | 344 if (!FirstRunStatus.getFirstRunFlowComplete()) { |
310 menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(fal se); | 345 allItems.remove(R.id.contextmenu_open_image_in_new_tab); |
311 menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(fals e); | 346 allItems.remove(R.id.contextmenu_open_in_other_window); |
312 menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false); | 347 allItems.remove(R.id.contextmenu_open_in_new_tab); |
313 menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(fal se); | 348 allItems.remove(R.id.contextmenu_open_in_incognito_tab); |
314 menu.findItem(R.id.contextmenu_search_by_image).setVisible(false); | 349 allItems.remove(R.id.contextmenu_search_by_image); |
315 menu.findItem(R.id.menu_id_open_in_chrome).setVisible(false); | 350 allItems.remove(R.id.menu_id_open_in_chrome); |
316 } | 351 } |
317 | 352 |
318 if (mMode == FULLSCREEN_TAB_MODE) { | 353 if (mMode == FULLSCREEN_TAB_MODE) { |
319 removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST); | 354 removeUnsupportedItems(allItems, FULLSCREEN_TAB_MODE_WHITELIST); |
320 } else if (mMode == CUSTOM_TAB_MODE) { | 355 } else if (mMode == CUSTOM_TAB_MODE) { |
321 removeUnsupportedItems(menu, CUSTOM_TAB_MODE_WHITELIST); | 356 removeUnsupportedItems(allItems, CUSTOM_TAB_MODE_WHITELIST); |
322 } else { | 357 } else { |
323 removeUnsupportedItems(menu, NORMAL_MODE_WHITELIST); | 358 removeUnsupportedItems(allItems, NORMAL_MODE_WHITELIST); |
324 } | 359 } |
325 } | 360 } |
326 | 361 |
327 private void removeUnsupportedItems(ContextMenu menu, int[] whitelist) { | 362 private void removeUnsupportedItems(Set<Integer> itemList, int[] whitelist) { |
328 Arrays.sort(BASE_WHITELIST); | 363 Arrays.sort(BASE_WHITELIST); |
329 Arrays.sort(whitelist); | 364 Arrays.sort(whitelist); |
330 for (int i = 0; i < menu.size(); i++) { | 365 for (Iterator<Integer> idIterator = itemList.iterator(); idIterator.hasN ext();) { |
331 MenuItem item = menu.getItem(i); | 366 int itemId = idIterator.next(); |
332 if (Arrays.binarySearch(whitelist, item.getItemId()) < 0 | 367 if (Arrays.binarySearch(whitelist, itemId) < 0 |
333 && Arrays.binarySearch(BASE_WHITELIST, item.getItemId()) < 0 ) { | 368 && Arrays.binarySearch(BASE_WHITELIST, itemId) < 0) { |
334 menu.removeItem(item.getItemId()); | 369 idIterator.remove(); |
335 i--; | |
336 } | 370 } |
337 } | 371 } |
338 } | 372 } |
339 | 373 |
340 @Override | 374 @Override |
341 public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams pa rams, int itemId) { | 375 public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams pa rams, int itemId) { |
342 if (itemId == R.id.contextmenu_open_in_other_window) { | 376 if (itemId == R.id.contextmenu_open_in_other_window) { |
343 ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_OTHER_WI NDOW); | 377 ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_OTHER_WI NDOW); |
344 mDelegate.onOpenInOtherWindow(params.getLinkUrl(), params.getReferre r()); | 378 mDelegate.onOpenInOtherWindow(params.getLinkUrl(), params.getReferre r()); |
345 } else if (itemId == R.id.contextmenu_open_in_new_tab) { | 379 } else if (itemId == R.id.contextmenu_open_in_new_tab) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 } | 466 } |
433 | 467 |
434 return true; | 468 return true; |
435 } | 469 } |
436 | 470 |
437 private void setHeaderText(Context context, ContextMenu menu, String text) { | 471 private void setHeaderText(Context context, ContextMenu menu, String text) { |
438 ContextMenuTitleView title = new ContextMenuTitleView(context, text); | 472 ContextMenuTitleView title = new ContextMenuTitleView(context, text); |
439 menu.setHeaderView(title); | 473 menu.setHeaderView(title); |
440 } | 474 } |
441 } | 475 } |
OLD | NEW |