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

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

Issue 2203273002: navigator.share: Resolve promise only after user chooses a target. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Null-check callback. Fixes crbug.com/637194. Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
index 6ee99ab36e0a232950239e430a812b401389f438..b1464afcba929f8e0fa01bfa9fd2b922f0ac6452 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -24,7 +24,9 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
+import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
import android.util.Pair;
import android.view.MenuItem;
import android.view.View;
@@ -89,6 +91,18 @@ public class ShareHelper {
}
/**
+ * Callback interface for when a target is chosen.
+ */
+ public static interface TargetChosenCallback {
+ /**
+ * Called when the user chooses a target in the share dialog.
+ *
+ * Note that if the user cancels the share dialog, this callback is never called.
+ */
+ public void onTargetChosen(ComponentName chosenComponent);
+ }
+
+ /**
* Receiver to record the chosen component when sharing an Intent.
*/
static class TargetChosenReceiver extends BroadcastReceiver {
@@ -98,12 +112,23 @@ public class ShareHelper {
private static String sTargetChosenReceiveAction;
private static TargetChosenReceiver sLastRegisteredReceiver;
+ private final boolean mSaveLastUsed;
+ @Nullable private final TargetChosenCallback mCallback;
+
+ private TargetChosenReceiver(boolean saveLastUsed,
+ @Nullable TargetChosenCallback callback) {
+ mSaveLastUsed = saveLastUsed;
+ mCallback = callback;
+ }
+
static boolean isSupported() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
- static void sendChooserIntent(Activity activity, Intent sharingIntent) {
+ static void sendChooserIntent(boolean saveLastUsed, Activity activity,
+ Intent sharingIntent,
+ @Nullable TargetChosenCallback callback) {
synchronized (LOCK) {
if (sTargetChosenReceiveAction == null) {
sTargetChosenReceiveAction = activity.getPackageName() + "/"
@@ -113,7 +138,7 @@ public class ShareHelper {
if (sLastRegisteredReceiver != null) {
context.unregisterReceiver(sLastRegisteredReceiver);
}
- sLastRegisteredReceiver = new TargetChosenReceiver();
+ sLastRegisteredReceiver = new TargetChosenReceiver(saveLastUsed, callback);
context.registerReceiver(
sLastRegisteredReceiver, new IntentFilter(sTargetChosenReceiveAction));
}
@@ -121,11 +146,11 @@ public class ShareHelper {
Intent intent = new Intent(sTargetChosenReceiveAction);
intent.setPackage(activity.getPackageName());
intent.putExtra(EXTRA_RECEIVER_TOKEN, sLastRegisteredReceiver.hashCode());
- final PendingIntent callback = PendingIntent.getBroadcast(activity, 0, intent,
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Intent chooserIntent = Intent.createChooser(sharingIntent,
activity.getString(R.string.share_link_chooser_title),
- callback.getIntentSender());
+ pendingIntent.getIntentSender());
activity.startActivity(chooserIntent);
}
@@ -142,7 +167,10 @@ public class ShareHelper {
}
ComponentName target = intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT);
- if (target != null) {
+ if (mCallback != null) {
+ mCallback.onTargetChosen(target);
+ }
+ if (mSaveLastUsed && target != null) {
setLastShareComponentName(target);
}
}
@@ -177,19 +205,27 @@ public class ShareHelper {
*
* @param shareDirectly Whether it should share directly with the activity that was most
* recently used to share.
+ * @param saveLastUsed Whether to save the chosen activity for future direct sharing.
* @param activity Activity that is used to access package manager.
* @param title Title of the page to be shared.
+ * @param text Text to be shared. If both |text| and |url| are supplied, they are concatenated
+ * with a space.
* @param url URL of the page to be shared.
* @param screenshot Screenshot of the page to be shared.
+ * @param callback Optional callback to be called when user makes a choice. Will not be called
+ * if receiving a response when the user makes a choice is not supported (on
+ * older Android versions).
*/
- public static void share(boolean shareDirectly, Activity activity, String title, String url,
- Bitmap screenshot) {
+ public static void share(boolean shareDirectly, boolean saveLastUsed, Activity activity,
+ String title, String text, String url, Bitmap screenshot,
+ @Nullable TargetChosenCallback callback) {
if (shareDirectly) {
- shareWithLastUsed(activity, title, url, screenshot);
+ shareWithLastUsed(activity, title, text, url, screenshot);
} else if (TargetChosenReceiver.isSupported()) {
- makeIntentAndShare(activity, title, url, screenshot, null);
+ makeIntentAndShare(saveLastUsed, activity, title, text, url, screenshot, null,
+ callback);
} else {
- showShareDialog(activity, title, url, screenshot);
+ showShareDialog(saveLastUsed, activity, title, text, url, screenshot, callback);
}
}
@@ -255,14 +291,21 @@ public class ShareHelper {
/**
* Creates and shows a share intent picker dialog.
*
+ * @param saveLastUsed Whether to save the chosen activity for future direct sharing.
* @param activity Activity that is used to access package manager.
* @param title Title of the page to be shared.
+ * @param text Text to be shared. If both |text| and |url| are supplied, they are concatenated
+ * with a space.
* @param url URL of the page to be shared.
* @param screenshot Screenshot of the page to be shared.
+ * @param callback Optional callback to be called when user makes a choice. Will not be called
+ * if receiving a response when the user makes a choice is not supported (on
+ * older Android versions).
*/
- private static void showShareDialog(final Activity activity, final String title,
- final String url, final Bitmap screenshot) {
- Intent intent = getShareIntent(activity, title, url, null);
+ private static void showShareDialog(final boolean saveLastUsed, final Activity activity,
+ final String title, final String text, final String url, final Bitmap screenshot,
+ @Nullable final TargetChosenCallback callback) {
+ Intent intent = getShareIntent(activity, title, text, url, null);
PackageManager manager = activity.getPackageManager();
List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
assert resolveInfoList.size() > 0;
@@ -284,8 +327,10 @@ public class ShareHelper {
ActivityInfo ai = info.activityInfo;
ComponentName component =
new ComponentName(ai.applicationInfo.packageName, ai.name);
- setLastShareComponentName(component);
- makeIntentAndShare(activity, title, url, screenshot, component);
+ if (callback != null) callback.onTargetChosen(component);
+ if (saveLastUsed) setLastShareComponentName(component);
+ makeIntentAndShare(false, activity, title, text, url, screenshot, component,
+ null);
dialog.dismiss();
}
});
@@ -296,30 +341,38 @@ public class ShareHelper {
* If there is no most recently used activity, it does nothing.
* @param activity Activity that is used to start the share intent.
* @param title Title of the page to be shared.
+ * @param text Text to be shared. If both |text| and |url| are supplied, they are concatenated
+ * with a space.
* @param url URL of the page to be shared.
* @param screenshot Screenshot of the page to be shared.
*/
private static void shareWithLastUsed(
- Activity activity, String title, String url, Bitmap screenshot) {
+ Activity activity, String title, String text, String url, Bitmap screenshot) {
ComponentName component = getLastShareComponentName();
if (component == null) return;
- makeIntentAndShare(activity, title, url, screenshot, component);
+ makeIntentAndShare(false, activity, title, text, url, screenshot, component, null);
}
- private static void shareIntent(Activity activity, Intent sharingIntent) {
+ private static void shareIntent(boolean saveLastUsed, Activity activity, Intent sharingIntent,
+ @Nullable TargetChosenCallback callback) {
if (sharingIntent.getComponent() != null) {
+ // If a component was specified, there should not also be a callback.
+ assert callback == null;
activity.startActivity(sharingIntent);
} else {
assert TargetChosenReceiver.isSupported();
- TargetChosenReceiver.sendChooserIntent(activity, sharingIntent);
+ TargetChosenReceiver.sendChooserIntent(saveLastUsed, activity, sharingIntent, callback);
}
}
- private static void makeIntentAndShare(final Activity activity, final String title,
- final String url, final Bitmap screenshot, final ComponentName component) {
+ private static void makeIntentAndShare(final boolean saveLastUsed, final Activity activity,
+ final String title, final String text, final String url, final Bitmap screenshot,
+ final ComponentName component, @Nullable final TargetChosenCallback callback) {
if (screenshot == null) {
- shareIntent(activity,
- getDirectShareIntentForComponent(activity, title, url, null, component));
+ shareIntent(
+ saveLastUsed, activity,
+ getDirectShareIntentForComponent(activity, title, text, url, null, component),
+ callback);
} else {
new AsyncTask<Void, Void, File>() {
@Override
@@ -358,8 +411,11 @@ public class ShareHelper {
!= ApplicationState.HAS_DESTROYED_ACTIVITIES) {
Uri screenshotUri = saveFile == null
? null : UiUtils.getUriForImageCaptureFile(activity, saveFile);
- shareIntent(activity, getDirectShareIntentForComponent(
- activity, title, url, screenshotUri, component));
+ shareIntent(
+ saveLastUsed, activity,
+ getDirectShareIntentForComponent(activity, title, text, url,
+ screenshotUri, component),
+ callback);
}
}
}.execute();
@@ -379,7 +435,7 @@ public class ShareHelper {
final ComponentName component = getLastShareComponentName();
boolean isComponentValid = false;
if (component != null) {
- Intent intent = getShareIntent(activity, "", "", null);
+ Intent intent = getShareIntent(activity, "", "", "", null);
intent.setPackage(component.getPackageName());
PackageManager manager = activity.getPackageManager();
List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
@@ -439,13 +495,22 @@ public class ShareHelper {
@VisibleForTesting
protected static Intent getShareIntent(
- Activity activity, String title, String url, Uri screenshotUri) {
- url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url);
+ Activity activity, String title, String text, String url, Uri screenshotUri) {
+ if (!TextUtils.isEmpty(url)) {
+ url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url);
+ if (!TextUtils.isEmpty(text)) {
+ // Concatenate text and URL with a space.
+ text = text + " " + url;
+ } else {
+ text = url;
+ }
+ }
+
Intent intent = new Intent(Intent.ACTION_SEND);
intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag());
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, title);
- intent.putExtra(Intent.EXTRA_TEXT, url);
+ intent.putExtra(Intent.EXTRA_TEXT, text);
intent.putExtra(EXTRA_TASK_ID, activity.getTaskId());
if (screenshotUri != null) {
@@ -469,9 +534,9 @@ public class ShareHelper {
}
private static Intent getDirectShareIntentForComponent(
- Activity activity, String title, String url,
+ Activity activity, String title, String text, String url,
Uri screenshotUri, ComponentName component) {
- Intent intent = getShareIntent(activity, title, url, screenshotUri);
+ Intent intent = getShareIntent(activity, title, text, url, screenshotUri);
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
| Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
intent.setComponent(component);

Powered by Google App Engine
This is Rietveld 408576698