some work to try to reduce the code size of some native libraries

- make sure that all binder Bn classes define a ctor and dtor in their respective library.
  This avoids duplication of the ctor/dtor in libraries where these objects are instantiated.
  This is also cleaner, should we want these ctor/dtor to do something one day.

- same change as above for some Bp classes and various other non-binder classes

- moved the definition of CHECK_INTERFACE() in IInterface.h instead of having it everywhere.

- improved the CHECK_INTERFACE() macro so it calls a single method in Parcel, instead of inlining its code everywhere

- IBinder::getInterfaceDescriptor() now returns a "const String16&" instead of String16, which saves calls to String16 and ~String16

- implemented a cache for BpBinder::getInterfaceDescriptor(), since this does an IPC. HOWEVER, this method never seems to be called.
  The cache makes BpBinder bigger, so we need to figure out if we need this method at all.
This commit is contained in:
Mathias Agopian 2009-05-22 19:00:22 -07:00
parent 5f2397488a
commit 83c0446f27
29 changed files with 163 additions and 116 deletions

View File

@ -1052,12 +1052,6 @@ status_t CameraService::dump(int fd, const Vector<String16>& args)
}
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t CameraService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -27,7 +27,7 @@ class BBinder : public IBinder
public:
BBinder();
virtual String16 getInterfaceDescriptor() const;
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);
@ -71,6 +71,7 @@ private:
Extras* mExtras;
void* mReserved0;
static String16 sEmptyDescriptor;
};
// ---------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ public:
inline int32_t handle() const { return mHandle; }
virtual String16 getInterfaceDescriptor() const;
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);
@ -106,6 +106,7 @@ private:
};
void reportOneDeath(const Obituary& obit);
bool isDescriptorCached() const;
mutable Mutex mLock;
volatile int32_t mAlive;
@ -113,6 +114,7 @@ private:
Vector<Obituary>* mObituaries;
ObjectManager mObjects;
Parcel* mConstantData;
mutable String16 mDescriptorCache;
};
}; // namespace android

View File

@ -56,7 +56,7 @@ public:
FLAG_ONEWAY = 0x00000001
};
inline IBinder() { }
IBinder();
/**
* Check if this IBinder implements the interface named by
@ -69,7 +69,7 @@ public:
* Return the canonical name of the interface provided by this IBinder
* object.
*/
virtual String16 getInterfaceDescriptor() const = 0;
virtual const String16& getInterfaceDescriptor() const = 0;
virtual bool isBinderAlive() const = 0;
virtual status_t pingBinder() = 0;
@ -147,7 +147,7 @@ public:
virtual BpBinder* remoteBinder();
protected:
inline virtual ~IBinder() { }
virtual ~IBinder();
private:
};

View File

@ -27,10 +27,12 @@ namespace android {
class IInterface : public virtual RefBase
{
public:
IInterface();
sp<IBinder> asBinder();
sp<const IBinder> asBinder() const;
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
@ -49,7 +51,7 @@ class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual String16 getInterfaceDescriptor() const;
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
@ -72,11 +74,14 @@ protected:
#define DECLARE_META_INTERFACE(INTERFACE) \
static const String16 descriptor; \
static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \
virtual String16 getInterfaceDescriptor() const; \
virtual const String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const String16 I##INTERFACE::descriptor(NAME); \
String16 I##INTERFACE::getInterfaceDescriptor() const { \
const String16& I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \
@ -92,9 +97,16 @@ protected:
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
#define CHECK_INTERFACE(interface, data, reply) \
if (!data.checkInterface(this)) { return PERMISSION_DENIED; } \
// ----------------------------------------------------------------------
// No user-servicable parts after this...
// No user-serviceable parts after this...
template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
@ -105,7 +117,7 @@ inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
}
template<typename INTERFACE>
inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const
inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const
{
return INTERFACE::getInterfaceDescriptor();
}

View File

@ -59,6 +59,10 @@ public:
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
BnMemoryHeap();
protected:
virtual ~BnMemoryHeap();
};
// ----------------------------------------------------------------------------
@ -85,6 +89,10 @@ public:
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
BnMemory();
protected:
virtual ~BnMemory();
};
// ----------------------------------------------------------------------------

View File

@ -39,6 +39,10 @@ class HeapInterface : public virtual BnMemoryHeap
public:
// all values must be page-aligned
virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0;
HeapInterface();
protected:
virtual ~HeapInterface();
};
// ----------------------------------------------------------------------------
@ -61,6 +65,10 @@ public:
virtual void dump(const char* what, uint32_t flags = 0) const = 0;
virtual void dump(String8& res,
const char* what, uint32_t flags = 0) const = 0;
AllocatorInterface();
protected:
virtual ~AllocatorInterface();
};
// ----------------------------------------------------------------------------
@ -71,6 +79,7 @@ public:
class SharedHeap : public HeapInterface, public MemoryHeapBase
{
public:
SharedHeap();
SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL);
virtual ~SharedHeap();
virtual sp<IMemory> mapMemory(size_t offset, size_t size);

View File

@ -57,7 +57,8 @@ public:
status_t writeInterfaceToken(const String16& interface);
bool enforceInterface(const String16& interface) const;
bool checkInterface(IBinder*) const;
void freeData();
const size_t* objects() const;
@ -147,7 +148,7 @@ public:
release_func relFunc, void* relCookie);
void print(TextOutput& to, uint32_t flags = 0) const;
private:
Parcel(const Parcel& o);
Parcel& operator=(const Parcel& o);

View File

@ -28,8 +28,8 @@ namespace android {
class TextOutput
{
public:
TextOutput() { }
virtual ~TextOutput() { }
TextOutput();
virtual ~TextOutput();
virtual status_t print(const char* txt, size_t len) = 0;
virtual void moveIndent(int delta) = 0;

View File

@ -108,15 +108,15 @@ namespace android {
*/
class DurationTimer {
public:
DurationTimer(void) {}
~DurationTimer(void) {}
DurationTimer() {}
~DurationTimer() {}
// Start the timer.
void start(void);
void start();
// Stop the timer.
void stop(void);
void stop();
// Get the duration in microseconds.
long long durationUsecs(void) const;
long long durationUsecs() const;
// Subtract two timevals. Returns the difference (ptv1-ptv2) in
// microseconds.

View File

@ -199,11 +199,11 @@ public:
// constructed and released when Autolock goes out of scope.
class Autolock {
public:
inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); }
inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); }
inline ~Autolock() { mpMutex->unlock(); }
inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
inline ~Autolock() { mLock.unlock(); }
private:
Mutex* mpMutex;
Mutex& mLock;
};
private:
@ -291,7 +291,7 @@ protected:
bool exitPending() const;
private:
// Derived class must implemtent threadLoop(). The thread starts its life
// Derived class must implement threadLoop(). The thread starts its life
// here. There are two ways of using the Thread object:
// 1) loop: if threadLoop() returns true, it will be called again if
// requestExit() wasn't called.

View File

@ -27,6 +27,17 @@ namespace android {
// ---------------------------------------------------------------------------
IBinder::IBinder()
: RefBase()
{
}
IBinder::~IBinder()
{
}
// ---------------------------------------------------------------------------
sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)
{
return NULL;
@ -58,6 +69,8 @@ public:
// ---------------------------------------------------------------------------
String16 BBinder::sEmptyDescriptor;
BBinder::BBinder()
: mExtras(NULL)
{
@ -73,10 +86,10 @@ status_t BBinder::pingBinder()
return NO_ERROR;
}
String16 BBinder::getInterfaceDescriptor() const
const String16& BBinder::getInterfaceDescriptor() const
{
LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
return String16();
return sEmptyDescriptor;
}
status_t BBinder::transact(

View File

@ -98,16 +98,33 @@ BpBinder::BpBinder(int32_t handle)
IPCThreadState::self()->incWeakHandle(handle);
}
String16 BpBinder::getInterfaceDescriptor() const
bool BpBinder::isDescriptorCached() const {
Mutex::Autolock _l(mLock);
return mDescriptorCache.size() ? true : false;
}
const String16& BpBinder::getInterfaceDescriptor() const
{
String16 res;
Parcel send, reply;
status_t err = const_cast<BpBinder*>(this)->transact(
INTERFACE_TRANSACTION, send, &reply);
if (err == NO_ERROR) {
res = reply.readString16();
if (isDescriptorCached() == false) {
Parcel send, reply;
// do the IPC without a lock held.
status_t err = const_cast<BpBinder*>(this)->transact(
INTERFACE_TRANSACTION, send, &reply);
if (err == NO_ERROR) {
String16 res(reply.readString16());
Mutex::Autolock _l(mLock);
// mDescriptorCache could have been assigned while the lock was
// released.
if (mDescriptorCache.size() == 0)
mDescriptorCache = res;
}
}
return res;
// we're returning a reference to a non-static object here. Usually this
// is not something smart to do, however, with binder objects it is
// (usually) safe because they are reference-counted.
return mDescriptorCache;
}
bool BpBinder::isBinderAlive() const

View File

@ -20,6 +20,13 @@ namespace android {
// ---------------------------------------------------------------------------
IInterface::IInterface()
: RefBase() {
}
IInterface::~IInterface() {
}
sp<IBinder> IInterface::asBinder()
{
return this ? onAsBinder() : NULL;

View File

@ -205,11 +205,11 @@ sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
BnMemory::BnMemory() {
}
BnMemory::~BnMemory() {
}
status_t BnMemory::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
@ -299,11 +299,11 @@ void BpMemoryHeap::assertReallyMapped() const
ssize_t size = reply.readInt32();
uint32_t flags = reply.readInt32();
LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",
asBinder().get(), parcel_fd, size, err, strerror(-err));
int fd = dup( parcel_fd );
LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",
parcel_fd, size, err, strerror(errno));
int access = PROT_READ;
@ -316,7 +316,7 @@ void BpMemoryHeap::assertReallyMapped() const
mRealHeap = true;
mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
if (mBase == MAP_FAILED) {
LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",
asBinder().get(), size, fd, strerror(errno));
close(fd);
} else {
@ -357,8 +357,14 @@ uint32_t BpMemoryHeap::getFlags() const {
IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
BnMemoryHeap::BnMemoryHeap() {
}
BnMemoryHeap::~BnMemoryHeap() {
}
status_t BnMemoryHeap::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case HEAP_ID: {

View File

@ -55,12 +55,6 @@ IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnPermissionController::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -178,12 +178,6 @@ IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnServiceManager::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -38,7 +38,15 @@
#include <sys/file.h>
namespace android {
// ----------------------------------------------------------------------------
HeapInterface::HeapInterface() { }
HeapInterface::~HeapInterface() { }
// ----------------------------------------------------------------------------
AllocatorInterface::AllocatorInterface() { }
AllocatorInterface::~AllocatorInterface() { }
// ----------------------------------------------------------------------------
@ -107,7 +115,7 @@ sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
if (new_memory != 0) {
memory = new Allocation(this, offset, size, new_memory);
} else {
LOGE("couldn't map [%8x, %d]", offset, size);
LOGE("couldn't map [%8lx, %u]", offset, size);
if (size) {
/* NOTE: it's VERY important to not free allocations of size 0
* because they're special as they don't have any record in the
@ -339,6 +347,10 @@ void SimpleBestFitAllocator::dump_l(String8& result,
// ----------------------------------------------------------------------------
SharedHeap::SharedHeap()
: HeapInterface(), MemoryHeapBase()
{
}
SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
: MemoryHeapBase(size, flags, name)

View File

@ -108,7 +108,7 @@ void SubRegionMemory::revoke()
// promote() it.
#if HAVE_ANDROID_OS
if (mSize != NULL) {
if (mSize != 0) {
const sp<MemoryHeapPmem>& heap(getHeap());
int our_fd = heap->heapID();
struct pmem_region sub;

View File

@ -441,9 +441,14 @@ status_t Parcel::writeInterfaceToken(const String16& interface)
return writeString16(interface);
}
bool Parcel::checkInterface(IBinder* binder) const
{
return enforceInterface(binder->getInterfaceDescriptor());
}
bool Parcel::enforceInterface(const String16& interface) const
{
String16 str = readString16();
const String16 str(readString16());
if (str == interface) {
return true;
} else {

View File

@ -221,12 +221,6 @@ IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnCamera::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -66,12 +66,6 @@ IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnCameraClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -49,12 +49,6 @@ IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnCameraService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -49,12 +49,6 @@ IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnOverlay::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -112,12 +112,6 @@ IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnSurface::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -156,62 +156,61 @@ IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags);
if (err == NO_ERROR)
return err;
CHECK_INTERFACE(ISurfaceComposer, data, reply);
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> b = createConnection()->asBinder();
reply->writeStrongBinder(b);
} break;
case OPEN_GLOBAL_TRANSACTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
openGlobalTransaction();
} break;
case CLOSE_GLOBAL_TRANSACTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
closeGlobalTransaction();
} break;
case SET_ORIENTATION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
int orientation = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( setOrientation(dpy, orientation, flags) );
} break;
case FREEZE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( freezeDisplay(dpy, flags) );
} break;
case UNFREEZE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayID dpy = data.readInt32();
uint32_t flags = data.readInt32();
reply->writeInt32( unfreezeDisplay(dpy, flags) );
} break;
case BOOT_FINISHED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
bootFinished();
} break;
case REVOKE_GPU: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
reply->writeInt32( revokeGPU() );
} break;
case SIGNAL: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
signal();
} break;
case GET_CBLK: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> b = getCblk()->asBinder();
reply->writeStrongBinder(b);
} break;
case REQUEST_GPU: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
// TODO: this should be protected by a permission
gpu_info_t info;
sp<IGPUCallback> callback
@ -232,7 +231,7 @@ status_t BnSurfaceComposer::onTransact(
reply->writeInt32(res);
} break;
default:
return UNKNOWN_TRANSACTION;
return BBinder::onTransact(code, data, reply, flags);
}
return NO_ERROR;
}

View File

@ -118,12 +118,6 @@ IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient
// ----------------------------------------------------------------------
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
return PERMISSION_DENIED; \
} } while (0)
status_t BnSurfaceFlingerClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

View File

@ -311,7 +311,8 @@ String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
} else {
void const* start = 0;
name = MapInfo::mapAddressToName(ip, "<unknown>", &start);
snprintf(tmp, 256, "pc %08lx %s", uintptr_t(ip)-uintptr_t(start), name);
snprintf(tmp, 256, "pc %08lx %s",
long(uintptr_t(ip)-uintptr_t(start)), name);
res.append(tmp);
}
res.append("\n");

View File

@ -22,9 +22,17 @@
#include <stdlib.h>
#include <string.h>
namespace android {
// ---------------------------------------------------------------------------
namespace android {
TextOutput::TextOutput() {
}
TextOutput::~TextOutput() {
}
// ---------------------------------------------------------------------------
TextOutput& operator<<(TextOutput& to, bool val)
{