From c0a7e690bfd32dd897ceccd04dd0fa6bf6e9cee6 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 13 Jul 2010 15:33:35 -0700 Subject: Add Parcel::readExceptionCode() and Parcel::writeNoException() Add native Parcel methods analogous to the Java versions. Currently, these don't do much, but upcoming StrictMode work changes the RPC calling conventions in some cases, so it's important that everybody uses these consistently, rather than having a lot of code trying to parse RPC responses out of Parcels themselves. As a summary, the current convention that Java Binder services use is to prepend the reply Parcel with an int32 signaling the exception status: 0: no exception -1: Security exception -2: Bad Parcelable -3: ... -4: ... -5: ... ... followed by Parceled String if the exception code is non-zero. With an upcoming change, it'll be the case that a response Parcel can, non-exceptionally return rich data in the header, and also return data to the caller. The important thing to note in this new case is that the first int32 in the reply parcel *will not be zero*, so anybody manually checking for it with reply.readInt32() will get false negative failures. Short summary: If you're calling into a Java service and manually checking the exception status with reply.readInt32(), change it to reply.readExceptionCode(). Change-Id: I23f9a0e53a8cfbbd9759242cfde16723641afe04 --- libs/binder/IPermissionController.cpp | 8 +++----- libs/binder/IServiceManager.cpp | 2 +- libs/binder/Parcel.cpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'libs/binder') diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp index bff4c9b..e13036f 100644 --- a/libs/binder/IPermissionController.cpp +++ b/libs/binder/IPermissionController.cpp @@ -36,7 +36,7 @@ public: : BpInterface(impl) { } - + virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) { Parcel data, reply; @@ -46,7 +46,7 @@ public: data.writeInt32(uid); remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply); // fail on exception - if (reply.readInt32() != 0) return 0; + if (reply.readExceptionCode() != 0) return 0; return reply.readInt32() != 0; } }; @@ -66,8 +66,7 @@ status_t BnPermissionController::onTransact( int32_t pid = data.readInt32(); int32_t uid = data.readInt32(); bool res = checkPermission(permission, pid, uid); - // write exception - reply->writeInt32(0); + reply->writeNoException(); reply->writeInt32(res ? 1 : 0); return NO_ERROR; } break; @@ -77,4 +76,3 @@ status_t BnPermissionController::onTransact( } }; // namespace android - diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index a3a3f0e..1fa4c35 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -158,7 +158,7 @@ public: data.writeString16(name); data.writeStrongBinder(service); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); - return err == NO_ERROR ? reply.readInt32() : err; + return err == NO_ERROR ? reply.readExceptionCode() : err; } virtual Vector listServices() diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index c2574bd..47be1bf 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -754,6 +754,11 @@ restart_write: goto restart_write; } +status_t Parcel::writeNoException() +{ + return writeInt32(0); +} + void Parcel::remove(size_t start, size_t amt) { LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!"); @@ -942,6 +947,12 @@ wp Parcel::readWeakBinder() const return val; } +int32_t Parcel::readExceptionCode() const +{ + int32_t exception_code = readAligned(); + // TODO: skip over the response header here, once that's in. + return exception_code; +} native_handle* Parcel::readNativeHandle() const { -- cgit v1.1