Skip to content
Snippets Groups Projects
Commit 78a5bdee authored by Jim Chen's avatar Jim Chen
Browse files

Bug 1412872 - 1. Implement Parcelable for GeckoBundle; r=snorp

Implement Parcelable interface for GeckoBundle so it can be marshalled
across processes over Bundle, AIDL, etc. Also, add a stub for a
`GeckoBundle.put` method that suggests alternatives to use.

MozReview-Commit-ID: IArNL7LYUPZ
parent adad5418
No related merge requests found
......@@ -641,6 +641,7 @@ GECKOVIEW_AIDLS = \
org/mozilla/gecko/media/IMediaManager.aidl \
org/mozilla/gecko/process/IChildProcess.aidl \
org/mozilla/gecko/process/IProcessManager.aidl \
org/mozilla/gecko/util/GeckoBundle.aidl \
$(NULL)
geckoview_aidl_src_path := $(topsrcdir)/mobile/android/geckoview/src/main/aidl
......
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
parcelable GeckoBundle;
......@@ -14,6 +14,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.util.SimpleArrayMap;
......@@ -27,7 +28,7 @@ import java.util.Iterator;
* int to double) in order to better cooperate with JS objects.
*/
@RobocopTarget
public final class GeckoBundle {
public final class GeckoBundle implements Parcelable {
private static final String LOGTAG = "GeckoBundle";
private static final boolean DEBUG = false;
......@@ -354,6 +355,23 @@ public final class GeckoBundle {
return ret;
}
private void put(final String key, final Object value) {
// We intentionally disallow a generic put() method for type safety and sanity. For
// example, we assume elsewhere in the code that a value belongs to a small list of
// predefined types, and cannot be any arbitrary object. If you want to put an
// Object in the bundle, check the type of the Object first and call the
// corresponding put methods. For example,
//
// if (obj instanceof Integer) {
// bundle.putInt(key, (Integer) key);
// } else if (obj instanceof String) {
// bundle.putString(key, (String) obj);
// } else {
// throw new IllegalArgumentException("unexpected type");
// }
throw new UnsupportedOperationException();
}
/**
* Map a key to a boolean value.
*
......@@ -894,4 +912,55 @@ public final class GeckoBundle {
}
return new GeckoBundle(keys, values);
}
@Override // Parcelable
public int describeContents() {
return 0;
}
@Override // Parcelable
public void writeToParcel(final Parcel dest, final int flags) {
final int len = mMap.size();
dest.writeInt(len);
for (int i = 0; i < len; i++) {
dest.writeString(mMap.keyAt(i));
dest.writeValue(mMap.valueAt(i));
}
}
// AIDL code may call readFromParcel even though it's not part of Parcelable.
public void readFromParcel(final Parcel source) {
final ClassLoader loader = getClass().getClassLoader();
final int len = source.readInt();
mMap.clear();
mMap.ensureCapacity(len);
for (int i = 0; i < len; i++) {
final String key = source.readString();
Object val = source.readValue(loader);
if (val instanceof Parcelable[]) {
final Parcelable[] array = (Parcelable[]) val;
val = Arrays.copyOf(array, array.length, GeckoBundle[].class);
}
mMap.put(key, val);
}
}
public static final Parcelable.Creator<GeckoBundle> CREATOR =
new Parcelable.Creator<GeckoBundle>() {
@Override
public GeckoBundle createFromParcel(final Parcel source) {
final GeckoBundle bundle = new GeckoBundle(0);
bundle.readFromParcel(source);
return bundle;
}
@Override
public GeckoBundle[] newArray(final int size) {
return new GeckoBundle[size];
}
};
}
......@@ -13,6 +13,8 @@ import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import android.os.Parcel;
/**
* Tests the proper operation of EventDispatcher,
*/
......@@ -370,6 +372,19 @@ public class testEventDispatcher extends JavascriptBridgeTest implements BundleE
fAssertEquals("Bundle mixed double array has correct length", 2, mixedDoubleArray.length);
fAssertEquals("Bundle mixed double array index 0 has correct value", 1.0, mixedDoubleArray[0]);
fAssertEquals("Bundle mixed double array index 1 has correct value", 1.5, mixedDoubleArray[1]);
final Parcel parcel = Parcel.obtain();
bundle.writeToParcel(parcel, 0);
bundle.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
final GeckoBundle unparceled = GeckoBundle.CREATOR.createFromParcel(parcel);
fAssertEquals("Bundle created from Parcel equals original", bundle, unparceled);
unparceled.clear();
fAssertEquals("Cleared Bundle is empty", 0, unparceled.size());
unparceled.readFromParcel(parcel);
fAssertEquals("Bundle read from Parcel equals original", bundle, unparceled);
parcel.recycle();
}
private static GeckoBundle createInnerBundle() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment