summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-05-22 14:53:18 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-05-22 14:53:18 -0700
commit9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a (patch)
treed00f0230d2e178a2f1aca915766f0901cc2262f8
parentccf1ab64846112846c0bcd7fc4a623f55588ee46 (diff)
parentd50a458bb291801ab9fdc119301bc7b84b42a6e3 (diff)
downloadframeworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.zip
frameworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.tar.gz
frameworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.tar.bz2
am d50a458b: Merge change 2351 into donut
Merge commit 'd50a458bb291801ab9fdc119301bc7b84b42a6e3' * commit 'd50a458bb291801ab9fdc119301bc7b84b42a6e3': Fix a major bug in Bundle when unparcelling from AIDL.
-rw-r--r--core/java/android/os/Bundle.java68
-rw-r--r--core/java/android/os/Parcel.java68
-rw-r--r--libs/binder/Parcel.cpp8
3 files changed, 69 insertions, 75 deletions
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index b669fa2..a91655f 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -78,6 +78,10 @@ public final class Bundle implements Parcelable, Cloneable {
readFromParcel(parcelledData);
}
+ /* package */ Bundle(Parcel parcelledData, int length) {
+ readFromParcelInner(parcelledData, length);
+ }
+
/**
* Constructs a new, empty Bundle that uses a specific ClassLoader for
* instantiating Parcelable and Serializable objects.
@@ -155,13 +159,14 @@ public final class Bundle implements Parcelable, Cloneable {
return;
}
- mParcelledData.setDataPosition(0);
- Bundle b = mParcelledData.readBundleUnpacked(mClassLoader);
- mMap = b.mMap;
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
-
+ int N = mParcelledData.readInt();
+ if (N < 0) {
+ return;
+ }
+ if (mMap == null) {
+ mMap = new HashMap<String, Object>();
+ }
+ mParcelledData.readMapInternal(mMap, N, mClassLoader);
mParcelledData.recycle();
mParcelledData = null;
}
@@ -1427,7 +1432,25 @@ public final class Bundle implements Parcelable, Cloneable {
* @param parcel The parcel to copy this bundle to.
*/
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeBundle(this);
+ if (mParcelledData != null) {
+ int length = mParcelledData.dataSize();
+ parcel.writeInt(length);
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+ parcel.appendFrom(mParcelledData, 0, length);
+ } else {
+ parcel.writeInt(-1); // dummy, will hold length
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+
+ int oldPos = parcel.dataPosition();
+ parcel.writeMapInternal(mMap);
+ int newPos = parcel.dataPosition();
+
+ // Backpatch length
+ parcel.setDataPosition(oldPos - 8);
+ int length = newPos - oldPos;
+ parcel.writeInt(length);
+ parcel.setDataPosition(newPos);
+ }
}
/**
@@ -1436,8 +1459,33 @@ public final class Bundle implements Parcelable, Cloneable {
* @param parcel The parcel to overwrite this bundle from.
*/
public void readFromParcel(Parcel parcel) {
- mParcelledData = parcel;
- mHasFds = mParcelledData.hasFileDescriptors();
+ int length = parcel.readInt();
+ if (length < 0) {
+ throw new RuntimeException("Bad length in parcel: " + length);
+ }
+ readFromParcelInner(parcel, length);
+ }
+
+ void readFromParcelInner(Parcel parcel, int length) {
+ int magic = parcel.readInt();
+ if (magic != 0x4C444E42) {
+ //noinspection ThrowableInstanceNeverThrown
+ String st = Log.getStackTraceString(new RuntimeException());
+ Log.e("Bundle", "readBundle: bad magic number");
+ Log.e("Bundle", "readBundle: trace = " + st);
+ }
+
+ // Advance within this Parcel
+ int offset = parcel.dataPosition();
+ parcel.setDataPosition(offset + length);
+
+ Parcel p = Parcel.obtain();
+ p.setDataPosition(0);
+ p.appendFrom(parcel, offset, length);
+ p.setDataPosition(0);
+
+ mParcelledData = p;
+ mHasFds = p.hasFileDescriptors();
mFdsKnown = true;
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 9a71f6e..6cfccee 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -457,7 +457,7 @@ public final class Parcel {
* Flatten a Map into the parcel at the current dataPosition(),
* growing dataCapacity() if needed. The Map keys must be String objects.
*/
- private void writeMapInternal(Map<String,Object> val) {
+ /* package */ void writeMapInternal(Map<String,Object> val) {
if (val == null) {
writeInt(-1);
return;
@@ -480,23 +480,7 @@ public final class Parcel {
return;
}
- if (val.mParcelledData != null) {
- int length = val.mParcelledData.dataSize();
- appendFrom(val.mParcelledData, 0, length);
- } else {
- writeInt(-1); // dummy, will hold length
- int oldPos = dataPosition();
- writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
-
- writeMapInternal(val.mMap);
- int newPos = dataPosition();
-
- // Backpatch length
- setDataPosition(oldPos - 4);
- int length = newPos - oldPos;
- writeInt(length);
- setDataPosition(newPos);
- }
+ val.writeToParcel(this, 0);
}
/**
@@ -1352,27 +1336,12 @@ public final class Parcel {
* Returns null if the previously written Bundle object was null.
*/
public final Bundle readBundle(ClassLoader loader) {
- int offset = dataPosition();
int length = readInt();
if (length < 0) {
return null;
}
- int magic = readInt();
- if (magic != 0x4C444E42) {
- //noinspection ThrowableInstanceNeverThrown
- String st = Log.getStackTraceString(new RuntimeException());
- Log.e("Bundle", "readBundle: bad magic number");
- Log.e("Bundle", "readBundle: trace = " + st);
- }
-
- // Advance within this Parcel
- setDataPosition(offset + length + 4);
-
- Parcel p = new Parcel(0);
- p.setDataPosition(0);
- p.appendFrom(this, offset, length + 4);
- p.setDataPosition(0);
- final Bundle bundle = new Bundle(p);
+
+ final Bundle bundle = new Bundle(this, length);
if (loader != null) {
bundle.setClassLoader(loader);
}
@@ -1380,33 +1349,6 @@ public final class Parcel {
}
/**
- * Read and return a new Bundle object from the parcel at the current
- * dataPosition(). Returns null if the previously written Bundle object was
- * null. The returned bundle will have its contents fully unpacked using
- * the given ClassLoader.
- */
- /* package */ Bundle readBundleUnpacked(ClassLoader loader) {
- int length = readInt();
- if (length == -1) {
- return null;
- }
- int magic = readInt();
- if (magic != 0x4C444E42) {
- //noinspection ThrowableInstanceNeverThrown
- String st = Log.getStackTraceString(new RuntimeException());
- Log.e("Bundle", "readBundleUnpacked: bad magic number");
- Log.e("Bundle", "readBundleUnpacked: trace = " + st);
- }
- Bundle m = new Bundle(loader);
- int N = readInt();
- if (N < 0) {
- return null;
- }
- readMapInternal(m.mMap, N, loader);
- return m;
- }
-
- /**
* Read and return a byte[] object from the parcel.
*/
public final native byte[] createByteArray();
@@ -1998,7 +1940,7 @@ public final class Parcel {
private native void init(int obj);
private native void destroy();
- private void readMapInternal(Map outVal, int N,
+ /* package */ void readMapInternal(Map outVal, int N,
ClassLoader loader) {
while (N > 0) {
Object key = readValue(loader);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 0819c29..3747de6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -409,12 +409,16 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
mObjects[idx++] = off;
mObjectsSize++;
- const flat_binder_object* flat
+ flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(mData + off);
acquire_object(proc, *flat, this);
- // take note if the object is a file descriptor
if (flat->type == BINDER_TYPE_FD) {
+ // If this is a file descriptor, we need to dup it so the
+ // new Parcel now owns its own fd, and can declare that we
+ // officially know we have fds.
+ flat->handle = dup(flat->handle);
+ flat->cookie = (void*)1;
mHasFds = mFdsKnown = true;
}
}