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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java

Issue 2917703004: [Android] Wrap all share parameters into the ShareParams class (Closed)
Patch Set: Update based on Ted and Yusuf's comments. Created 3 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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.share; 5 package org.chromium.chrome.browser.share;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.app.Activity; 8 import android.app.Activity;
9 import android.app.PendingIntent; 9 import android.app.PendingIntent;
10 import android.content.BroadcastReceiver; 10 import android.content.BroadcastReceiver;
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 278
279 /** 279 /**
280 * Creates and shows a share intent picker dialog or starts a share intent d irectly with the 280 * Creates and shows a share intent picker dialog or starts a share intent d irectly with the
281 * activity that was most recently used to share based on shareDirectly valu e. 281 * activity that was most recently used to share based on shareDirectly valu e.
282 * 282 *
283 * This function will save |screenshot| under {app's root}/files/images/scre enshot (or 283 * This function will save |screenshot| under {app's root}/files/images/scre enshot (or
284 * /sdcard/DCIM/browser-images/screenshot if ADK is lower than JB MR2). 284 * /sdcard/DCIM/browser-images/screenshot if ADK is lower than JB MR2).
285 * Cleaning up doesn't happen automatically, and so an app should call clear SharedScreenshots() 285 * Cleaning up doesn't happen automatically, and so an app should call clear SharedScreenshots()
286 * explicitly when needed. 286 * explicitly when needed.
287 * 287 *
288 * @param shareDirectly Whether it should share directly with the activity t hat was most 288 * @param params The container holding the share parameters.
289 * recently used to share.
290 * @param saveLastUsed Whether to save the chosen activity for future direct sharing.
291 * @param activity Activity that is used to access package manager.
292 * @param title Title of the page to be shared.
293 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated
294 * with a space.
295 * @param url URL of the page to be shared.
296 * @param offlineUri URI to the offline MHTML file to be shared.
297 * @param screenshotUri Uri of the screenshot of the page to be shared.
298 * @param callback Optional callback to be called when user makes a choice. Will not be called
299 * if receiving a response when the user makes a choice is n ot supported (on
300 * older Android versions).
301 */ 289 */
302 public static void share(boolean shareDirectly, boolean saveLastUsed, Activi ty activity, 290 public static void share(ShareParams params) {
303 String title, String text, String url, @Nullable Uri offlineUri, Uri screenshotUri, 291 if (params.isShareDirectly()) {
304 @Nullable TargetChosenCallback callback) { 292 ComponentName component = getLastShareComponentName();
305 if (shareDirectly) { 293 if (component == null) return;
306 shareWithLastUsed(activity, title, text, url, offlineUri, screenshot Uri); 294 makeIntentAndShare(params, component);
307 } else if (TargetChosenReceiver.isSupported()) { 295 } else if (TargetChosenReceiver.isSupported()) {
308 makeIntentAndShare(saveLastUsed, activity, title, text, url, offline Uri, screenshotUri, 296 makeIntentAndShare(params, null);
309 null, callback);
310 } else { 297 } else {
311 showShareDialog( 298 showShareDialog(params);
312 saveLastUsed, activity, title, text, url, offlineUri, screen shotUri, callback);
313 } 299 }
314 } 300 }
315 301
316 /** 302 /**
317 * Trigger the share action for the given image data. 303 * Trigger the share action for the given image data.
318 * @param activity The activity used to trigger the share action. 304 * @param activity The activity used to trigger the share action.
319 * @param jpegImageData The image data to be shared in jpeg format. 305 * @param jpegImageData The image data to be shared in jpeg format.
320 * @param name When this is not null, it will share the image directly with the 306 * @param name When this is not null, it will share the image directly with the
321 * {@link ComponentName} 307 * {@link ComponentName}
322 */ 308 */
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 fileUri = ApiCompatibilityUtils.getUriForImageCaptureFile(sa vedFile); 419 fileUri = ApiCompatibilityUtils.getUriForImageCaptureFile(sa vedFile);
434 } 420 }
435 callback.onResult(fileUri); 421 callback.onResult(fileUri);
436 } 422 }
437 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 423 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
438 } 424 }
439 425
440 /** 426 /**
441 * Creates and shows a share intent picker dialog. 427 * Creates and shows a share intent picker dialog.
442 * 428 *
443 * @param saveLastUsed Whether to save the chosen activity for future direct sharing. 429 * @param params The container holding the share parameters.
444 * @param activity Activity that is used to access package manager.
445 * @param title Title of the page to be shared.
446 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated
447 * with a space.
448 * @param url URL of the page to be shared.
449 * @oaram offlineUri URI of the offline page to be shared.
450 * @param screenshotUri Uri of the screenshot of the page to be shared.
451 * @param callback Optional callback to be called when user makes a choice. Will not be called
452 * if receiving a response when the user makes a choice is n ot supported (on
453 * older Android versions).
454 */ 430 */
455 private static void showShareDialog(final boolean saveLastUsed, final Activi ty activity, 431 private static void showShareDialog(final ShareParams params) {
456 final String title, final String text, final String url, final Uri o fflineUri, 432 Activity activity = params.getActivity();
457 final Uri screenshotUri, @Nullable final TargetChosenCallback callba ck) { 433 final TargetChosenCallback callback = params.getCallback();
458 Intent intent = getShareIntent(activity, title, text, url, null, null); 434 Intent intent = getShareLinkAppCompatibilityIntent();
459 PackageManager manager = activity.getPackageManager(); 435 PackageManager manager = activity.getPackageManager();
460 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent , 0); 436 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent , 0);
461 assert resolveInfoList.size() > 0; 437 assert resolveInfoList.size() > 0;
462 if (resolveInfoList.size() == 0) return; 438 if (resolveInfoList.size() == 0) return;
463 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator( manager)); 439 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator( manager));
464 440
465 final ShareDialogAdapter adapter = 441 final ShareDialogAdapter adapter =
466 new ShareDialogAdapter(activity, manager, resolveInfoList); 442 new ShareDialogAdapter(activity, manager, resolveInfoList);
467 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style. AlertDialogTheme); 443 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style. AlertDialogTheme);
468 builder.setTitle(activity.getString(R.string.share_link_chooser_title)); 444 builder.setTitle(activity.getString(R.string.share_link_chooser_title));
469 builder.setAdapter(adapter, null); 445 builder.setAdapter(adapter, null);
470 446
471 // Need a mutable object to record whether the callback has been fired. 447 // Need a mutable object to record whether the callback has been fired.
472 final boolean[] callbackCalled = new boolean[1]; 448 final boolean[] callbackCalled = new boolean[1];
473 449
474 final AlertDialog dialog = builder.create(); 450 final AlertDialog dialog = builder.create();
475 dialog.show(); 451 dialog.show();
476 dialog.getListView().setOnItemClickListener(new OnItemClickListener() { 452 dialog.getListView().setOnItemClickListener(new OnItemClickListener() {
477 @Override 453 @Override
478 public void onItemClick(AdapterView<?> parent, View view, int positi on, long id) { 454 public void onItemClick(AdapterView<?> parent, View view, int positi on, long id) {
479 ResolveInfo info = adapter.getItem(position); 455 ResolveInfo info = adapter.getItem(position);
480 ActivityInfo ai = info.activityInfo; 456 ActivityInfo ai = info.activityInfo;
481 ComponentName component = 457 ComponentName component =
482 new ComponentName(ai.applicationInfo.packageName, ai.nam e); 458 new ComponentName(ai.applicationInfo.packageName, ai.nam e);
459
483 if (callback != null && !callbackCalled[0]) { 460 if (callback != null && !callbackCalled[0]) {
484 callback.onTargetChosen(component); 461 callback.onTargetChosen(component);
485 callbackCalled[0] = true; 462 callbackCalled[0] = true;
486 } 463 }
487 if (saveLastUsed) setLastShareComponentName(component); 464 if (params.isSaveLastUsed()) setLastShareComponentName(component );
488 makeIntentAndShare(false, activity, title, text, url, offlineUri , screenshotUri, 465 makeIntentAndShare(params, component);
489 component, null);
490 dialog.dismiss(); 466 dialog.dismiss();
491 } 467 }
492 }); 468 });
493 469
494 if (callback != null) { 470 if (callback != null) {
495 dialog.setOnDismissListener(new OnDismissListener() { 471 dialog.setOnDismissListener(new OnDismissListener() {
496 @Override 472 @Override
497 public void onDismiss(DialogInterface dialog) { 473 public void onDismiss(DialogInterface dialog) {
498 if (!callbackCalled[0]) { 474 if (!callbackCalled[0]) {
499 callback.onCancel(); 475 callback.onCancel();
500 callbackCalled[0] = true; 476 callbackCalled[0] = true;
501 } 477 }
502 } 478 }
503 }); 479 });
504 } 480 }
505 481
506 if (sFakeIntentReceiverForTesting != null) { 482 if (sFakeIntentReceiverForTesting != null) {
507 sFakeIntentReceiverForTesting.onCustomChooserShown(dialog); 483 sFakeIntentReceiverForTesting.onCustomChooserShown(dialog);
508 } 484 }
509 } 485 }
510 486
511 /** 487 private static void makeIntentAndShare(ShareParams params, @Nullable Compone ntName component) {
512 * Starts a share intent with the activity that was most recently used to sh are. 488 Intent intent = getShareLinkIntent(params);
513 * If there is no most recently used activity, it does nothing. 489 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVI TY_PREVIOUS_IS_TOP);
514 * @param activity Activity that is used to start the share intent. 490 intent.setComponent(component);
515 * @param title Title of the page to be shared. 491 if (intent.getComponent() != null) {
516 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated
517 * with a space.
518 * @param url URL of the page to be shared.
519 * @oaram offlineUri URI of the offline page to be shared.
520 * @param screenshotUri Uri of the screenshot of the page to be shared.
521 */
522 private static void shareWithLastUsed(Activity activity, String title, Strin g text, String url,
523 Uri offlineUri, Uri screenshotUri) {
524 ComponentName component = getLastShareComponentName();
525 if (component == null) return;
526 makeIntentAndShare(
527 false, activity, title, text, url, offlineUri, screenshotUri, co mponent, null);
528 }
529
530 private static void shareIntent(boolean saveLastUsed, Activity activity, Int ent sharingIntent,
531 @Nullable TargetChosenCallback callback) {
532 if (sharingIntent.getComponent() != null) {
533 // If a component was specified, there should not also be a callback . 492 // If a component was specified, there should not also be a callback .
534 assert callback == null; 493 assert params.getCallback() == null;
535 fireIntent(activity, sharingIntent); 494 fireIntent(params.getActivity(), intent);
536 } else { 495 } else {
537 assert TargetChosenReceiver.isSupported(); 496 assert TargetChosenReceiver.isSupported();
538 TargetChosenReceiver.sendChooserIntent(saveLastUsed, activity, shari ngIntent, callback); 497 TargetChosenReceiver.sendChooserIntent(
498 params.isSaveLastUsed(), params.getActivity(), intent, param s.getCallback());
539 } 499 }
540 } 500 }
541 501
542 private static void makeIntentAndShare(final boolean saveLastUsed, final Act ivity activity,
543 final String title, final String text, final String url, final Uri o fflineUri,
544 final Uri screenshotUri, final ComponentName component,
545 @Nullable final TargetChosenCallback callback) {
546 Intent intent = getDirectShareIntentForComponent(
547 activity, title, text, url, offlineUri, screenshotUri, component );
548 shareIntent(saveLastUsed, activity, intent, callback);
549 }
550
551 /** 502 /**
552 * Set the icon and the title for the menu item used for direct share. 503 * Set the icon and the title for the menu item used for direct share.
553 * 504 *
554 * @param activity Activity that is used to access the package manager. 505 * @param activity Activity that is used to access the package manager.
555 * @param item The menu item that is used for direct share 506 * @param item The menu item that is used for direct share
556 */ 507 */
557 public static void configureDirectShareMenuItem(Activity activity, MenuItem item) { 508 public static void configureDirectShareMenuItem(Activity activity, MenuItem item) {
558 Intent shareIntent = getShareIntent(activity, "", "", "", null, null); 509 Intent shareIntent = getShareLinkAppCompatibilityIntent();
559 Pair<Drawable, CharSequence> directShare = getShareableIconAndName(activ ity, shareIntent); 510 Pair<Drawable, CharSequence> directShare = getShareableIconAndName(activ ity, shareIntent);
560 Drawable directShareIcon = directShare.first; 511 Drawable directShareIcon = directShare.first;
561 CharSequence directShareTitle = directShare.second; 512 CharSequence directShareTitle = directShare.second;
562 513
563 item.setIcon(directShareIcon); 514 item.setIcon(directShareIcon);
564 if (directShareTitle != null) { 515 if (directShareTitle != null) {
565 item.setTitle( 516 item.setTitle(
566 activity.getString(R.string.accessibility_menu_share_via, di rectShareTitle)); 517 activity.getString(R.string.accessibility_menu_share_via, di rectShareTitle));
567 } 518 }
568 } 519 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 @VisibleForTesting 593 @VisibleForTesting
643 public static void setLastShareComponentName(ComponentName component) { 594 public static void setLastShareComponentName(ComponentName component) {
644 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); 595 SharedPreferences preferences = ContextUtils.getAppSharedPreferences();
645 SharedPreferences.Editor editor = preferences.edit(); 596 SharedPreferences.Editor editor = preferences.edit();
646 editor.putString(PACKAGE_NAME_KEY, component.getPackageName()); 597 editor.putString(PACKAGE_NAME_KEY, component.getPackageName());
647 editor.putString(CLASS_NAME_KEY, component.getClassName()); 598 editor.putString(CLASS_NAME_KEY, component.getClassName());
648 editor.apply(); 599 editor.apply();
649 } 600 }
650 601
651 @VisibleForTesting 602 @VisibleForTesting
652 public static Intent getShareIntent(Activity activity, String title, String text, String url, 603 public static Intent getShareLinkIntent(ShareParams params) {
653 Uri offlineUri, Uri screenshotUri) { 604 String url = params.getUrl();
605 String text = params.getText();
654 if (!TextUtils.isEmpty(url)) { 606 if (!TextUtils.isEmpty(url)) {
655 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); 607 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url);
656 if (!TextUtils.isEmpty(text)) { 608 if (!TextUtils.isEmpty(text)) {
657 // Concatenate text and URL with a space. 609 // Concatenate text and URL with a space.
658 text = text + " " + url; 610 text = text + " " + url;
659 } else { 611 } else {
660 text = url; 612 text = url;
661 } 613 }
662 } 614 }
663 615
664 Intent intent = new Intent(Intent.ACTION_SEND); 616 Intent intent = new Intent(Intent.ACTION_SEND);
665 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); 617 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag());
666 intent.putExtra(Intent.EXTRA_SUBJECT, title); 618 intent.putExtra(Intent.EXTRA_SUBJECT, params.getTitle());
667 intent.putExtra(Intent.EXTRA_TEXT, text); 619 intent.putExtra(Intent.EXTRA_TEXT, text);
668 intent.putExtra(EXTRA_TASK_ID, activity.getTaskId()); 620 intent.putExtra(EXTRA_TASK_ID, params.getActivity().getTaskId());
669 621
622 Uri screenshotUri = params.getScreenshotUri();
670 if (screenshotUri != null) { 623 if (screenshotUri != null) {
671 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 624 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
672 }
673 if (screenshotUri != null) {
674 // To give read access to an Intent target, we need to put |screensh otUri| in clipData 625 // To give read access to an Intent target, we need to put |screensh otUri| in clipData
675 // because adding Intent.FLAG_GRANT_READ_URI_PERMISSION doesn't work for 626 // because adding Intent.FLAG_GRANT_READ_URI_PERMISSION doesn't work for
676 // EXTRA_SHARE_SCREENSHOT_AS_STREAM. 627 // EXTRA_SHARE_SCREENSHOT_AS_STREAM.
677 intent.setClipData(ClipData.newRawUri("", screenshotUri)); 628 intent.setClipData(ClipData.newRawUri("", screenshotUri));
678 intent.putExtra(EXTRA_SHARE_SCREENSHOT_AS_STREAM, screenshotUri); 629 intent.putExtra(EXTRA_SHARE_SCREENSHOT_AS_STREAM, screenshotUri);
679 } 630 }
680 if (offlineUri == null) { 631 if (params.getOfflineUri() == null) {
681 intent.setType("text/plain"); 632 intent.setType("text/plain");
682 } else { 633 } else {
683 intent.setType("multipart/related"); 634 intent.setType("multipart/related");
684 intent.putExtra(Intent.EXTRA_STREAM, offlineUri); 635 intent.putExtra(Intent.EXTRA_STREAM, params.getOfflineUri());
685 } 636 }
686 return intent; 637 return intent;
687 } 638 }
688 639
689 /** 640 /**
690 * Creates an Intent to share an image. 641 * Creates an Intent to share an image.
691 * @param imageUri The Uri of the image. 642 * @param imageUri The Uri of the image.
692 * @return The Intent used to share the image. 643 * @return The Intent used to share the image.
693 */ 644 */
694 public static Intent getShareImageIntent(Uri imageUri) { 645 public static Intent getShareImageIntent(Uri imageUri) {
695 Intent intent = new Intent(Intent.ACTION_SEND); 646 Intent intent = new Intent(Intent.ACTION_SEND);
696 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); 647 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag());
697 intent.setType("image/jpeg"); 648 intent.setType("image/jpeg");
698 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 649 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
699 intent.putExtra(Intent.EXTRA_STREAM, imageUri); 650 intent.putExtra(Intent.EXTRA_STREAM, imageUri);
700 return intent; 651 return intent;
701 } 652 }
702 653
703 private static Intent getDirectShareIntentForComponent(Activity activity, St ring title, 654 /**
704 String text, String url, Uri offlineUri, Uri screenshotUri, Componen tName component) { 655 * Convenient method to create an Intent to retrieve all the apps support sh aring text.
Yusuf 2017/06/02 20:07:46 Convenience
ltian 2017/06/02 23:44:39 Done.
705 Intent intent = getShareIntent(activity, title, text, url, offlineUri, s creenshotUri); 656 */
706 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT 657 public static Intent getShareLinkAppCompatibilityIntent() {
707 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 658 Intent intent = new Intent(Intent.ACTION_SEND);
708 intent.setComponent(component); 659 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag());
660 intent.putExtra(Intent.EXTRA_SUBJECT, "");
661 intent.putExtra(Intent.EXTRA_TEXT, "");
662 intent.setType("text/plain");
709 return intent; 663 return intent;
710 } 664 }
711 665
712 /** 666 /**
713 * Gets the {@link ComponentName} of the app that was used to last share. 667 * Gets the {@link ComponentName} of the app that was used to last share.
714 */ 668 */
715 @Nullable 669 @Nullable
716 public static ComponentName getLastShareComponentName() { 670 public static ComponentName getLastShareComponentName() {
717 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); 671 SharedPreferences preferences = ContextUtils.getAppSharedPreferences();
718 String packageName = preferences.getString(PACKAGE_NAME_KEY, null); 672 String packageName = preferences.getString(PACKAGE_NAME_KEY, null);
719 String className = preferences.getString(CLASS_NAME_KEY, null); 673 String className = preferences.getString(CLASS_NAME_KEY, null);
720 if (packageName == null || className == null) return null; 674 if (packageName == null || className == null) return null;
721 return new ComponentName(packageName, className); 675 return new ComponentName(packageName, className);
722 } 676 }
723 } 677 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698