Fix handling of "allow fds" state.

Didn't take into account nesting of bundles.  Boo.

Change-Id: Ic8cf21ad8d6f4938a3e105128624c9d162310d01
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index e698c1d..28206b7 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -1597,7 +1597,7 @@
      * @param parcel The parcel to copy this bundle to.
      */
     public void writeToParcel(Parcel parcel, int flags) {
-        final boolean oldAllowFds = parcel.setAllowFds(mAllowFds);
+        final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
         try {
             if (mParcelledData != null) {
                 int length = mParcelledData.dataSize();
@@ -1619,7 +1619,7 @@
                 parcel.setDataPosition(newPos);
             }
         } finally {
-            parcel.setAllowFds(oldAllowFds);
+            parcel.restoreAllowFds(oldAllowFds);
         }
     }
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 36a08b9..15e3af4 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -324,7 +324,10 @@
     public final native void setDataCapacity(int size);
 
     /** @hide */
-    public final native boolean setAllowFds(boolean allowFds);
+    public final native boolean pushAllowFds(boolean allowFds);
+
+    /** @hide */
+    public final native void restoreAllowFds(boolean lastValue);
 
     /**
      * Returns the raw bytes of the parcel.
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index efdaad6..1718e74 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1303,16 +1303,24 @@
     }
 }
 
-static jboolean android_os_Parcel_setAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
+static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
 {
     Parcel* parcel = parcelForJavaObject(env, clazz);
     jboolean ret = JNI_TRUE;
     if (parcel != NULL) {
-        ret = (jboolean)parcel->setAllowFds((bool)allowFds);
+        ret = (jboolean)parcel->pushAllowFds(allowFds);
     }
     return ret;
 }
 
+static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
+{
+    Parcel* parcel = parcelForJavaObject(env, clazz);
+    if (parcel != NULL) {
+        parcel->restoreAllowFds((bool)lastValue);
+    }
+}
+
 static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
                                           jobject data, jint offset,
                                           jint length)
@@ -1810,7 +1818,8 @@
     {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
     {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
     {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
-    {"setAllowFds",         "(Z)Z", (void*)android_os_Parcel_setAllowFds},
+    {"pushAllowFds",        "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
+    {"restoreAllowFds",     "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
     {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
     {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
     {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index d9737852..3fa2acb 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -59,7 +59,8 @@
     status_t            appendFrom(const Parcel *parcel,
                                    size_t start, size_t len);
 
-    bool                setAllowFds(bool allowFds);
+    bool                pushAllowFds(bool allowFds);
+    void                restoreAllowFds(bool lastValue);
 
     bool                hasFileDescriptors() const;
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 9552c1c..608877e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -447,13 +447,20 @@
     return err;
 }
 
-bool Parcel::setAllowFds(bool allowFds)
+bool Parcel::pushAllowFds(bool allowFds)
 {
     const bool origValue = mAllowFds;
-    mAllowFds = allowFds;
+    if (!allowFds) {
+        mAllowFds = false;
+    }
     return origValue;
 }
 
+void Parcel::restoreAllowFds(bool lastValue)
+{
+    mAllowFds = lastValue;
+}
+
 bool Parcel::hasFileDescriptors() const
 {
     if (!mFdsKnown) {