Index: chrome/android/java/src/org/chromium/chrome/browser/util/IntentUtils.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/IntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/util/IntentUtils.java |
index ae7f1182eb2fa21ca09529ce71cad562532e1398..401e2692aeb6307060d0c31794132ca55b41cbe3 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/util/IntentUtils.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/util/IntentUtils.java |
@@ -8,11 +8,15 @@ import android.content.ComponentName; |
import android.content.Context; |
import android.content.Intent; |
import android.content.pm.ResolveInfo; |
+import android.os.Build; |
import android.os.Bundle; |
+import android.os.IBinder; |
import android.os.Parcelable; |
import org.chromium.base.Log; |
+import org.chromium.base.VisibleForTesting; |
+import java.lang.reflect.Method; |
import java.util.ArrayList; |
import java.util.List; |
@@ -167,4 +171,62 @@ public class IntentUtils { |
return null; |
} |
} |
+ |
+ /** |
+ * @return a Binder from an Intent, or null. |
+ * |
+ * Creates a temporary copy of the extra Bundle, which is required as |
+ * Intent#getBinderExtra() doesn't exist, but Bundle.getBinder() does. |
+ */ |
+ public static IBinder safeGetBinderExtra(Intent intent, String name) { |
+ if (!intent.hasExtra(name)) return null; |
+ try { |
+ Bundle extras = intent.getExtras(); |
+ // Bundle#getBinder() is public starting at API level 18, but exists |
+ // in previous SDKs as a hidden method named "getIBinder" (which |
+ // still exists as of L MR1 but is hidden and deprecated). |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { |
+ return extras.getBinder(name); |
+ } else { |
+ Method getBinderMethod = Bundle.class.getMethod("getIBinder", String.class); |
+ return (IBinder) getBinderMethod.invoke(extras, name); |
+ } |
+ } catch (Throwable t) { |
+ // Catches un-parceling exceptions. |
+ Log.e(TAG, "getBinder failed on intent " + intent); |
+ return null; |
+ } |
+ } |
+ |
+ /** |
+ * Inserts a {@link Binder} value into an Intent as an extra. |
+ * |
+ * This is the same as {@link Bundle#putBinder()}, but works below API level |
+ * 18. |
+ * |
+ * @param intent Intent to put the binder into. |
+ * @param name Key. |
+ * @param binder Binder object. |
+ */ |
+ @VisibleForTesting |
+ public static void safePutBinderExtra(Intent intent, String name, IBinder binder) { |
+ if (intent == null) return; |
+ Bundle bundle = new Bundle(); |
+ try { |
+ // Bundle#putBinder() is public starting at API level 18, but exists |
+ // in previous SDKs as a hidden method named "putIBinder" (which |
+ // still exists as of L MR1 but is hidden and deprecated). |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { |
+ bundle.putBinder(name, binder); |
+ } else { |
+ Method putBinderMethod = |
+ Bundle.class.getMethod("putIBinder", String.class, IBinder.class); |
+ putBinderMethod.invoke(bundle, name, binder); |
+ } |
+ } catch (Throwable t) { |
+ // Catches parceling exceptions. |
+ Log.e(TAG, "putBinder failed on bundle " + bundle); |
+ } |
+ intent.putExtras(bundle); |
+ } |
} |