summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/binder/Android.mk45
-rw-r--r--libs/binder/Binder.cpp256
-rw-r--r--libs/binder/BpBinder.cpp365
-rw-r--r--libs/binder/IInterface.cpp42
-rw-r--r--libs/binder/IMemory.cpp480
-rw-r--r--libs/binder/IPCThreadState.cpp1131
-rw-r--r--libs/binder/IPermissionController.cpp78
-rw-r--r--libs/binder/IServiceManager.cpp230
-rw-r--r--libs/binder/MemoryBase.cpp46
-rw-r--r--libs/binder/MemoryDealer.cpp468
-rw-r--r--libs/binder/MemoryHeapBase.cpp192
-rw-r--r--libs/binder/Parcel.cpp1590
-rw-r--r--libs/binder/PermissionCache.cpp113
-rw-r--r--libs/binder/ProcessState.cpp359
-rw-r--r--libs/binder/Static.cpp53
-rw-r--r--libs/gui/Android.mk53
-rw-r--r--libs/gui/BitTube.cpp123
-rw-r--r--libs/gui/BufferQueue.cpp957
-rw-r--r--libs/gui/DisplayEventReceiver.cpp108
-rw-r--r--libs/gui/IDisplayEventConnection.cpp98
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp116
-rw-r--r--libs/gui/ISensorEventConnection.cpp111
-rw-r--r--libs/gui/ISensorServer.cpp102
-rw-r--r--libs/gui/ISurface.cpp66
-rw-r--r--libs/gui/ISurfaceComposer.cpp290
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp133
-rw-r--r--libs/gui/ISurfaceTexture.cpp345
-rw-r--r--libs/gui/LayerState.cpp72
-rw-r--r--libs/gui/Sensor.cpp193
-rw-r--r--libs/gui/SensorEventQueue.cpp149
-rw-r--r--libs/gui/SensorManager.cpp150
-rw-r--r--libs/gui/Surface.cpp386
-rw-r--r--libs/gui/SurfaceComposerClient.cpp603
-rw-r--r--libs/gui/SurfaceTexture.cpp505
-rw-r--r--libs/gui/SurfaceTextureClient.cpp713
-rw-r--r--libs/gui/tests/Android.mk42
-rw-r--r--libs/gui/tests/SurfaceTextureClient_test.cpp697
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp1730
-rw-r--r--libs/gui/tests/Surface_test.cpp132
-rw-r--r--libs/ui/Android.mk48
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp345
-rw-r--r--libs/ui/GraphicBuffer.cpp278
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp150
-rw-r--r--libs/ui/GraphicBufferMapper.cpp99
-rw-r--r--libs/ui/MODULE_LICENSE_APACHE20
-rw-r--r--libs/ui/NOTICE190
-rw-r--r--libs/ui/PixelFormat.cpp146
-rw-r--r--libs/ui/Rect.cpp95
-rw-r--r--libs/ui/Region.cpp679
-rw-r--r--libs/ui/tests/Android.mk6
-rw-r--r--libs/ui/tests/region/Android.mk16
-rw-r--r--libs/ui/tests/region/region.cpp69
-rw-r--r--libs/utils/Android.mk108
-rw-r--r--libs/utils/BasicHashtable.cpp338
-rw-r--r--libs/utils/BlobCache.cpp378
-rw-r--r--libs/utils/BufferedTextOutput.cpp279
-rw-r--r--libs/utils/CallStack.cpp129
-rw-r--r--libs/utils/Debug.cpp318
-rw-r--r--libs/utils/FileMap.cpp225
-rw-r--r--libs/utils/Flattenable.cpp24
-rw-r--r--libs/utils/LinearTransform.cpp262
-rw-r--r--libs/utils/Looper.cpp744
-rw-r--r--libs/utils/MODULE_LICENSE_APACHE20
-rw-r--r--libs/utils/NOTICE190
-rw-r--r--libs/utils/PropertyMap.cpp218
-rw-r--r--libs/utils/README289
-rw-r--r--libs/utils/RefBase.cpp628
-rw-r--r--libs/utils/SharedBuffer.cpp113
-rw-r--r--libs/utils/Static.cpp91
-rw-r--r--libs/utils/StopWatch.cpp88
-rw-r--r--libs/utils/String16.cpp418
-rw-r--r--libs/utils/String8.cpp634
-rw-r--r--libs/utils/StringArray.cpp113
-rw-r--r--libs/utils/SystemClock.cpp139
-rw-r--r--libs/utils/TextOutput.cpp154
-rw-r--r--libs/utils/Threads.cpp952
-rw-r--r--libs/utils/Timers.cpp133
-rw-r--r--libs/utils/Tokenizer.cpp163
-rw-r--r--libs/utils/Trace.cpp47
-rw-r--r--libs/utils/Unicode.cpp576
-rw-r--r--libs/utils/VectorImpl.cpp624
-rw-r--r--libs/utils/misc.cpp185
-rwxr-xr-xlibs/utils/primes.py47
-rw-r--r--libs/utils/tests/Android.mk43
-rw-r--r--libs/utils/tests/BasicHashtable_test.cpp577
-rw-r--r--libs/utils/tests/BlobCache_test.cpp421
-rw-r--r--libs/utils/tests/Looper_test.cpp693
-rw-r--r--libs/utils/tests/String8_test.cpp75
-rw-r--r--libs/utils/tests/TestHelpers.h79
-rw-r--r--libs/utils/tests/Unicode_test.cpp115
90 files changed, 0 insertions, 26053 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
deleted file mode 100644
index d449298..0000000
--- a/libs/binder/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# we have the common sources, plus some device-specific stuff
-sources := \
- Binder.cpp \
- BpBinder.cpp \
- IInterface.cpp \
- IMemory.cpp \
- IPCThreadState.cpp \
- IPermissionController.cpp \
- IServiceManager.cpp \
- MemoryDealer.cpp \
- MemoryBase.cpp \
- MemoryHeapBase.cpp \
- Parcel.cpp \
- PermissionCache.cpp \
- ProcessState.cpp \
- Static.cpp
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
-LOCAL_MODULE := libbinder
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
-LOCAL_SRC_FILES := $(sources)
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
-LOCAL_MODULE := libbinder
-LOCAL_SRC_FILES := $(sources)
-include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
deleted file mode 100644
index e20d8a3..0000000
--- a/libs/binder/Binder.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/Binder.h>
-
-#include <utils/Atomic.h>
-#include <binder/BpBinder.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-#include <stdio.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-IBinder::IBinder()
- : RefBase()
-{
-}
-
-IBinder::~IBinder()
-{
-}
-
-// ---------------------------------------------------------------------------
-
-sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor)
-{
- return NULL;
-}
-
-BBinder* IBinder::localBinder()
-{
- return NULL;
-}
-
-BpBinder* IBinder::remoteBinder()
-{
- return NULL;
-}
-
-bool IBinder::checkSubclass(const void* /*subclassID*/) const
-{
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
-class BBinder::Extras
-{
-public:
- Mutex mLock;
- BpBinder::ObjectManager mObjects;
-};
-
-// ---------------------------------------------------------------------------
-
-BBinder::BBinder()
- : mExtras(NULL)
-{
-}
-
-bool BBinder::isBinderAlive() const
-{
- return true;
-}
-
-status_t BBinder::pingBinder()
-{
- return NO_ERROR;
-}
-
-const String16& BBinder::getInterfaceDescriptor() const
-{
- // This is a local static rather than a global static,
- // to avoid static initializer ordering issues.
- static String16 sEmptyDescriptor;
- ALOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
- return sEmptyDescriptor;
-}
-
-status_t BBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- data.setDataPosition(0);
-
- status_t err = NO_ERROR;
- switch (code) {
- case PING_TRANSACTION:
- reply->writeInt32(pingBinder());
- break;
- default:
- err = onTransact(code, data, reply, flags);
- break;
- }
-
- if (reply != NULL) {
- reply->setDataPosition(0);
- }
-
- return err;
-}
-
-status_t BBinder::linkToDeath(
- const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
-{
- return INVALID_OPERATION;
-}
-
-status_t BBinder::unlinkToDeath(
- const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
- wp<DeathRecipient>* outRecipient)
-{
- return INVALID_OPERATION;
-}
-
-status_t BBinder::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-void BBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
- Extras* e = mExtras;
-
- if (!e) {
- e = new Extras;
- if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
- reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
- delete e;
- e = mExtras;
- }
- if (e == 0) return; // out of memory
- }
-
- AutoMutex _l(e->mLock);
- e->mObjects.attach(objectID, object, cleanupCookie, func);
-}
-
-void* BBinder::findObject(const void* objectID) const
-{
- Extras* e = mExtras;
- if (!e) return NULL;
-
- AutoMutex _l(e->mLock);
- return e->mObjects.find(objectID);
-}
-
-void BBinder::detachObject(const void* objectID)
-{
- Extras* e = mExtras;
- if (!e) return;
-
- AutoMutex _l(e->mLock);
- e->mObjects.detach(objectID);
-}
-
-BBinder* BBinder::localBinder()
-{
- return this;
-}
-
-BBinder::~BBinder()
-{
- if (mExtras) delete mExtras;
-}
-
-
-status_t BBinder::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case INTERFACE_TRANSACTION:
- reply->writeString16(getInterfaceDescriptor());
- return NO_ERROR;
-
- case DUMP_TRANSACTION: {
- int fd = data.readFileDescriptor();
- int argc = data.readInt32();
- Vector<String16> args;
- for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
- args.add(data.readString16());
- }
- return dump(fd, args);
- }
- default:
- return UNKNOWN_TRANSACTION;
- }
-}
-
-// ---------------------------------------------------------------------------
-
-enum {
- // This is used to transfer ownership of the remote binder from
- // the BpRefBase object holding it (when it is constructed), to the
- // owner of the BpRefBase object when it first acquires that BpRefBase.
- kRemoteAcquired = 0x00000001
-};
-
-BpRefBase::BpRefBase(const sp<IBinder>& o)
- : mRemote(o.get()), mRefs(NULL), mState(0)
-{
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
-
- if (mRemote) {
- mRemote->incStrong(this); // Removed on first IncStrong().
- mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
- }
-}
-
-BpRefBase::~BpRefBase()
-{
- if (mRemote) {
- if (!(mState&kRemoteAcquired)) {
- mRemote->decStrong(this);
- }
- mRefs->decWeak(this);
- }
-}
-
-void BpRefBase::onFirstRef()
-{
- android_atomic_or(kRemoteAcquired, &mState);
-}
-
-void BpRefBase::onLastStrongRef(const void* id)
-{
- if (mRemote) {
- mRemote->decStrong(this);
- }
-}
-
-bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- return mRemote ? mRefs->attemptIncStrong(this) : false;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
deleted file mode 100644
index 47a62db..0000000
--- a/libs/binder/BpBinder.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BpBinder"
-//#define LOG_NDEBUG 0
-
-#include <binder/BpBinder.h>
-
-#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-
-//#undef ALOGV
-//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-BpBinder::ObjectManager::ObjectManager()
-{
-}
-
-BpBinder::ObjectManager::~ObjectManager()
-{
- kill();
-}
-
-void BpBinder::ObjectManager::attach(
- const void* objectID, void* object, void* cleanupCookie,
- IBinder::object_cleanup_func func)
-{
- entry_t e;
- e.object = object;
- e.cleanupCookie = cleanupCookie;
- e.func = func;
-
- if (mObjects.indexOfKey(objectID) >= 0) {
- ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
- objectID, this, object);
- return;
- }
-
- mObjects.add(objectID, e);
-}
-
-void* BpBinder::ObjectManager::find(const void* objectID) const
-{
- const ssize_t i = mObjects.indexOfKey(objectID);
- if (i < 0) return NULL;
- return mObjects.valueAt(i).object;
-}
-
-void BpBinder::ObjectManager::detach(const void* objectID)
-{
- mObjects.removeItem(objectID);
-}
-
-void BpBinder::ObjectManager::kill()
-{
- const size_t N = mObjects.size();
- ALOGV("Killing %d objects in manager %p", N, this);
- for (size_t i=0; i<N; i++) {
- const entry_t& e = mObjects.valueAt(i);
- if (e.func != NULL) {
- e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
- }
- }
-
- mObjects.clear();
-}
-
-// ---------------------------------------------------------------------------
-
-BpBinder::BpBinder(int32_t handle)
- : mHandle(handle)
- , mAlive(1)
- , mObitsSent(0)
- , mObituaries(NULL)
-{
- ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
-
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
-}
-
-bool BpBinder::isDescriptorCached() const {
- Mutex::Autolock _l(mLock);
- return mDescriptorCache.size() ? true : false;
-}
-
-const String16& BpBinder::getInterfaceDescriptor() const
-{
- 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;
- }
- }
-
- // 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
-{
- return mAlive != 0;
-}
-
-status_t BpBinder::pingBinder()
-{
- Parcel send;
- Parcel reply;
- status_t err = transact(PING_TRANSACTION, send, &reply);
- if (err != NO_ERROR) return err;
- if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
- return (status_t)reply.readInt32();
-}
-
-status_t BpBinder::dump(int fd, const Vector<String16>& args)
-{
- Parcel send;
- Parcel reply;
- send.writeFileDescriptor(fd);
- const size_t numArgs = args.size();
- send.writeInt32(numArgs);
- for (size_t i = 0; i < numArgs; i++) {
- send.writeString16(args[i]);
- }
- status_t err = transact(DUMP_TRANSACTION, send, &reply);
- return err;
-}
-
-status_t BpBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- // Once a binder has died, it will never come back to life.
- if (mAlive) {
- status_t status = IPCThreadState::self()->transact(
- mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
- return status;
- }
-
- return DEAD_OBJECT;
-}
-
-status_t BpBinder::linkToDeath(
- const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
-{
- Obituary ob;
- ob.recipient = recipient;
- ob.cookie = cookie;
- ob.flags = flags;
-
- LOG_ALWAYS_FATAL_IF(recipient == NULL,
- "linkToDeath(): recipient must be non-NULL");
-
- {
- AutoMutex _l(mLock);
-
- if (!mObitsSent) {
- if (!mObituaries) {
- mObituaries = new Vector<Obituary>;
- if (!mObituaries) {
- return NO_MEMORY;
- }
- ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
- getWeakRefs()->incWeak(this);
- IPCThreadState* self = IPCThreadState::self();
- self->requestDeathNotification(mHandle, this);
- self->flushCommands();
- }
- ssize_t res = mObituaries->add(ob);
- return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
- }
- }
-
- return DEAD_OBJECT;
-}
-
-status_t BpBinder::unlinkToDeath(
- const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
- wp<DeathRecipient>* outRecipient)
-{
- AutoMutex _l(mLock);
-
- if (mObitsSent) {
- return DEAD_OBJECT;
- }
-
- const size_t N = mObituaries ? mObituaries->size() : 0;
- for (size_t i=0; i<N; i++) {
- const Obituary& obit = mObituaries->itemAt(i);
- if ((obit.recipient == recipient
- || (recipient == NULL && obit.cookie == cookie))
- && obit.flags == flags) {
- const uint32_t allFlags = obit.flags|flags;
- if (outRecipient != NULL) {
- *outRecipient = mObituaries->itemAt(i).recipient;
- }
- mObituaries->removeAt(i);
- if (mObituaries->size() == 0) {
- ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- delete mObituaries;
- mObituaries = NULL;
- }
- return NO_ERROR;
- }
- }
-
- return NAME_NOT_FOUND;
-}
-
-void BpBinder::sendObituary()
-{
- ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
- this, mHandle, mObitsSent ? "true" : "false");
-
- mAlive = 0;
- if (mObitsSent) return;
-
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- mObituaries = NULL;
- }
- mObitsSent = 1;
- mLock.unlock();
-
- ALOGV("Reporting death of proxy %p for %d recipients\n",
- this, obits ? obits->size() : 0);
-
- if (obits != NULL) {
- const size_t N = obits->size();
- for (size_t i=0; i<N; i++) {
- reportOneDeath(obits->itemAt(i));
- }
-
- delete obits;
- }
-}
-
-void BpBinder::reportOneDeath(const Obituary& obit)
-{
- sp<DeathRecipient> recipient = obit.recipient.promote();
- ALOGV("Reporting death to recipient: %p\n", recipient.get());
- if (recipient == NULL) return;
-
- recipient->binderDied(this);
-}
-
-
-void BpBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
-{
- AutoMutex _l(mLock);
- ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
- mObjects.attach(objectID, object, cleanupCookie, func);
-}
-
-void* BpBinder::findObject(const void* objectID) const
-{
- AutoMutex _l(mLock);
- return mObjects.find(objectID);
-}
-
-void BpBinder::detachObject(const void* objectID)
-{
- AutoMutex _l(mLock);
- mObjects.detach(objectID);
-}
-
-BpBinder* BpBinder::remoteBinder()
-{
- return this;
-}
-
-BpBinder::~BpBinder()
-{
- ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
-
- IPCThreadState* ipc = IPCThreadState::self();
-
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- if (ipc) ipc->clearDeathNotification(mHandle, this);
- mObituaries = NULL;
- }
- mLock.unlock();
-
- if (obits != NULL) {
- // XXX Should we tell any remaining DeathRecipient
- // objects that the last strong ref has gone away, so they
- // are no longer linked?
- delete obits;
- }
-
- if (ipc) {
- ipc->expungeHandle(mHandle, this);
- ipc->decWeakHandle(mHandle);
- }
-}
-
-void BpBinder::onFirstRef()
-{
- ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->incStrongHandle(mHandle);
-}
-
-void BpBinder::onLastStrongRef(const void* id)
-{
- ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
- IF_ALOGV() {
- printRefs();
- }
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->decStrongHandle(mHandle);
-}
-
-bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
deleted file mode 100644
index 29acf5d..0000000
--- a/libs/binder/IInterface.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/IInterface.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-IInterface::IInterface()
- : RefBase() {
-}
-
-IInterface::~IInterface() {
-}
-
-sp<IBinder> IInterface::asBinder()
-{
- return this ? onAsBinder() : NULL;
-}
-
-sp<const IBinder> IInterface::asBinder() const
-{
- return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
deleted file mode 100644
index cd2451a..0000000
--- a/libs/binder/IMemory.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "IMemory"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <binder/IMemory.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <binder/Parcel.h>
-#include <utils/CallStack.h>
-
-#define VERBOSE 0
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-class HeapCache : public IBinder::DeathRecipient
-{
-public:
- HeapCache();
- virtual ~HeapCache();
-
- virtual void binderDied(const wp<IBinder>& who);
-
- sp<IMemoryHeap> find_heap(const sp<IBinder>& binder);
- void free_heap(const sp<IBinder>& binder);
- sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
- void dump_heaps();
-
-private:
- // For IMemory.cpp
- struct heap_info_t {
- sp<IMemoryHeap> heap;
- int32_t count;
- };
-
- void free_heap(const wp<IBinder>& binder);
-
- Mutex mHeapCacheLock;
- KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
-};
-
-static sp<HeapCache> gHeapCache = new HeapCache();
-
-/******************************************************************************/
-
-enum {
- HEAP_ID = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpMemoryHeap : public BpInterface<IMemoryHeap>
-{
-public:
- BpMemoryHeap(const sp<IBinder>& impl);
- virtual ~BpMemoryHeap();
-
- virtual int getHeapID() const;
- virtual void* getBase() const;
- virtual size_t getSize() const;
- virtual uint32_t getFlags() const;
- virtual uint32_t getOffset() const;
-
-private:
- friend class IMemory;
- friend class HeapCache;
-
- // for debugging in this module
- static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
- return gHeapCache->find_heap(binder);
- }
- static inline void free_heap(const sp<IBinder>& binder) {
- gHeapCache->free_heap(binder);
- }
- static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) {
- return gHeapCache->get_heap(binder);
- }
- static inline void dump_heaps() {
- gHeapCache->dump_heaps();
- }
-
- void assertMapped() const;
- void assertReallyMapped() const;
-
- mutable volatile int32_t mHeapId;
- mutable void* mBase;
- mutable size_t mSize;
- mutable uint32_t mFlags;
- mutable uint32_t mOffset;
- mutable bool mRealHeap;
- mutable Mutex mLock;
-};
-
-// ----------------------------------------------------------------------------
-
-enum {
- GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpMemory : public BpInterface<IMemory>
-{
-public:
- BpMemory(const sp<IBinder>& impl);
- virtual ~BpMemory();
- virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
-
-private:
- mutable sp<IMemoryHeap> mHeap;
- mutable ssize_t mOffset;
- mutable size_t mSize;
-};
-
-/******************************************************************************/
-
-void* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const
-{
- sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
- void* const base = realHeap->base();
- if (base == MAP_FAILED)
- return 0;
- return static_cast<char*>(base) + offset;
-}
-
-void* IMemory::pointer() const {
- ssize_t offset;
- sp<IMemoryHeap> heap = getMemory(&offset);
- void* const base = heap!=0 ? heap->base() : MAP_FAILED;
- if (base == MAP_FAILED)
- return 0;
- return static_cast<char*>(base) + offset;
-}
-
-size_t IMemory::size() const {
- size_t size;
- getMemory(NULL, &size);
- return size;
-}
-
-ssize_t IMemory::offset() const {
- ssize_t offset;
- getMemory(&offset);
- return offset;
-}
-
-/******************************************************************************/
-
-BpMemory::BpMemory(const sp<IBinder>& impl)
- : BpInterface<IMemory>(impl), mOffset(0), mSize(0)
-{
-}
-
-BpMemory::~BpMemory()
-{
-}
-
-sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
-{
- if (mHeap == 0) {
- Parcel data, reply;
- data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
- if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
- sp<IBinder> heap = reply.readStrongBinder();
- ssize_t o = reply.readInt32();
- size_t s = reply.readInt32();
- if (heap != 0) {
- mHeap = interface_cast<IMemoryHeap>(heap);
- if (mHeap != 0) {
- mOffset = o;
- mSize = s;
- }
- }
- }
- }
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return mHeap;
-}
-
-// ---------------------------------------------------------------------------
-
-IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
-
-BnMemory::BnMemory() {
-}
-
-BnMemory::~BnMemory() {
-}
-
-status_t BnMemory::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_MEMORY: {
- CHECK_INTERFACE(IMemory, data, reply);
- ssize_t offset;
- size_t size;
- reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
- reply->writeInt32(offset);
- reply->writeInt32(size);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-
-/******************************************************************************/
-
-BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
- : BpInterface<IMemoryHeap>(impl),
- mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mOffset(0), mRealHeap(false)
-{
-}
-
-BpMemoryHeap::~BpMemoryHeap() {
- if (mHeapId != -1) {
- close(mHeapId);
- if (mRealHeap) {
- // by construction we're the last one
- if (mBase != MAP_FAILED) {
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
-
- if (VERBOSE) {
- ALOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
- binder.get(), this, mSize, mHeapId);
- CallStack stack;
- stack.update();
- stack.dump("callstack");
- }
-
- munmap(mBase, mSize);
- }
- } else {
- // remove from list only if it was mapped before
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
- free_heap(binder);
- }
- }
-}
-
-void BpMemoryHeap::assertMapped() const
-{
- if (mHeapId == -1) {
- sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
- sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
- heap->assertReallyMapped();
- if (heap->mBase != MAP_FAILED) {
- Mutex::Autolock _l(mLock);
- if (mHeapId == -1) {
- mBase = heap->mBase;
- mSize = heap->mSize;
- mOffset = heap->mOffset;
- android_atomic_write( dup( heap->mHeapId ), &mHeapId );
- }
- } else {
- // something went wrong
- free_heap(binder);
- }
- }
-}
-
-void BpMemoryHeap::assertReallyMapped() const
-{
- if (mHeapId == -1) {
-
- // remote call without mLock held, worse case scenario, we end up
- // calling transact() from multiple threads, but that's not a problem,
- // only mmap below must be in the critical section.
-
- Parcel data, reply;
- data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
- status_t err = remote()->transact(HEAP_ID, data, &reply);
- int parcel_fd = reply.readFileDescriptor();
- ssize_t size = reply.readInt32();
- uint32_t flags = reply.readInt32();
- uint32_t offset = reply.readInt32();
-
- ALOGE_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 );
- ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",
- parcel_fd, size, err, strerror(errno));
-
- int access = PROT_READ;
- if (!(flags & READ_ONLY)) {
- access |= PROT_WRITE;
- }
-
- Mutex::Autolock _l(mLock);
- if (mHeapId == -1) {
- mRealHeap = true;
- mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
- if (mBase == MAP_FAILED) {
- ALOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",
- asBinder().get(), size, fd, strerror(errno));
- close(fd);
- } else {
- mSize = size;
- mFlags = flags;
- mOffset = offset;
- android_atomic_write(fd, &mHeapId);
- }
- }
- }
-}
-
-int BpMemoryHeap::getHeapID() const {
- assertMapped();
- return mHeapId;
-}
-
-void* BpMemoryHeap::getBase() const {
- assertMapped();
- return mBase;
-}
-
-size_t BpMemoryHeap::getSize() const {
- assertMapped();
- return mSize;
-}
-
-uint32_t BpMemoryHeap::getFlags() const {
- assertMapped();
- return mFlags;
-}
-
-uint32_t BpMemoryHeap::getOffset() const {
- assertMapped();
- return mOffset;
-}
-
-// ---------------------------------------------------------------------------
-
-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)
-{
- switch(code) {
- case HEAP_ID: {
- CHECK_INTERFACE(IMemoryHeap, data, reply);
- reply->writeFileDescriptor(getHeapID());
- reply->writeInt32(getSize());
- reply->writeInt32(getFlags());
- reply->writeInt32(getOffset());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-/*****************************************************************************/
-
-HeapCache::HeapCache()
- : DeathRecipient()
-{
-}
-
-HeapCache::~HeapCache()
-{
-}
-
-void HeapCache::binderDied(const wp<IBinder>& binder)
-{
- //ALOGD("binderDied binder=%p", binder.unsafe_get());
- free_heap(binder);
-}
-
-sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder)
-{
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info = mHeapCache.editValueAt(i);
- ALOGD_IF(VERBOSE,
- "found binder=%p, heap=%p, size=%d, fd=%d, count=%d",
- binder.get(), info.heap.get(),
- static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
- static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
- info.count);
- android_atomic_inc(&info.count);
- return info.heap;
- } else {
- heap_info_t info;
- info.heap = interface_cast<IMemoryHeap>(binder);
- info.count = 1;
- //ALOGD("adding binder=%p, heap=%p, count=%d",
- // binder.get(), info.heap.get(), info.count);
- mHeapCache.add(binder, info);
- return info.heap;
- }
-}
-
-void HeapCache::free_heap(const sp<IBinder>& binder) {
- free_heap( wp<IBinder>(binder) );
-}
-
-void HeapCache::free_heap(const wp<IBinder>& binder)
-{
- sp<IMemoryHeap> rel;
- {
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) {
- heap_info_t& info(mHeapCache.editValueAt(i));
- int32_t c = android_atomic_dec(&info.count);
- if (c == 1) {
- ALOGD_IF(VERBOSE,
- "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
- binder.unsafe_get(), info.heap.get(),
- static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
- static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
- info.count);
- rel = mHeapCache.valueAt(i).heap;
- mHeapCache.removeItemsAt(i);
- }
- } else {
- ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
- }
- }
-}
-
-sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
-{
- sp<IMemoryHeap> realHeap;
- Mutex::Autolock _l(mHeapCacheLock);
- ssize_t i = mHeapCache.indexOfKey(binder);
- if (i>=0) realHeap = mHeapCache.valueAt(i).heap;
- else realHeap = interface_cast<IMemoryHeap>(binder);
- return realHeap;
-}
-
-void HeapCache::dump_heaps()
-{
- Mutex::Autolock _l(mHeapCacheLock);
- int c = mHeapCache.size();
- for (int i=0 ; i<c ; i++) {
- const heap_info_t& info = mHeapCache.valueAt(i);
- BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
- ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
- mHeapCache.keyAt(i).unsafe_get(),
- info.heap.get(), info.count,
- h->mHeapId, h->mBase, h->mSize);
- }
-}
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
deleted file mode 100644
index 96cef2c..0000000
--- a/libs/binder/IPCThreadState.cpp
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "IPCThreadState"
-
-#include <binder/IPCThreadState.h>
-
-#include <binder/Binder.h>
-#include <binder/BpBinder.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/binder/binder_module.h>
-#include <private/binder/Static.h>
-
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#include <sched.h>
-#include <sys/resource.h>
-#endif
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#endif
-
-
-#if LOG_NDEBUG
-
-#define IF_LOG_TRANSACTIONS() if (false)
-#define IF_LOG_COMMANDS() if (false)
-#define LOG_REMOTEREFS(...)
-#define IF_LOG_REMOTEREFS() if (false)
-#define LOG_THREADPOOL(...)
-#define LOG_ONEWAY(...)
-
-#else
-
-#define IF_LOG_TRANSACTIONS() IF_ALOG(LOG_VERBOSE, "transact")
-#define IF_LOG_COMMANDS() IF_ALOG(LOG_VERBOSE, "ipc")
-#define LOG_REMOTEREFS(...) ALOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
-#define IF_LOG_REMOTEREFS() IF_ALOG(LOG_DEBUG, "remoterefs")
-#define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
-#define LOG_ONEWAY(...) ALOG(LOG_DEBUG, "ipc", __VA_ARGS__)
-
-#endif
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-static const char* getReturnString(size_t idx);
-static const char* getCommandString(size_t idx);
-static const void* printReturnCommand(TextOutput& out, const void* _cmd);
-static const void* printCommand(TextOutput& out, const void* _cmd);
-
-// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
-// conditionals don't get stripped... but that is probably what we want.
-#if !LOG_NDEBUG
-static const char *kReturnStrings[] = {
- "BR_ERROR",
- "BR_OK",
- "BR_TRANSACTION",
- "BR_REPLY",
- "BR_ACQUIRE_RESULT",
- "BR_DEAD_REPLY",
- "BR_TRANSACTION_COMPLETE",
- "BR_INCREFS",
- "BR_ACQUIRE",
- "BR_RELEASE",
- "BR_DECREFS",
- "BR_ATTEMPT_ACQUIRE",
- "BR_NOOP",
- "BR_SPAWN_LOOPER",
- "BR_FINISHED",
- "BR_DEAD_BINDER",
- "BR_CLEAR_DEATH_NOTIFICATION_DONE",
- "BR_FAILED_REPLY"
-};
-
-static const char *kCommandStrings[] = {
- "BC_TRANSACTION",
- "BC_REPLY",
- "BC_ACQUIRE_RESULT",
- "BC_FREE_BUFFER",
- "BC_INCREFS",
- "BC_ACQUIRE",
- "BC_RELEASE",
- "BC_DECREFS",
- "BC_INCREFS_DONE",
- "BC_ACQUIRE_DONE",
- "BC_ATTEMPT_ACQUIRE",
- "BC_REGISTER_LOOPER",
- "BC_ENTER_LOOPER",
- "BC_EXIT_LOOPER",
- "BC_REQUEST_DEATH_NOTIFICATION",
- "BC_CLEAR_DEATH_NOTIFICATION",
- "BC_DEAD_BINDER_DONE"
-};
-
-static const char* getReturnString(size_t idx)
-{
- if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
- return kReturnStrings[idx];
- else
- return "unknown";
-}
-
-static const char* getCommandString(size_t idx)
-{
- if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
- return kCommandStrings[idx];
- else
- return "unknown";
-}
-
-static const void* printBinderTransactionData(TextOutput& out, const void* data)
-{
- const binder_transaction_data* btd =
- (const binder_transaction_data*)data;
- if (btd->target.handle < 1024) {
- /* want to print descriptors in decimal; guess based on value */
- out << "target.desc=" << btd->target.handle;
- } else {
- out << "target.ptr=" << btd->target.ptr;
- }
- out << " (cookie " << btd->cookie << ")" << endl
- << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
- << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
- << " bytes)" << endl
- << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
- << " bytes)";
- return btd+1;
-}
-
-static const void* printReturnCommand(TextOutput& out, const void* _cmd)
-{
- static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
- const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
- size_t cmdIndex = code & 0xff;
- if (code == (int32_t) BR_ERROR) {
- out << "BR_ERROR: " << (void*)(*cmd++) << endl;
- return cmd;
- } else if (cmdIndex >= N) {
- out << "Unknown reply: " << code << endl;
- return cmd;
- }
- out << kReturnStrings[cmdIndex];
-
- switch (code) {
- case BR_TRANSACTION:
- case BR_REPLY: {
- out << ": " << indent;
- cmd = (const int32_t *)printBinderTransactionData(out, cmd);
- out << dedent;
- } break;
-
- case BR_ACQUIRE_RESULT: {
- const int32_t res = *cmd++;
- out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
- } break;
-
- case BR_INCREFS:
- case BR_ACQUIRE:
- case BR_RELEASE:
- case BR_DECREFS: {
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
- } break;
-
- case BR_ATTEMPT_ACQUIRE: {
- const int32_t p = *cmd++;
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c
- << "), pri=" << p;
- } break;
-
- case BR_DEAD_BINDER:
- case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
- const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
- } break;
-
- default:
- // no details to show for: BR_OK, BR_DEAD_REPLY,
- // BR_TRANSACTION_COMPLETE, BR_FINISHED
- break;
- }
-
- out << endl;
- return cmd;
-}
-
-static const void* printCommand(TextOutput& out, const void* _cmd)
-{
- static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
- const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
- size_t cmdIndex = code & 0xff;
-
- if (cmdIndex >= N) {
- out << "Unknown command: " << code << endl;
- return cmd;
- }
- out << kCommandStrings[cmdIndex];
-
- switch (code) {
- case BC_TRANSACTION:
- case BC_REPLY: {
- out << ": " << indent;
- cmd = (const int32_t *)printBinderTransactionData(out, cmd);
- out << dedent;
- } break;
-
- case BC_ACQUIRE_RESULT: {
- const int32_t res = *cmd++;
- out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
- } break;
-
- case BC_FREE_BUFFER: {
- const int32_t buf = *cmd++;
- out << ": buffer=" << (void*)buf;
- } break;
-
- case BC_INCREFS:
- case BC_ACQUIRE:
- case BC_RELEASE:
- case BC_DECREFS: {
- const int32_t d = *cmd++;
- out << ": desc=" << d;
- } break;
-
- case BC_INCREFS_DONE:
- case BC_ACQUIRE_DONE: {
- const int32_t b = *cmd++;
- const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
- } break;
-
- case BC_ATTEMPT_ACQUIRE: {
- const int32_t p = *cmd++;
- const int32_t d = *cmd++;
- out << ": desc=" << d << ", pri=" << p;
- } break;
-
- case BC_REQUEST_DEATH_NOTIFICATION:
- case BC_CLEAR_DEATH_NOTIFICATION: {
- const int32_t h = *cmd++;
- const int32_t c = *cmd++;
- out << ": handle=" << h << " (death cookie " << (void*)c << ")";
- } break;
-
- case BC_DEAD_BINDER_DONE: {
- const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
- } break;
-
- default:
- // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
- // BC_EXIT_LOOPER
- break;
- }
-
- out << endl;
- return cmd;
-}
-#endif
-
-static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
-static bool gHaveTLS = false;
-static pthread_key_t gTLS = 0;
-static bool gShutdown = false;
-static bool gDisableBackgroundScheduling = false;
-
-IPCThreadState* IPCThreadState::self()
-{
- if (gHaveTLS) {
-restart:
- const pthread_key_t k = gTLS;
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
- if (st) return st;
- return new IPCThreadState;
- }
-
- if (gShutdown) return NULL;
-
- pthread_mutex_lock(&gTLSMutex);
- if (!gHaveTLS) {
- if (pthread_key_create(&gTLS, threadDestructor) != 0) {
- pthread_mutex_unlock(&gTLSMutex);
- return NULL;
- }
- gHaveTLS = true;
- }
- pthread_mutex_unlock(&gTLSMutex);
- goto restart;
-}
-
-IPCThreadState* IPCThreadState::selfOrNull()
-{
- if (gHaveTLS) {
- const pthread_key_t k = gTLS;
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
- return st;
- }
- return NULL;
-}
-
-void IPCThreadState::shutdown()
-{
- gShutdown = true;
-
- if (gHaveTLS) {
- // XXX Need to wait for all thread pool threads to exit!
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
- if (st) {
- delete st;
- pthread_setspecific(gTLS, NULL);
- }
- gHaveTLS = false;
- }
-}
-
-void IPCThreadState::disableBackgroundScheduling(bool disable)
-{
- gDisableBackgroundScheduling = disable;
-}
-
-sp<ProcessState> IPCThreadState::process()
-{
- return mProcess;
-}
-
-status_t IPCThreadState::clearLastError()
-{
- const status_t err = mLastError;
- mLastError = NO_ERROR;
- return err;
-}
-
-int IPCThreadState::getCallingPid()
-{
- return mCallingPid;
-}
-
-int IPCThreadState::getCallingUid()
-{
- return mCallingUid;
-}
-
-int IPCThreadState::getOrigCallingUid()
-{
- return mOrigCallingUid;
-}
-
-int64_t IPCThreadState::clearCallingIdentity()
-{
- int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
- clearCaller();
- return token;
-}
-
-void IPCThreadState::setStrictModePolicy(int32_t policy)
-{
- mStrictModePolicy = policy;
-}
-
-int32_t IPCThreadState::getStrictModePolicy() const
-{
- return mStrictModePolicy;
-}
-
-void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
-{
- mLastTransactionBinderFlags = flags;
-}
-
-int32_t IPCThreadState::getLastTransactionBinderFlags() const
-{
- return mLastTransactionBinderFlags;
-}
-
-void IPCThreadState::restoreCallingIdentity(int64_t token)
-{
- mCallingUid = (int)(token>>32);
- mCallingPid = (int)token;
-}
-
-void IPCThreadState::clearCaller()
-{
- mCallingPid = getpid();
- mCallingUid = getuid();
-}
-
-void IPCThreadState::flushCommands()
-{
- if (mProcess->mDriverFD <= 0)
- return;
- talkWithDriver(false);
-}
-
-void IPCThreadState::joinThreadPool(bool isMain)
-{
- LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
-
- mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
-
- // This thread may have been spawned by a thread that was in the background
- // scheduling group, so first we will make sure it is in the default/foreground
- // one to avoid performing an initial transaction in the background.
- androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
-
- status_t result;
- do {
- int32_t cmd;
-
- // When we've cleared the incoming command queue, process any pending derefs
- if (mIn.dataPosition() >= mIn.dataSize()) {
- size_t numPending = mPendingWeakDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- RefBase::weakref_type* refs = mPendingWeakDerefs[i];
- refs->decWeak(mProcess.get());
- }
- mPendingWeakDerefs.clear();
- }
-
- numPending = mPendingStrongDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- BBinder* obj = mPendingStrongDerefs[i];
- obj->decStrong(mProcess.get());
- }
- mPendingStrongDerefs.clear();
- }
- }
-
- // now get the next command to be processed, waiting if necessary
- result = talkWithDriver();
- if (result >= NO_ERROR) {
- size_t IN = mIn.dataAvail();
- if (IN < sizeof(int32_t)) continue;
- cmd = mIn.readInt32();
- IF_LOG_COMMANDS() {
- alog << "Processing top-level Command: "
- << getReturnString(cmd) << endl;
- }
-
-
- result = executeCommand(cmd);
- }
-
- // After executing the command, ensure that the thread is returned to the
- // default cgroup before rejoining the pool. The driver takes care of
- // restoring the priority, but doesn't do anything with cgroups so we
- // need to take care of that here in userspace. Note that we do make
- // sure to go in the foreground after executing a transaction, but
- // there are other callbacks into user code that could have changed
- // our group so we want to make absolutely sure it is put back.
- androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
-
- // Let this thread exit the thread pool if it is no longer
- // needed and it is not the main process thread.
- if(result == TIMED_OUT && !isMain) {
- break;
- }
- } while (result != -ECONNREFUSED && result != -EBADF);
-
- LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
- (void*)pthread_self(), getpid(), (void*)result);
-
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
-}
-
-void IPCThreadState::stopProcess(bool immediate)
-{
- //ALOGI("**** STOPPING PROCESS");
- flushCommands();
- int fd = mProcess->mDriverFD;
- mProcess->mDriverFD = -1;
- close(fd);
- //kill(getpid(), SIGKILL);
-}
-
-status_t IPCThreadState::transact(int32_t handle,
- uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags)
-{
- status_t err = data.errorCheck();
-
- flags |= TF_ACCEPT_FDS;
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
- << handle << " / code " << TypeCode(code) << ": "
- << indent << data << dedent << endl;
- }
-
- if (err == NO_ERROR) {
- LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
- (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
- err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
- }
-
- if (err != NO_ERROR) {
- if (reply) reply->setError(err);
- return (mLastError = err);
- }
-
- if ((flags & TF_ONE_WAY) == 0) {
- #if 0
- if (code == 4) { // relayout
- ALOGI(">>>>>> CALLING transaction 4");
- } else {
- ALOGI(">>>>>> CALLING transaction %d", code);
- }
- #endif
- if (reply) {
- err = waitForResponse(reply);
- } else {
- Parcel fakeReply;
- err = waitForResponse(&fakeReply);
- }
- #if 0
- if (code == 4) { // relayout
- ALOGI("<<<<<< RETURNING transaction 4");
- } else {
- ALOGI("<<<<<< RETURNING transaction %d", code);
- }
- #endif
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
- << handle << ": ";
- if (reply) alog << indent << *reply << dedent << endl;
- else alog << "(none requested)" << endl;
- }
- } else {
- err = waitForResponse(NULL, NULL);
- }
-
- return err;
-}
-
-void IPCThreadState::incStrongHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
- mOut.writeInt32(BC_ACQUIRE);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::decStrongHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
- mOut.writeInt32(BC_RELEASE);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::incWeakHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
-}
-
-void IPCThreadState::decWeakHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
- mOut.writeInt32(BC_DECREFS);
- mOut.writeInt32(handle);
-}
-
-status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
-{
- LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
- mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
- mOut.writeInt32(0); // xxx was thread priority
- mOut.writeInt32(handle);
- status_t result = UNKNOWN_ERROR;
-
- waitForResponse(NULL, &result);
-
-#if LOG_REFCOUNTS
- printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
- handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
-#endif
-
- return result;
-}
-
-void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
-{
-#if LOG_REFCOUNTS
- printf("IPCThreadState::expungeHandle(%ld)\n", handle);
-#endif
- self()->mProcess->expungeHandle(handle, binder);
-}
-
-status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
-{
- mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
- mOut.writeInt32((int32_t)handle);
- mOut.writeInt32((int32_t)proxy);
- return NO_ERROR;
-}
-
-status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
-{
- mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
- mOut.writeInt32((int32_t)handle);
- mOut.writeInt32((int32_t)proxy);
- return NO_ERROR;
-}
-
-IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self()),
- mMyThreadId(androidGetTid()),
- mStrictModePolicy(0),
- mLastTransactionBinderFlags(0)
-{
- pthread_setspecific(gTLS, this);
- clearCaller();
- mOrigCallingUid = mCallingUid;
- mIn.setDataCapacity(256);
- mOut.setDataCapacity(256);
-}
-
-IPCThreadState::~IPCThreadState()
-{
-}
-
-status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
-{
- status_t err;
- status_t statusBuffer;
- err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
- if (err < NO_ERROR) return err;
-
- return waitForResponse(NULL, NULL);
-}
-
-status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
-{
- int32_t cmd;
- int32_t err;
-
- while (1) {
- if ((err=talkWithDriver()) < NO_ERROR) break;
- err = mIn.errorCheck();
- if (err < NO_ERROR) break;
- if (mIn.dataAvail() == 0) continue;
-
- cmd = mIn.readInt32();
-
- IF_LOG_COMMANDS() {
- alog << "Processing waitForResponse Command: "
- << getReturnString(cmd) << endl;
- }
-
- switch (cmd) {
- case BR_TRANSACTION_COMPLETE:
- if (!reply && !acquireResult) goto finish;
- break;
-
- case BR_DEAD_REPLY:
- err = DEAD_OBJECT;
- goto finish;
-
- case BR_FAILED_REPLY:
- err = FAILED_TRANSACTION;
- goto finish;
-
- case BR_ACQUIRE_RESULT:
- {
- ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
- const int32_t result = mIn.readInt32();
- if (!acquireResult) continue;
- *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
- }
- goto finish;
-
- case BR_REPLY:
- {
- binder_transaction_data tr;
- err = mIn.read(&tr, sizeof(tr));
- ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
- if (err != NO_ERROR) goto finish;
-
- if (reply) {
- if ((tr.flags & TF_STATUS_CODE) == 0) {
- reply->ipcSetDataReference(
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t),
- freeBuffer, this);
- } else {
- err = *static_cast<const status_t*>(tr.data.ptr.buffer);
- freeBuffer(NULL,
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), this);
- }
- } else {
- freeBuffer(NULL,
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), this);
- continue;
- }
- }
- goto finish;
-
- default:
- err = executeCommand(cmd);
- if (err != NO_ERROR) goto finish;
- break;
- }
- }
-
-finish:
- if (err != NO_ERROR) {
- if (acquireResult) *acquireResult = err;
- if (reply) reply->setError(err);
- mLastError = err;
- }
-
- return err;
-}
-
-status_t IPCThreadState::talkWithDriver(bool doReceive)
-{
- ALOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
-
- binder_write_read bwr;
-
- // Is the read buffer empty?
- const bool needRead = mIn.dataPosition() >= mIn.dataSize();
-
- // We don't want to write anything if we are still reading
- // from data left in the input buffer and the caller
- // has requested to read the next data.
- const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
-
- bwr.write_size = outAvail;
- bwr.write_buffer = (long unsigned int)mOut.data();
-
- // This is what we'll read.
- if (doReceive && needRead) {
- bwr.read_size = mIn.dataCapacity();
- bwr.read_buffer = (long unsigned int)mIn.data();
- } else {
- bwr.read_size = 0;
- bwr.read_buffer = 0;
- }
-
- IF_LOG_COMMANDS() {
- TextOutput::Bundle _b(alog);
- if (outAvail != 0) {
- alog << "Sending commands to driver: " << indent;
- const void* cmds = (const void*)bwr.write_buffer;
- const void* end = ((const uint8_t*)cmds)+bwr.write_size;
- alog << HexDump(cmds, bwr.write_size) << endl;
- while (cmds < end) cmds = printCommand(alog, cmds);
- alog << dedent;
- }
- alog << "Size of receive buffer: " << bwr.read_size
- << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
- }
-
- // Return immediately if there is nothing to do.
- if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
-
- bwr.write_consumed = 0;
- bwr.read_consumed = 0;
- status_t err;
- do {
- IF_LOG_COMMANDS() {
- alog << "About to read/write, write size = " << mOut.dataSize() << endl;
- }
-#if defined(HAVE_ANDROID_OS)
- if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
- err = NO_ERROR;
- else
- err = -errno;
-#else
- err = INVALID_OPERATION;
-#endif
- IF_LOG_COMMANDS() {
- alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
- }
- } while (err == -EINTR);
-
- IF_LOG_COMMANDS() {
- alog << "Our err: " << (void*)err << ", write consumed: "
- << bwr.write_consumed << " (of " << mOut.dataSize()
- << "), read consumed: " << bwr.read_consumed << endl;
- }
-
- if (err >= NO_ERROR) {
- if (bwr.write_consumed > 0) {
- if (bwr.write_consumed < (ssize_t)mOut.dataSize())
- mOut.remove(0, bwr.write_consumed);
- else
- mOut.setDataSize(0);
- }
- if (bwr.read_consumed > 0) {
- mIn.setDataSize(bwr.read_consumed);
- mIn.setDataPosition(0);
- }
- IF_LOG_COMMANDS() {
- TextOutput::Bundle _b(alog);
- alog << "Remaining data size: " << mOut.dataSize() << endl;
- alog << "Received commands from driver: " << indent;
- const void* cmds = mIn.data();
- const void* end = mIn.data() + mIn.dataSize();
- alog << HexDump(cmds, mIn.dataSize()) << endl;
- while (cmds < end) cmds = printReturnCommand(alog, cmds);
- alog << dedent;
- }
- return NO_ERROR;
- }
-
- return err;
-}
-
-status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
- int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
-{
- binder_transaction_data tr;
-
- tr.target.handle = handle;
- tr.code = code;
- tr.flags = binderFlags;
- tr.cookie = 0;
- tr.sender_pid = 0;
- tr.sender_euid = 0;
-
- const status_t err = data.errorCheck();
- if (err == NO_ERROR) {
- tr.data_size = data.ipcDataSize();
- tr.data.ptr.buffer = data.ipcData();
- tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
- tr.data.ptr.offsets = data.ipcObjects();
- } else if (statusBuffer) {
- tr.flags |= TF_STATUS_CODE;
- *statusBuffer = err;
- tr.data_size = sizeof(status_t);
- tr.data.ptr.buffer = statusBuffer;
- tr.offsets_size = 0;
- tr.data.ptr.offsets = NULL;
- } else {
- return (mLastError = err);
- }
-
- mOut.writeInt32(cmd);
- mOut.write(&tr, sizeof(tr));
-
- return NO_ERROR;
-}
-
-sp<BBinder> the_context_object;
-
-void setTheContextObject(sp<BBinder> obj)
-{
- the_context_object = obj;
-}
-
-status_t IPCThreadState::executeCommand(int32_t cmd)
-{
- BBinder* obj;
- RefBase::weakref_type* refs;
- status_t result = NO_ERROR;
-
- switch (cmd) {
- case BR_ERROR:
- result = mIn.readInt32();
- break;
-
- case BR_OK:
- break;
-
- case BR_ACQUIRE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- ALOG_ASSERT(refs->refBase() == obj,
- "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
- obj->incStrong(mProcess.get());
- IF_LOG_REMOTEREFS() {
- LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
- obj->printRefs();
- }
- mOut.writeInt32(BC_ACQUIRE_DONE);
- mOut.writeInt32((int32_t)refs);
- mOut.writeInt32((int32_t)obj);
- break;
-
- case BR_RELEASE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- ALOG_ASSERT(refs->refBase() == obj,
- "BR_RELEASE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
- IF_LOG_REMOTEREFS() {
- LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
- obj->printRefs();
- }
- mPendingStrongDerefs.push(obj);
- break;
-
- case BR_INCREFS:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- refs->incWeak(mProcess.get());
- mOut.writeInt32(BC_INCREFS_DONE);
- mOut.writeInt32((int32_t)refs);
- mOut.writeInt32((int32_t)obj);
- break;
-
- case BR_DECREFS:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
- // NOTE: This assertion is not valid, because the object may no
- // longer exist (thus the (BBinder*)cast above resulting in a different
- // memory address).
- //ALOG_ASSERT(refs->refBase() == obj,
- // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
- // refs, obj, refs->refBase());
- mPendingWeakDerefs.push(refs);
- break;
-
- case BR_ATTEMPT_ACQUIRE:
- refs = (RefBase::weakref_type*)mIn.readInt32();
- obj = (BBinder*)mIn.readInt32();
-
- {
- const bool success = refs->attemptIncStrong(mProcess.get());
- ALOG_ASSERT(success && refs->refBase() == obj,
- "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
- refs, obj, refs->refBase());
-
- mOut.writeInt32(BC_ACQUIRE_RESULT);
- mOut.writeInt32((int32_t)success);
- }
- break;
-
- case BR_TRANSACTION:
- {
- binder_transaction_data tr;
- result = mIn.read(&tr, sizeof(tr));
- ALOG_ASSERT(result == NO_ERROR,
- "Not enough command data for brTRANSACTION");
- if (result != NO_ERROR) break;
-
- Parcel buffer;
- buffer.ipcSetDataReference(
- reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
- tr.data_size,
- reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(size_t), freeBuffer, this);
-
- const pid_t origPid = mCallingPid;
- const uid_t origUid = mCallingUid;
-
- mCallingPid = tr.sender_pid;
- mCallingUid = tr.sender_euid;
- mOrigCallingUid = tr.sender_euid;
-
- int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
- if (gDisableBackgroundScheduling) {
- if (curPrio > ANDROID_PRIORITY_NORMAL) {
- // We have inherited a reduced priority from the caller, but do not
- // want to run in that state in this process. The driver set our
- // priority already (though not our scheduling class), so bounce
- // it back to the default before invoking the transaction.
- setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
- }
- } else {
- if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
- // We want to use the inherited priority from the caller.
- // Ensure this thread is in the background scheduling class,
- // since the driver won't modify scheduling classes for us.
- // The scheduling group is reset to default by the caller
- // once this method returns after the transaction is complete.
- androidSetThreadSchedulingGroup(mMyThreadId,
- ANDROID_TGROUP_BG_NONINTERACT);
- }
- }
-
- //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
-
- Parcel reply;
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BR_TRANSACTION thr " << (void*)pthread_self()
- << " / obj " << tr.target.ptr << " / code "
- << TypeCode(tr.code) << ": " << indent << buffer
- << dedent << endl
- << "Data addr = "
- << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
- << ", offsets addr="
- << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
- }
- if (tr.target.ptr) {
- sp<BBinder> b((BBinder*)tr.cookie);
- const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
- if (error < NO_ERROR) reply.setError(error);
-
- } else {
- const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
- if (error < NO_ERROR) reply.setError(error);
- }
-
- //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
- // mCallingPid, origPid, origUid);
-
- if ((tr.flags & TF_ONE_WAY) == 0) {
- LOG_ONEWAY("Sending reply to %d!", mCallingPid);
- sendReply(reply, 0);
- } else {
- LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
- }
-
- mCallingPid = origPid;
- mCallingUid = origUid;
- mOrigCallingUid = origUid;
-
- IF_LOG_TRANSACTIONS() {
- TextOutput::Bundle _b(alog);
- alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
- << tr.target.ptr << ": " << indent << reply << dedent << endl;
- }
-
- }
- break;
-
- case BR_DEAD_BINDER:
- {
- BpBinder *proxy = (BpBinder*)mIn.readInt32();
- proxy->sendObituary();
- mOut.writeInt32(BC_DEAD_BINDER_DONE);
- mOut.writeInt32((int32_t)proxy);
- } break;
-
- case BR_CLEAR_DEATH_NOTIFICATION_DONE:
- {
- BpBinder *proxy = (BpBinder*)mIn.readInt32();
- proxy->getWeakRefs()->decWeak(proxy);
- } break;
-
- case BR_FINISHED:
- result = TIMED_OUT;
- break;
-
- case BR_NOOP:
- break;
-
- case BR_SPAWN_LOOPER:
- mProcess->spawnPooledThread(false);
- break;
-
- default:
- printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
- result = UNKNOWN_ERROR;
- break;
- }
-
- if (result != NO_ERROR) {
- mLastError = result;
- }
-
- return result;
-}
-
-void IPCThreadState::threadDestructor(void *st)
-{
- IPCThreadState* const self = static_cast<IPCThreadState*>(st);
- if (self) {
- self->flushCommands();
-#if defined(HAVE_ANDROID_OS)
- ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
-#endif
- delete self;
- }
-}
-
-
-void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
- const size_t* objects, size_t objectsSize,
- void* cookie)
-{
- //ALOGI("Freeing parcel %p", &parcel);
- IF_LOG_COMMANDS() {
- alog << "Writing BC_FREE_BUFFER for " << data << endl;
- }
- ALOG_ASSERT(data != NULL, "Called with NULL data");
- if (parcel != NULL) parcel->closeFileDescriptors();
- IPCThreadState* state = self();
- state->mOut.writeInt32(BC_FREE_BUFFER);
- state->mOut.writeInt32((int32_t)data);
-}
-
-}; // namespace android
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
deleted file mode 100644
index e13036f..0000000
--- a/libs/binder/IPermissionController.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "PermissionController"
-
-#include <binder/IPermissionController.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-
-#include <private/binder/Static.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpPermissionController : public BpInterface<IPermissionController>
-{
-public:
- BpPermissionController(const sp<IBinder>& impl)
- : BpInterface<IPermissionController>(impl)
- {
- }
-
- virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
- data.writeString16(permission);
- data.writeInt32(pid);
- data.writeInt32(uid);
- remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
- // fail on exception
- if (reply.readExceptionCode() != 0) return 0;
- return reply.readInt32() != 0;
- }
-};
-
-IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
-
-// ----------------------------------------------------------------------
-
-status_t BnPermissionController::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- //printf("PermissionController received: "); data.print();
- switch(code) {
- case CHECK_PERMISSION_TRANSACTION: {
- CHECK_INTERFACE(IPermissionController, data, reply);
- String16 permission = data.readString16();
- int32_t pid = data.readInt32();
- int32_t uid = data.readInt32();
- bool res = checkPermission(permission, pid, uid);
- reply->writeNoException();
- reply->writeInt32(res ? 1 : 0);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
deleted file mode 100644
index 1750640..0000000
--- a/libs/binder/IServiceManager.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ServiceManager"
-
-#include <binder/IServiceManager.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-#include <utils/SystemClock.h>
-
-#include <private/binder/Static.h>
-
-#include <unistd.h>
-
-namespace android {
-
-sp<IServiceManager> defaultServiceManager()
-{
- if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
-
- {
- AutoMutex _l(gDefaultServiceManagerLock);
- if (gDefaultServiceManager == NULL) {
- gDefaultServiceManager = interface_cast<IServiceManager>(
- ProcessState::self()->getContextObject(NULL));
- }
- }
-
- return gDefaultServiceManager;
-}
-
-bool checkCallingPermission(const String16& permission)
-{
- return checkCallingPermission(permission, NULL, NULL);
-}
-
-static String16 _permission("permission");
-
-
-bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
-{
- IPCThreadState* ipcState = IPCThreadState::self();
- pid_t pid = ipcState->getCallingPid();
- uid_t uid = ipcState->getCallingUid();
- if (outPid) *outPid = pid;
- if (outUid) *outUid = uid;
- return checkPermission(permission, pid, uid);
-}
-
-bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
-{
- sp<IPermissionController> pc;
- gDefaultServiceManagerLock.lock();
- pc = gPermissionController;
- gDefaultServiceManagerLock.unlock();
-
- int64_t startTime = 0;
-
- while (true) {
- if (pc != NULL) {
- bool res = pc->checkPermission(permission, pid, uid);
- if (res) {
- if (startTime != 0) {
- ALOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
- (int)((uptimeMillis()-startTime)/1000),
- String8(permission).string(), uid, pid);
- }
- return res;
- }
-
- // Is this a permission failure, or did the controller go away?
- if (pc->asBinder()->isBinderAlive()) {
- ALOGW("Permission failure: %s from uid=%d pid=%d",
- String8(permission).string(), uid, pid);
- return false;
- }
-
- // Object is dead!
- gDefaultServiceManagerLock.lock();
- if (gPermissionController == pc) {
- gPermissionController = NULL;
- }
- gDefaultServiceManagerLock.unlock();
- }
-
- // Need to retrieve the permission controller.
- sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
- if (binder == NULL) {
- // Wait for the permission controller to come back...
- if (startTime == 0) {
- startTime = uptimeMillis();
- ALOGI("Waiting to check permission %s from uid=%d pid=%d",
- String8(permission).string(), uid, pid);
- }
- sleep(1);
- } else {
- pc = interface_cast<IPermissionController>(binder);
- // Install the new permission controller, and try again.
- gDefaultServiceManagerLock.lock();
- gPermissionController = pc;
- gDefaultServiceManagerLock.unlock();
- }
- }
-}
-
-// ----------------------------------------------------------------------
-
-class BpServiceManager : public BpInterface<IServiceManager>
-{
-public:
- BpServiceManager(const sp<IBinder>& impl)
- : BpInterface<IServiceManager>(impl)
- {
- }
-
- virtual sp<IBinder> getService(const String16& name) const
- {
- unsigned n;
- for (n = 0; n < 5; n++){
- sp<IBinder> svc = checkService(name);
- if (svc != NULL) return svc;
- ALOGI("Waiting for service %s...\n", String8(name).string());
- sleep(1);
- }
- return NULL;
- }
-
- virtual sp<IBinder> checkService( const String16& name) const
- {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
- return reply.readStrongBinder();
- }
-
- virtual status_t addService(const String16& name, const sp<IBinder>& service,
- bool allowIsolated)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeStrongBinder(service);
- data.writeInt32(allowIsolated ? 1 : 0);
- status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
- return err == NO_ERROR ? reply.readExceptionCode() : err;
- }
-
- virtual Vector<String16> listServices()
- {
- Vector<String16> res;
- int n = 0;
-
- for (;;) {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeInt32(n++);
- status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
- if (err != NO_ERROR)
- break;
- res.add(reply.readString16());
- }
- return res;
- }
-};
-
-IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
-
-// ----------------------------------------------------------------------
-
-status_t BnServiceManager::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- //printf("ServiceManager received: "); data.print();
- switch(code) {
- case GET_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
- reply->writeStrongBinder(b);
- return NO_ERROR;
- } break;
- case CHECK_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
- reply->writeStrongBinder(b);
- return NO_ERROR;
- } break;
- case ADD_SERVICE_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- String16 which = data.readString16();
- sp<IBinder> b = data.readStrongBinder();
- status_t err = addService(which, b);
- reply->writeInt32(err);
- return NO_ERROR;
- } break;
- case LIST_SERVICES_TRANSACTION: {
- CHECK_INTERFACE(IServiceManager, data, reply);
- Vector<String16> list = listServices();
- const size_t N = list.size();
- reply->writeInt32(N);
- for (size_t i=0; i<N; i++) {
- reply->writeString16(list[i]);
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/binder/MemoryBase.cpp b/libs/binder/MemoryBase.cpp
deleted file mode 100644
index 033066b..0000000
--- a/libs/binder/MemoryBase.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <binder/MemoryBase.h>
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
- ssize_t offset, size_t size)
- : mSize(size), mOffset(offset), mHeap(heap)
-{
-}
-
-sp<IMemoryHeap> MemoryBase::getMemory(ssize_t* offset, size_t* size) const
-{
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return mHeap;
-}
-
-MemoryBase::~MemoryBase()
-{
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
deleted file mode 100644
index 8d0e0a7..0000000
--- a/libs/binder/MemoryDealer.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MemoryDealer"
-
-#include <binder/MemoryDealer.h>
-#include <binder/IPCThreadState.h>
-#include <binder/MemoryBase.h>
-
-#include <utils/Log.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/file.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-/*
- * A simple templatized doubly linked-list implementation
- */
-
-template <typename NODE>
-class LinkedList
-{
- NODE* mFirst;
- NODE* mLast;
-
-public:
- LinkedList() : mFirst(0), mLast(0) { }
- bool isEmpty() const { return mFirst == 0; }
- NODE const* head() const { return mFirst; }
- NODE* head() { return mFirst; }
- NODE const* tail() const { return mLast; }
- NODE* tail() { return mLast; }
-
- void insertAfter(NODE* node, NODE* newNode) {
- newNode->prev = node;
- newNode->next = node->next;
- if (node->next == 0) mLast = newNode;
- else node->next->prev = newNode;
- node->next = newNode;
- }
-
- void insertBefore(NODE* node, NODE* newNode) {
- newNode->prev = node->prev;
- newNode->next = node;
- if (node->prev == 0) mFirst = newNode;
- else node->prev->next = newNode;
- node->prev = newNode;
- }
-
- void insertHead(NODE* newNode) {
- if (mFirst == 0) {
- mFirst = mLast = newNode;
- newNode->prev = newNode->next = 0;
- } else {
- newNode->prev = 0;
- newNode->next = mFirst;
- mFirst->prev = newNode;
- mFirst = newNode;
- }
- }
-
- void insertTail(NODE* newNode) {
- if (mLast == 0) {
- insertHead(newNode);
- } else {
- newNode->prev = mLast;
- newNode->next = 0;
- mLast->next = newNode;
- mLast = newNode;
- }
- }
-
- NODE* remove(NODE* node) {
- if (node->prev == 0) mFirst = node->next;
- else node->prev->next = node->next;
- if (node->next == 0) mLast = node->prev;
- else node->next->prev = node->prev;
- return node;
- }
-};
-
-// ----------------------------------------------------------------------------
-
-class Allocation : public MemoryBase {
-public:
- Allocation(const sp<MemoryDealer>& dealer,
- const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
- virtual ~Allocation();
-private:
- sp<MemoryDealer> mDealer;
-};
-
-// ----------------------------------------------------------------------------
-
-class SimpleBestFitAllocator
-{
- enum {
- PAGE_ALIGNED = 0x00000001
- };
-public:
- SimpleBestFitAllocator(size_t size);
- ~SimpleBestFitAllocator();
-
- size_t allocate(size_t size, uint32_t flags = 0);
- status_t deallocate(size_t offset);
- size_t size() const;
- void dump(const char* what) const;
- void dump(String8& res, const char* what) const;
-
-private:
-
- struct chunk_t {
- chunk_t(size_t start, size_t size)
- : start(start), size(size), free(1), prev(0), next(0) {
- }
- size_t start;
- size_t size : 28;
- int free : 4;
- mutable chunk_t* prev;
- mutable chunk_t* next;
- };
-
- ssize_t alloc(size_t size, uint32_t flags);
- chunk_t* dealloc(size_t start);
- void dump_l(const char* what) const;
- void dump_l(String8& res, const char* what) const;
-
- static const int kMemoryAlign;
- mutable Mutex mLock;
- LinkedList<chunk_t> mList;
- size_t mHeapSize;
-};
-
-// ----------------------------------------------------------------------------
-
-Allocation::Allocation(
- const sp<MemoryDealer>& dealer,
- const sp<IMemoryHeap>& heap, ssize_t offset, size_t size)
- : MemoryBase(heap, offset, size), mDealer(dealer)
-{
-#ifndef NDEBUG
- void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
- memset(start_ptr, 0xda, size);
-#endif
-}
-
-Allocation::~Allocation()
-{
- size_t freedOffset = getOffset();
- size_t freedSize = getSize();
- if (freedSize) {
- /* 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 allocator
- * and could alias some real allocation (their offset is zero). */
-
- // keep the size to unmap in excess
- size_t pagesize = getpagesize();
- size_t start = freedOffset;
- size_t end = start + freedSize;
- start &= ~(pagesize-1);
- end = (end + pagesize-1) & ~(pagesize-1);
-
- // give back to the kernel the pages we don't need
- size_t free_start = freedOffset;
- size_t free_end = free_start + freedSize;
- if (start < free_start)
- start = free_start;
- if (end > free_end)
- end = free_end;
- start = (start + pagesize-1) & ~(pagesize-1);
- end &= ~(pagesize-1);
-
- if (start < end) {
- void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
- size_t size = end-start;
-
-#ifndef NDEBUG
- memset(start_ptr, 0xdf, size);
-#endif
-
- // MADV_REMOVE is not defined on Dapper based Goobuntu
-#ifdef MADV_REMOVE
- if (size) {
- int err = madvise(start_ptr, size, MADV_REMOVE);
- ALOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
- start_ptr, size, err<0 ? strerror(errno) : "Ok");
- }
-#endif
- }
-
- // This should be done after madvise(MADV_REMOVE), otherwise madvise()
- // might kick out the memory region that's allocated and/or written
- // right after the deallocation.
- mDealer->deallocate(freedOffset);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-MemoryDealer::MemoryDealer(size_t size, const char* name)
- : mHeap(new MemoryHeapBase(size, 0, name)),
- mAllocator(new SimpleBestFitAllocator(size))
-{
-}
-
-MemoryDealer::~MemoryDealer()
-{
- delete mAllocator;
-}
-
-sp<IMemory> MemoryDealer::allocate(size_t size)
-{
- sp<IMemory> memory;
- const ssize_t offset = allocator()->allocate(size);
- if (offset >= 0) {
- memory = new Allocation(this, heap(), offset, size);
- }
- return memory;
-}
-
-void MemoryDealer::deallocate(size_t offset)
-{
- allocator()->deallocate(offset);
-}
-
-void MemoryDealer::dump(const char* what) const
-{
- allocator()->dump(what);
-}
-
-const sp<IMemoryHeap>& MemoryDealer::heap() const {
- return mHeap;
-}
-
-SimpleBestFitAllocator* MemoryDealer::allocator() const {
- return mAllocator;
-}
-
-// ----------------------------------------------------------------------------
-
-// align all the memory blocks on a cache-line boundary
-const int SimpleBestFitAllocator::kMemoryAlign = 32;
-
-SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
-{
- size_t pagesize = getpagesize();
- mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
-
- chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
- mList.insertHead(node);
-}
-
-SimpleBestFitAllocator::~SimpleBestFitAllocator()
-{
- while(!mList.isEmpty()) {
- delete mList.remove(mList.head());
- }
-}
-
-size_t SimpleBestFitAllocator::size() const
-{
- return mHeapSize;
-}
-
-size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
-{
- Mutex::Autolock _l(mLock);
- ssize_t offset = alloc(size, flags);
- return offset;
-}
-
-status_t SimpleBestFitAllocator::deallocate(size_t offset)
-{
- Mutex::Autolock _l(mLock);
- chunk_t const * const freed = dealloc(offset);
- if (freed) {
- return NO_ERROR;
- }
- return NAME_NOT_FOUND;
-}
-
-ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
-{
- if (size == 0) {
- return 0;
- }
- size = (size + kMemoryAlign-1) / kMemoryAlign;
- chunk_t* free_chunk = 0;
- chunk_t* cur = mList.head();
-
- size_t pagesize = getpagesize();
- while (cur) {
- int extra = 0;
- if (flags & PAGE_ALIGNED)
- extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
-
- // best fit
- if (cur->free && (cur->size >= (size+extra))) {
- if ((!free_chunk) || (cur->size < free_chunk->size)) {
- free_chunk = cur;
- }
- if (cur->size == size) {
- break;
- }
- }
- cur = cur->next;
- }
-
- if (free_chunk) {
- const size_t free_size = free_chunk->size;
- free_chunk->free = 0;
- free_chunk->size = size;
- if (free_size > size) {
- int extra = 0;
- if (flags & PAGE_ALIGNED)
- extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
- if (extra) {
- chunk_t* split = new chunk_t(free_chunk->start, extra);
- free_chunk->start += extra;
- mList.insertBefore(free_chunk, split);
- }
-
- ALOGE_IF((flags&PAGE_ALIGNED) &&
- ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
- "PAGE_ALIGNED requested, but page is not aligned!!!");
-
- const ssize_t tail_free = free_size - (size+extra);
- if (tail_free > 0) {
- chunk_t* split = new chunk_t(
- free_chunk->start + free_chunk->size, tail_free);
- mList.insertAfter(free_chunk, split);
- }
- }
- return (free_chunk->start)*kMemoryAlign;
- }
- return NO_MEMORY;
-}
-
-SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
-{
- start = start / kMemoryAlign;
- chunk_t* cur = mList.head();
- while (cur) {
- if (cur->start == start) {
- LOG_FATAL_IF(cur->free,
- "block at offset 0x%08lX of size 0x%08lX already freed",
- cur->start*kMemoryAlign, cur->size*kMemoryAlign);
-
- // merge freed blocks together
- chunk_t* freed = cur;
- cur->free = 1;
- do {
- chunk_t* const p = cur->prev;
- chunk_t* const n = cur->next;
- if (p && (p->free || !cur->size)) {
- freed = p;
- p->size += cur->size;
- mList.remove(cur);
- delete cur;
- }
- cur = n;
- } while (cur && cur->free);
-
- #ifndef NDEBUG
- if (!freed->free) {
- dump_l("dealloc (!freed->free)");
- }
- #endif
- LOG_FATAL_IF(!freed->free,
- "freed block at offset 0x%08lX of size 0x%08lX is not free!",
- freed->start * kMemoryAlign, freed->size * kMemoryAlign);
-
- return freed;
- }
- cur = cur->next;
- }
- return 0;
-}
-
-void SimpleBestFitAllocator::dump(const char* what) const
-{
- Mutex::Autolock _l(mLock);
- dump_l(what);
-}
-
-void SimpleBestFitAllocator::dump_l(const char* what) const
-{
- String8 result;
- dump_l(result, what);
- ALOGD("%s", result.string());
-}
-
-void SimpleBestFitAllocator::dump(String8& result,
- const char* what) const
-{
- Mutex::Autolock _l(mLock);
- dump_l(result, what);
-}
-
-void SimpleBestFitAllocator::dump_l(String8& result,
- const char* what) const
-{
- size_t size = 0;
- int32_t i = 0;
- chunk_t const* cur = mList.head();
-
- const size_t SIZE = 256;
- char buffer[SIZE];
- snprintf(buffer, SIZE, " %s (%p, size=%u)\n",
- what, this, (unsigned int)mHeapSize);
-
- result.append(buffer);
-
- while (cur) {
- const char* errs[] = {"", "| link bogus NP",
- "| link bogus PN", "| link bogus NP+PN" };
- int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
- int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
-
- snprintf(buffer, SIZE, " %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
- i, int(cur), int(cur->start*kMemoryAlign),
- int(cur->size*kMemoryAlign),
- int(cur->free) ? "F" : "A",
- errs[np|pn]);
-
- result.append(buffer);
-
- if (!cur->free)
- size += cur->size*kMemoryAlign;
-
- i++;
- cur = cur->next;
- }
- snprintf(buffer, SIZE,
- " size allocated: %u (%u KB)\n", int(size), int(size/1024));
- result.append(buffer);
-}
-
-
-}; // namespace android
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
deleted file mode 100644
index d1cbf1c..0000000
--- a/libs/binder/MemoryHeapBase.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MemoryHeapBase"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/ashmem.h>
-#include <cutils/atomic.h>
-
-#include <binder/MemoryHeapBase.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapBase::MemoryHeapBase()
- : mFD(-1), mSize(0), mBase(MAP_FAILED),
- mDevice(NULL), mNeedUnmap(false), mOffset(0)
-{
-}
-
-MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
-{
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
- ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
- if (fd >= 0) {
- if (mapfd(fd, size) == NO_ERROR) {
- if (flags & READ_ONLY) {
- ashmem_set_prot_region(fd, PROT_READ);
- }
- }
- }
-}
-
-MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
-{
- int open_flags = O_RDWR;
- if (flags & NO_CACHING)
- open_flags |= O_SYNC;
-
- int fd = open(device, open_flags);
- ALOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
- if (fd >= 0) {
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- if (mapfd(fd, size) == NO_ERROR) {
- mDevice = device;
- }
- }
-}
-
-MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, uint32_t offset)
- : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false), mOffset(0)
-{
- const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- mapfd(dup(fd), size, offset);
-}
-
-status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
-{
- if (mFD != -1) {
- return INVALID_OPERATION;
- }
- mFD = fd;
- mBase = base;
- mSize = size;
- mFlags = flags;
- mDevice = device;
- return NO_ERROR;
-}
-
-status_t MemoryHeapBase::mapfd(int fd, size_t size, uint32_t offset)
-{
- if (size == 0) {
- // try to figure out the size automatically
-#ifdef HAVE_ANDROID_OS
- // first try the PMEM ioctl
- pmem_region reg;
- int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
- if (err == 0)
- size = reg.len;
-#endif
- if (size == 0) { // try fstat
- struct stat sb;
- if (fstat(fd, &sb) == 0)
- size = sb.st_size;
- }
- // if it didn't work, let mmap() fail.
- }
-
- if ((mFlags & DONT_MAP_LOCALLY) == 0) {
- void* base = (uint8_t*)mmap(0, size,
- PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
- if (base == MAP_FAILED) {
- ALOGE("mmap(fd=%d, size=%u) failed (%s)",
- fd, uint32_t(size), strerror(errno));
- close(fd);
- return -errno;
- }
- //ALOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
- mBase = base;
- mNeedUnmap = true;
- } else {
- mBase = 0; // not MAP_FAILED
- mNeedUnmap = false;
- }
- mFD = fd;
- mSize = size;
- mOffset = offset;
- return NO_ERROR;
-}
-
-MemoryHeapBase::~MemoryHeapBase()
-{
- dispose();
-}
-
-void MemoryHeapBase::dispose()
-{
- int fd = android_atomic_or(-1, &mFD);
- if (fd >= 0) {
- if (mNeedUnmap) {
- //ALOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
- munmap(mBase, mSize);
- }
- mBase = 0;
- mSize = 0;
- close(fd);
- }
-}
-
-int MemoryHeapBase::getHeapID() const {
- return mFD;
-}
-
-void* MemoryHeapBase::getBase() const {
- return mBase;
-}
-
-size_t MemoryHeapBase::getSize() const {
- return mSize;
-}
-
-uint32_t MemoryHeapBase::getFlags() const {
- return mFlags;
-}
-
-const char* MemoryHeapBase::getDevice() const {
- return mDevice;
-}
-
-uint32_t MemoryHeapBase::getOffset() const {
- return mOffset;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
deleted file mode 100644
index dea14bb..0000000
--- a/libs/binder/Parcel.cpp
+++ /dev/null
@@ -1,1590 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Parcel"
-//#define LOG_NDEBUG 0
-
-#include <binder/Parcel.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/Binder.h>
-#include <binder/BpBinder.h>
-#include <utils/Debug.h>
-#include <binder/ProcessState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <utils/TextOutput.h>
-#include <utils/misc.h>
-#include <utils/Flattenable.h>
-#include <cutils/ashmem.h>
-
-#include <private/binder/binder_module.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/mman.h>
-
-#ifndef INT32_MAX
-#define INT32_MAX ((int32_t)(2147483647))
-#endif
-
-#define LOG_REFS(...)
-//#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
-
-// ---------------------------------------------------------------------------
-
-#define PAD_SIZE(s) (((s)+3)&~3)
-
-// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
-#define STRICT_MODE_PENALTY_GATHER 0x100
-
-// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
-#define EX_HAS_REPLY_HEADER -128
-
-// Maximum size of a blob to transfer in-place.
-static const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
-
-// XXX This can be made public if we want to provide
-// support for typed data.
-struct small_flat_data
-{
- uint32_t type;
- uint32_t data;
-};
-
-namespace android {
-
-void acquire_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
-{
- switch (obj.type) {
- case BINDER_TYPE_BINDER:
- if (obj.binder) {
- LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
- static_cast<IBinder*>(obj.cookie)->incStrong(who);
- }
- return;
- case BINDER_TYPE_WEAK_BINDER:
- if (obj.binder)
- static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
- return;
- case BINDER_TYPE_HANDLE: {
- const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
- if (b != NULL) {
- LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
- b->incStrong(who);
- }
- return;
- }
- case BINDER_TYPE_WEAK_HANDLE: {
- const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
- if (b != NULL) b.get_refs()->incWeak(who);
- return;
- }
- case BINDER_TYPE_FD: {
- // intentionally blank -- nothing to do to acquire this, but we do
- // recognize it as a legitimate object type.
- return;
- }
- }
-
- ALOGD("Invalid object type 0x%08lx", obj.type);
-}
-
-void release_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
-{
- switch (obj.type) {
- case BINDER_TYPE_BINDER:
- if (obj.binder) {
- LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
- static_cast<IBinder*>(obj.cookie)->decStrong(who);
- }
- return;
- case BINDER_TYPE_WEAK_BINDER:
- if (obj.binder)
- static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
- return;
- case BINDER_TYPE_HANDLE: {
- const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
- if (b != NULL) {
- LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
- b->decStrong(who);
- }
- return;
- }
- case BINDER_TYPE_WEAK_HANDLE: {
- const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
- if (b != NULL) b.get_refs()->decWeak(who);
- return;
- }
- case BINDER_TYPE_FD: {
- if (obj.cookie != (void*)0) close(obj.handle);
- return;
- }
- }
-
- ALOGE("Invalid object type 0x%08lx", obj.type);
-}
-
-inline static status_t finish_flatten_binder(
- const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
-{
- return out->writeObject(flat, false);
-}
-
-status_t flatten_binder(const sp<ProcessState>& proc,
- const sp<IBinder>& binder, Parcel* out)
-{
- flat_binder_object obj;
-
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- if (binder != NULL) {
- IBinder *local = binder->localBinder();
- if (!local) {
- BpBinder *proxy = binder->remoteBinder();
- if (proxy == NULL) {
- ALOGE("null proxy");
- }
- const int32_t handle = proxy ? proxy->handle() : 0;
- obj.type = BINDER_TYPE_HANDLE;
- obj.handle = handle;
- obj.cookie = NULL;
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = local->getWeakRefs();
- obj.cookie = local;
- }
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- }
-
- return finish_flatten_binder(binder, obj, out);
-}
-
-status_t flatten_binder(const sp<ProcessState>& proc,
- const wp<IBinder>& binder, Parcel* out)
-{
- flat_binder_object obj;
-
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- if (binder != NULL) {
- sp<IBinder> real = binder.promote();
- if (real != NULL) {
- IBinder *local = real->localBinder();
- if (!local) {
- BpBinder *proxy = real->remoteBinder();
- if (proxy == NULL) {
- ALOGE("null proxy");
- }
- const int32_t handle = proxy ? proxy->handle() : 0;
- obj.type = BINDER_TYPE_WEAK_HANDLE;
- obj.handle = handle;
- obj.cookie = NULL;
- } else {
- obj.type = BINDER_TYPE_WEAK_BINDER;
- obj.binder = binder.get_refs();
- obj.cookie = binder.unsafe_get();
- }
- return finish_flatten_binder(real, obj, out);
- }
-
- // XXX How to deal? In order to flatten the given binder,
- // we need to probe it for information, which requires a primary
- // reference... but we don't have one.
- //
- // The OpenBinder implementation uses a dynamic_cast<> here,
- // but we can't do that with the different reference counting
- // implementation we are using.
- ALOGE("Unable to unflatten Binder weak reference!");
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- return finish_flatten_binder(NULL, obj, out);
-
- } else {
- obj.type = BINDER_TYPE_BINDER;
- obj.binder = NULL;
- obj.cookie = NULL;
- return finish_flatten_binder(NULL, obj, out);
- }
-}
-
-inline static status_t finish_unflatten_binder(
- BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
-{
- return NO_ERROR;
-}
-
-status_t unflatten_binder(const sp<ProcessState>& proc,
- const Parcel& in, sp<IBinder>* out)
-{
- const flat_binder_object* flat = in.readObject(false);
-
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_BINDER:
- *out = static_cast<IBinder*>(flat->cookie);
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_HANDLE:
- *out = proc->getStrongProxyForHandle(flat->handle);
- return finish_unflatten_binder(
- static_cast<BpBinder*>(out->get()), *flat, in);
- }
- }
- return BAD_TYPE;
-}
-
-status_t unflatten_binder(const sp<ProcessState>& proc,
- const Parcel& in, wp<IBinder>* out)
-{
- const flat_binder_object* flat = in.readObject(false);
-
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_BINDER:
- *out = static_cast<IBinder*>(flat->cookie);
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_WEAK_BINDER:
- if (flat->binder != NULL) {
- out->set_object_and_refs(
- static_cast<IBinder*>(flat->cookie),
- static_cast<RefBase::weakref_type*>(flat->binder));
- } else {
- *out = NULL;
- }
- return finish_unflatten_binder(NULL, *flat, in);
- case BINDER_TYPE_HANDLE:
- case BINDER_TYPE_WEAK_HANDLE:
- *out = proc->getWeakProxyForHandle(flat->handle);
- return finish_unflatten_binder(
- static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
- }
- }
- return BAD_TYPE;
-}
-
-// ---------------------------------------------------------------------------
-
-Parcel::Parcel()
-{
- initState();
-}
-
-Parcel::~Parcel()
-{
- freeDataNoInit();
-}
-
-const uint8_t* Parcel::data() const
-{
- return mData;
-}
-
-size_t Parcel::dataSize() const
-{
- return (mDataSize > mDataPos ? mDataSize : mDataPos);
-}
-
-size_t Parcel::dataAvail() const
-{
- // TODO: decide what to do about the possibility that this can
- // report an available-data size that exceeds a Java int's max
- // positive value, causing havoc. Fortunately this will only
- // happen if someone constructs a Parcel containing more than two
- // gigabytes of data, which on typical phone hardware is simply
- // not possible.
- return dataSize() - dataPosition();
-}
-
-size_t Parcel::dataPosition() const
-{
- return mDataPos;
-}
-
-size_t Parcel::dataCapacity() const
-{
- return mDataCapacity;
-}
-
-status_t Parcel::setDataSize(size_t size)
-{
- status_t err;
- err = continueWrite(size);
- if (err == NO_ERROR) {
- mDataSize = size;
- ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
- }
- return err;
-}
-
-void Parcel::setDataPosition(size_t pos) const
-{
- mDataPos = pos;
- mNextObjectHint = 0;
-}
-
-status_t Parcel::setDataCapacity(size_t size)
-{
- if (size > mDataCapacity) return continueWrite(size);
- return NO_ERROR;
-}
-
-status_t Parcel::setData(const uint8_t* buffer, size_t len)
-{
- status_t err = restartWrite(len);
- if (err == NO_ERROR) {
- memcpy(const_cast<uint8_t*>(data()), buffer, len);
- mDataSize = len;
- mFdsKnown = false;
- }
- return err;
-}
-
-status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
-{
- const sp<ProcessState> proc(ProcessState::self());
- status_t err;
- const uint8_t *data = parcel->mData;
- const size_t *objects = parcel->mObjects;
- size_t size = parcel->mObjectsSize;
- int startPos = mDataPos;
- int firstIndex = -1, lastIndex = -2;
-
- if (len == 0) {
- return NO_ERROR;
- }
-
- // range checks against the source parcel size
- if ((offset > parcel->mDataSize)
- || (len > parcel->mDataSize)
- || (offset + len > parcel->mDataSize)) {
- return BAD_VALUE;
- }
-
- // Count objects in range
- for (int i = 0; i < (int) size; i++) {
- size_t off = objects[i];
- if ((off >= offset) && (off < offset + len)) {
- if (firstIndex == -1) {
- firstIndex = i;
- }
- lastIndex = i;
- }
- }
- int numObjects = lastIndex - firstIndex + 1;
-
- if ((mDataSize+len) > mDataCapacity) {
- // grow data
- err = growData(len);
- if (err != NO_ERROR) {
- return err;
- }
- }
-
- // append data
- memcpy(mData + mDataPos, data + offset, len);
- mDataPos += len;
- mDataSize += len;
-
- err = NO_ERROR;
-
- if (numObjects > 0) {
- // grow objects
- if (mObjectsCapacity < mObjectsSize + numObjects) {
- int newSize = ((mObjectsSize + numObjects)*3)/2;
- size_t *objects =
- (size_t*)realloc(mObjects, newSize*sizeof(size_t));
- if (objects == (size_t*)0) {
- return NO_MEMORY;
- }
- mObjects = objects;
- mObjectsCapacity = newSize;
- }
-
- // append and acquire objects
- int idx = mObjectsSize;
- for (int i = firstIndex; i <= lastIndex; i++) {
- size_t off = objects[i] - offset + startPos;
- mObjects[idx++] = off;
- mObjectsSize++;
-
- flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData + off);
- acquire_object(proc, *flat, this);
-
- 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;
- if (!mAllowFds) {
- err = FDS_NOT_ALLOWED;
- }
- }
- }
- }
-
- return err;
-}
-
-bool Parcel::pushAllowFds(bool allowFds)
-{
- const bool origValue = mAllowFds;
- if (!allowFds) {
- mAllowFds = false;
- }
- return origValue;
-}
-
-void Parcel::restoreAllowFds(bool lastValue)
-{
- mAllowFds = lastValue;
-}
-
-bool Parcel::hasFileDescriptors() const
-{
- if (!mFdsKnown) {
- scanForFds();
- }
- return mHasFds;
-}
-
-// Write RPC headers. (previously just the interface token)
-status_t Parcel::writeInterfaceToken(const String16& interface)
-{
- writeInt32(IPCThreadState::self()->getStrictModePolicy() |
- STRICT_MODE_PENALTY_GATHER);
- // currently the interface identification token is just its name as a string
- return writeString16(interface);
-}
-
-bool Parcel::checkInterface(IBinder* binder) const
-{
- return enforceInterface(binder->getInterfaceDescriptor());
-}
-
-bool Parcel::enforceInterface(const String16& interface,
- IPCThreadState* threadState) const
-{
- int32_t strictPolicy = readInt32();
- if (threadState == NULL) {
- threadState = IPCThreadState::self();
- }
- if ((threadState->getLastTransactionBinderFlags() &
- IBinder::FLAG_ONEWAY) != 0) {
- // For one-way calls, the callee is running entirely
- // disconnected from the caller, so disable StrictMode entirely.
- // Not only does disk/network usage not impact the caller, but
- // there's no way to commuicate back any violations anyway.
- threadState->setStrictModePolicy(0);
- } else {
- threadState->setStrictModePolicy(strictPolicy);
- }
- const String16 str(readString16());
- if (str == interface) {
- return true;
- } else {
- ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
- String8(interface).string(), String8(str).string());
- return false;
- }
-}
-
-const size_t* Parcel::objects() const
-{
- return mObjects;
-}
-
-size_t Parcel::objectsCount() const
-{
- return mObjectsSize;
-}
-
-status_t Parcel::errorCheck() const
-{
- return mError;
-}
-
-void Parcel::setError(status_t err)
-{
- mError = err;
-}
-
-status_t Parcel::finishWrite(size_t len)
-{
- //printf("Finish write of %d\n", len);
- mDataPos += len;
- ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
- if (mDataPos > mDataSize) {
- mDataSize = mDataPos;
- ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
- }
- //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
- return NO_ERROR;
-}
-
-status_t Parcel::writeUnpadded(const void* data, size_t len)
-{
- size_t end = mDataPos + len;
- if (end < mDataPos) {
- // integer overflow
- return BAD_VALUE;
- }
-
- if (end <= mDataCapacity) {
-restart_write:
- memcpy(mData+mDataPos, data, len);
- return finishWrite(len);
- }
-
- status_t err = growData(len);
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::write(const void* data, size_t len)
-{
- void* const d = writeInplace(len);
- if (d) {
- memcpy(d, data, len);
- return NO_ERROR;
- }
- return mError;
-}
-
-void* Parcel::writeInplace(size_t len)
-{
- const size_t padded = PAD_SIZE(len);
-
- // sanity check for integer overflow
- if (mDataPos+padded < mDataPos) {
- return NULL;
- }
-
- if ((mDataPos+padded) <= mDataCapacity) {
-restart_write:
- //printf("Writing %ld bytes, padded to %ld\n", len, padded);
- uint8_t* const data = mData+mDataPos;
-
- // Need to pad at end?
- if (padded != len) {
-#if BYTE_ORDER == BIG_ENDIAN
- static const uint32_t mask[4] = {
- 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
- };
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN
- static const uint32_t mask[4] = {
- 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
- };
-#endif
- //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
- // *reinterpret_cast<void**>(data+padded-4));
- *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
- }
-
- finishWrite(padded);
- return data;
- }
-
- status_t err = growData(padded);
- if (err == NO_ERROR) goto restart_write;
- return NULL;
-}
-
-status_t Parcel::writeInt32(int32_t val)
-{
- return writeAligned(val);
-}
-
-status_t Parcel::writeInt64(int64_t val)
-{
- return writeAligned(val);
-}
-
-status_t Parcel::writeFloat(float val)
-{
- return writeAligned(val);
-}
-
-status_t Parcel::writeDouble(double val)
-{
- return writeAligned(val);
-}
-
-status_t Parcel::writeIntPtr(intptr_t val)
-{
- return writeAligned(val);
-}
-
-status_t Parcel::writeCString(const char* str)
-{
- return write(str, strlen(str)+1);
-}
-
-status_t Parcel::writeString8(const String8& str)
-{
- status_t err = writeInt32(str.bytes());
- // only write string if its length is more than zero characters,
- // as readString8 will only read if the length field is non-zero.
- // this is slightly different from how writeString16 works.
- if (str.bytes() > 0 && err == NO_ERROR) {
- err = write(str.string(), str.bytes()+1);
- }
- return err;
-}
-
-status_t Parcel::writeString16(const String16& str)
-{
- return writeString16(str.string(), str.size());
-}
-
-status_t Parcel::writeString16(const char16_t* str, size_t len)
-{
- if (str == NULL) return writeInt32(-1);
-
- status_t err = writeInt32(len);
- if (err == NO_ERROR) {
- len *= sizeof(char16_t);
- uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
- if (data) {
- memcpy(data, str, len);
- *reinterpret_cast<char16_t*>(data+len) = 0;
- return NO_ERROR;
- }
- err = mError;
- }
- return err;
-}
-
-status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
-{
- return flatten_binder(ProcessState::self(), val, this);
-}
-
-status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
-{
- return flatten_binder(ProcessState::self(), val, this);
-}
-
-status_t Parcel::writeNativeHandle(const native_handle* handle)
-{
- if (!handle || handle->version != sizeof(native_handle))
- return BAD_TYPE;
-
- status_t err;
- err = writeInt32(handle->numFds);
- if (err != NO_ERROR) return err;
-
- err = writeInt32(handle->numInts);
- if (err != NO_ERROR) return err;
-
- for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
- err = writeDupFileDescriptor(handle->data[i]);
-
- if (err != NO_ERROR) {
- ALOGD("write native handle, write dup fd failed");
- return err;
- }
- err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
- return err;
-}
-
-status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
-{
- flat_binder_object obj;
- obj.type = BINDER_TYPE_FD;
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- obj.handle = fd;
- obj.cookie = (void*) (takeOwnership ? 1 : 0);
- return writeObject(obj, true);
-}
-
-status_t Parcel::writeDupFileDescriptor(int fd)
-{
- int dupFd = dup(fd);
- if (dupFd < 0) {
- return -errno;
- }
- status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
- if (err) {
- close(dupFd);
- }
- return err;
-}
-
-status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
-{
- status_t status;
-
- if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
- ALOGV("writeBlob: write in place");
- status = writeInt32(0);
- if (status) return status;
-
- void* ptr = writeInplace(len);
- if (!ptr) return NO_MEMORY;
-
- outBlob->init(false /*mapped*/, ptr, len);
- return NO_ERROR;
- }
-
- ALOGV("writeBlob: write to ashmem");
- int fd = ashmem_create_region("Parcel Blob", len);
- if (fd < 0) return NO_MEMORY;
-
- int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
- if (result < 0) {
- status = result;
- } else {
- void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (ptr == MAP_FAILED) {
- status = -errno;
- } else {
- result = ashmem_set_prot_region(fd, PROT_READ);
- if (result < 0) {
- status = result;
- } else {
- status = writeInt32(1);
- if (!status) {
- status = writeFileDescriptor(fd, true /*takeOwnership*/);
- if (!status) {
- outBlob->init(true /*mapped*/, ptr, len);
- return NO_ERROR;
- }
- }
- }
- }
- ::munmap(ptr, len);
- }
- ::close(fd);
- return status;
-}
-
-status_t Parcel::write(const Flattenable& val)
-{
- status_t err;
-
- // size if needed
- size_t len = val.getFlattenedSize();
- size_t fd_count = val.getFdCount();
-
- err = this->writeInt32(len);
- if (err) return err;
-
- err = this->writeInt32(fd_count);
- if (err) return err;
-
- // payload
- void* buf = this->writeInplace(PAD_SIZE(len));
- if (buf == NULL)
- return BAD_VALUE;
-
- int* fds = NULL;
- if (fd_count) {
- fds = new int[fd_count];
- }
-
- err = val.flatten(buf, len, fds, fd_count);
- for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
- err = this->writeDupFileDescriptor( fds[i] );
- }
-
- if (fd_count) {
- delete [] fds;
- }
-
- return err;
-}
-
-status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
-{
- const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
- const bool enoughObjects = mObjectsSize < mObjectsCapacity;
- if (enoughData && enoughObjects) {
-restart_write:
- *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
-
- // Need to write meta-data?
- if (nullMetaData || val.binder != NULL) {
- mObjects[mObjectsSize] = mDataPos;
- acquire_object(ProcessState::self(), val, this);
- mObjectsSize++;
- }
-
- // remember if it's a file descriptor
- if (val.type == BINDER_TYPE_FD) {
- if (!mAllowFds) {
- return FDS_NOT_ALLOWED;
- }
- mHasFds = mFdsKnown = true;
- }
-
- return finishWrite(sizeof(flat_binder_object));
- }
-
- if (!enoughData) {
- const status_t err = growData(sizeof(val));
- if (err != NO_ERROR) return err;
- }
- if (!enoughObjects) {
- size_t newSize = ((mObjectsSize+2)*3)/2;
- size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
- if (objects == NULL) return NO_MEMORY;
- mObjects = objects;
- mObjectsCapacity = newSize;
- }
-
- 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!");
-}
-
-status_t Parcel::read(void* outData, size_t len) const
-{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
- memcpy(outData, mData+mDataPos, len);
- mDataPos += PAD_SIZE(len);
- ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
- return NO_ERROR;
- }
- return NOT_ENOUGH_DATA;
-}
-
-const void* Parcel::readInplace(size_t len) const
-{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += PAD_SIZE(len);
- ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
- return data;
- }
- return NULL;
-}
-
-template<class T>
-status_t Parcel::readAligned(T *pArg) const {
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
- if ((mDataPos+sizeof(T)) <= mDataSize) {
- const void* data = mData+mDataPos;
- mDataPos += sizeof(T);
- *pArg = *reinterpret_cast<const T*>(data);
- return NO_ERROR;
- } else {
- return NOT_ENOUGH_DATA;
- }
-}
-
-template<class T>
-T Parcel::readAligned() const {
- T result;
- if (readAligned(&result) != NO_ERROR) {
- result = 0;
- }
-
- return result;
-}
-
-template<class T>
-status_t Parcel::writeAligned(T val) {
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
- *reinterpret_cast<T*>(mData+mDataPos) = val;
- return finishWrite(sizeof(val));
- }
-
- status_t err = growData(sizeof(val));
- if (err == NO_ERROR) goto restart_write;
- return err;
-}
-
-status_t Parcel::readInt32(int32_t *pArg) const
-{
- return readAligned(pArg);
-}
-
-int32_t Parcel::readInt32() const
-{
- return readAligned<int32_t>();
-}
-
-
-status_t Parcel::readInt64(int64_t *pArg) const
-{
- return readAligned(pArg);
-}
-
-
-int64_t Parcel::readInt64() const
-{
- return readAligned<int64_t>();
-}
-
-status_t Parcel::readFloat(float *pArg) const
-{
- return readAligned(pArg);
-}
-
-
-float Parcel::readFloat() const
-{
- return readAligned<float>();
-}
-
-status_t Parcel::readDouble(double *pArg) const
-{
- return readAligned(pArg);
-}
-
-
-double Parcel::readDouble() const
-{
- return readAligned<double>();
-}
-
-status_t Parcel::readIntPtr(intptr_t *pArg) const
-{
- return readAligned(pArg);
-}
-
-
-intptr_t Parcel::readIntPtr() const
-{
- return readAligned<intptr_t>();
-}
-
-
-const char* Parcel::readCString() const
-{
- const size_t avail = mDataSize-mDataPos;
- if (avail > 0) {
- const char* str = reinterpret_cast<const char*>(mData+mDataPos);
- // is the string's trailing NUL within the parcel's valid bounds?
- const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
- if (eos) {
- const size_t len = eos - str;
- mDataPos += PAD_SIZE(len+1);
- ALOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
- return str;
- }
- }
- return NULL;
-}
-
-String8 Parcel::readString8() const
-{
- int32_t size = readInt32();
- // watch for potential int overflow adding 1 for trailing NUL
- if (size > 0 && size < INT32_MAX) {
- const char* str = (const char*)readInplace(size+1);
- if (str) return String8(str, size);
- }
- return String8();
-}
-
-String16 Parcel::readString16() const
-{
- size_t len;
- const char16_t* str = readString16Inplace(&len);
- if (str) return String16(str, len);
- ALOGE("Reading a NULL string not supported here.");
- return String16();
-}
-
-const char16_t* Parcel::readString16Inplace(size_t* outLen) const
-{
- int32_t size = readInt32();
- // watch for potential int overflow from size+1
- if (size >= 0 && size < INT32_MAX) {
- *outLen = size;
- const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
- if (str != NULL) {
- return str;
- }
- }
- *outLen = 0;
- return NULL;
-}
-
-sp<IBinder> Parcel::readStrongBinder() const
-{
- sp<IBinder> val;
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
-}
-
-wp<IBinder> Parcel::readWeakBinder() const
-{
- wp<IBinder> val;
- unflatten_binder(ProcessState::self(), *this, &val);
- return val;
-}
-
-int32_t Parcel::readExceptionCode() const
-{
- int32_t exception_code = readAligned<int32_t>();
- if (exception_code == EX_HAS_REPLY_HEADER) {
- int32_t header_size = readAligned<int32_t>();
- // Skip over fat responses headers. Not used (or propagated) in
- // native code
- setDataPosition(dataPosition() + header_size);
- // And fat response headers are currently only used when there are no
- // exceptions, so return no error:
- return 0;
- }
- return exception_code;
-}
-
-native_handle* Parcel::readNativeHandle() const
-{
- int numFds, numInts;
- status_t err;
- err = readInt32(&numFds);
- if (err != NO_ERROR) return 0;
- err = readInt32(&numInts);
- if (err != NO_ERROR) return 0;
-
- native_handle* h = native_handle_create(numFds, numInts);
- for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
- h->data[i] = dup(readFileDescriptor());
- if (h->data[i] < 0) err = BAD_VALUE;
- }
- err = read(h->data + numFds, sizeof(int)*numInts);
- if (err != NO_ERROR) {
- native_handle_close(h);
- native_handle_delete(h);
- h = 0;
- }
- return h;
-}
-
-
-int Parcel::readFileDescriptor() const
-{
- const flat_binder_object* flat = readObject(true);
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_FD:
- //ALOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
- return flat->handle;
- }
- }
- return BAD_TYPE;
-}
-
-status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
-{
- int32_t useAshmem;
- status_t status = readInt32(&useAshmem);
- if (status) return status;
-
- if (!useAshmem) {
- ALOGV("readBlob: read in place");
- const void* ptr = readInplace(len);
- if (!ptr) return BAD_VALUE;
-
- outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
- return NO_ERROR;
- }
-
- ALOGV("readBlob: read from ashmem");
- int fd = readFileDescriptor();
- if (fd == int(BAD_TYPE)) return BAD_VALUE;
-
- void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
- if (!ptr) return NO_MEMORY;
-
- outBlob->init(true /*mapped*/, ptr, len);
- return NO_ERROR;
-}
-
-status_t Parcel::read(Flattenable& val) const
-{
- // size
- const size_t len = this->readInt32();
- const size_t fd_count = this->readInt32();
-
- // payload
- void const* buf = this->readInplace(PAD_SIZE(len));
- if (buf == NULL)
- return BAD_VALUE;
-
- int* fds = NULL;
- if (fd_count) {
- fds = new int[fd_count];
- }
-
- status_t err = NO_ERROR;
- for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
- fds[i] = dup(this->readFileDescriptor());
- if (fds[i] < 0) err = BAD_VALUE;
- }
-
- if (err == NO_ERROR) {
- err = val.unflatten(buf, len, fds, fd_count);
- }
-
- if (fd_count) {
- delete [] fds;
- }
-
- return err;
-}
-const flat_binder_object* Parcel::readObject(bool nullMetaData) const
-{
- const size_t DPOS = mDataPos;
- if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
- const flat_binder_object* obj
- = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
- mDataPos = DPOS + sizeof(flat_binder_object);
- if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
- // When transferring a NULL object, we don't write it into
- // the object list, so we don't want to check for it when
- // reading.
- ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
-
- // Ensure that this object is valid...
- size_t* const OBJS = mObjects;
- const size_t N = mObjectsSize;
- size_t opos = mNextObjectHint;
-
- if (N > 0) {
- ALOGV("Parcel %p looking for obj at %d, hint=%d\n",
- this, DPOS, opos);
-
- // Start at the current hint position, looking for an object at
- // the current data position.
- if (opos < N) {
- while (opos < (N-1) && OBJS[opos] < DPOS) {
- opos++;
- }
- } else {
- opos = N-1;
- }
- if (OBJS[opos] == DPOS) {
- // Found it!
- ALOGV("Parcel found obj %d at index %d with forward search",
- this, DPOS, opos);
- mNextObjectHint = opos+1;
- ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
-
- // Look backwards for it...
- while (opos > 0 && OBJS[opos] > DPOS) {
- opos--;
- }
- if (OBJS[opos] == DPOS) {
- // Found it!
- ALOGV("Parcel found obj %d at index %d with backward search",
- this, DPOS, opos);
- mNextObjectHint = opos+1;
- ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
- return obj;
- }
- }
- ALOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
- this, DPOS);
- }
- return NULL;
-}
-
-void Parcel::closeFileDescriptors()
-{
- size_t i = mObjectsSize;
- if (i > 0) {
- //ALOGI("Closing file descriptors for %d objects...", mObjectsSize);
- }
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- //ALOGI("Closing fd: %ld\n", flat->handle);
- close(flat->handle);
- }
- }
-}
-
-const uint8_t* Parcel::ipcData() const
-{
- return mData;
-}
-
-size_t Parcel::ipcDataSize() const
-{
- return (mDataSize > mDataPos ? mDataSize : mDataPos);
-}
-
-const size_t* Parcel::ipcObjects() const
-{
- return mObjects;
-}
-
-size_t Parcel::ipcObjectsCount() const
-{
- return mObjectsSize;
-}
-
-void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
- const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-{
- freeDataNoInit();
- mError = NO_ERROR;
- mData = const_cast<uint8_t*>(data);
- mDataSize = mDataCapacity = dataSize;
- //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
- mDataPos = 0;
- ALOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
- mObjects = const_cast<size_t*>(objects);
- mObjectsSize = mObjectsCapacity = objectsCount;
- mNextObjectHint = 0;
- mOwner = relFunc;
- mOwnerCookie = relCookie;
- scanForFds();
-}
-
-void Parcel::print(TextOutput& to, uint32_t flags) const
-{
- to << "Parcel(";
-
- if (errorCheck() != NO_ERROR) {
- const status_t err = errorCheck();
- to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
- } else if (dataSize() > 0) {
- const uint8_t* DATA = data();
- to << indent << HexDump(DATA, dataSize()) << dedent;
- const size_t* OBJS = objects();
- const size_t N = objectsCount();
- for (size_t i=0; i<N; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
- to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
- << TypeCode(flat->type & 0x7f7f7f00)
- << " = " << flat->binder;
- }
- } else {
- to << "NULL";
- }
-
- to << ")";
-}
-
-void Parcel::releaseObjects()
-{
- const sp<ProcessState> proc(ProcessState::self());
- size_t i = mObjectsSize;
- uint8_t* const data = mData;
- size_t* const objects = mObjects;
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(data+objects[i]);
- release_object(proc, *flat, this);
- }
-}
-
-void Parcel::acquireObjects()
-{
- const sp<ProcessState> proc(ProcessState::self());
- size_t i = mObjectsSize;
- uint8_t* const data = mData;
- size_t* const objects = mObjects;
- while (i > 0) {
- i--;
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(data+objects[i]);
- acquire_object(proc, *flat, this);
- }
-}
-
-void Parcel::freeData()
-{
- freeDataNoInit();
- initState();
-}
-
-void Parcel::freeDataNoInit()
-{
- if (mOwner) {
- //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
- mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
- } else {
- releaseObjects();
- if (mData) free(mData);
- if (mObjects) free(mObjects);
- }
-}
-
-status_t Parcel::growData(size_t len)
-{
- size_t newSize = ((mDataSize+len)*3)/2;
- return (newSize <= mDataSize)
- ? (status_t) NO_MEMORY
- : continueWrite(newSize);
-}
-
-status_t Parcel::restartWrite(size_t desired)
-{
- if (mOwner) {
- freeData();
- return continueWrite(desired);
- }
-
- uint8_t* data = (uint8_t*)realloc(mData, desired);
- if (!data && desired > mDataCapacity) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- releaseObjects();
-
- if (data) {
- mData = data;
- mDataCapacity = desired;
- }
-
- mDataSize = mDataPos = 0;
- ALOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
- ALOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
-
- free(mObjects);
- mObjects = NULL;
- mObjectsSize = mObjectsCapacity = 0;
- mNextObjectHint = 0;
- mHasFds = false;
- mFdsKnown = true;
- mAllowFds = true;
-
- return NO_ERROR;
-}
-
-status_t Parcel::continueWrite(size_t desired)
-{
- // If shrinking, first adjust for any objects that appear
- // after the new data size.
- size_t objectsSize = mObjectsSize;
- if (desired < mDataSize) {
- if (desired == 0) {
- objectsSize = 0;
- } else {
- while (objectsSize > 0) {
- if (mObjects[objectsSize-1] < desired)
- break;
- objectsSize--;
- }
- }
- }
-
- if (mOwner) {
- // If the size is going to zero, just release the owner's data.
- if (desired == 0) {
- freeData();
- return NO_ERROR;
- }
-
- // If there is a different owner, we need to take
- // posession.
- uint8_t* data = (uint8_t*)malloc(desired);
- if (!data) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
- size_t* objects = NULL;
-
- if (objectsSize) {
- objects = (size_t*)malloc(objectsSize*sizeof(size_t));
- if (!objects) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- // Little hack to only acquire references on objects
- // we will be keeping.
- size_t oldObjectsSize = mObjectsSize;
- mObjectsSize = objectsSize;
- acquireObjects();
- mObjectsSize = oldObjectsSize;
- }
-
- if (mData) {
- memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
- }
- if (objects && mObjects) {
- memcpy(objects, mObjects, objectsSize*sizeof(size_t));
- }
- //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
- mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
- mOwner = NULL;
-
- mData = data;
- mObjects = objects;
- mDataSize = (mDataSize < desired) ? mDataSize : desired;
- ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- mDataCapacity = desired;
- mObjectsSize = mObjectsCapacity = objectsSize;
- mNextObjectHint = 0;
-
- } else if (mData) {
- if (objectsSize < mObjectsSize) {
- // Need to release refs on any objects we are dropping.
- const sp<ProcessState> proc(ProcessState::self());
- for (size_t i=objectsSize; i<mObjectsSize; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- // will need to rescan because we may have lopped off the only FDs
- mFdsKnown = false;
- }
- release_object(proc, *flat, this);
- }
- size_t* objects =
- (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
- if (objects) {
- mObjects = objects;
- }
- mObjectsSize = objectsSize;
- mNextObjectHint = 0;
- }
-
- // We own the data, so we can just do a realloc().
- if (desired > mDataCapacity) {
- uint8_t* data = (uint8_t*)realloc(mData, desired);
- if (data) {
- mData = data;
- mDataCapacity = desired;
- } else if (desired > mDataCapacity) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
- } else {
- if (mDataSize > desired) {
- mDataSize = desired;
- ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- }
- if (mDataPos > desired) {
- mDataPos = desired;
- ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
- }
- }
-
- } else {
- // This is the first data. Easy!
- uint8_t* data = (uint8_t*)malloc(desired);
- if (!data) {
- mError = NO_MEMORY;
- return NO_MEMORY;
- }
-
- if(!(mDataCapacity == 0 && mObjects == NULL
- && mObjectsCapacity == 0)) {
- ALOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
- }
-
- mData = data;
- mDataSize = mDataPos = 0;
- ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
- mDataCapacity = desired;
- }
-
- return NO_ERROR;
-}
-
-void Parcel::initState()
-{
- mError = NO_ERROR;
- mData = 0;
- mDataSize = 0;
- mDataCapacity = 0;
- mDataPos = 0;
- ALOGV("initState Setting data size of %p to %d\n", this, mDataSize);
- ALOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
- mObjects = NULL;
- mObjectsSize = 0;
- mObjectsCapacity = 0;
- mNextObjectHint = 0;
- mHasFds = false;
- mFdsKnown = true;
- mAllowFds = true;
- mOwner = NULL;
-}
-
-void Parcel::scanForFds() const
-{
- bool hasFds = false;
- for (size_t i=0; i<mObjectsSize; i++) {
- const flat_binder_object* flat
- = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
- if (flat->type == BINDER_TYPE_FD) {
- hasFds = true;
- break;
- }
- }
- mHasFds = hasFds;
- mFdsKnown = true;
-}
-
-// --- Parcel::Blob ---
-
-Parcel::Blob::Blob() :
- mMapped(false), mData(NULL), mSize(0) {
-}
-
-Parcel::Blob::~Blob() {
- release();
-}
-
-void Parcel::Blob::release() {
- if (mMapped && mData) {
- ::munmap(mData, mSize);
- }
- clear();
-}
-
-void Parcel::Blob::init(bool mapped, void* data, size_t size) {
- mMapped = mapped;
- mData = data;
- mSize = size;
-}
-
-void Parcel::Blob::clear() {
- mMapped = false;
- mData = NULL;
- mSize = 0;
-}
-
-}; // namespace android
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
deleted file mode 100644
index a503be8..0000000
--- a/libs/binder/PermissionCache.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "PermissionCache"
-
-#include <stdint.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/PermissionCache.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE(PermissionCache) ;
-
-// ----------------------------------------------------------------------------
-
-PermissionCache::PermissionCache() {
-}
-
-status_t PermissionCache::check(bool* granted,
- const String16& permission, uid_t uid) const {
- Mutex::Autolock _l(mLock);
- Entry e;
- e.name = permission;
- e.uid = uid;
- ssize_t index = mCache.indexOf(e);
- if (index >= 0) {
- *granted = mCache.itemAt(index).granted;
- return NO_ERROR;
- }
- return NAME_NOT_FOUND;
-}
-
-void PermissionCache::cache(const String16& permission,
- uid_t uid, bool granted) {
- Mutex::Autolock _l(mLock);
- Entry e;
- ssize_t index = mPermissionNamesPool.indexOf(permission);
- if (index > 0) {
- e.name = mPermissionNamesPool.itemAt(index);
- } else {
- mPermissionNamesPool.add(permission);
- e.name = permission;
- }
- // note, we don't need to store the pid, which is not actually used in
- // permission checks
- e.uid = uid;
- e.granted = granted;
- index = mCache.indexOf(e);
- if (index < 0) {
- mCache.add(e);
- }
-}
-
-void PermissionCache::purge() {
- Mutex::Autolock _l(mLock);
- mCache.clear();
-}
-
-bool PermissionCache::checkCallingPermission(const String16& permission) {
- return PermissionCache::checkCallingPermission(permission, NULL, NULL);
-}
-
-bool PermissionCache::checkCallingPermission(
- const String16& permission, int32_t* outPid, int32_t* outUid) {
- IPCThreadState* ipcState = IPCThreadState::self();
- pid_t pid = ipcState->getCallingPid();
- uid_t uid = ipcState->getCallingUid();
- if (outPid) *outPid = pid;
- if (outUid) *outUid = uid;
- return PermissionCache::checkPermission(permission, pid, uid);
-}
-
-bool PermissionCache::checkPermission(
- const String16& permission, pid_t pid, uid_t uid) {
- if ((uid == 0) || (pid == getpid())) {
- // root and ourselves is always okay
- return true;
- }
-
- PermissionCache& pc(PermissionCache::getInstance());
- bool granted = false;
- if (pc.check(&granted, permission, uid) != NO_ERROR) {
- nsecs_t t = -systemTime();
- granted = android::checkPermission(permission, pid, uid);
- t += systemTime();
- ALOGD("checking %s for uid=%d => %s (%d us)",
- String8(permission).string(), uid,
- granted?"granted":"denied", (int)ns2us(t));
- pc.cache(permission, uid, granted);
- }
- return granted;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
deleted file mode 100644
index 9fa412c..0000000
--- a/libs/binder/ProcessState.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ProcessState"
-
-#include <cutils/process_name.h>
-
-#include <binder/ProcessState.h>
-
-#include <utils/Atomic.h>
-#include <binder/BpBinder.h>
-#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <binder/IServiceManager.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <private/binder/binder_module.h>
-#include <private/binder/Static.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
-
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// Global variables
-int mArgC;
-const char* const* mArgV;
-int mArgLen;
-
-class PoolThread : public Thread
-{
-public:
- PoolThread(bool isMain)
- : mIsMain(isMain)
- {
- }
-
-protected:
- virtual bool threadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- return false;
- }
-
- const bool mIsMain;
-};
-
-sp<ProcessState> ProcessState::self()
-{
- if (gProcess != NULL) return gProcess;
-
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
-}
-
-void ProcessState::setContextObject(const sp<IBinder>& object)
-{
- setContextObject(object, String16("default"));
-}
-
-sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
-{
- return getStrongProxyForHandle(0);
-}
-
-void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
-{
- AutoMutex _l(mLock);
- mContexts.add(name, object);
-}
-
-sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
-{
- mLock.lock();
- sp<IBinder> object(
- mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
- mLock.unlock();
-
- //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
-
- if (object != NULL) return object;
-
- // Don't attempt to retrieve contexts if we manage them
- if (mManagesContexts) {
- ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
- String8(name).string());
- return NULL;
- }
-
- IPCThreadState* ipc = IPCThreadState::self();
- {
- Parcel data, reply;
- // no interface token on this magic transaction
- data.writeString16(name);
- data.writeStrongBinder(caller);
- status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
- if (result == NO_ERROR) {
- object = reply.readStrongBinder();
- }
- }
-
- ipc->flushCommands();
-
- if (object != NULL) setContextObject(object, name);
- return object;
-}
-
-void ProcessState::startThreadPool()
-{
- AutoMutex _l(mLock);
- if (!mThreadPoolStarted) {
- mThreadPoolStarted = true;
- spawnPooledThread(true);
- }
-}
-
-bool ProcessState::isContextManager(void) const
-{
- return mManagesContexts;
-}
-
-bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
-{
- if (!mManagesContexts) {
- AutoMutex _l(mLock);
- mBinderContextCheckFunc = checkFunc;
- mBinderContextUserData = userData;
-
- int dummy = 0;
- status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
- if (result == 0) {
- mManagesContexts = true;
- } else if (result == -1) {
- mBinderContextCheckFunc = NULL;
- mBinderContextUserData = NULL;
- ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
- }
- }
- return mManagesContexts;
-}
-
-ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
-{
- const size_t N=mHandleToObject.size();
- if (N <= (size_t)handle) {
- handle_entry e;
- e.binder = NULL;
- e.refs = NULL;
- status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
- if (err < NO_ERROR) return NULL;
- }
- return &mHandleToObject.editItemAt(handle);
-}
-
-sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
-{
- sp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. See comment
- // in getWeakProxyForHandle() for more info about this.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- result = b;
- } else {
- // This little bit of nastyness is to allow us to add a primary
- // reference to the remote proxy when this team doesn't have one
- // but another team is sending the handle to us.
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
-{
- wp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. The
- // attemptIncWeak() is safe because we know the BpBinder destructor will always
- // call expungeHandle(), which acquires the same lock we are holding now.
- // We need to do this because there is a race condition between someone
- // releasing a reference on this BpBinder, and a new reference on its handle
- // arriving from the driver.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- result = b;
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- } else {
- result = b;
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
-{
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- // This handle may have already been replaced with a new BpBinder
- // (if someone failed the AttemptIncWeak() above); we don't want
- // to overwrite it.
- if (e && e->binder == binder) e->binder = NULL;
-}
-
-void ProcessState::setArgs(int argc, const char* const argv[])
-{
- mArgC = argc;
- mArgV = (const char **)argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
-}
-
-int ProcessState::getArgC() const
-{
- return mArgC;
-}
-
-const char* const* ProcessState::getArgV() const
-{
- return mArgV;
-}
-
-void ProcessState::setArgV0(const char* txt)
-{
- if (mArgV != NULL) {
- strncpy((char*)mArgV[0], txt, mArgLen);
- set_process_name(txt);
- }
-}
-
-void ProcessState::spawnPooledThread(bool isMain)
-{
- if (mThreadPoolStarted) {
- int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[16];
- snprintf(buf, sizeof(buf), "Binder_%X", s);
- ALOGV("Spawning new pooled thread, name=%s\n", buf);
- sp<Thread> t = new PoolThread(isMain);
- t->run(buf);
- }
-}
-
-static int open_driver()
-{
- int fd = open("/dev/binder", O_RDWR);
- if (fd >= 0) {
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- int vers;
- status_t result = ioctl(fd, BINDER_VERSION, &vers);
- if (result == -1) {
- ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
- close(fd);
- fd = -1;
- }
- if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
- ALOGE("Binder driver protocol does not match user space protocol!");
- close(fd);
- fd = -1;
- }
- size_t maxThreads = 15;
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
- if (result == -1) {
- ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
- }
- } else {
- ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
- }
- return fd;
-}
-
-ProcessState::ProcessState()
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
-{
- if (mDriverFD >= 0) {
- // XXX Ideally, there should be a specific define for whether we
- // have mmap (or whether we could possibly have the kernel module
- // availabla).
-#if !defined(HAVE_WIN32_IPC)
- // mmap the binder, providing a chunk of virtual address space to receive transactions.
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
- if (mVMStart == MAP_FAILED) {
- // *sigh*
- ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
- close(mDriverFD);
- mDriverFD = -1;
- }
-#else
- mDriverFD = -1;
-#endif
- }
-
- LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
-}
-
-ProcessState::~ProcessState()
-{
-}
-
-}; // namespace android
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
deleted file mode 100644
index 12b0308..0000000
--- a/libs/binder/Static.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// All static variables go here, to control initialization and
-// destruction order in the library.
-
-#include <private/binder/Static.h>
-
-#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-
-namespace android {
-
-// ------------ ProcessState.cpp
-
-Mutex gProcessMutex;
-sp<ProcessState> gProcess;
-
-class LibUtilsIPCtStatics
-{
-public:
- LibUtilsIPCtStatics()
- {
- }
-
- ~LibUtilsIPCtStatics()
- {
- IPCThreadState::shutdown();
- }
-};
-
-static LibUtilsIPCtStatics gIPCStatics;
-
-// ------------ ServiceManager.cpp
-
-Mutex gDefaultServiceManagerLock;
-sp<IServiceManager> gDefaultServiceManager;
-sp<IPermissionController> gPermissionController;
-
-} // namespace android
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
deleted file mode 100644
index 2f4ac62..0000000
--- a/libs/gui/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- BitTube.cpp \
- BufferQueue.cpp \
- DisplayEventReceiver.cpp \
- IDisplayEventConnection.cpp \
- ISensorEventConnection.cpp \
- ISensorServer.cpp \
- ISurfaceTexture.cpp \
- Sensor.cpp \
- SensorEventQueue.cpp \
- SensorManager.cpp \
- SurfaceTexture.cpp \
- SurfaceTextureClient.cpp \
- ISurfaceComposer.cpp \
- ISurface.cpp \
- ISurfaceComposerClient.cpp \
- IGraphicBufferAlloc.cpp \
- LayerState.cpp \
- Surface.cpp \
- SurfaceComposerClient.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libhardware \
- libhardware_legacy \
- libui \
- libEGL \
- libGLESv2 \
-
-
-LOCAL_MODULE:= libgui
-
-ifeq ($(TARGET_BOARD_PLATFORM), omap4)
- LOCAL_CFLAGS += -DUSE_FENCE_SYNC
-endif
-ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
- LOCAL_CFLAGS += -DUSE_FENCE_SYNC
-endif
-
-ifeq ($(TARGET_BOARD_PLATFORM), tegra)
- LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
deleted file mode 100644
index 55f4178..0000000
--- a/libs/gui/BitTube.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <utils/Errors.h>
-
-#include <binder/Parcel.h>
-
-#include <gui/BitTube.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-BitTube::BitTube()
- : mSendFd(-1), mReceiveFd(-1)
-{
- int fds[2];
- if (pipe(fds) == 0) {
- mReceiveFd = fds[0];
- mSendFd = fds[1];
- fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
- fcntl(mSendFd, F_SETFL, O_NONBLOCK);
- // ignore SIGPIPE, we handle write errors through EPIPE instead
- signal(SIGPIPE, SIG_IGN);
- } else {
- mReceiveFd = -errno;
- ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
- }
-}
-
-BitTube::BitTube(const Parcel& data)
- : mSendFd(-1), mReceiveFd(-1)
-{
- mReceiveFd = dup(data.readFileDescriptor());
- if (mReceiveFd >= 0) {
- fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
- } else {
- mReceiveFd = -errno;
- ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)",
- strerror(-mReceiveFd));
- }
-}
-
-BitTube::~BitTube()
-{
- if (mSendFd >= 0)
- close(mSendFd);
-
- if (mReceiveFd >= 0)
- close(mReceiveFd);
-}
-
-status_t BitTube::initCheck() const
-{
- if (mReceiveFd < 0) {
- return status_t(mReceiveFd);
- }
- return NO_ERROR;
-}
-
-int BitTube::getFd() const
-{
- return mReceiveFd;
-}
-
-ssize_t BitTube::write(void const* vaddr, size_t size)
-{
- ssize_t err, len;
- do {
- len = ::write(mSendFd, vaddr, size);
- err = len < 0 ? errno : 0;
- } while (err == EINTR);
- return err == 0 ? len : -err;
-
-}
-
-ssize_t BitTube::read(void* vaddr, size_t size)
-{
- ssize_t err, len;
- do {
- len = ::read(mReceiveFd, vaddr, size);
- err = len < 0 ? errno : 0;
- } while (err == EINTR);
- if (err == EAGAIN || err == EWOULDBLOCK) {
- // EAGAIN means that we have non-blocking I/O but there was
- // no data to be read. Nothing the client should care about.
- return 0;
- }
- return err == 0 ? len : -err;
-}
-
-status_t BitTube::writeToParcel(Parcel* reply) const
-{
- if (mReceiveFd < 0)
- return -EINVAL;
-
- status_t result = reply->writeDupFileDescriptor(mReceiveFd);
- close(mReceiveFd);
- mReceiveFd = -1;
- return result;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
deleted file mode 100644
index cb8abdd..0000000
--- a/libs/gui/BufferQueue.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BufferQueue"
-//#define LOG_NDEBUG 0
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <gui/BufferQueue.h>
-#include <gui/ISurfaceComposer.h>
-#include <private/gui/ComposerService.h>
-
-#include <utils/Log.h>
-#include <gui/SurfaceTexture.h>
-#include <utils/Trace.h>
-
-// This compile option causes SurfaceTexture to return the buffer that is currently
-// attached to the GL texture from dequeueBuffer when no other buffers are
-// available. It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do
-// implicit cross-process synchronization to prevent the buffer from being
-// written to before the buffer has (a) been detached from the GL texture and
-// (b) all GL reads from the buffer have completed.
-
-// During refactoring, do not support dequeuing the current buffer
-#undef ALLOW_DEQUEUE_CURRENT_BUFFER
-
-#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
-#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true
-#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
-#else
-#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false
-#endif
-
-// Macros for including the BufferQueue name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
-
-#define ATRACE_BUFFER_INDEX(index) \
- char ___traceBuf[1024]; \
- snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), (index)); \
- android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);
-
-namespace android {
-
-// Get an ID that's unique within this process.
-static int32_t createProcessUniqueId() {
- static volatile int32_t globalCounter = 0;
- return android_atomic_inc(&globalCounter);
-}
-
-BufferQueue::BufferQueue( bool allowSynchronousMode ) :
- mDefaultWidth(1),
- mDefaultHeight(1),
- mPixelFormat(PIXEL_FORMAT_RGBA_8888),
- mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
- mClientBufferCount(0),
- mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
- mNextTransform(0),
- mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
- mSynchronousMode(false),
- mAllowSynchronousMode(allowSynchronousMode),
- mConnectedApi(NO_CONNECTED_API),
- mAbandoned(false),
- mFrameCounter(0),
- mBufferHasBeenQueued(false)
-{
- // Choose a name using the PID and a process-unique ID.
- mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
-
- ST_LOGV("BufferQueue");
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
- mNextCrop.makeInvalid();
-}
-
-BufferQueue::~BufferQueue() {
- ST_LOGV("~BufferQueue");
-}
-
-status_t BufferQueue::setBufferCountServerLocked(int bufferCount) {
- if (bufferCount > NUM_BUFFER_SLOTS)
- return BAD_VALUE;
-
- // special-case, nothing to do
- if (bufferCount == mBufferCount)
- return OK;
-
- if (!mClientBufferCount &&
- bufferCount >= mBufferCount) {
- // easy, we just have more buffers
- mBufferCount = bufferCount;
- mServerBufferCount = bufferCount;
- mDequeueCondition.broadcast();
- } else {
- // we're here because we're either
- // - reducing the number of available buffers
- // - or there is a client-buffer-count in effect
-
- // less than 2 buffers is never allowed
- if (bufferCount < 2)
- return BAD_VALUE;
-
- // when there is non client-buffer-count in effect, the client is not
- // allowed to dequeue more than one buffer at a time,
- // so the next time they dequeue a buffer, we know that they don't
- // own one. the actual resizing will happen during the next
- // dequeueBuffer.
-
- mServerBufferCount = bufferCount;
- }
- return OK;
-}
-
-bool BufferQueue::isSynchronousMode() const {
- Mutex::Autolock lock(mMutex);
- return mSynchronousMode;
-}
-
-void BufferQueue::setConsumerName(const String8& name) {
- Mutex::Autolock lock(mMutex);
- mConsumerName = name;
-}
-
-void BufferQueue::setFrameAvailableListener(
- const sp<FrameAvailableListener>& listener) {
- ST_LOGV("setFrameAvailableListener");
- Mutex::Autolock lock(mMutex);
- mFrameAvailableListener = listener;
-}
-
-status_t BufferQueue::setBufferCount(int bufferCount) {
- ST_LOGV("setBufferCount: count=%d", bufferCount);
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- if (bufferCount > NUM_BUFFER_SLOTS) {
- ST_LOGE("setBufferCount: bufferCount larger than slots available");
- return BAD_VALUE;
- }
-
- // Error out if the user has dequeued buffers
- for (int i=0 ; i<mBufferCount ; i++) {
- if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
- ST_LOGE("setBufferCount: client owns some buffers");
- return -EINVAL;
- }
- }
-
- const int minBufferSlots = mSynchronousMode ?
- MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
- if (bufferCount == 0) {
- mClientBufferCount = 0;
- bufferCount = (mServerBufferCount >= minBufferSlots) ?
- mServerBufferCount : minBufferSlots;
- return setBufferCountServerLocked(bufferCount);
- }
-
- if (bufferCount < minBufferSlots) {
- ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
- "minimum (%d)", bufferCount, minBufferSlots);
- return BAD_VALUE;
- }
-
- // here we're guaranteed that the client doesn't have dequeued buffers
- // and will release all of its buffer references.
- freeAllBuffersLocked();
- mBufferCount = bufferCount;
- mClientBufferCount = bufferCount;
- mBufferHasBeenQueued = false;
- mQueue.clear();
- mDequeueCondition.broadcast();
- return OK;
-}
-
-int BufferQueue::query(int what, int* outValue)
-{
- ATRACE_CALL();
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGE("query: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
-
- int value;
- switch (what) {
- case NATIVE_WINDOW_WIDTH:
- value = mDefaultWidth;
- break;
- case NATIVE_WINDOW_HEIGHT:
- value = mDefaultHeight;
- break;
- case NATIVE_WINDOW_FORMAT:
- value = mPixelFormat;
- break;
- case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
- value = mSynchronousMode ?
- (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
- break;
- default:
- return BAD_VALUE;
- }
- outValue[0] = value;
- return NO_ERROR;
-}
-
-status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
- ATRACE_CALL();
- ST_LOGV("requestBuffer: slot=%d", slot);
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- if (slot < 0 || mBufferCount <= slot) {
- ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, slot);
- return BAD_VALUE;
- }
- mSlots[slot].mRequestBufferCalled = true;
- *buf = mSlots[slot].mGraphicBuffer;
- return NO_ERROR;
-}
-
-status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
- uint32_t format, uint32_t usage) {
- ATRACE_CALL();
- ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
-
- if ((w && !h) || (!w && h)) {
- ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
- return BAD_VALUE;
- }
-
- status_t returnFlags(OK);
- EGLDisplay dpy = EGL_NO_DISPLAY;
- EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-
- { // Scope for the lock
- Mutex::Autolock lock(mMutex);
-
- int found = -1;
- int foundSync = -1;
- int dequeuedCount = 0;
- bool tryAgain = true;
- while (tryAgain) {
- if (mAbandoned) {
- ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
-
- // We need to wait for the FIFO to drain if the number of buffer
- // needs to change.
- //
- // The condition "number of buffers needs to change" is true if
- // - the client doesn't care about how many buffers there are
- // - AND the actual number of buffer is different from what was
- // set in the last setBufferCountServer()
- // - OR -
- // setBufferCountServer() was set to a value incompatible with
- // the synchronization mode (for instance because the sync mode
- // changed since)
- //
- // As long as this condition is true AND the FIFO is not empty, we
- // wait on mDequeueCondition.
-
- const int minBufferCountNeeded = mSynchronousMode ?
- MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
-
- const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
- ((mServerBufferCount != mBufferCount) ||
- (mServerBufferCount < minBufferCountNeeded));
-
- if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
- // wait for the FIFO to drain
- mDequeueCondition.wait(mMutex);
- // NOTE: we continue here because we need to reevaluate our
- // whole state (eg: we could be abandoned or disconnected)
- continue;
- }
-
- if (numberOfBuffersNeedsToChange) {
- // here we're guaranteed that mQueue is empty
- freeAllBuffersLocked();
- // XXX: signal?
- mBufferCount = mServerBufferCount;
- if (mBufferCount < minBufferCountNeeded)
- mBufferCount = minBufferCountNeeded;
- mBufferHasBeenQueued = false;
- returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
- }
-
- // look for a free buffer to give to the client
- found = INVALID_BUFFER_SLOT;
- foundSync = INVALID_BUFFER_SLOT;
- dequeuedCount = 0;
- for (int i = 0; i < mBufferCount; i++) {
- const int state = mSlots[i].mBufferState;
- if (state == BufferSlot::DEQUEUED) {
- dequeuedCount++;
- }
-
- // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
- // but dequeuing the current buffer is disabled.
- if (false) {
- // This functionality has been temporarily removed so
- // BufferQueue and SurfaceTexture can be refactored into
- // separate objects
- } else {
- if (state == BufferSlot::FREE) {
- /* We return the oldest of the free buffers to avoid
- * stalling the producer if possible. This is because
- * the consumer may still have pending reads of the
- * buffers in flight.
- */
- bool isOlder = mSlots[i].mFrameNumber <
- mSlots[found].mFrameNumber;
- if (found < 0 || isOlder) {
- foundSync = i;
- found = i;
- }
- }
- }
- }
-
- // clients are not allowed to dequeue more than one buffer
- // if they didn't set a buffer count.
- if (!mClientBufferCount && dequeuedCount) {
- ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
- "setting the buffer count");
- return -EINVAL;
- }
-
- // See whether a buffer has been queued since the last
- // setBufferCount so we know whether to perform the
- // MIN_UNDEQUEUED_BUFFERS check below.
- if (mBufferHasBeenQueued) {
- // make sure the client is not trying to dequeue more buffers
- // than allowed.
- const int avail = mBufferCount - (dequeuedCount+1);
- if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
- ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
- "(dequeued=%d)",
- MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
- dequeuedCount);
- return -EBUSY;
- }
- }
-
- // if no buffer is found, wait for a buffer to be released
- tryAgain = found == INVALID_BUFFER_SLOT;
- if (tryAgain) {
- mDequeueCondition.wait(mMutex);
- }
- }
-
-
- if (found == INVALID_BUFFER_SLOT) {
- // This should not happen.
- ST_LOGE("dequeueBuffer: no available buffer slots");
- return -EBUSY;
- }
-
- const int buf = found;
- *outBuf = found;
-
- ATRACE_BUFFER_INDEX(buf);
-
- const bool useDefaultSize = !w && !h;
- if (useDefaultSize) {
- // use the default size
- w = mDefaultWidth;
- h = mDefaultHeight;
- }
-
- const bool updateFormat = (format != 0);
- if (!updateFormat) {
- // keep the current (or default) format
- format = mPixelFormat;
- }
-
- // buffer is now in DEQUEUED (but can also be current at the same time,
- // if we're in synchronous mode)
- mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
-
- const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
- if ((buffer == NULL) ||
- (uint32_t(buffer->width) != w) ||
- (uint32_t(buffer->height) != h) ||
- (uint32_t(buffer->format) != format) ||
- ((uint32_t(buffer->usage) & usage) != usage))
- {
- usage |= GraphicBuffer::USAGE_HW_TEXTURE;
- status_t error;
- sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(
- w, h, format, usage, &error));
- if (graphicBuffer == 0) {
- ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
- "failed");
- return error;
- }
- if (updateFormat) {
- mPixelFormat = format;
- }
-
- mSlots[buf].mAcquireCalled = false;
- mSlots[buf].mGraphicBuffer = graphicBuffer;
- mSlots[buf].mRequestBufferCalled = false;
- mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
-
-
-
-
- returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
- }
-
- dpy = mSlots[buf].mEglDisplay;
- fence = mSlots[buf].mFence;
- mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- } // end lock scope
-
- if (fence != EGL_NO_SYNC_KHR) {
- EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
- // If something goes wrong, log the error, but return the buffer without
- // synchronizing access to it. It's too late at this point to abort the
- // dequeue operation.
- if (result == EGL_FALSE) {
- ALOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
- } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
- ALOGE("dequeueBuffer: timeout waiting for fence");
- }
- eglDestroySyncKHR(dpy, fence);
-
- }
-
- ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
- mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
-
- return returnFlags;
-}
-
-status_t BufferQueue::setSynchronousMode(bool enabled) {
- ATRACE_CALL();
- ST_LOGV("setSynchronousMode: enabled=%d", enabled);
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
-
- status_t err = OK;
- if (!mAllowSynchronousMode && enabled)
- return err;
-
- if (!enabled) {
- // going to asynchronous mode, drain the queue
- err = drainQueueLocked();
- if (err != NO_ERROR)
- return err;
- }
-
- if (mSynchronousMode != enabled) {
- // - if we're going to asynchronous mode, the queue is guaranteed to be
- // empty here
- // - if the client set the number of buffers, we're guaranteed that
- // we have at least 3 (because we don't allow less)
- mSynchronousMode = enabled;
- mDequeueCondition.broadcast();
- }
- return err;
-}
-
-status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
- uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
- ATRACE_CALL();
- ATRACE_BUFFER_INDEX(buf);
-
- ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp);
-
- sp<FrameAvailableListener> listener;
-
- { // scope for the lock
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
- if (buf < 0 || buf >= mBufferCount) {
- ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return -EINVAL;
- } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
- ST_LOGE("queueBuffer: slot %d is not owned by the client "
- "(state=%d)", buf, mSlots[buf].mBufferState);
- return -EINVAL;
- } else if (!mSlots[buf].mRequestBufferCalled) {
- ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
- "buffer", buf);
- return -EINVAL;
- }
-
- if (mSynchronousMode) {
- // In synchronous mode we queue all buffers in a FIFO.
- mQueue.push_back(buf);
-
- // Synchronous mode always signals that an additional frame should
- // be consumed.
- listener = mFrameAvailableListener;
- } else {
- // In asynchronous mode we only keep the most recent buffer.
- if (mQueue.empty()) {
- mQueue.push_back(buf);
-
- // Asynchronous mode only signals that a frame should be
- // consumed if no previous frame was pending. If a frame were
- // pending then the consumer would have already been notified.
- listener = mFrameAvailableListener;
- } else {
- Fifo::iterator front(mQueue.begin());
- // buffer currently queued is freed
- mSlots[*front].mBufferState = BufferSlot::FREE;
- // and we record the new buffer index in the queued list
- *front = buf;
- }
- }
-
- mSlots[buf].mBufferState = BufferSlot::QUEUED;
- mSlots[buf].mCrop = mNextCrop;
- mSlots[buf].mTransform = mNextTransform;
- mSlots[buf].mScalingMode = mNextScalingMode;
- mSlots[buf].mTimestamp = timestamp;
- mFrameCounter++;
- mSlots[buf].mFrameNumber = mFrameCounter;
-
- mBufferHasBeenQueued = true;
- mDequeueCondition.broadcast();
-
- *outWidth = mDefaultWidth;
- *outHeight = mDefaultHeight;
- *outTransform = 0;
-
- ATRACE_INT(mConsumerName.string(), mQueue.size());
- } // scope for the lock
-
- // call back without lock held
- if (listener != 0) {
- listener->onFrameAvailable();
- }
- return OK;
-}
-
-void BufferQueue::cancelBuffer(int buf) {
- ATRACE_CALL();
- ST_LOGV("cancelBuffer: slot=%d", buf);
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
- return;
- }
-
- if (buf < 0 || buf >= mBufferCount) {
- ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return;
- } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
- ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
- buf, mSlots[buf].mBufferState);
- return;
- }
- mSlots[buf].mBufferState = BufferSlot::FREE;
- mSlots[buf].mFrameNumber = 0;
- mDequeueCondition.broadcast();
-}
-
-status_t BufferQueue::setCrop(const Rect& crop) {
- ATRACE_CALL();
- ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right,
- crop.bottom);
-
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("setCrop: BufferQueue has been abandoned!");
- return NO_INIT;
- }
- mNextCrop = crop;
- return OK;
-}
-
-status_t BufferQueue::setTransform(uint32_t transform) {
- ATRACE_CALL();
- ST_LOGV("setTransform: xform=%#x", transform);
- Mutex::Autolock lock(mMutex);
- if (mAbandoned) {
- ST_LOGE("setTransform: BufferQueue has been abandoned!");
- return NO_INIT;
- }
- mNextTransform = transform;
- return OK;
-}
-
-status_t BufferQueue::setScalingMode(int mode) {
- ATRACE_CALL();
- ST_LOGV("setScalingMode: mode=%d", mode);
-
- switch (mode) {
- case NATIVE_WINDOW_SCALING_MODE_FREEZE:
- case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
- break;
- default:
- ST_LOGE("unknown scaling mode: %d", mode);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mMutex);
- mNextScalingMode = mode;
- return OK;
-}
-
-status_t BufferQueue::connect(int api,
- uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
- ATRACE_CALL();
- ST_LOGV("connect: api=%d", api);
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGE("connect: BufferQueue has been abandoned!");
- return NO_INIT;
- }
-
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- case NATIVE_WINDOW_API_CPU:
- case NATIVE_WINDOW_API_MEDIA:
- case NATIVE_WINDOW_API_CAMERA:
- if (mConnectedApi != NO_CONNECTED_API) {
- ST_LOGE("connect: already connected (cur=%d, req=%d)",
- mConnectedApi, api);
- err = -EINVAL;
- } else {
- mConnectedApi = api;
- *outWidth = mDefaultWidth;
- *outHeight = mDefaultHeight;
- *outTransform = 0;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- mBufferHasBeenQueued = false;
-
- return err;
-}
-
-status_t BufferQueue::disconnect(int api) {
- ATRACE_CALL();
- ST_LOGV("disconnect: api=%d", api);
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- // it is not really an error to disconnect after the surface
- // has been abandoned, it should just be a no-op.
- return NO_ERROR;
- }
-
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- case NATIVE_WINDOW_API_CPU:
- case NATIVE_WINDOW_API_MEDIA:
- case NATIVE_WINDOW_API_CAMERA:
- if (mConnectedApi == api) {
- drainQueueAndFreeBuffersLocked();
- mConnectedApi = NO_CONNECTED_API;
- mNextCrop.makeInvalid();
- mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
- mNextTransform = 0;
- mDequeueCondition.broadcast();
- } else {
- ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
- mConnectedApi, api);
- err = -EINVAL;
- }
- break;
- default:
- ST_LOGE("disconnect: unknown API %d", api);
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-void BufferQueue::dump(String8& result) const
-{
- char buffer[1024];
- BufferQueue::dump(result, "", buffer, 1024);
-}
-
-void BufferQueue::dump(String8& result, const char* prefix,
- char* buffer, size_t SIZE) const
-{
- Mutex::Autolock _l(mMutex);
- snprintf(buffer, SIZE,
- "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x}\n"
- ,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
- mNextCrop.bottom, mNextTransform
- );
- result.append(buffer);
-
- String8 fifo;
- int fifoSize = 0;
- Fifo::const_iterator i(mQueue.begin());
- while (i != mQueue.end()) {
- snprintf(buffer, SIZE, "%02d ", *i++);
- fifoSize++;
- fifo.append(buffer);
- }
-
- snprintf(buffer, SIZE,
- "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
- "mPixelFormat=%d, FIFO(%d)={%s}\n",
- prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
- mDefaultHeight, mPixelFormat, fifoSize, fifo.string());
- result.append(buffer);
-
-
- struct {
- const char * operator()(int state) const {
- switch (state) {
- case BufferSlot::DEQUEUED: return "DEQUEUED";
- case BufferSlot::QUEUED: return "QUEUED";
- case BufferSlot::FREE: return "FREE";
- case BufferSlot::ACQUIRED: return "ACQUIRED";
- default: return "Unknown";
- }
- }
- } stateName;
-
- for (int i=0 ; i<mBufferCount ; i++) {
- const BufferSlot& slot(mSlots[i]);
- snprintf(buffer, SIZE,
- "%s%s[%02d] "
- "state=%-8s, crop=[%d,%d,%d,%d], "
- "transform=0x%02x, timestamp=%lld",
- prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
- stateName(slot.mBufferState),
- slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
- slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
- );
- result.append(buffer);
-
- const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
- if (buf != NULL) {
- snprintf(buffer, SIZE,
- ", %p [%4ux%4u:%4u,%3X]",
- buf->handle, buf->width, buf->height, buf->stride,
- buf->format);
- result.append(buffer);
- }
- result.append("\n");
- }
-}
-
-void BufferQueue::freeBufferLocked(int i) {
- mSlots[i].mGraphicBuffer = 0;
- mSlots[i].mBufferState = BufferSlot::FREE;
- mSlots[i].mFrameNumber = 0;
- mSlots[i].mAcquireCalled = false;
-
- // destroy fence as BufferQueue now takes ownership
- if (mSlots[i].mFence != EGL_NO_SYNC_KHR) {
- eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence);
- mSlots[i].mFence = EGL_NO_SYNC_KHR;
- }
-}
-
-void BufferQueue::freeAllBuffersLocked() {
- ALOGW_IF(!mQueue.isEmpty(),
- "freeAllBuffersLocked called but mQueue is not empty");
- mQueue.clear();
- mBufferHasBeenQueued = false;
- for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- freeBufferLocked(i);
- }
-}
-
-status_t BufferQueue::acquire(BufferItem *buffer) {
- ATRACE_CALL();
- Mutex::Autolock _l(mMutex);
- // check if queue is empty
- // In asynchronous mode the list is guaranteed to be one buffer
- // deep, while in synchronous mode we use the oldest buffer.
- if (!mQueue.empty()) {
- Fifo::iterator front(mQueue.begin());
- int buf = *front;
-
- ATRACE_BUFFER_INDEX(buf);
-
- if (mSlots[buf].mAcquireCalled) {
- buffer->mGraphicBuffer = NULL;
- }
- else {
- buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
- }
- buffer->mCrop = mSlots[buf].mCrop;
- buffer->mTransform = mSlots[buf].mTransform;
- buffer->mScalingMode = mSlots[buf].mScalingMode;
- buffer->mFrameNumber = mSlots[buf].mFrameNumber;
- buffer->mTimestamp = mSlots[buf].mTimestamp;
- buffer->mBuf = buf;
- mSlots[buf].mAcquireCalled = true;
-
- mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
- mQueue.erase(front);
- mDequeueCondition.broadcast();
-
- ATRACE_INT(mConsumerName.string(), mQueue.size());
- }
- else {
- return -EINVAL; //should be a better return code
- }
-
- return OK;
-}
-
-status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
- EGLSyncKHR fence) {
- ATRACE_CALL();
- ATRACE_BUFFER_INDEX(buf);
-
- Mutex::Autolock _l(mMutex);
-
- if (buf == INVALID_BUFFER_SLOT) {
- return -EINVAL;
- }
-
- mSlots[buf].mEglDisplay = display;
- mSlots[buf].mFence = fence;
-
- // The current buffer becomes FREE if it was still in the queued
- // state. If it has already been given to the client
- // (synchronous mode), then it stays in DEQUEUED state.
- if (mSlots[buf].mBufferState == BufferSlot::QUEUED
- || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
- mSlots[buf].mBufferState = BufferSlot::FREE;
- }
-
- mDequeueCondition.broadcast();
-
- return OK;
-}
-
-status_t BufferQueue::consumerDisconnect() {
- Mutex::Autolock lock(mMutex);
- // Once the SurfaceTexture disconnects, the BufferQueue
- // is considered abandoned
- mAbandoned = true;
- freeAllBuffersLocked();
- mDequeueCondition.broadcast();
- return OK;
-}
-
-status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
-{
- ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
- if (!w || !h) {
- ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
- w, h);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mMutex);
- mDefaultWidth = w;
- mDefaultHeight = h;
- return OK;
-}
-
-status_t BufferQueue::setBufferCountServer(int bufferCount) {
- ATRACE_CALL();
- Mutex::Autolock lock(mMutex);
- return setBufferCountServerLocked(bufferCount);
-}
-
-void BufferQueue::freeAllBuffersExceptHeadLocked() {
- ALOGW_IF(!mQueue.isEmpty(),
- "freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
- int head = -1;
- if (!mQueue.empty()) {
- Fifo::iterator front(mQueue.begin());
- head = *front;
- }
- mBufferHasBeenQueued = false;
- for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- if (i != head) {
- freeBufferLocked(i);
- }
- }
-}
-
-status_t BufferQueue::drainQueueLocked() {
- while (mSynchronousMode && !mQueue.isEmpty()) {
- mDequeueCondition.wait(mMutex);
- if (mAbandoned) {
- ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
- return NO_INIT;
- }
- if (mConnectedApi == NO_CONNECTED_API) {
- ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
- return NO_INIT;
- }
- }
- return NO_ERROR;
-}
-
-status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
- status_t err = drainQueueLocked();
- if (err == NO_ERROR) {
- if (mSynchronousMode) {
- freeAllBuffersLocked();
- } else {
- freeAllBuffersExceptHeadLocked();
- }
- }
- return err;
-}
-
-}; // namespace android
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
deleted file mode 100644
index a6790ad..0000000
--- a/libs/gui/DisplayEventReceiver.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#include <utils/Errors.h>
-
-#include <gui/BitTube.h>
-#include <gui/DisplayEventReceiver.h>
-#include <gui/IDisplayEventConnection.h>
-#include <gui/ISurfaceComposer.h>
-
-#include <private/gui/ComposerService.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-DisplayEventReceiver::DisplayEventReceiver() {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- if (sf != NULL) {
- mEventConnection = sf->createDisplayEventConnection();
- if (mEventConnection != NULL) {
- mDataChannel = mEventConnection->getDataChannel();
- }
- }
-}
-
-DisplayEventReceiver::~DisplayEventReceiver() {
-}
-
-status_t DisplayEventReceiver::initCheck() const {
- if (mDataChannel != NULL)
- return NO_ERROR;
- return NO_INIT;
-}
-
-int DisplayEventReceiver::getFd() const {
- if (mDataChannel == NULL)
- return NO_INIT;
-
- return mDataChannel->getFd();
-}
-
-status_t DisplayEventReceiver::setVsyncRate(uint32_t count) {
- if (int32_t(count) < 0)
- return BAD_VALUE;
-
- if (mEventConnection != NULL) {
- mEventConnection->setVsyncRate(count);
- return NO_ERROR;
- }
- return NO_INIT;
-}
-
-status_t DisplayEventReceiver::requestNextVsync() {
- if (mEventConnection != NULL) {
- mEventConnection->requestNextVsync();
- return NO_ERROR;
- }
- return NO_INIT;
-}
-
-
-ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
- size_t count) {
- return DisplayEventReceiver::getEvents(mDataChannel, events, count);
-}
-
-ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel,
- Event* events, size_t count)
-{
- ssize_t size = dataChannel->read(events, sizeof(events[0])*count);
- ALOGE_IF(size<0,
- "DisplayEventReceiver::getEvents error (%s)",
- strerror(-size));
- if (size >= 0) {
- // Note: if (size % sizeof(events[0])) != 0, we've got a
- // partial read. This can happen if the queue filed up (ie: if we
- // didn't pull from it fast enough).
- // We discard the partial event and rely on the sender to
- // re-send the event if appropriate (some events, like VSYNC
- // can be lost forever).
-
- // returns number of events read
- size /= sizeof(events[0]);
- }
- return size;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
deleted file mode 100644
index 887d176..0000000
--- a/libs/gui/IDisplayEventConnection.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-#include <binder/Parcel.h>
-#include <binder/IInterface.h>
-
-#include <gui/IDisplayEventConnection.h>
-#include <gui/BitTube.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-enum {
- GET_DATA_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
- SET_VSYNC_RATE,
- REQUEST_NEXT_VSYNC
-};
-
-class BpDisplayEventConnection : public BpInterface<IDisplayEventConnection>
-{
-public:
- BpDisplayEventConnection(const sp<IBinder>& impl)
- : BpInterface<IDisplayEventConnection>(impl)
- {
- }
-
- virtual sp<BitTube> getDataChannel() const
- {
- Parcel data, reply;
- data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
- remote()->transact(GET_DATA_CHANNEL, data, &reply);
- return new BitTube(reply);
- }
-
- virtual void setVsyncRate(uint32_t count) {
- Parcel data, reply;
- data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
- data.writeInt32(count);
- remote()->transact(SET_VSYNC_RATE, data, &reply);
- }
-
- virtual void requestNextVsync() {
- Parcel data, reply;
- data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
- remote()->transact(REQUEST_NEXT_VSYNC, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection");
-
-// ----------------------------------------------------------------------------
-
-status_t BnDisplayEventConnection::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_DATA_CHANNEL: {
- CHECK_INTERFACE(IDisplayEventConnection, data, reply);
- sp<BitTube> channel(getDataChannel());
- channel->writeToParcel(reply);
- return NO_ERROR;
- } break;
- case SET_VSYNC_RATE: {
- CHECK_INTERFACE(IDisplayEventConnection, data, reply);
- setVsyncRate(data.readInt32());
- return NO_ERROR;
- } break;
- case REQUEST_NEXT_VSYNC: {
- CHECK_INTERFACE(IDisplayEventConnection, data, reply);
- requestNextVsync();
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
deleted file mode 100644
index a70a5e8..0000000
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include <gui/IGraphicBufferAlloc.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
- CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
-{
-public:
- BpGraphicBufferAlloc(const sp<IBinder>& impl)
- : BpInterface<IGraphicBufferAlloc>(impl)
- {
- }
-
- virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage, status_t* error) {
- Parcel data, reply;
- data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
- remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
- sp<GraphicBuffer> graphicBuffer;
- status_t result = reply.readInt32();
- if (result == NO_ERROR) {
- graphicBuffer = new GraphicBuffer();
- reply.read(*graphicBuffer);
- // reply.readStrongBinder();
- // here we don't even have to read the BufferReference from
- // the parcel, it'll die with the parcel.
- }
- *error = result;
- return graphicBuffer;
- }
-};
-
-IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
-
-// ----------------------------------------------------------------------
-
-status_t BnGraphicBufferAlloc::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- // codes that don't require permission check
-
- /* BufferReference just keeps a strong reference to a
- * GraphicBuffer until it is destroyed (that is, until
- * no local or remote process have a reference to it).
- */
- class BufferReference : public BBinder {
- sp<GraphicBuffer> buffer;
- public:
- BufferReference(const sp<GraphicBuffer>& buffer) : buffer(buffer) { }
- };
-
-
- switch(code) {
- case CREATE_GRAPHIC_BUFFER: {
- CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t usage = data.readInt32();
- status_t error;
- sp<GraphicBuffer> result =
- createGraphicBuffer(w, h, format, usage, &error);
- reply->writeInt32(error);
- if (result != 0) {
- reply->write(*result);
- // We add a BufferReference to this parcel to make sure the
- // buffer stays alive until the GraphicBuffer object on
- // the other side has been created.
- // This is needed so that the buffer handle can be
- // registered before the buffer is destroyed on implementations
- // that do not use file-descriptors to track their buffers.
- reply->writeStrongBinder( new BufferReference(result) );
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
deleted file mode 100644
index 0e51e8e..0000000
--- a/libs/gui/ISensorEventConnection.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-#include <binder/Parcel.h>
-#include <binder/IInterface.h>
-
-#include <gui/ISensorEventConnection.h>
-#include <gui/BitTube.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-enum {
- GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
- ENABLE_DISABLE,
- SET_EVENT_RATE
-};
-
-class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
-{
-public:
- BpSensorEventConnection(const sp<IBinder>& impl)
- : BpInterface<ISensorEventConnection>(impl)
- {
- }
-
- virtual sp<BitTube> getSensorChannel() const
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
- remote()->transact(GET_SENSOR_CHANNEL, data, &reply);
- return new BitTube(reply);
- }
-
- virtual status_t enableDisable(int handle, bool enabled)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
- data.writeInt32(handle);
- data.writeInt32(enabled);
- remote()->transact(ENABLE_DISABLE, data, &reply);
- return reply.readInt32();
- }
-
- virtual status_t setEventRate(int handle, nsecs_t ns)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
- data.writeInt32(handle);
- data.writeInt64(ns);
- remote()->transact(SET_EVENT_RATE, data, &reply);
- return reply.readInt32();
- }
-};
-
-IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
-
-// ----------------------------------------------------------------------------
-
-status_t BnSensorEventConnection::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_SENSOR_CHANNEL: {
- CHECK_INTERFACE(ISensorEventConnection, data, reply);
- sp<BitTube> channel(getSensorChannel());
- channel->writeToParcel(reply);
- return NO_ERROR;
- } break;
- case ENABLE_DISABLE: {
- CHECK_INTERFACE(ISensorEventConnection, data, reply);
- int handle = data.readInt32();
- int enabled = data.readInt32();
- status_t result = enableDisable(handle, enabled);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case SET_EVENT_RATE: {
- CHECK_INTERFACE(ISensorEventConnection, data, reply);
- int handle = data.readInt32();
- int ns = data.readInt64();
- status_t result = setEventRate(handle, ns);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
deleted file mode 100644
index 7111092..0000000
--- a/libs/gui/ISensorServer.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-
-#include <binder/Parcel.h>
-#include <binder/IInterface.h>
-
-#include <gui/Sensor.h>
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-enum {
- GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_SENSOR_EVENT_CONNECTION,
-};
-
-class BpSensorServer : public BpInterface<ISensorServer>
-{
-public:
- BpSensorServer(const sp<IBinder>& impl)
- : BpInterface<ISensorServer>(impl)
- {
- }
-
- virtual Vector<Sensor> getSensorList()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
- remote()->transact(GET_SENSOR_LIST, data, &reply);
- Sensor s;
- Vector<Sensor> v;
- int32_t n = reply.readInt32();
- v.setCapacity(n);
- while (n--) {
- reply.read(static_cast<Flattenable&>(s));
- v.add(s);
- }
- return v;
- }
-
- virtual sp<ISensorEventConnection> createSensorEventConnection()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
- remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
- return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
- }
-};
-
-IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
-
-// ----------------------------------------------------------------------
-
-status_t BnSensorServer::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_SENSOR_LIST: {
- CHECK_INTERFACE(ISensorServer, data, reply);
- Vector<Sensor> v(getSensorList());
- size_t n = v.size();
- reply->writeInt32(n);
- for (size_t i=0 ; i<n ; i++) {
- reply->write(static_cast<const Flattenable&>(v[i]));
- }
- return NO_ERROR;
- } break;
- case CREATE_SENSOR_EVENT_CONNECTION: {
- CHECK_INTERFACE(ISensorServer, data, reply);
- sp<ISensorEventConnection> connection(createSensorEventConnection());
- reply->writeStrongBinder(connection->asBinder());
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp
deleted file mode 100644
index c2ea183..0000000
--- a/libs/gui/ISurface.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ISurface"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-
-#include <gui/ISurface.h>
-#include <gui/ISurfaceTexture.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpSurface : public BpInterface<ISurface>
-{
-public:
- BpSurface(const sp<IBinder>& impl)
- : BpInterface<ISurface>(impl)
- {
- }
-
- virtual sp<ISurfaceTexture> getSurfaceTexture() const {
- Parcel data, reply;
- data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
- remote()->transact(GET_SURFACE_TEXTURE, data, &reply);
- return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
- }
-};
-
-IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurface::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case GET_SURFACE_TEXTURE: {
- CHECK_INTERFACE(ISurface, data, reply);
- reply->writeStrongBinder( getSurfaceTexture()->asBinder() );
- return NO_ERROR;
- }
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-}; // namespace android
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
deleted file mode 100644
index 1f1794c..0000000
--- a/libs/gui/ISurfaceComposer.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/BitTube.h>
-#include <gui/IDisplayEventConnection.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/ISurfaceTexture.h>
-
-#include <private/gui/LayerState.h>
-
-#include <ui/DisplayInfo.h>
-
-#include <utils/Log.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class IDisplayEventConnection;
-
-class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
-{
-public:
- BpSurfaceComposer(const sp<IBinder>& impl)
- : BpInterface<ISurfaceComposer>(impl)
- {
- }
-
- virtual sp<ISurfaceComposerClient> createConnection()
- {
- uint32_t n;
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
- return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
- }
-
- virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
- {
- uint32_t n;
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);
- return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());
- }
-
- virtual sp<IMemoryHeap> getCblk() const
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
- return interface_cast<IMemoryHeap>(reply.readStrongBinder());
- }
-
- virtual void setTransactionState(const Vector<ComposerState>& state,
- int orientation, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- Vector<ComposerState>::const_iterator b(state.begin());
- Vector<ComposerState>::const_iterator e(state.end());
- data.writeInt32(state.size());
- for ( ; b != e ; ++b ) {
- b->write(data);
- }
- data.writeInt32(orientation);
- data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
- }
-
- virtual void bootFinished()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
- }
-
- virtual status_t captureScreen(DisplayID dpy,
- sp<IMemoryHeap>* heap,
- uint32_t* width, uint32_t* height, PixelFormat* format,
- uint32_t reqWidth, uint32_t reqHeight,
- uint32_t minLayerZ, uint32_t maxLayerZ)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(reqWidth);
- data.writeInt32(reqHeight);
- data.writeInt32(minLayerZ);
- data.writeInt32(maxLayerZ);
- remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
- *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
- *width = reply.readInt32();
- *height = reply.readInt32();
- *format = reply.readInt32();
- return reply.readInt32();
- }
-
- virtual status_t turnElectronBeamOff(int32_t mode)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(mode);
- remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
- return reply.readInt32();
- }
-
- virtual status_t turnElectronBeamOn(int32_t mode)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(mode);
- remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_ON, data, &reply);
- return reply.readInt32();
- }
-
- virtual bool authenticateSurfaceTexture(
- const sp<ISurfaceTexture>& surfaceTexture) const
- {
- Parcel data, reply;
- int err = NO_ERROR;
- err = data.writeInterfaceToken(
- ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
- "interface descriptor: %s (%d)", strerror(-err), -err);
- return false;
- }
- err = data.writeStrongBinder(surfaceTexture->asBinder());
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
- "strong binder to parcel: %s (%d)", strerror(-err), -err);
- return false;
- }
- err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
- &reply);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
- "performing transaction: %s (%d)", strerror(-err), -err);
- return false;
- }
- int32_t result = 0;
- err = reply.readInt32(&result);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
- "retrieving result: %s (%d)", strerror(-err), -err);
- return false;
- }
- return result != 0;
- }
-
- virtual sp<IDisplayEventConnection> createDisplayEventConnection()
- {
- Parcel data, reply;
- sp<IDisplayEventConnection> result;
- int err = data.writeInterfaceToken(
- ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- return result;
- }
- err = remote()->transact(
- BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
- data, &reply);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
- "transaction: %s (%d)", strerror(-err), -err);
- return result;
- }
- result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
- return result;
- }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceComposer::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case CREATE_CONNECTION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = createConnection()->asBinder();
- reply->writeStrongBinder(b);
- } break;
- case CREATE_GRAPHIC_BUFFER_ALLOC: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
- reply->writeStrongBinder(b);
- } break;
- case SET_TRANSACTION_STATE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- size_t count = data.readInt32();
- ComposerState s;
- Vector<ComposerState> state;
- state.setCapacity(count);
- for (size_t i=0 ; i<count ; i++) {
- s.read(data);
- state.add(s);
- }
- int orientation = data.readInt32();
- uint32_t flags = data.readInt32();
- setTransactionState(state, orientation, flags);
- } break;
- case BOOT_FINISHED: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- bootFinished();
- } break;
- case GET_CBLK: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = getCblk()->asBinder();
- reply->writeStrongBinder(b);
- } break;
- case CAPTURE_SCREEN: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- DisplayID dpy = data.readInt32();
- uint32_t reqWidth = data.readInt32();
- uint32_t reqHeight = data.readInt32();
- uint32_t minLayerZ = data.readInt32();
- uint32_t maxLayerZ = data.readInt32();
- sp<IMemoryHeap> heap;
- uint32_t w, h;
- PixelFormat f;
- status_t res = captureScreen(dpy, &heap, &w, &h, &f,
- reqWidth, reqHeight, minLayerZ, maxLayerZ);
- reply->writeStrongBinder(heap->asBinder());
- reply->writeInt32(w);
- reply->writeInt32(h);
- reply->writeInt32(f);
- reply->writeInt32(res);
- } break;
- case TURN_ELECTRON_BEAM_OFF: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int32_t mode = data.readInt32();
- status_t res = turnElectronBeamOff(mode);
- reply->writeInt32(res);
- } break;
- case TURN_ELECTRON_BEAM_ON: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int32_t mode = data.readInt32();
- status_t res = turnElectronBeamOn(mode);
- reply->writeInt32(res);
- } break;
- case AUTHENTICATE_SURFACE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<ISurfaceTexture> surfaceTexture =
- interface_cast<ISurfaceTexture>(data.readStrongBinder());
- int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
- reply->writeInt32(result);
- } break;
- case CREATE_DISPLAY_EVENT_CONNECTION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IDisplayEventConnection> connection(createDisplayEventConnection());
- reply->writeStrongBinder(connection->asBinder());
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-};
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
deleted file mode 100644
index ca9ed5b..0000000
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <gui/ISurface.h>
-#include <gui/ISurfaceComposerClient.h>
-#include <private/gui/LayerState.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
- CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
- DESTROY_SURFACE
-};
-
-class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
-{
-public:
- BpSurfaceComposerClient(const sp<IBinder>& impl)
- : BpInterface<ISurfaceComposerClient>(impl)
- {
- }
-
- virtual sp<ISurface> createSurface( surface_data_t* params,
- const String8& name,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
- data.writeString8(name);
- data.writeInt32(display);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(flags);
- remote()->transact(CREATE_SURFACE, data, &reply);
- params->readFromParcel(reply);
- return interface_cast<ISurface>(reply.readStrongBinder());
- }
-
- virtual status_t destroySurface(SurfaceID sid)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
- data.writeInt32(sid);
- remote()->transact(DESTROY_SURFACE, data, &reply);
- return reply.readInt32();
- }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceComposerClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case CREATE_SURFACE: {
- CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- surface_data_t params;
- String8 name = data.readString8();
- DisplayID display = data.readInt32();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t flags = data.readInt32();
- sp<ISurface> s = createSurface(&params, name, display, w, h,
- format, flags);
- params.writeToParcel(reply);
- reply->writeStrongBinder(s->asBinder());
- return NO_ERROR;
- } break;
- case DESTROY_SURFACE: {
- CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- reply->writeInt32( destroySurface( data.readInt32() ) );
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------
-
-status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
- token = parcel.readInt32();
- identity = parcel.readInt32();
- return NO_ERROR;
-}
-
-status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
- parcel->writeInt32(token);
- parcel->writeInt32(identity);
- return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
deleted file mode 100644
index d2e5627..0000000
--- a/libs/gui/ISurfaceTexture.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-
-#include <binder/Parcel.h>
-#include <binder/IInterface.h>
-
-#include <gui/ISurfaceTexture.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-enum {
- REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
- SET_BUFFER_COUNT,
- DEQUEUE_BUFFER,
- QUEUE_BUFFER,
- CANCEL_BUFFER,
- SET_CROP,
- SET_TRANSFORM,
- QUERY,
- SET_SYNCHRONOUS_MODE,
- CONNECT,
- DISCONNECT,
- SET_SCALING_MODE,
-};
-
-
-class BpSurfaceTexture : public BpInterface<ISurfaceTexture>
-{
-public:
- BpSurfaceTexture(const sp<IBinder>& impl)
- : BpInterface<ISurfaceTexture>(impl)
- {
- }
-
- virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(bufferIdx);
- status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- bool nonNull = reply.readInt32();
- if (nonNull) {
- *buf = new GraphicBuffer();
- reply.read(**buf);
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t setBufferCount(int bufferCount)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(bufferCount);
- status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
- uint32_t format, uint32_t usage) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
- status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- *buf = reply.readInt32();
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t queueBuffer(int buf, int64_t timestamp,
- uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(buf);
- data.writeInt64(timestamp);
- status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- *outWidth = reply.readInt32();
- *outHeight = reply.readInt32();
- *outTransform = reply.readInt32();
- result = reply.readInt32();
- return result;
- }
-
- virtual void cancelBuffer(int buf) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(buf);
- remote()->transact(CANCEL_BUFFER, data, &reply);
- }
-
- virtual status_t setCrop(const Rect& reg) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeFloat(reg.left);
- data.writeFloat(reg.top);
- data.writeFloat(reg.right);
- data.writeFloat(reg.bottom);
- status_t result = remote()->transact(SET_CROP, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t setTransform(uint32_t transform) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(transform);
- status_t result = remote()->transact(SET_TRANSFORM, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t setScalingMode(int mode) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(mode);
- status_t result = remote()->transact(SET_SCALING_MODE, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual int query(int what, int* value) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(what);
- status_t result = remote()->transact(QUERY, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- value[0] = reply.readInt32();
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t setSynchronousMode(bool enabled) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(enabled);
- status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t connect(int api,
- uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(api);
- status_t result = remote()->transact(CONNECT, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- *outWidth = reply.readInt32();
- *outHeight = reply.readInt32();
- *outTransform = reply.readInt32();
- result = reply.readInt32();
- return result;
- }
-
- virtual status_t disconnect(int api) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- data.writeInt32(api);
- status_t result =remote()->transact(DISCONNECT, data, &reply);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readInt32();
- return result;
- }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceTexture::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case REQUEST_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int bufferIdx = data.readInt32();
- sp<GraphicBuffer> buffer;
- int result = requestBuffer(bufferIdx, &buffer);
- reply->writeInt32(buffer != 0);
- if (buffer != 0) {
- reply->write(*buffer);
- }
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case SET_BUFFER_COUNT: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int bufferCount = data.readInt32();
- int result = setBufferCount(bufferCount);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case DEQUEUE_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- uint32_t format = data.readInt32();
- uint32_t usage = data.readInt32();
- int buf;
- int result = dequeueBuffer(&buf, w, h, format, usage);
- reply->writeInt32(buf);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case QUEUE_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int buf = data.readInt32();
- int64_t timestamp = data.readInt64();
- uint32_t outWidth, outHeight, outTransform;
- status_t result = queueBuffer(buf, timestamp,
- &outWidth, &outHeight, &outTransform);
- reply->writeInt32(outWidth);
- reply->writeInt32(outHeight);
- reply->writeInt32(outTransform);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case CANCEL_BUFFER: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int buf = data.readInt32();
- cancelBuffer(buf);
- return NO_ERROR;
- } break;
- case SET_CROP: {
- Rect reg;
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- reg.left = data.readFloat();
- reg.top = data.readFloat();
- reg.right = data.readFloat();
- reg.bottom = data.readFloat();
- status_t result = setCrop(reg);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case SET_TRANSFORM: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- uint32_t transform = data.readInt32();
- status_t result = setTransform(transform);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case SET_SCALING_MODE: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int mode = data.readInt32();
- status_t result = setScalingMode(mode);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
- case QUERY: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int value;
- int what = data.readInt32();
- int res = query(what, &value);
- reply->writeInt32(value);
- reply->writeInt32(res);
- return NO_ERROR;
- } break;
- case SET_SYNCHRONOUS_MODE: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- bool enabled = data.readInt32();
- status_t res = setSynchronousMode(enabled);
- reply->writeInt32(res);
- return NO_ERROR;
- } break;
- case CONNECT: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int api = data.readInt32();
- uint32_t outWidth, outHeight, outTransform;
- status_t res = connect(api,
- &outWidth, &outHeight, &outTransform);
- reply->writeInt32(outWidth);
- reply->writeInt32(outHeight);
- reply->writeInt32(outTransform);
- reply->writeInt32(res);
- return NO_ERROR;
- } break;
- case DISCONNECT: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- int api = data.readInt32();
- status_t res = disconnect(api);
- reply->writeInt32(res);
- return NO_ERROR;
- } break;
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
deleted file mode 100644
index 224c305..0000000
--- a/libs/gui/LayerState.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Errors.h>
-#include <binder/Parcel.h>
-#include <gui/ISurfaceComposerClient.h>
-#include <private/gui/LayerState.h>
-
-namespace android {
-
-status_t layer_state_t::write(Parcel& output) const
-{
- status_t err;
-
- size_t len = transparentRegion.write(NULL, 0);
- err = output.writeInt32(len);
- if (err < NO_ERROR) return err;
-
- void* buf = output.writeInplace(len);
- if (buf == NULL) return NO_MEMORY;
-
- err = transparentRegion.write(buf, len);
- if (err < NO_ERROR) return err;
-
- // NOTE: regions are at the end of the structure
- size_t size = sizeof(layer_state_t);
- size -= sizeof(transparentRegion);
- err = output.write(this, size);
- return err;
-}
-
-status_t layer_state_t::read(const Parcel& input)
-{
- status_t err;
- size_t len = input.readInt32();
- void const* buf = input.readInplace(len);
- if (buf == NULL) return NO_MEMORY;
-
- err = transparentRegion.read(buf);
- if (err < NO_ERROR) return err;
-
- // NOTE: regions are at the end of the structure
- size_t size = sizeof(layer_state_t);
- size -= sizeof(transparentRegion);
- input.read(this, size);
- return NO_ERROR;
-}
-
-status_t ComposerState::write(Parcel& output) const {
- output.writeStrongBinder(client->asBinder());
- return state.write(output);
-}
-
-status_t ComposerState::read(const Parcel& input) {
- client = interface_cast<ISurfaceComposerClient>(input.readStrongBinder());
- return state.read(input);
-}
-
-}; // namespace android
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
deleted file mode 100644
index f9a2c04..0000000
--- a/libs/gui/Sensor.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/Flattenable.h>
-
-#include <hardware/sensors.h>
-
-#include <gui/Sensor.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-Sensor::Sensor()
- : mHandle(0), mType(0),
- mMinValue(0), mMaxValue(0), mResolution(0),
- mPower(0), mMinDelay(0)
-{
-}
-
-Sensor::Sensor(struct sensor_t const* hwSensor)
-{
- mName = hwSensor->name;
- mVendor = hwSensor->vendor;
- mHandle = hwSensor->handle;
- mType = hwSensor->type;
- mMinValue = 0; // FIXME: minValue
- mMaxValue = hwSensor->maxRange; // FIXME: maxValue
- mResolution = hwSensor->resolution;
- mPower = hwSensor->power;
- mMinDelay = hwSensor->minDelay;
-}
-
-Sensor::~Sensor()
-{
-}
-
-const String8& Sensor::getName() const {
- return mName;
-}
-
-const String8& Sensor::getVendor() const {
- return mVendor;
-}
-
-int32_t Sensor::getHandle() const {
- return mHandle;
-}
-
-int32_t Sensor::getType() const {
- return mType;
-}
-
-float Sensor::getMinValue() const {
- return mMinValue;
-}
-
-float Sensor::getMaxValue() const {
- return mMaxValue;
-}
-
-float Sensor::getResolution() const {
- return mResolution;
-}
-
-float Sensor::getPowerUsage() const {
- return mPower;
-}
-
-int32_t Sensor::getMinDelay() const {
- return mMinDelay;
-}
-
-nsecs_t Sensor::getMinDelayNs() const {
- return getMinDelay() * 1000;
-}
-
-int32_t Sensor::getVersion() const {
- return mVersion;
-}
-
-size_t Sensor::getFlattenedSize() const
-{
- return sizeof(int32_t) + ((mName.length() + 3) & ~3) +
- sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
- sizeof(int32_t) * 2 +
- sizeof(float) * 4 +
- sizeof(int32_t);
-}
-
-size_t Sensor::getFdCount() const
-{
- return 0;
-}
-
-static inline
-size_t write(void* buffer, size_t offset, const String8& value) {
- memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length());
- return (value.length() + 3) & ~3;
-}
-
-static inline
-size_t write(void* buffer, size_t offset, float value) {
- *reinterpret_cast<float*>(static_cast<char*>(buffer) + offset) = value;
- return sizeof(float);
-}
-
-static inline
-size_t write(void* buffer, size_t offset, int32_t value) {
- *reinterpret_cast<int32_t*>(static_cast<char*>(buffer) + offset) = value;
- return sizeof(int32_t);
-}
-
-status_t Sensor::flatten(void* buffer, size_t size,
- int fds[], size_t count) const
-{
- if (size < Sensor::getFlattenedSize())
- return -ENOMEM;
-
- size_t offset = 0;
- offset += write(buffer, offset, int32_t(mName.length()));
- offset += write(buffer, offset, mName);
- offset += write(buffer, offset, int32_t(mVendor.length()));
- offset += write(buffer, offset, mVendor);
- offset += write(buffer, offset, mHandle);
- offset += write(buffer, offset, mType);
- offset += write(buffer, offset, mMinValue);
- offset += write(buffer, offset, mMaxValue);
- offset += write(buffer, offset, mResolution);
- offset += write(buffer, offset, mPower);
- offset += write(buffer, offset, mMinDelay);
-
- return NO_ERROR;
-}
-
-static inline
-size_t read(void const* buffer, size_t offset, String8* value, int32_t len) {
- value->setTo(static_cast<char const*>(buffer) + offset, len);
- return (len + 3) & ~3;
-}
-
-static inline
-size_t read(void const* buffer, size_t offset, float* value) {
- *value = *reinterpret_cast<float const*>(static_cast<char const*>(buffer) + offset);
- return sizeof(float);
-}
-
-static inline
-size_t read(void const* buffer, size_t offset, int32_t* value) {
- *value = *reinterpret_cast<int32_t const*>(static_cast<char const*>(buffer) + offset);
- return sizeof(int32_t);
-}
-
-status_t Sensor::unflatten(void const* buffer, size_t size,
- int fds[], size_t count)
-{
- int32_t len;
- size_t offset = 0;
- offset += read(buffer, offset, &len);
- offset += read(buffer, offset, &mName, len);
- offset += read(buffer, offset, &len);
- offset += read(buffer, offset, &mVendor, len);
- offset += read(buffer, offset, &mHandle);
- offset += read(buffer, offset, &mType);
- offset += read(buffer, offset, &mMinValue);
- offset += read(buffer, offset, &mMaxValue);
- offset += read(buffer, offset, &mResolution);
- offset += read(buffer, offset, &mPower);
- offset += read(buffer, offset, &mMinDelay);
-
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
deleted file mode 100644
index b95dd90..0000000
--- a/libs/gui/SensorEventQueue.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Sensors"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Looper.h>
-
-#include <gui/Sensor.h>
-#include <gui/BitTube.h>
-#include <gui/SensorEventQueue.h>
-#include <gui/ISensorEventConnection.h>
-
-#include <android/sensor.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
- : mSensorEventConnection(connection)
-{
-}
-
-SensorEventQueue::~SensorEventQueue()
-{
-}
-
-void SensorEventQueue::onFirstRef()
-{
- mSensorChannel = mSensorEventConnection->getSensorChannel();
-}
-
-int SensorEventQueue::getFd() const
-{
- return mSensorChannel->getFd();
-}
-
-ssize_t SensorEventQueue::write(ASensorEvent const* events, size_t numEvents)
-{
- ssize_t size = mSensorChannel->write(events, numEvents * sizeof(events[0]));
- if (size >= 0) {
- if (size % sizeof(events[0])) {
- // partial write!!! should never happen.
- return -EINVAL;
- }
- // returns number of events written
- size /= sizeof(events[0]);
- }
- return size;
-}
-
-ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)
-{
- ssize_t size = mSensorChannel->read(events, numEvents*sizeof(events[0]));
- ALOGE_IF(size<0 && size!=-EAGAIN,
- "SensorChannel::read error (%s)", strerror(-size));
- if (size >= 0) {
- if (size % sizeof(events[0])) {
- // partial read!!! should never happen.
- ALOGE("SensorEventQueue partial read (event-size=%u, read=%d)",
- sizeof(events[0]), int(size));
- return -EINVAL;
- }
- // returns number of events read
- size /= sizeof(events[0]);
- }
- return size;
-}
-
-sp<Looper> SensorEventQueue::getLooper() const
-{
- Mutex::Autolock _l(mLock);
- if (mLooper == 0) {
- mLooper = new Looper(true);
- mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL);
- }
- return mLooper;
-}
-
-status_t SensorEventQueue::waitForEvent() const
-{
- const int fd = getFd();
- sp<Looper> looper(getLooper());
-
- int32_t result;
- do {
- result = looper->pollOnce(-1);
- if (result == ALOOPER_EVENT_ERROR) {
- ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
- result = -EPIPE; // unknown error, so we make up one
- break;
- }
- } while (result != fd);
-
- return (result == fd) ? status_t(NO_ERROR) : result;
-}
-
-status_t SensorEventQueue::wake() const
-{
- sp<Looper> looper(getLooper());
- looper->wake();
- return NO_ERROR;
-}
-
-status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
- return mSensorEventConnection->enableDisable(sensor->getHandle(), true);
-}
-
-status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
- return mSensorEventConnection->enableDisable(sensor->getHandle(), false);
-}
-
-status_t SensorEventQueue::enableSensor(int32_t handle, int32_t us) const {
- status_t err = mSensorEventConnection->enableDisable(handle, true);
- if (err == NO_ERROR) {
- mSensorEventConnection->setEventRate(handle, us2ns(us));
- }
- return err;
-}
-
-status_t SensorEventQueue::disableSensor(int32_t handle) const {
- return mSensorEventConnection->enableDisable(handle, false);
-}
-
-status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
- return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
deleted file mode 100644
index b80da56..0000000
--- a/libs/gui/SensorManager.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Sensors"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Singleton.h>
-
-#include <binder/IBinder.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/ISensorServer.h>
-#include <gui/ISensorEventConnection.h>
-#include <gui/Sensor.h>
-#include <gui/SensorManager.h>
-#include <gui/SensorEventQueue.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
-
-SensorManager::SensorManager()
- : mSensorList(0)
-{
- // okay we're not locked here, but it's not needed during construction
- assertStateLocked();
-}
-
-SensorManager::~SensorManager()
-{
- free(mSensorList);
-}
-
-void SensorManager::sensorManagerDied()
-{
- Mutex::Autolock _l(mLock);
- mSensorServer.clear();
- free(mSensorList);
- mSensorList = NULL;
- mSensors.clear();
-}
-
-status_t SensorManager::assertStateLocked() const {
- if (mSensorServer == NULL) {
- // try for one second
- const String16 name("sensorservice");
- for (int i=0 ; i<4 ; i++) {
- status_t err = getService(name, &mSensorServer);
- if (err == NAME_NOT_FOUND) {
- usleep(250000);
- continue;
- }
- if (err != NO_ERROR) {
- return err;
- }
- break;
- }
-
- class DeathObserver : public IBinder::DeathRecipient {
- SensorManager& mSensorManger;
- virtual void binderDied(const wp<IBinder>& who) {
- ALOGW("sensorservice died [%p]", who.unsafe_get());
- mSensorManger.sensorManagerDied();
- }
- public:
- DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
- };
-
- mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
- mSensorServer->asBinder()->linkToDeath(mDeathObserver);
-
- mSensors = mSensorServer->getSensorList();
- size_t count = mSensors.size();
- mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
- for (size_t i=0 ; i<count ; i++) {
- mSensorList[i] = mSensors.array() + i;
- }
- }
-
- return NO_ERROR;
-}
-
-
-
-ssize_t SensorManager::getSensorList(Sensor const* const** list) const
-{
- Mutex::Autolock _l(mLock);
- status_t err = assertStateLocked();
- if (err < 0) {
- return ssize_t(err);
- }
- *list = mSensorList;
- return mSensors.size();
-}
-
-Sensor const* SensorManager::getDefaultSensor(int type)
-{
- Mutex::Autolock _l(mLock);
- if (assertStateLocked() == NO_ERROR) {
- // For now we just return the first sensor of that type we find.
- // in the future it will make sense to let the SensorService make
- // that decision.
- for (size_t i=0 ; i<mSensors.size() ; i++) {
- if (mSensorList[i]->getType() == type)
- return mSensorList[i];
- }
- }
- return NULL;
-}
-
-sp<SensorEventQueue> SensorManager::createEventQueue()
-{
- sp<SensorEventQueue> queue;
-
- Mutex::Autolock _l(mLock);
- while (assertStateLocked() == NO_ERROR) {
- sp<ISensorEventConnection> connection =
- mSensorServer->createSensorEventConnection();
- if (connection == NULL) {
- // SensorService just died.
- ALOGE("createEventQueue: connection is NULL. SensorService died.");
- continue;
- }
- queue = new SensorEventQueue(connection);
- break;
- }
- return queue;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
deleted file mode 100644
index 72b27ed..0000000
--- a/libs/gui/Surface.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Surface"
-
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <utils/CallStack.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <binder/IPCThreadState.h>
-
-#include <ui/DisplayInfo.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/Rect.h>
-
-#include <gui/ISurface.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/SurfaceTextureClient.h>
-
-namespace android {
-
-// ============================================================================
-// SurfaceControl
-// ============================================================================
-
-SurfaceControl::SurfaceControl(
- const sp<SurfaceComposerClient>& client,
- const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data)
- : mClient(client), mSurface(surface),
- mToken(data.token), mIdentity(data.identity)
-{
-}
-
-SurfaceControl::~SurfaceControl()
-{
- destroy();
-}
-
-void SurfaceControl::destroy()
-{
- if (isValid()) {
- mClient->destroySurface(mToken);
- }
-
- // clear all references and trigger an IPC now, to make sure things
- // happen without delay, since these resources are quite heavy.
- mClient.clear();
- mSurface.clear();
- IPCThreadState::self()->flushCommands();
-}
-
-void SurfaceControl::clear()
-{
- // here, the window manager tells us explicitly that we should destroy
- // the surface's resource. Soon after this call, it will also release
- // its last reference (which will call the dtor); however, it is possible
- // that a client living in the same process still holds references which
- // would delay the call to the dtor -- that is why we need this explicit
- // "clear()" call.
- destroy();
-}
-
-bool SurfaceControl::isSameSurface(
- const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
-{
- if (lhs == 0 || rhs == 0)
- return false;
- return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
-status_t SurfaceControl::setLayer(int32_t layer) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setLayer(mToken, layer);
-}
-status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setPosition(mToken, x, y);
-}
-status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setSize(mToken, w, h);
-}
-status_t SurfaceControl::hide() {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->hide(mToken);
-}
-status_t SurfaceControl::show(int32_t layer) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->show(mToken, layer);
-}
-status_t SurfaceControl::freeze() {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->freeze(mToken);
-}
-status_t SurfaceControl::unfreeze() {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->unfreeze(mToken);
-}
-status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setFlags(mToken, flags, mask);
-}
-status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setTransparentRegionHint(mToken, transparent);
-}
-status_t SurfaceControl::setAlpha(float alpha) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setAlpha(mToken, alpha);
-}
-status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
-}
-status_t SurfaceControl::setFreezeTint(uint32_t tint) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setFreezeTint(mToken, tint);
-}
-
-status_t SurfaceControl::validate() const
-{
- if (mToken<0 || mClient==0) {
- ALOGE("invalid token (%d, identity=%u) or client (%p)",
- mToken, mIdentity, mClient.get());
- return NO_INIT;
- }
- return NO_ERROR;
-}
-
-status_t SurfaceControl::writeSurfaceToParcel(
- const sp<SurfaceControl>& control, Parcel* parcel)
-{
- sp<ISurface> sur;
- uint32_t identity = 0;
- if (SurfaceControl::isValid(control)) {
- sur = control->mSurface;
- identity = control->mIdentity;
- }
- parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
- parcel->writeStrongBinder(NULL); // NULL ISurfaceTexture in this case.
- parcel->writeInt32(identity);
- return NO_ERROR;
-}
-
-sp<Surface> SurfaceControl::getSurface() const
-{
- Mutex::Autolock _l(mLock);
- if (mSurfaceData == 0) {
- sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this));
- mSurfaceData = new Surface(surface_control);
- }
- return mSurfaceData;
-}
-
-// ============================================================================
-// Surface
-// ============================================================================
-
-// ---------------------------------------------------------------------------
-
-Surface::Surface(const sp<SurfaceControl>& surface)
- : SurfaceTextureClient(),
- mSurface(surface->mSurface),
- mIdentity(surface->mIdentity)
-{
- sp<ISurfaceTexture> st;
- if (mSurface != NULL) {
- st = mSurface->getSurfaceTexture();
- }
- init(st);
-}
-
-Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
- : SurfaceTextureClient()
-{
- mSurface = interface_cast<ISurface>(ref);
- sp<IBinder> st_binder(parcel.readStrongBinder());
- sp<ISurfaceTexture> st;
- if (st_binder != NULL) {
- st = interface_cast<ISurfaceTexture>(st_binder);
- } else if (mSurface != NULL) {
- st = mSurface->getSurfaceTexture();
- }
-
- mIdentity = parcel.readInt32();
- init(st);
-}
-
-Surface::Surface(const sp<ISurfaceTexture>& st)
- : SurfaceTextureClient(),
- mSurface(NULL),
- mIdentity(0)
-{
- init(st);
-}
-
-status_t Surface::writeToParcel(
- const sp<Surface>& surface, Parcel* parcel)
-{
- sp<ISurface> sur;
- sp<ISurfaceTexture> st;
- uint32_t identity = 0;
- if (Surface::isValid(surface)) {
- sur = surface->mSurface;
- st = surface->getISurfaceTexture();
- identity = surface->mIdentity;
- } else if (surface != 0 &&
- (surface->mSurface != NULL ||
- surface->getISurfaceTexture() != NULL)) {
- ALOGE("Parceling invalid surface with non-NULL ISurface/ISurfaceTexture as NULL: "
- "mSurface = %p, surfaceTexture = %p, mIdentity = %d, ",
- surface->mSurface.get(), surface->getISurfaceTexture().get(),
- surface->mIdentity);
- }
-
- parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL);
- parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL);
- parcel->writeInt32(identity);
- return NO_ERROR;
-
-}
-
-Mutex Surface::sCachedSurfacesLock;
-DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
-
-sp<Surface> Surface::readFromParcel(const Parcel& data) {
- Mutex::Autolock _l(sCachedSurfacesLock);
- sp<IBinder> binder(data.readStrongBinder());
- sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
- if (surface == 0) {
- surface = new Surface(data, binder);
- sCachedSurfaces.add(binder, surface);
- } else {
- // The Surface was found in the cache, but we still should clear any
- // remaining data from the parcel.
- data.readStrongBinder(); // ISurfaceTexture
- data.readInt32(); // identity
- }
- if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) {
- surface = 0;
- }
- cleanCachedSurfacesLocked();
- return surface;
-}
-
-// Remove the stale entries from the surface cache. This should only be called
-// with sCachedSurfacesLock held.
-void Surface::cleanCachedSurfacesLocked() {
- for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
- wp<Surface> s(sCachedSurfaces.valueAt(i));
- if (s == 0 || s.promote() == 0) {
- sCachedSurfaces.removeItemsAt(i);
- }
- }
-}
-
-void Surface::init(const sp<ISurfaceTexture>& surfaceTexture)
-{
- if (mSurface != NULL || surfaceTexture != NULL) {
- ALOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
- if (surfaceTexture != NULL) {
- setISurfaceTexture(surfaceTexture);
- setUsage(GraphicBuffer::USAGE_HW_RENDER);
- }
-
- DisplayInfo dinfo;
- SurfaceComposerClient::getDisplayInfo(0, &dinfo);
- const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
- const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
- const_cast<uint32_t&>(ANativeWindow::flags) = 0;
- }
-}
-
-Surface::~Surface()
-{
- // clear all references and trigger an IPC now, to make sure things
- // happen without delay, since these resources are quite heavy.
- mSurface.clear();
- IPCThreadState::self()->flushCommands();
-}
-
-bool Surface::isValid() {
- return getISurfaceTexture() != NULL;
-}
-
-sp<ISurfaceTexture> Surface::getSurfaceTexture() {
- return getISurfaceTexture();
-}
-
-sp<IBinder> Surface::asBinder() const {
- return mSurface!=0 ? mSurface->asBinder() : 0;
-}
-
-// ----------------------------------------------------------------------------
-
-int Surface::query(int what, int* value) const {
- switch (what) {
- case NATIVE_WINDOW_CONCRETE_TYPE:
- *value = NATIVE_WINDOW_SURFACE;
- return NO_ERROR;
- }
- return SurfaceTextureClient::query(what, value);
-}
-
-// ----------------------------------------------------------------------------
-
-status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {
- ANativeWindow_Buffer outBuffer;
-
- ARect temp;
- ARect* inOutDirtyBounds = NULL;
- if (inOutDirtyRegion) {
- temp = inOutDirtyRegion->getBounds();
- inOutDirtyBounds = &temp;
- }
-
- status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
-
- if (err == NO_ERROR) {
- other->w = uint32_t(outBuffer.width);
- other->h = uint32_t(outBuffer.height);
- other->s = uint32_t(outBuffer.stride);
- other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
- other->format = uint32_t(outBuffer.format);
- other->bits = outBuffer.bits;
- }
-
- if (inOutDirtyRegion) {
- inOutDirtyRegion->set( static_cast<Rect const&>(temp) );
- }
-
- return err;
-}
-
-status_t Surface::unlockAndPost() {
- return SurfaceTextureClient::unlockAndPost();
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
deleted file mode 100644
index ceb1ba6..0000000
--- a/libs/gui/SurfaceComposerClient.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceComposerClient"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/Singleton.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <binder/IMemory.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/DisplayInfo.h>
-
-#include <gui/ISurface.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/ISurfaceComposerClient.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <private/gui/ComposerService.h>
-#include <private/gui/LayerState.h>
-#include <private/gui/SharedBufferStack.h>
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
-
-ComposerService::ComposerService()
-: Singleton<ComposerService>() {
- const String16 name("SurfaceFlinger");
- while (getService(name, &mComposerService) != NO_ERROR) {
- usleep(250000);
- }
- mServerCblkMemory = mComposerService->getCblk();
- mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
- mServerCblkMemory->getBase());
-}
-
-sp<ISurfaceComposer> ComposerService::getComposerService() {
- return ComposerService::getInstance().mComposerService;
-}
-
-surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
- return ComposerService::getInstance().mServerCblk;
-}
-
-static inline sp<ISurfaceComposer> getComposerService() {
- return ComposerService::getComposerService();
-}
-
-static inline surface_flinger_cblk_t const volatile * get_cblk() {
- return ComposerService::getControlBlock();
-}
-
-// ---------------------------------------------------------------------------
-
-// NOTE: this is NOT a member function (it's a friend defined with its
-// declaration).
-static inline
-int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
- if (lhs.client < rhs.client) return -1;
- if (lhs.client > rhs.client) return 1;
- if (lhs.state.surface < rhs.state.surface) return -1;
- if (lhs.state.surface > rhs.state.surface) return 1;
- return 0;
-}
-
-class Composer : public Singleton<Composer>
-{
- friend class Singleton<Composer>;
-
- mutable Mutex mLock;
- SortedVector<ComposerState> mStates;
- int mOrientation;
- uint32_t mForceSynchronous;
-
- Composer() : Singleton<Composer>(),
- mOrientation(ISurfaceComposer::eOrientationUnchanged),
- mForceSynchronous(0)
- { }
-
- void closeGlobalTransactionImpl(bool synchronous);
-
- layer_state_t* getLayerStateLocked(
- const sp<SurfaceComposerClient>& client, SurfaceID id);
-
-public:
-
- status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
- float x, float y);
- status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
- uint32_t w, uint32_t h);
- status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
- int32_t z);
- status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
- uint32_t flags, uint32_t mask);
- status_t setTransparentRegionHint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
- const Region& transparentRegion);
- status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
- float alpha);
- status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
- float dsdx, float dtdx, float dsdy, float dtdy);
- status_t setFreezeTint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
- uint32_t tint);
- status_t setOrientation(int orientation);
-
- static void closeGlobalTransaction(bool synchronous) {
- Composer::getInstance().closeGlobalTransactionImpl(synchronous);
- }
-};
-
-ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
-
-// ---------------------------------------------------------------------------
-
-void Composer::closeGlobalTransactionImpl(bool synchronous) {
- sp<ISurfaceComposer> sm(getComposerService());
-
- Vector<ComposerState> transaction;
- int orientation;
- uint32_t flags = 0;
-
- { // scope for the lock
- Mutex::Autolock _l(mLock);
- transaction = mStates;
- mStates.clear();
-
- orientation = mOrientation;
- mOrientation = ISurfaceComposer::eOrientationUnchanged;
-
- if (synchronous || mForceSynchronous) {
- flags |= ISurfaceComposer::eSynchronous;
- }
- mForceSynchronous = false;
- }
-
- sm->setTransactionState(transaction, orientation, flags);
-}
-
-layer_state_t* Composer::getLayerStateLocked(
- const sp<SurfaceComposerClient>& client, SurfaceID id) {
-
- ComposerState s;
- s.client = client->mClient;
- s.state.surface = id;
-
- ssize_t index = mStates.indexOf(s);
- if (index < 0) {
- // we don't have it, add an initialized layer_state to our list
- index = mStates.add(s);
- }
-
- ComposerState* const out = mStates.editArray();
- return &(out[index].state);
-}
-
-status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float x, float y) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::ePositionChanged;
- s->x = x;
- s->y = y;
- return NO_ERROR;
-}
-
-status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t w, uint32_t h) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eSizeChanged;
- s->w = w;
- s->h = h;
-
- // Resizing a surface makes the transaction synchronous.
- mForceSynchronous = true;
-
- return NO_ERROR;
-}
-
-status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
- SurfaceID id, int32_t z) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eLayerChanged;
- s->z = z;
- return NO_ERROR;
-}
-
-status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t flags,
- uint32_t mask) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eVisibilityChanged;
- s->flags &= ~mask;
- s->flags |= (flags & mask);
- s->mask |= mask;
- return NO_ERROR;
-}
-
-status_t Composer::setTransparentRegionHint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
- const Region& transparentRegion) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eTransparentRegionChanged;
- s->transparentRegion = transparentRegion;
- return NO_ERROR;
-}
-
-status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float alpha) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eAlphaChanged;
- s->alpha = alpha;
- return NO_ERROR;
-}
-
-status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float dsdx, float dtdx,
- float dsdy, float dtdy) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eMatrixChanged;
- layer_state_t::matrix22_t matrix;
- matrix.dsdx = dsdx;
- matrix.dtdx = dtdx;
- matrix.dsdy = dsdy;
- matrix.dtdy = dtdy;
- s->matrix = matrix;
- return NO_ERROR;
-}
-
-status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t tint) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eFreezeTintChanged;
- s->tint = tint;
- return NO_ERROR;
-}
-
-status_t Composer::setOrientation(int orientation) {
- Mutex::Autolock _l(mLock);
- mOrientation = orientation;
-
- // Changing the orientation makes the transaction synchronous.
- mForceSynchronous = true;
-
- return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
-
-SurfaceComposerClient::SurfaceComposerClient()
- : mStatus(NO_INIT), mComposer(Composer::getInstance())
-{
-}
-
-void SurfaceComposerClient::onFirstRef() {
- sp<ISurfaceComposer> sm(getComposerService());
- if (sm != 0) {
- sp<ISurfaceComposerClient> conn = sm->createConnection();
- if (conn != 0) {
- mClient = conn;
- mStatus = NO_ERROR;
- }
- }
-}
-
-SurfaceComposerClient::~SurfaceComposerClient() {
- dispose();
-}
-
-status_t SurfaceComposerClient::initCheck() const {
- return mStatus;
-}
-
-sp<IBinder> SurfaceComposerClient::connection() const {
- return (mClient != 0) ? mClient->asBinder() : 0;
-}
-
-status_t SurfaceComposerClient::linkToComposerDeath(
- const sp<IBinder::DeathRecipient>& recipient,
- void* cookie, uint32_t flags) {
- sp<ISurfaceComposer> sm(getComposerService());
- return sm->asBinder()->linkToDeath(recipient, cookie, flags);
-}
-
-void SurfaceComposerClient::dispose() {
- // this can be called more than once.
- sp<ISurfaceComposerClient> client;
- Mutex::Autolock _lm(mLock);
- if (mClient != 0) {
- client = mClient; // hold ref while lock is held
- mClient.clear();
- }
- mStatus = NO_INIT;
-}
-
-sp<SurfaceControl> SurfaceComposerClient::createSurface(
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
-{
- String8 name;
- const size_t SIZE = 128;
- char buffer[SIZE];
- snprintf(buffer, SIZE, "<pid_%d>", getpid());
- name.append(buffer);
-
- return SurfaceComposerClient::createSurface(name, display,
- w, h, format, flags);
-}
-
-sp<SurfaceControl> SurfaceComposerClient::createSurface(
- const String8& name,
- DisplayID display,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
-{
- sp<SurfaceControl> result;
- if (mStatus == NO_ERROR) {
- ISurfaceComposerClient::surface_data_t data;
- sp<ISurface> surface = mClient->createSurface(&data, name,
- display, w, h, format, flags);
- if (surface != 0) {
- result = new SurfaceControl(this, surface, data);
- }
- }
- return result;
-}
-
-status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
- if (mStatus != NO_ERROR)
- return mStatus;
- status_t err = mClient->destroySurface(sid);
- return err;
-}
-
-inline Composer& SurfaceComposerClient::getComposer() {
- return mComposer;
-}
-
-// ----------------------------------------------------------------------------
-
-void SurfaceComposerClient::openGlobalTransaction() {
- // Currently a no-op
-}
-
-void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
- Composer::closeGlobalTransaction(synchronous);
-}
-
-// ----------------------------------------------------------------------------
-
-status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
- return getComposer().setFreezeTint(this, id, tint);
-}
-
-status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
- return getComposer().setPosition(this, id, x, y);
-}
-
-status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
- return getComposer().setSize(this, id, w, h);
-}
-
-status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
- return getComposer().setLayer(this, id, z);
-}
-
-status_t SurfaceComposerClient::hide(SurfaceID id) {
- return getComposer().setFlags(this, id,
- ISurfaceComposer::eLayerHidden,
- ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
- return getComposer().setFlags(this, id,
- 0,
- ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::freeze(SurfaceID id) {
- return getComposer().setFlags(this, id,
- ISurfaceComposer::eLayerFrozen,
- ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
- return getComposer().setFlags(this, id,
- 0,
- ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
- uint32_t mask) {
- return getComposer().setFlags(this, id, flags, mask);
-}
-
-status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
- const Region& transparentRegion) {
- return getComposer().setTransparentRegionHint(this, id, transparentRegion);
-}
-
-status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
- return getComposer().setAlpha(this, id, alpha);
-}
-
-status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
- float dsdy, float dtdy) {
- return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
-}
-
-status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
- int orientation, uint32_t flags)
-{
- return Composer::getInstance().setOrientation(orientation);
-}
-
-// ----------------------------------------------------------------------------
-
-status_t SurfaceComposerClient::getDisplayInfo(
- DisplayID dpy, DisplayInfo* info)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
-
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-
- info->w = dcblk->w;
- info->h = dcblk->h;
- info->orientation = dcblk->orientation;
- info->xdpi = dcblk->xdpi;
- info->ydpi = dcblk->ydpi;
- info->fps = dcblk->fps;
- info->density = dcblk->density;
- return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
-}
-
-ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->w;
-}
-
-ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->h;
-}
-
-ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
-{
- if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
- return BAD_VALUE;
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- volatile display_cblk_t const * dcblk = cblk->displays + dpy;
- return dcblk->orientation;
-}
-
-ssize_t SurfaceComposerClient::getNumberOfDisplays()
-{
- volatile surface_flinger_cblk_t const * cblk = get_cblk();
- uint32_t connected = cblk->connected;
- int n = 0;
- while (connected) {
- if (connected&1) n++;
- connected >>= 1;
- }
- return n;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- // This has been made a no-op because it can cause Gralloc buffer deadlocks.
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- // This has been made a no-op because it can cause Gralloc buffer deadlocks.
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-ScreenshotClient::ScreenshotClient()
- : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
-}
-
-status_t ScreenshotClient::update() {
- sp<ISurfaceComposer> s(ComposerService::getComposerService());
- if (s == NULL) return NO_INIT;
- mHeap = 0;
- return s->captureScreen(0, &mHeap,
- &mWidth, &mHeight, &mFormat, 0, 0,
- 0, -1UL);
-}
-
-status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
- sp<ISurfaceComposer> s(ComposerService::getComposerService());
- if (s == NULL) return NO_INIT;
- mHeap = 0;
- return s->captureScreen(0, &mHeap,
- &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
- 0, -1UL);
-}
-
-status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
- uint32_t minLayerZ, uint32_t maxLayerZ) {
- sp<ISurfaceComposer> s(ComposerService::getComposerService());
- if (s == NULL) return NO_INIT;
- mHeap = 0;
- return s->captureScreen(0, &mHeap,
- &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
- minLayerZ, maxLayerZ);
-}
-
-void ScreenshotClient::release() {
- mHeap = 0;
-}
-
-void const* ScreenshotClient::getPixels() const {
- return mHeap->getBase();
-}
-
-uint32_t ScreenshotClient::getWidth() const {
- return mWidth;
-}
-
-uint32_t ScreenshotClient::getHeight() const {
- return mHeight;
-}
-
-PixelFormat ScreenshotClient::getFormat() const {
- return mFormat;
-}
-
-uint32_t ScreenshotClient::getStride() const {
- return mWidth;
-}
-
-size_t ScreenshotClient::getSize() const {
- return mHeap->getSize();
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
deleted file mode 100644
index b42aa34..0000000
--- a/libs/gui/SurfaceTexture.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceTexture"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <hardware/hardware.h>
-
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/SurfaceTexture.h>
-
-#include <private/gui/ComposerService.h>
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/Trace.h>
-
-// This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension
-// to synchronize access to the buffers. It will cause dequeueBuffer to stall,
-// waiting for the GL reads for the buffer being dequeued to complete before
-// allowing the buffer to be dequeued.
-#ifdef USE_FENCE_SYNC
-#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
-#error "USE_FENCE_SYNC and ALLOW_DEQUEUE_CURRENT_BUFFER are incompatible"
-#endif
-#endif
-
-// Macros for including the SurfaceTexture name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
-
-namespace android {
-
-// Transform matrices
-static float mtxIdentity[16] = {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1,
-};
-static float mtxFlipH[16] = {
- -1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 1, 0, 0, 1,
-};
-static float mtxFlipV[16] = {
- 1, 0, 0, 0,
- 0, -1, 0, 0,
- 0, 0, 1, 0,
- 0, 1, 0, 1,
-};
-static float mtxRot90[16] = {
- 0, 1, 0, 0,
- -1, 0, 0, 0,
- 0, 0, 1, 0,
- 1, 0, 0, 1,
-};
-static float mtxRot180[16] = {
- -1, 0, 0, 0,
- 0, -1, 0, 0,
- 0, 0, 1, 0,
- 1, 1, 0, 1,
-};
-static float mtxRot270[16] = {
- 0, -1, 0, 0,
- 1, 0, 0, 0,
- 0, 0, 1, 0,
- 0, 1, 0, 1,
-};
-
-static void mtxMul(float out[16], const float a[16], const float b[16]);
-
-// Get an ID that's unique within this process.
-static int32_t createProcessUniqueId() {
- static volatile int32_t globalCounter = 0;
- return android_atomic_inc(&globalCounter);
-}
-
-SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
- GLenum texTarget, bool useFenceSync) :
- BufferQueue(allowSynchronousMode),
- mCurrentTransform(0),
- mCurrentTimestamp(0),
- mTexName(tex),
-#ifdef USE_FENCE_SYNC
- mUseFenceSync(useFenceSync),
-#else
- mUseFenceSync(false),
-#endif
- mTexTarget(texTarget),
- mAbandoned(false),
- mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT)
-{
- // Choose a name using the PID and a process-unique ID.
- mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
- BufferQueue::setConsumerName(mName);
-
- ST_LOGV("SurfaceTexture");
- memcpy(mCurrentTransformMatrix, mtxIdentity,
- sizeof(mCurrentTransformMatrix));
-}
-
-SurfaceTexture::~SurfaceTexture() {
- ST_LOGV("~SurfaceTexture");
- abandon();
-}
-
-status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
- Mutex::Autolock lock(mMutex);
- return BufferQueue::setBufferCountServer(bufferCount);
-}
-
-
-status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
-{
- return BufferQueue::setDefaultBufferSize(w, h);
-}
-
-status_t SurfaceTexture::updateTexImage() {
- ATRACE_CALL();
- ST_LOGV("updateTexImage");
- Mutex::Autolock lock(mMutex);
-
- if (mAbandoned) {
- ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
- return NO_INIT;
- }
-
- BufferItem item;
-
- // In asynchronous mode the list is guaranteed to be one buffer
- // deep, while in synchronous mode we use the oldest buffer.
- if (acquire(&item) == NO_ERROR) {
- int buf = item.mBuf;
- // This buffer was newly allocated, so we need to clean up on our side
- if (item.mGraphicBuffer != NULL) {
- mEGLSlots[buf].mGraphicBuffer = 0;
- if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mEGLSlots[buf].mEglDisplay,
- mEGLSlots[buf].mEglImage);
- mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
- mEGLSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
- }
- mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
- }
-
- // Update the GL texture object.
- EGLImageKHR image = mEGLSlots[buf].mEglImage;
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (image == EGL_NO_IMAGE_KHR) {
- if (item.mGraphicBuffer == 0) {
- ST_LOGE("buffer at slot %d is null", buf);
- return BAD_VALUE;
- }
- image = createImage(dpy, item.mGraphicBuffer);
- mEGLSlots[buf].mEglImage = image;
- mEGLSlots[buf].mEglDisplay = dpy;
- if (image == EGL_NO_IMAGE_KHR) {
- // NOTE: if dpy was invalid, createImage() is guaranteed to
- // fail. so we'd end up here.
- return -EINVAL;
- }
- }
-
- GLint error;
- while ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
- }
-
- glBindTexture(mTexTarget, mTexName);
- glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
-
- bool failed = false;
- while ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGE("error binding external texture image %p (slot %d): %#04x",
- image, buf, error);
- failed = true;
- }
- if (failed) {
- releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
- mEGLSlots[buf].mFence);
- return -EINVAL;
- }
-
- if (mCurrentTexture != INVALID_BUFFER_SLOT) {
- if (mUseFenceSync) {
- EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR,
- NULL);
- if (fence == EGL_NO_SYNC_KHR) {
- ALOGE("updateTexImage: error creating fence: %#x",
- eglGetError());
- releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
- mEGLSlots[buf].mFence);
- return -EINVAL;
- }
- glFlush();
- mEGLSlots[mCurrentTexture].mFence = fence;
- }
- }
-
- ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)",
- mCurrentTexture,
- mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0,
- buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0);
-
- // release old buffer
- releaseBuffer(mCurrentTexture,
- mEGLSlots[mCurrentTexture].mEglDisplay,
- mEGLSlots[mCurrentTexture].mFence);
-
- // Update the SurfaceTexture state.
- mCurrentTexture = buf;
- mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer;
- mCurrentCrop = item.mCrop;
- mCurrentTransform = item.mTransform;
- mCurrentScalingMode = item.mScalingMode;
- mCurrentTimestamp = item.mTimestamp;
- computeCurrentTransformMatrix();
-
- // Now that we've passed the point at which failures can happen,
- // it's safe to remove the buffer from the front of the queue.
-
- } else {
- // We always bind the texture even if we don't update its contents.
- glBindTexture(mTexTarget, mTexName);
- }
-
- return OK;
-}
-
-bool SurfaceTexture::isExternalFormat(uint32_t format)
-{
- switch (format) {
- // supported YUV formats
- case HAL_PIXEL_FORMAT_YV12:
- // Legacy/deprecated YUV formats
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- return true;
- }
-
- // Any OEM format needs to be considered
- if (format>=0x100 && format<=0x1FF)
- return true;
-
- return false;
-}
-
-GLenum SurfaceTexture::getCurrentTextureTarget() const {
- return mTexTarget;
-}
-
-void SurfaceTexture::getTransformMatrix(float mtx[16]) {
- Mutex::Autolock lock(mMutex);
- memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
-}
-
-void SurfaceTexture::computeCurrentTransformMatrix() {
- ST_LOGV("computeCurrentTransformMatrix");
-
- float xform[16];
- for (int i = 0; i < 16; i++) {
- xform[i] = mtxIdentity[i];
- }
- if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
- float result[16];
- mtxMul(result, xform, mtxFlipH);
- for (int i = 0; i < 16; i++) {
- xform[i] = result[i];
- }
- }
- if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
- float result[16];
- mtxMul(result, xform, mtxFlipV);
- for (int i = 0; i < 16; i++) {
- xform[i] = result[i];
- }
- }
- if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
- float result[16];
- mtxMul(result, xform, mtxRot90);
- for (int i = 0; i < 16; i++) {
- xform[i] = result[i];
- }
- }
-
- sp<GraphicBuffer>& buf(mCurrentTextureBuf);
- float tx, ty, sx, sy;
- if (!mCurrentCrop.isEmpty()) {
- // In order to prevent bilinear sampling at the of the crop rectangle we
- // may need to shrink it by 2 texels in each direction. Normally this
- // would just need to take 1/2 a texel off each end, but because the
- // chroma channels will likely be subsampled we need to chop off a whole
- // texel. This will cause artifacts if someone does nearest sampling
- // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
- // accomodate the bilinear and nearest sampling uses.
- //
- // If nearest sampling turns out to be a desirable usage of these
- // textures then we could add the ability to switch a SurfaceTexture to
- // nearest-mode. Preferably, however, the image producers (video
- // decoder, camera, etc.) would simply not use a crop rectangle (or at
- // least not tell the framework about it) so that the GPU can do the
- // correct edge behavior.
- int xshrink = 0, yshrink = 0;
- if (mCurrentCrop.left > 0) {
- tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
- xshrink++;
- } else {
- tx = 0.0f;
- }
- if (mCurrentCrop.right < int32_t(buf->getWidth())) {
- xshrink++;
- }
- if (mCurrentCrop.bottom < int32_t(buf->getHeight())) {
- ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
- float(buf->getHeight());
- yshrink++;
- } else {
- ty = 0.0f;
- }
- if (mCurrentCrop.top > 0) {
- yshrink++;
- }
- sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
- sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
- } else {
- tx = 0.0f;
- ty = 0.0f;
- sx = 1.0f;
- sy = 1.0f;
- }
- float crop[16] = {
- sx, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, 1, 0,
- tx, ty, 0, 1,
- };
-
- float mtxBeforeFlipV[16];
- mtxMul(mtxBeforeFlipV, crop, xform);
-
- // SurfaceFlinger expects the top of its window textures to be at a Y
- // coordinate of 0, so SurfaceTexture must behave the same way. We don't
- // want to expose this to applications, however, so we must add an
- // additional vertical flip to the transform after all the other transforms.
- mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
-}
-
-nsecs_t SurfaceTexture::getTimestamp() {
- ST_LOGV("getTimestamp");
- Mutex::Autolock lock(mMutex);
- return mCurrentTimestamp;
-}
-
-void SurfaceTexture::setFrameAvailableListener(
- const sp<FrameAvailableListener>& listener) {
- ST_LOGV("setFrameAvailableListener");
- Mutex::Autolock lock(mMutex);
- BufferQueue::setFrameAvailableListener(listener);
-}
-
-EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
- const sp<GraphicBuffer>& graphicBuffer) {
- EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
- EGLint attrs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE,
- };
- EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
- EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
- if (image == EGL_NO_IMAGE_KHR) {
- EGLint error = eglGetError();
- ST_LOGE("error creating EGLImage: %#x", error);
- }
- return image;
-}
-
-sp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentTextureBuf;
-}
-
-Rect SurfaceTexture::getCurrentCrop() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentCrop;
-}
-
-uint32_t SurfaceTexture::getCurrentTransform() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentTransform;
-}
-
-uint32_t SurfaceTexture::getCurrentScalingMode() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentScalingMode;
-}
-
-bool SurfaceTexture::isSynchronousMode() const {
- Mutex::Autolock lock(mMutex);
- return BufferQueue::isSynchronousMode();
-}
-
-void SurfaceTexture::abandon() {
- Mutex::Autolock lock(mMutex);
- mAbandoned = true;
- mCurrentTextureBuf.clear();
-
- // destroy all egl buffers
- for (int i =0; i < NUM_BUFFER_SLOTS; i++) {
- mEGLSlots[i].mGraphicBuffer = 0;
- if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mEGLSlots[i].mEglDisplay,
- mEGLSlots[i].mEglImage);
- mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
- mEGLSlots[i].mEglDisplay = EGL_NO_DISPLAY;
- }
- }
-
- // disconnect from the BufferQueue
- BufferQueue::consumerDisconnect();
-}
-
-void SurfaceTexture::setName(const String8& name) {
- Mutex::Autolock _l(mMutex);
- mName = name;
- BufferQueue::setConsumerName(name);
-}
-
-void SurfaceTexture::dump(String8& result) const
-{
- char buffer[1024];
- dump(result, "", buffer, 1024);
-}
-
-void SurfaceTexture::dump(String8& result, const char* prefix,
- char* buffer, size_t SIZE) const
-{
- Mutex::Autolock _l(mMutex);
- snprintf(buffer, SIZE, "%smTexName=%d\n", prefix, mTexName);
- result.append(buffer);
-
- snprintf(buffer, SIZE,
- "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
- ,prefix, mCurrentCrop.left,
- mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
- mCurrentTransform, mCurrentTexture
- );
- result.append(buffer);
-
-
- BufferQueue::dump(result, prefix, buffer, SIZE);
-}
-
-static void mtxMul(float out[16], const float a[16], const float b[16]) {
- out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
- out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
- out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
- out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
-
- out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
- out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
- out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
- out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
-
- out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
- out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
- out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
- out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
-
- out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
- out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
- out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
- out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
-}
-
-}; // namespace android
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
deleted file mode 100644
index f88dcaf..0000000
--- a/libs/gui/SurfaceTextureClient.cpp
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceTextureClient"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/SurfaceTextureClient.h>
-
-#include <private/gui/ComposerService.h>
-
-namespace android {
-
-SurfaceTextureClient::SurfaceTextureClient(
- const sp<ISurfaceTexture>& surfaceTexture)
-{
- SurfaceTextureClient::init();
- SurfaceTextureClient::setISurfaceTexture(surfaceTexture);
-}
-
-SurfaceTextureClient::SurfaceTextureClient() {
- SurfaceTextureClient::init();
-}
-
-SurfaceTextureClient::~SurfaceTextureClient() {
- if (mConnectedToCpu) {
- SurfaceTextureClient::disconnect(NATIVE_WINDOW_API_CPU);
- }
-}
-
-void SurfaceTextureClient::init() {
- // Initialize the ANativeWindow function pointers.
- ANativeWindow::setSwapInterval = hook_setSwapInterval;
- ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
- ANativeWindow::cancelBuffer = hook_cancelBuffer;
- ANativeWindow::lockBuffer = hook_lockBuffer;
- ANativeWindow::queueBuffer = hook_queueBuffer;
- ANativeWindow::query = hook_query;
- ANativeWindow::perform = hook_perform;
-
- const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
- const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
-
- mReqWidth = 0;
- mReqHeight = 0;
- mReqFormat = 0;
- mReqUsage = 0;
- mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
- mDefaultWidth = 0;
- mDefaultHeight = 0;
- mTransformHint = 0;
- mConnectedToCpu = false;
-}
-
-void SurfaceTextureClient::setISurfaceTexture(
- const sp<ISurfaceTexture>& surfaceTexture)
-{
- mSurfaceTexture = surfaceTexture;
-}
-
-sp<ISurfaceTexture> SurfaceTextureClient::getISurfaceTexture() const {
- return mSurfaceTexture;
-}
-
-int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interval) {
- SurfaceTextureClient* c = getSelf(window);
- return c->setSwapInterval(interval);
-}
-
-int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window,
- ANativeWindowBuffer** buffer) {
- SurfaceTextureClient* c = getSelf(window);
- return c->dequeueBuffer(buffer);
-}
-
-int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window,
- ANativeWindowBuffer* buffer) {
- SurfaceTextureClient* c = getSelf(window);
- return c->cancelBuffer(buffer);
-}
-
-int SurfaceTextureClient::hook_lockBuffer(ANativeWindow* window,
- ANativeWindowBuffer* buffer) {
- SurfaceTextureClient* c = getSelf(window);
- return c->lockBuffer(buffer);
-}
-
-int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window,
- ANativeWindowBuffer* buffer) {
- SurfaceTextureClient* c = getSelf(window);
- return c->queueBuffer(buffer);
-}
-
-int SurfaceTextureClient::hook_query(const ANativeWindow* window,
- int what, int* value) {
- const SurfaceTextureClient* c = getSelf(window);
- return c->query(what, value);
-}
-
-int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...) {
- va_list args;
- va_start(args, operation);
- SurfaceTextureClient* c = getSelf(window);
- return c->perform(operation, args);
-}
-
-int SurfaceTextureClient::setSwapInterval(int interval) {
- ATRACE_CALL();
- // EGL specification states:
- // interval is silently clamped to minimum and maximum implementation
- // dependent values before being stored.
- // Although we don't have to, we apply the same logic here.
-
- if (interval < minSwapInterval)
- interval = minSwapInterval;
-
- if (interval > maxSwapInterval)
- interval = maxSwapInterval;
-
- status_t res = mSurfaceTexture->setSynchronousMode(interval ? true : false);
-
- return res;
-}
-
-int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::dequeueBuffer");
- Mutex::Autolock lock(mMutex);
- int buf = -1;
- status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,
- mReqFormat, mReqUsage);
- if (result < 0) {
- ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
- "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
- result);
- return result;
- }
- sp<GraphicBuffer>& gbuf(mSlots[buf]);
- if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
- freeAllBuffers();
- }
-
- if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- result = mSurfaceTexture->requestBuffer(buf, &gbuf);
- if (result != NO_ERROR) {
- ALOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
- result);
- return result;
- }
- }
- *buffer = gbuf.get();
- return OK;
-}
-
-int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::cancelBuffer");
- Mutex::Autolock lock(mMutex);
- int i = getSlotFromBufferLocked(buffer);
- if (i < 0) {
- return i;
- }
- mSurfaceTexture->cancelBuffer(i);
- return OK;
-}
-
-int SurfaceTextureClient::getSlotFromBufferLocked(
- android_native_buffer_t* buffer) const {
- bool dumpedState = false;
- for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- // XXX: Dump the slots whenever we hit a NULL entry while searching for
- // a buffer.
- if (mSlots[i] == NULL) {
- if (!dumpedState) {
- ALOGD("getSlotFromBufferLocked: encountered NULL buffer in slot %d "
- "looking for buffer %p", i, buffer->handle);
- for (int j = 0; j < NUM_BUFFER_SLOTS; j++) {
- if (mSlots[j] == NULL) {
- ALOGD("getSlotFromBufferLocked: %02d: NULL", j);
- } else {
- ALOGD("getSlotFromBufferLocked: %02d: %p", j, mSlots[j]->handle);
- }
- }
- dumpedState = true;
- }
- }
-
- if (mSlots[i] != NULL && mSlots[i]->handle == buffer->handle) {
- return i;
- }
- }
- ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
- return BAD_VALUE;
-}
-
-int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
- ALOGV("SurfaceTextureClient::lockBuffer");
- Mutex::Autolock lock(mMutex);
- return OK;
-}
-
-int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::queueBuffer");
- Mutex::Autolock lock(mMutex);
- int64_t timestamp;
- if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
- timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
- timestamp / 1000000.f);
- } else {
- timestamp = mTimestamp;
- }
- int i = getSlotFromBufferLocked(buffer);
- if (i < 0) {
- return i;
- }
- status_t err = mSurfaceTexture->queueBuffer(i, timestamp,
- &mDefaultWidth, &mDefaultHeight, &mTransformHint);
- if (err != OK) {
- ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
- }
- return err;
-}
-
-int SurfaceTextureClient::query(int what, int* value) const {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::query");
- { // scope for the lock
- Mutex::Autolock lock(mMutex);
- switch (what) {
- case NATIVE_WINDOW_FORMAT:
- if (mReqFormat) {
- *value = mReqFormat;
- return NO_ERROR;
- }
- break;
- case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- {
- sp<ISurfaceComposer> composer(
- ComposerService::getComposerService());
- if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
- *value = 1;
- } else {
- *value = 0;
- }
- }
- return NO_ERROR;
- case NATIVE_WINDOW_CONCRETE_TYPE:
- *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
- return NO_ERROR;
- case NATIVE_WINDOW_DEFAULT_WIDTH:
- *value = mDefaultWidth;
- return NO_ERROR;
- case NATIVE_WINDOW_DEFAULT_HEIGHT:
- *value = mDefaultHeight;
- return NO_ERROR;
- case NATIVE_WINDOW_TRANSFORM_HINT:
- *value = mTransformHint;
- return NO_ERROR;
- }
- }
- return mSurfaceTexture->query(what, value);
-}
-
-int SurfaceTextureClient::perform(int operation, va_list args)
-{
- int res = NO_ERROR;
- switch (operation) {
- case NATIVE_WINDOW_CONNECT:
- // deprecated. must return NO_ERROR.
- break;
- case NATIVE_WINDOW_DISCONNECT:
- // deprecated. must return NO_ERROR.
- break;
- case NATIVE_WINDOW_SET_USAGE:
- res = dispatchSetUsage(args);
- break;
- case NATIVE_WINDOW_SET_CROP:
- res = dispatchSetCrop(args);
- break;
- case NATIVE_WINDOW_SET_BUFFER_COUNT:
- res = dispatchSetBufferCount(args);
- break;
- case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
- res = dispatchSetBuffersGeometry(args);
- break;
- case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
- res = dispatchSetBuffersTransform(args);
- break;
- case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
- res = dispatchSetBuffersTimestamp(args);
- break;
- case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
- res = dispatchSetBuffersDimensions(args);
- break;
- case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
- res = dispatchSetBuffersFormat(args);
- break;
- case NATIVE_WINDOW_LOCK:
- res = dispatchLock(args);
- break;
- case NATIVE_WINDOW_UNLOCK_AND_POST:
- res = dispatchUnlockAndPost(args);
- break;
- case NATIVE_WINDOW_SET_SCALING_MODE:
- res = dispatchSetScalingMode(args);
- break;
- case NATIVE_WINDOW_API_CONNECT:
- res = dispatchConnect(args);
- break;
- case NATIVE_WINDOW_API_DISCONNECT:
- res = dispatchDisconnect(args);
- break;
- default:
- res = NAME_NOT_FOUND;
- break;
- }
- return res;
-}
-
-int SurfaceTextureClient::dispatchConnect(va_list args) {
- int api = va_arg(args, int);
- return connect(api);
-}
-
-int SurfaceTextureClient::dispatchDisconnect(va_list args) {
- int api = va_arg(args, int);
- return disconnect(api);
-}
-
-int SurfaceTextureClient::dispatchSetUsage(va_list args) {
- int usage = va_arg(args, int);
- return setUsage(usage);
-}
-
-int SurfaceTextureClient::dispatchSetCrop(va_list args) {
- android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
- return setCrop(reinterpret_cast<Rect const*>(rect));
-}
-
-int SurfaceTextureClient::dispatchSetBufferCount(va_list args) {
- size_t bufferCount = va_arg(args, size_t);
- return setBufferCount(bufferCount);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- int f = va_arg(args, int);
- int err = setBuffersDimensions(w, h);
- if (err != 0) {
- return err;
- }
- return setBuffersFormat(f);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- return setBuffersDimensions(w, h);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) {
- int f = va_arg(args, int);
- return setBuffersFormat(f);
-}
-
-int SurfaceTextureClient::dispatchSetScalingMode(va_list args) {
- int m = va_arg(args, int);
- return setScalingMode(m);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) {
- int transform = va_arg(args, int);
- return setBuffersTransform(transform);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
- int64_t timestamp = va_arg(args, int64_t);
- return setBuffersTimestamp(timestamp);
-}
-
-int SurfaceTextureClient::dispatchLock(va_list args) {
- ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
- ARect* inOutDirtyBounds = va_arg(args, ARect*);
- return lock(outBuffer, inOutDirtyBounds);
-}
-
-int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
- return unlockAndPost();
-}
-
-
-int SurfaceTextureClient::connect(int api) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::connect");
- Mutex::Autolock lock(mMutex);
- int err = mSurfaceTexture->connect(api,
- &mDefaultWidth, &mDefaultHeight, &mTransformHint);
- if (!err && api == NATIVE_WINDOW_API_CPU) {
- mConnectedToCpu = true;
- }
- return err;
-}
-
-int SurfaceTextureClient::disconnect(int api) {
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::disconnect");
- Mutex::Autolock lock(mMutex);
- freeAllBuffers();
- int err = mSurfaceTexture->disconnect(api);
- if (!err) {
- mReqFormat = 0;
- mReqWidth = 0;
- mReqHeight = 0;
- mReqUsage = 0;
- if (api == NATIVE_WINDOW_API_CPU) {
- mConnectedToCpu = false;
- }
- }
- return err;
-}
-
-int SurfaceTextureClient::setUsage(uint32_t reqUsage)
-{
- ALOGV("SurfaceTextureClient::setUsage");
- Mutex::Autolock lock(mMutex);
- mReqUsage = reqUsage;
- return OK;
-}
-
-int SurfaceTextureClient::setCrop(Rect const* rect)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setCrop");
- Mutex::Autolock lock(mMutex);
-
- Rect realRect;
- if (rect == NULL || rect->isEmpty()) {
- realRect = Rect(0, 0);
- } else {
- realRect = *rect;
- }
-
- status_t err = mSurfaceTexture->setCrop(*rect);
- ALOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
-
- return err;
-}
-
-int SurfaceTextureClient::setBufferCount(int bufferCount)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setBufferCount");
- Mutex::Autolock lock(mMutex);
-
- status_t err = mSurfaceTexture->setBufferCount(bufferCount);
- ALOGE_IF(err, "ISurfaceTexture::setBufferCount(%d) returned %s",
- bufferCount, strerror(-err));
-
- if (err == NO_ERROR) {
- freeAllBuffers();
- }
-
- return err;
-}
-
-int SurfaceTextureClient::setBuffersDimensions(int w, int h)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setBuffersDimensions");
- Mutex::Autolock lock(mMutex);
-
- if (w<0 || h<0)
- return BAD_VALUE;
-
- if ((w && !h) || (!w && h))
- return BAD_VALUE;
-
- mReqWidth = w;
- mReqHeight = h;
-
- status_t err = mSurfaceTexture->setCrop(Rect(0, 0));
- ALOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
-
- return err;
-}
-
-int SurfaceTextureClient::setBuffersFormat(int format)
-{
- ALOGV("SurfaceTextureClient::setBuffersFormat");
- Mutex::Autolock lock(mMutex);
-
- if (format<0)
- return BAD_VALUE;
-
- mReqFormat = format;
-
- return NO_ERROR;
-}
-
-int SurfaceTextureClient::setScalingMode(int mode)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
- Mutex::Autolock lock(mMutex);
- // mode is validated on the server
- status_t err = mSurfaceTexture->setScalingMode(mode);
- ALOGE_IF(err, "ISurfaceTexture::setScalingMode(%d) returned %s",
- mode, strerror(-err));
-
- return err;
-}
-
-int SurfaceTextureClient::setBuffersTransform(int transform)
-{
- ATRACE_CALL();
- ALOGV("SurfaceTextureClient::setBuffersTransform");
- Mutex::Autolock lock(mMutex);
- status_t err = mSurfaceTexture->setTransform(transform);
- return err;
-}
-
-int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
-{
- ALOGV("SurfaceTextureClient::setBuffersTimestamp");
- Mutex::Autolock lock(mMutex);
- mTimestamp = timestamp;
- return NO_ERROR;
-}
-
-void SurfaceTextureClient::freeAllBuffers() {
- for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- mSlots[i] = 0;
- }
-}
-
-// ----------------------------------------------------------------------
-// the lock/unlock APIs must be used from the same thread
-
-static status_t copyBlt(
- const sp<GraphicBuffer>& dst,
- const sp<GraphicBuffer>& src,
- const Region& reg)
-{
- // src and dst with, height and format must be identical. no verification
- // is done here.
- status_t err;
- uint8_t const * src_bits = NULL;
- err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
- ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
-
- uint8_t* dst_bits = NULL;
- err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
- ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
-
- Region::const_iterator head(reg.begin());
- Region::const_iterator tail(reg.end());
- if (head != tail && src_bits && dst_bits) {
- const size_t bpp = bytesPerPixel(src->format);
- const size_t dbpr = dst->stride * bpp;
- const size_t sbpr = src->stride * bpp;
-
- while (head != tail) {
- const Rect& r(*head++);
- ssize_t h = r.height();
- if (h <= 0) continue;
- size_t size = r.width() * bpp;
- uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
- uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
- if (dbpr==sbpr && size==sbpr) {
- size *= h;
- h = 1;
- }
- do {
- memcpy(d, s, size);
- d += dbpr;
- s += sbpr;
- } while (--h > 0);
- }
- }
-
- if (src_bits)
- src->unlock();
-
- if (dst_bits)
- dst->unlock();
-
- return err;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t SurfaceTextureClient::lock(
- ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
-{
- if (mLockedBuffer != 0) {
- ALOGE("Surface::lock failed, already locked");
- return INVALID_OPERATION;
- }
-
- if (!mConnectedToCpu) {
- int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
- if (err) {
- return err;
- }
- // we're intending to do software rendering from this point
- setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
- }
-
- ANativeWindowBuffer* out;
- status_t err = dequeueBuffer(&out);
- ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
- if (err == NO_ERROR) {
- sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
- err = lockBuffer(backBuffer.get());
- ALOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
- backBuffer->handle, strerror(-err));
- if (err == NO_ERROR) {
- const Rect bounds(backBuffer->width, backBuffer->height);
-
- Region newDirtyRegion;
- if (inOutDirtyBounds) {
- newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
- newDirtyRegion.andSelf(bounds);
- } else {
- newDirtyRegion.set(bounds);
- }
-
- // figure out if we can copy the frontbuffer back
- const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
- const bool canCopyBack = (frontBuffer != 0 &&
- backBuffer->width == frontBuffer->width &&
- backBuffer->height == frontBuffer->height &&
- backBuffer->format == frontBuffer->format);
-
- if (canCopyBack) {
- // copy the area that is invalid and not repainted this round
- const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
- if (!copyback.isEmpty())
- copyBlt(backBuffer, frontBuffer, copyback);
- } else {
- // if we can't copy-back anything, modify the user's dirty
- // region to make sure they redraw the whole buffer
- newDirtyRegion.set(bounds);
- }
-
- // keep track of the are of the buffer that is "clean"
- // (ie: that will be redrawn)
- mOldDirtyRegion = newDirtyRegion;
-
- if (inOutDirtyBounds) {
- *inOutDirtyBounds = newDirtyRegion.getBounds();
- }
-
- void* vaddr;
- status_t res = backBuffer->lock(
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- newDirtyRegion.bounds(), &vaddr);
-
- ALOGW_IF(res, "failed locking buffer (handle = %p)",
- backBuffer->handle);
-
- mLockedBuffer = backBuffer;
- outBuffer->width = backBuffer->width;
- outBuffer->height = backBuffer->height;
- outBuffer->stride = backBuffer->stride;
- outBuffer->format = backBuffer->format;
- outBuffer->bits = vaddr;
- }
- }
- return err;
-}
-
-status_t SurfaceTextureClient::unlockAndPost()
-{
- if (mLockedBuffer == 0) {
- ALOGE("Surface::unlockAndPost failed, no locked buffer");
- return INVALID_OPERATION;
- }
-
- status_t err = mLockedBuffer->unlock();
- ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
-
- err = queueBuffer(mLockedBuffer.get());
- ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
- mLockedBuffer->handle, strerror(-err));
-
- mPostedBuffer = mLockedBuffer;
- mLockedBuffer = 0;
- return err;
-}
-
-}; // namespace android
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
deleted file mode 100644
index 55ac133..0000000
--- a/libs/gui/tests/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# Build the unit tests,
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := SurfaceTexture_test
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
- Surface_test.cpp \
- SurfaceTextureClient_test.cpp \
- SurfaceTexture_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libEGL \
- libGLESv2 \
- libandroid \
- libbinder \
- libcutils \
- libgui \
- libstlport \
- libui \
- libutils \
-
-LOCAL_C_INCLUDES := \
- bionic \
- bionic/libstdc++/include \
- external/gtest/include \
- external/stlport/stlport \
-
-# Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-# to integrate with auto-test framework.
-include $(BUILD_NATIVE_TEST)
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
deleted file mode 100644
index c1a3c98..0000000
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <EGL/egl.h>
-#include <gtest/gtest.h>
-#include <gui/SurfaceTextureClient.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class SurfaceTextureClientTest : public ::testing::Test {
-protected:
- SurfaceTextureClientTest():
- mEglDisplay(EGL_NO_DISPLAY),
- mEglSurface(EGL_NO_SURFACE),
- mEglContext(EGL_NO_CONTEXT) {
- }
-
- virtual void SetUp() {
- mST = new SurfaceTexture(123);
- mSTC = new SurfaceTextureClient(mST);
- mANW = mSTC;
-
- // We need a valid GL context so we can test updateTexImage()
- // This initializes EGL and create a dummy GL context with a
- // pbuffer render target.
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
- EGLint majorVersion, minorVersion;
- EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLConfig myConfig;
- EGLint numConfigs = 0;
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(),
- &myConfig, 1, &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLint pbufferAttribs[] = {
- EGL_WIDTH, 16,
- EGL_HEIGHT, 16,
- EGL_NONE };
- mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig, pbufferAttribs);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
- mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 0);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- }
-
- virtual void TearDown() {
- mST.clear();
- mSTC.clear();
- mANW.clear();
-
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(mEglDisplay, mEglContext);
- eglDestroySurface(mEglDisplay, mEglSurface);
- eglTerminate(mEglDisplay);
- }
-
- virtual EGLint const* getConfigAttribs() {
- static EGLint sDefaultConfigAttribs[] = {
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- EGL_NONE
- };
-
- return sDefaultConfigAttribs;
- }
-
- sp<SurfaceTexture> mST;
- sp<SurfaceTextureClient> mSTC;
- sp<ANativeWindow> mANW;
-
- EGLDisplay mEglDisplay;
- EGLSurface mEglSurface;
- EGLContext mEglContext;
-};
-
-TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
- sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
- ASSERT_TRUE(ist != NULL);
-}
-
-TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
- int result = -123;
- int err = mANW->query(mANW.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
- &result);
- EXPECT_EQ(NO_ERROR, err);
- EXPECT_EQ(0, result);
-}
-
-TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
- int result = -123;
- int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
- EXPECT_EQ(NO_ERROR, err);
- EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
-}
-
-TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
- EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_DISPLAY, dpy);
-
- EGLint majorVersion;
- EGLint minorVersion;
- EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLConfig myConfig = {0};
- EGLint numConfigs = 0;
- EGLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 16,
- EGL_STENCIL_SIZE, 8,
- EGL_NONE };
- EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
- &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, mANW.get(),
- NULL);
- EXPECT_NE(EGL_NO_SURFACE, eglSurface);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
- eglTerminate(dpy);
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, 0, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, -1, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, -1));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 8, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 8, 0, 0));
-}
-
-TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
- ANativeWindowBuffer* buf;
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(1, buf->width);
- EXPECT_EQ(1, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(16, buf->width);
- EXPECT_EQ(8, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(1, buf->width);
- EXPECT_EQ(1, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(16, buf->width);
- EXPECT_EQ(8, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(16, buf->width);
- EXPECT_EQ(8, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(1, buf->width);
- EXPECT_EQ(1, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(1, buf->width);
- EXPECT_EQ(1, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(16, buf->width);
- EXPECT_EQ(8, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
- sp<SurfaceTexture> st(mST);
- ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
- EXPECT_EQ(16, buf->width);
- EXPECT_EQ(8, buf->height);
- EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
- ANativeWindowBuffer* buf[2];
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_NE(buf[0], buf[1]);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
- EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_EQ(16, buf[0]->width);
- EXPECT_EQ(16, buf[1]->width);
- EXPECT_EQ(8, buf[0]->height);
- EXPECT_EQ(8, buf[1]->height);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
- ANativeWindowBuffer* buf[2];
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_EQ(16, buf[0]->width);
- EXPECT_EQ(16, buf[1]->width);
- EXPECT_EQ(8, buf[0]->height);
- EXPECT_EQ(8, buf[1]->height);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_EQ(12, buf[0]->width);
- EXPECT_EQ(12, buf[1]->width);
- EXPECT_EQ(24, buf[0]->height);
- EXPECT_EQ(24, buf[1]->height);
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(false));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(OK, mST->updateTexImage());
-
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
-
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(OK, mST->updateTexImage());
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_NE(buf[1], buf[2]);
- EXPECT_NE(buf[2], buf[0]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_NE(buf[1], buf[2]);
- EXPECT_NE(buf[2], buf[0]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_NE(buf[0], buf[1]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
- EXPECT_NE(buf[1], buf[2]);
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
-}
-
-// XXX: We currently have no hardware that properly handles dequeuing the
-// buffer that is currently bound to the texture.
-TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
- android_native_buffer_t* buf[3];
- android_native_buffer_t* firstBuf;
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &firstBuf));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf));
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf);
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
- EXPECT_NE(buf[0], buf[1]);
- EXPECT_NE(buf[1], buf[2]);
- EXPECT_NE(buf[2], buf[0]);
- EXPECT_EQ(firstBuf, buf[2]);
-}
-
-TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
-
- // We should be able to dequeue all the buffers before we've queued mANWy.
- EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
-
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
-
- EXPECT_EQ(OK, mST->updateTexImage());
- EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
-
- EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
-
- // Once we've queued a buffer, however we should not be able to dequeue more
- // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
- EXPECT_EQ(-EBUSY, mANW->dequeueBuffer(mANW.get(), &buf[1]));
-
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
-}
-
-// XXX: This is not expected to pass until the synchronization hacks are removed
-// from the SurfaceTexture class.
-TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
- class MyThread : public Thread {
- sp<SurfaceTexture> mST;
- EGLContext ctx;
- EGLSurface sur;
- EGLDisplay dpy;
- bool mBufferRetired;
- Mutex mLock;
- virtual bool threadLoop() {
- eglMakeCurrent(dpy, sur, sur, ctx);
- usleep(20000);
- Mutex::Autolock _l(mLock);
- mST->updateTexImage();
- mBufferRetired = true;
- eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- return false;
- }
- public:
- MyThread(const sp<SurfaceTexture>& mST)
- : mST(mST), mBufferRetired(false) {
- ctx = eglGetCurrentContext();
- sur = eglGetCurrentSurface(EGL_DRAW);
- dpy = eglGetCurrentDisplay();
- eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- ~MyThread() {
- eglMakeCurrent(dpy, sur, sur, ctx);
- }
- void bufferDequeued() {
- Mutex::Autolock _l(mLock);
- EXPECT_EQ(true, mBufferRetired);
- }
- };
-
- android_native_buffer_t* buf[3];
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
- // dequeue/queue/update so we have a current buffer
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- mST->updateTexImage();
-
- MyThread* thread = new MyThread(mST);
- sp<Thread> threadBase(thread);
-
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- thread->run();
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
- //ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
- //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
- thread->bufferDequeued();
- thread->requestExitAndWait();
-}
-
-TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
- android_native_buffer_t* buf[3];
- float mtx[16] = {};
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mST->updateTexImage());
- mST->getTransformMatrix(mtx);
-
- EXPECT_EQ(1.f, mtx[0]);
- EXPECT_EQ(0.f, mtx[1]);
- EXPECT_EQ(0.f, mtx[2]);
- EXPECT_EQ(0.f, mtx[3]);
-
- EXPECT_EQ(0.f, mtx[4]);
- EXPECT_EQ(-1.f, mtx[5]);
- EXPECT_EQ(0.f, mtx[6]);
- EXPECT_EQ(0.f, mtx[7]);
-
- EXPECT_EQ(0.f, mtx[8]);
- EXPECT_EQ(0.f, mtx[9]);
- EXPECT_EQ(1.f, mtx[10]);
- EXPECT_EQ(0.f, mtx[11]);
-
- EXPECT_EQ(0.f, mtx[12]);
- EXPECT_EQ(1.f, mtx[13]);
- EXPECT_EQ(0.f, mtx[14]);
- EXPECT_EQ(1.f, mtx[15]);
-}
-
-TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
- android_native_buffer_t* buf[3];
- float mtx[16] = {};
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mST->updateTexImage());
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
- mST->getTransformMatrix(mtx);
-
- EXPECT_EQ(1.f, mtx[0]);
- EXPECT_EQ(0.f, mtx[1]);
- EXPECT_EQ(0.f, mtx[2]);
- EXPECT_EQ(0.f, mtx[3]);
-
- EXPECT_EQ(0.f, mtx[4]);
- EXPECT_EQ(-1.f, mtx[5]);
- EXPECT_EQ(0.f, mtx[6]);
- EXPECT_EQ(0.f, mtx[7]);
-
- EXPECT_EQ(0.f, mtx[8]);
- EXPECT_EQ(0.f, mtx[9]);
- EXPECT_EQ(1.f, mtx[10]);
- EXPECT_EQ(0.f, mtx[11]);
-
- EXPECT_EQ(0.f, mtx[12]);
- EXPECT_EQ(1.f, mtx[13]);
- EXPECT_EQ(0.f, mtx[14]);
- EXPECT_EQ(1.f, mtx[15]);
-}
-
-TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
- android_native_buffer_t* buf[3];
- float mtx[16] = {};
- android_native_rect_t crop;
- crop.left = 0;
- crop.top = 0;
- crop.right = 5;
- crop.bottom = 5;
-
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
- ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
- ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
- ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
- ASSERT_EQ(OK, mST->updateTexImage());
- ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
- mST->getTransformMatrix(mtx);
-
- // This accounts for the 1 texel shrink for each edge that's included in the
- // transform matrix to avoid texturing outside the crop region.
- EXPECT_EQ(.5f, mtx[0]);
- EXPECT_EQ(0.f, mtx[1]);
- EXPECT_EQ(0.f, mtx[2]);
- EXPECT_EQ(0.f, mtx[3]);
-
- EXPECT_EQ(0.f, mtx[4]);
- EXPECT_EQ(-.5f, mtx[5]);
- EXPECT_EQ(0.f, mtx[6]);
- EXPECT_EQ(0.f, mtx[7]);
-
- EXPECT_EQ(0.f, mtx[8]);
- EXPECT_EQ(0.f, mtx[9]);
- EXPECT_EQ(1.f, mtx[10]);
- EXPECT_EQ(0.f, mtx[11]);
-
- EXPECT_EQ(0.f, mtx[12]);
- EXPECT_EQ(.5f, mtx[13]);
- EXPECT_EQ(0.f, mtx[14]);
- EXPECT_EQ(1.f, mtx[15]);
-}
-
-// This test verifies that the buffer format can be queried immediately after
-// it is set.
-TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
- sp<ANativeWindow> anw(mSTC);
- int fmts[] = {
- // RGBA_8888 should not come first, as it's the default
- HAL_PIXEL_FORMAT_RGBX_8888,
- HAL_PIXEL_FORMAT_RGBA_8888,
- HAL_PIXEL_FORMAT_RGB_888,
- HAL_PIXEL_FORMAT_RGB_565,
- HAL_PIXEL_FORMAT_BGRA_8888,
- HAL_PIXEL_FORMAT_RGBA_5551,
- HAL_PIXEL_FORMAT_RGBA_4444,
- HAL_PIXEL_FORMAT_YV12,
- };
-
- const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
- for (int i = 0; i < numFmts; i++) {
- int fmt = -1;
- ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
- ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
- EXPECT_EQ(fmts[i], fmt);
- }
-}
-
-class MultiSurfaceTextureClientTest : public ::testing::Test {
-
-public:
- MultiSurfaceTextureClientTest() :
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT) {
- for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
- mEglSurfaces[i] = EGL_NO_CONTEXT;
- }
- }
-
-protected:
-
- enum { NUM_SURFACE_TEXTURES = 32 };
-
- virtual void SetUp() {
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
- EGLint majorVersion, minorVersion;
- EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLConfig myConfig;
- EGLint numConfigs = 0;
- EGLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_NONE
- };
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
- &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
- 0);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
- for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
- sp<SurfaceTexture> st(new SurfaceTexture(i));
- sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
- mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
- static_cast<ANativeWindow*>(stc.get()), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
- }
- }
-
- virtual void TearDown() {
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
-
- for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
- if (mEglSurfaces[i] != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
- }
- }
-
- if (mEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mEglContext);
- }
-
- if (mEglDisplay != EGL_NO_DISPLAY) {
- eglTerminate(mEglDisplay);
- }
- }
-
- EGLDisplay mEglDisplay;
- EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
- EGLContext mEglContext;
-};
-
-// XXX: This test is disabled because it causes a hang on some devices. See bug
-// 5015672.
-TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
- for (int iter = 0; iter < 8; iter++) {
- for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
- eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
- mEglContext);
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
- }
- }
-}
-
-} // namespace android
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
deleted file mode 100644
index 8c6defe..0000000
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ /dev/null
@@ -1,1730 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceTexture_test"
-//#define LOG_NDEBUG 0
-
-#include <gtest/gtest.h>
-#include <gui/SurfaceTexture.h>
-#include <gui/SurfaceTextureClient.h>
-#include <ui/GraphicBuffer.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <gui/ISurfaceComposer.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <ui/FramebufferNativeWindow.h>
-
-namespace android {
-
-class GLTest : public ::testing::Test {
-protected:
-
- GLTest():
- mEglDisplay(EGL_NO_DISPLAY),
- mEglSurface(EGL_NO_SURFACE),
- mEglContext(EGL_NO_CONTEXT) {
- }
-
- virtual void SetUp() {
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
- EGLint majorVersion;
- EGLint minorVersion;
- EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- RecordProperty("EglVersionMajor", majorVersion);
- RecordProperty("EglVersionMajor", minorVersion);
-
- EGLint numConfigs = 0;
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
- 1, &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
- if (displaySecsEnv != NULL) {
- mDisplaySecs = atoi(displaySecsEnv);
- if (mDisplaySecs < 0) {
- mDisplaySecs = 0;
- }
- } else {
- mDisplaySecs = 0;
- }
-
- if (mDisplaySecs > 0) {
- mComposerClient = new SurfaceComposerClient;
- ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
- mSurfaceControl = mComposerClient->createSurface(
- String8("Test Surface"), 0,
- getSurfaceWidth(), getSurfaceHeight(),
- PIXEL_FORMAT_RGB_888, 0);
-
- ASSERT_TRUE(mSurfaceControl != NULL);
- ASSERT_TRUE(mSurfaceControl->isValid());
-
- SurfaceComposerClient::openGlobalTransaction();
- ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
- ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
- SurfaceComposerClient::closeGlobalTransaction();
-
- sp<ANativeWindow> window = mSurfaceControl->getSurface();
- mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
- window.get(), NULL);
- } else {
- EGLint pbufferAttribs[] = {
- EGL_WIDTH, getSurfaceWidth(),
- EGL_HEIGHT, getSurfaceHeight(),
- EGL_NONE };
-
- mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
- pbufferAttribs);
- }
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
- mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
- getContextAttribs());
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLint w, h;
- EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- RecordProperty("EglSurfaceWidth", w);
- RecordProperty("EglSurfaceHeight", h);
-
- glViewport(0, 0, w, h);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- }
-
- virtual void TearDown() {
- // Display the result
- if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
- eglSwapBuffers(mEglDisplay, mEglSurface);
- sleep(mDisplaySecs);
- }
-
- if (mComposerClient != NULL) {
- mComposerClient->dispose();
- }
- if (mEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mEglContext);
- }
- if (mEglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mEglSurface);
- }
- if (mEglDisplay != EGL_NO_DISPLAY) {
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- eglTerminate(mEglDisplay);
- }
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- }
-
- virtual EGLint const* getConfigAttribs() {
- static EGLint sDefaultConfigAttribs[] = {
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 16,
- EGL_STENCIL_SIZE, 8,
- EGL_NONE };
-
- return sDefaultConfigAttribs;
- }
-
- virtual EGLint const* getContextAttribs() {
- static EGLint sDefaultContextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE };
-
- return sDefaultContextAttribs;
- }
-
- virtual EGLint getSurfaceWidth() {
- return 512;
- }
-
- virtual EGLint getSurfaceHeight() {
- return 512;
- }
-
- void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
- GLuint shader = glCreateShader(shaderType);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- if (shader) {
- glShaderSource(shader, 1, &pSource, NULL);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glCompileShader(shader);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- GLint compiled = 0;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- if (!compiled) {
- GLint infoLen = 0;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- if (infoLen) {
- char* buf = (char*) malloc(infoLen);
- if (buf) {
- glGetShaderInfoLog(shader, infoLen, NULL, buf);
- printf("Shader compile log:\n%s\n", buf);
- free(buf);
- FAIL();
- }
- } else {
- char* buf = (char*) malloc(0x1000);
- if (buf) {
- glGetShaderInfoLog(shader, 0x1000, NULL, buf);
- printf("Shader compile log:\n%s\n", buf);
- free(buf);
- FAIL();
- }
- }
- glDeleteShader(shader);
- shader = 0;
- }
- }
- ASSERT_TRUE(shader != 0);
- *outShader = shader;
- }
-
- void createProgram(const char* pVertexSource, const char* pFragmentSource,
- GLuint* outPgm) {
- GLuint vertexShader, fragmentShader;
- {
- SCOPED_TRACE("compiling vertex shader");
- loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
- if (HasFatalFailure()) {
- return;
- }
- }
- {
- SCOPED_TRACE("compiling fragment shader");
- loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
- if (HasFatalFailure()) {
- return;
- }
- }
-
- GLuint program = glCreateProgram();
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- if (program) {
- glAttachShader(program, vertexShader);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glAttachShader(program, fragmentShader);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glLinkProgram(program);
- GLint linkStatus = GL_FALSE;
- glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
- if (linkStatus != GL_TRUE) {
- GLint bufLength = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
- if (bufLength) {
- char* buf = (char*) malloc(bufLength);
- if (buf) {
- glGetProgramInfoLog(program, bufLength, NULL, buf);
- printf("Program link log:\n%s\n", buf);
- free(buf);
- FAIL();
- }
- }
- glDeleteProgram(program);
- program = 0;
- }
- }
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- ASSERT_TRUE(program != 0);
- *outPgm = program;
- }
-
- static int abs(int value) {
- return value > 0 ? value : -value;
- }
-
- ::testing::AssertionResult checkPixel(int x, int y, int r,
- int g, int b, int a, int tolerance=2) {
- GLubyte pixel[4];
- String8 msg;
- glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
- GLenum err = glGetError();
- if (err != GL_NO_ERROR) {
- msg += String8::format("error reading pixel: %#x", err);
- while ((err = glGetError()) != GL_NO_ERROR) {
- msg += String8::format(", %#x", err);
- }
- fprintf(stderr, "pixel check failure: %s\n", msg.string());
- return ::testing::AssertionFailure(
- ::testing::Message(msg.string()));
- }
- if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
- msg += String8::format("r(%d isn't %d)", pixel[0], r);
- }
- if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
- if (!msg.isEmpty()) {
- msg += " ";
- }
- msg += String8::format("g(%d isn't %d)", pixel[1], g);
- }
- if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
- if (!msg.isEmpty()) {
- msg += " ";
- }
- msg += String8::format("b(%d isn't %d)", pixel[2], b);
- }
- if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
- if (!msg.isEmpty()) {
- msg += " ";
- }
- msg += String8::format("a(%d isn't %d)", pixel[3], a);
- }
- if (!msg.isEmpty()) {
- fprintf(stderr, "pixel check failure: %s\n", msg.string());
- return ::testing::AssertionFailure(
- ::testing::Message(msg.string()));
- } else {
- return ::testing::AssertionSuccess();
- }
- }
-
- int mDisplaySecs;
- sp<SurfaceComposerClient> mComposerClient;
- sp<SurfaceControl> mSurfaceControl;
-
- EGLDisplay mEglDisplay;
- EGLSurface mEglSurface;
- EGLContext mEglContext;
- EGLConfig mGlConfig;
-};
-
-// XXX: Code above this point should live elsewhere
-
-class SurfaceTextureGLTest : public GLTest {
-protected:
- enum { TEX_ID = 123 };
-
- virtual void SetUp() {
- GLTest::SetUp();
- mST = new SurfaceTexture(TEX_ID);
- mSTC = new SurfaceTextureClient(mST);
- mANW = mSTC;
-
- const char vsrc[] =
- "attribute vec4 vPosition;\n"
- "varying vec2 texCoords;\n"
- "uniform mat4 texMatrix;\n"
- "void main() {\n"
- " vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
- " texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
- " gl_Position = vPosition;\n"
- "}\n";
-
- const char fsrc[] =
- "#extension GL_OES_EGL_image_external : require\n"
- "precision mediump float;\n"
- "uniform samplerExternalOES texSampler;\n"
- "varying vec2 texCoords;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texSampler, texCoords);\n"
- "}\n";
-
- {
- SCOPED_TRACE("creating shader program");
- createProgram(vsrc, fsrc, &mPgm);
- if (HasFatalFailure()) {
- return;
- }
- }
-
- mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- ASSERT_NE(-1, mPositionHandle);
- mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- ASSERT_NE(-1, mTexSamplerHandle);
- mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- ASSERT_NE(-1, mTexMatrixHandle);
- }
-
- virtual void TearDown() {
- mANW.clear();
- mSTC.clear();
- mST.clear();
- GLTest::TearDown();
- }
-
- // drawTexture draws the SurfaceTexture over the entire GL viewport.
- void drawTexture() {
- const GLfloat triangleVertices[] = {
- -1.0f, 1.0f,
- -1.0f, -1.0f,
- 1.0f, -1.0f,
- 1.0f, 1.0f,
- };
-
- glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
- triangleVertices);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glEnableVertexAttribArray(mPositionHandle);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
- glUseProgram(mPgm);
- glUniform1i(mTexSamplerHandle, 0);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
- // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
- // they're setting the defautls for that target, but when hacking things
- // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
- GL_LINEAR);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
- GL_LINEAR);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
- GLfloat texMatrix[16];
- mST->getTransformMatrix(texMatrix);
- glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- }
-
- class FrameWaiter : public SurfaceTexture::FrameAvailableListener {
- public:
- FrameWaiter():
- mPendingFrames(0) {
- }
-
- void waitForFrame() {
- Mutex::Autolock lock(mMutex);
- while (mPendingFrames == 0) {
- mCondition.wait(mMutex);
- }
- mPendingFrames--;
- }
-
- virtual void onFrameAvailable() {
- Mutex::Autolock lock(mMutex);
- mPendingFrames++;
- mCondition.signal();
- }
-
- int mPendingFrames;
- Mutex mMutex;
- Condition mCondition;
- };
-
- sp<SurfaceTexture> mST;
- sp<SurfaceTextureClient> mSTC;
- sp<ANativeWindow> mANW;
-
- GLuint mPgm;
- GLint mPositionHandle;
- GLint mTexSamplerHandle;
- GLint mTexMatrixHandle;
-};
-
-// Fill a YV12 buffer with a multi-colored checkerboard pattern
-void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
- const int blockWidth = w > 16 ? w / 16 : 1;
- const int blockHeight = h > 16 ? h / 16 : 1;
- const int yuvTexOffsetY = 0;
- int yuvTexStrideY = stride;
- int yuvTexOffsetV = yuvTexStrideY * h;
- int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
- int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
- int yuvTexStrideU = yuvTexStrideV;
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- int parityX = (x / blockWidth) & 1;
- int parityY = (y / blockHeight) & 1;
- unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
- buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
- if (x < w / 2 && y < h / 2) {
- buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
- if (x * 2 < w / 2 && y * 2 < h / 2) {
- buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
- buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
- buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
- buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
- intensity;
- }
- }
- }
- }
-}
-
-// Fill a YV12 buffer with red outside a given rectangle and green inside it.
-void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
- const android_native_rect_t& rect) {
- const int yuvTexOffsetY = 0;
- int yuvTexStrideY = stride;
- int yuvTexOffsetV = yuvTexStrideY * h;
- int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
- int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
- int yuvTexStrideU = yuvTexStrideV;
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- bool inside = rect.left <= x && x < rect.right &&
- rect.top <= y && y < rect.bottom;
- buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
- if (x < w / 2 && y < h / 2) {
- bool inside = rect.left <= 2*x && 2*x < rect.right &&
- rect.top <= 2*y && 2*y < rect.bottom;
- buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
- buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
- inside ? 16 : 255;
- }
- }
- }
-}
-
-void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
- const size_t PIXEL_SIZE = 4;
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- off_t offset = (y * stride + x) * PIXEL_SIZE;
- for (int c = 0; c < 4; c++) {
- int parityX = (x / (1 << (c+2))) & 1;
- int parityY = (y / (1 << (c+2))) & 1;
- buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
- }
- }
- }
-}
-
-void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
- uint8_t g, uint8_t b, uint8_t a) {
- const size_t PIXEL_SIZE = 4;
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < h; x++) {
- off_t offset = (y * stride + x) * PIXEL_SIZE;
- buf[offset + 0] = r;
- buf[offset + 1] = g;
- buf[offset + 2] = b;
- buf[offset + 3] = a;
- }
- }
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
- const int texWidth = 64;
- const int texHeight = 66;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- ANativeWindowBuffer* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
-
- // Fill the buffer with the a checkerboard pattern
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
-
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel(63, 65, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255));
-
- EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(52, 51, 98, 255, 73, 255));
- EXPECT_TRUE(checkPixel( 7, 31, 155, 0, 118, 255));
- EXPECT_TRUE(checkPixel(31, 9, 107, 24, 87, 255));
- EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
- const int texWidth = 64;
- const int texHeight = 64;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- ANativeWindowBuffer* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
-
- // Fill the buffer with the a checkerboard pattern
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
-
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel(63, 0, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
-
- EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255));
- EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255));
- EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255));
- EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
- EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255));
- EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
- const int texWidth = 64;
- const int texHeight = 66;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- android_native_rect_t crops[] = {
- {4, 6, 22, 36},
- {0, 6, 22, 36},
- {4, 0, 22, 36},
- {4, 6, texWidth, 36},
- {4, 6, 22, texHeight},
- };
-
- for (int i = 0; i < 5; i++) {
- const android_native_rect_t& crop(crops[i]);
- SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
- crop.left, crop.top, crop.right, crop.bottom).string());
-
- ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
-
- ANativeWindowBuffer* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
- buf->getNativeBuffer()));
-
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
- buf->getNativeBuffer()));
-
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, 64, 64);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(63, 0, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(63, 63, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel( 0, 63, 82, 255, 35, 255));
-
- EXPECT_TRUE(checkPixel(25, 14, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(35, 31, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(57, 6, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel( 5, 42, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(32, 33, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(16, 26, 82, 255, 35, 255));
- EXPECT_TRUE(checkPixel(46, 51, 82, 255, 35, 255));
- }
-}
-
-// This test is intended to catch synchronization bugs between the CPU-written
-// and GPU-read buffers.
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
- enum { texWidth = 16 };
- enum { texHeight = 16 };
- enum { numFrames = 1024 };
-
- ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
- ASSERT_EQ(NO_ERROR, mST->setBufferCountServer(2));
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- struct TestPixel {
- int x;
- int y;
- };
- const TestPixel testPixels[] = {
- { 4, 11 },
- { 12, 14 },
- { 7, 2 },
- };
- enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
-
- class ProducerThread : public Thread {
- public:
- ProducerThread(const sp<ANativeWindow>& anw,
- const TestPixel* testPixels):
- mANW(anw),
- mTestPixels(testPixels) {
- }
-
- virtual ~ProducerThread() {
- }
-
- virtual bool threadLoop() {
- for (int i = 0; i < numFrames; i++) {
- ANativeWindowBuffer* anb;
- if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
- return false;
- }
- if (anb == NULL) {
- return false;
- }
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- if (mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())
- != NO_ERROR) {
- return false;
- }
-
- const int yuvTexOffsetY = 0;
- int stride = buf->getStride();
- int yuvTexStrideY = stride;
- int yuvTexOffsetV = yuvTexStrideY * texHeight;
- int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
- int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
- int yuvTexStrideU = yuvTexStrideV;
-
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-
- // Gray out all the test pixels first, so we're more likely to
- // see a failure if GL is still texturing from the buffer we
- // just dequeued.
- for (int j = 0; j < numTestPixels; j++) {
- int x = mTestPixels[j].x;
- int y = mTestPixels[j].y;
- uint8_t value = 128;
- img[y*stride + x] = value;
- }
-
- // Fill the buffer with gray.
- for (int y = 0; y < texHeight; y++) {
- for (int x = 0; x < texWidth; x++) {
- img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
- img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
- img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
- }
- }
-
- // Set the test pixels to either white or black.
- for (int j = 0; j < numTestPixels; j++) {
- int x = mTestPixels[j].x;
- int y = mTestPixels[j].y;
- uint8_t value = 0;
- if (j == (i % numTestPixels)) {
- value = 255;
- }
- img[y*stride + x] = value;
- }
-
- buf->unlock();
- if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())
- != NO_ERROR) {
- return false;
- }
- }
- return false;
- }
-
- sp<ANativeWindow> mANW;
- const TestPixel* mTestPixels;
- };
-
- sp<FrameWaiter> fw(new FrameWaiter);
- mST->setFrameAvailableListener(fw);
-
- sp<Thread> pt(new ProducerThread(mANW, testPixels));
- pt->run();
-
- glViewport(0, 0, texWidth, texHeight);
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // We wait for the first two frames up front so that the producer will be
- // likely to dequeue the buffer that's currently being textured from.
- fw->waitForFrame();
- fw->waitForFrame();
-
- for (int i = 0; i < numFrames; i++) {
- SCOPED_TRACE(String8::format("frame %d", i).string());
-
- // We must wait for each frame to come in because if we ever do an
- // updateTexImage call that doesn't consume a newly available buffer
- // then the producer and consumer will get out of sync, which will cause
- // a deadlock.
- if (i > 1) {
- fw->waitForFrame();
- }
- mST->updateTexImage();
- drawTexture();
-
- for (int j = 0; j < numTestPixels; j++) {
- int x = testPixels[j].x;
- int y = testPixels[j].y;
- uint8_t value = 0;
- if (j == (i % numTestPixels)) {
- // We must y-invert the texture coords
- EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
- } else {
- // We must y-invert the texture coords
- EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
- }
- }
- }
-
- pt->requestExitAndWait();
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
- const int texWidth = 64;
- const int texHeight = 66;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- android_native_buffer_t* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
-
- // Fill the buffer with the a checkerboard pattern
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
-
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35));
- EXPECT_TRUE(checkPixel(63, 0, 231, 231, 231, 231));
- EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
- EXPECT_TRUE(checkPixel( 0, 65, 35, 35, 35, 35));
-
- EXPECT_TRUE(checkPixel(15, 10, 35, 231, 231, 231));
- EXPECT_TRUE(checkPixel(23, 65, 231, 35, 231, 35));
- EXPECT_TRUE(checkPixel(19, 40, 35, 231, 35, 35));
- EXPECT_TRUE(checkPixel(38, 30, 231, 35, 35, 35));
- EXPECT_TRUE(checkPixel(42, 54, 35, 35, 35, 231));
- EXPECT_TRUE(checkPixel(37, 34, 35, 231, 231, 231));
- EXPECT_TRUE(checkPixel(31, 8, 231, 35, 35, 231));
- EXPECT_TRUE(checkPixel(37, 47, 231, 35, 231, 231));
- EXPECT_TRUE(checkPixel(25, 38, 35, 35, 35, 35));
- EXPECT_TRUE(checkPixel(49, 6, 35, 231, 35, 35));
- EXPECT_TRUE(checkPixel(54, 50, 35, 231, 231, 231));
- EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
- EXPECT_TRUE(checkPixel(10, 6, 35, 35, 231, 231));
- EXPECT_TRUE(checkPixel(29, 4, 35, 35, 35, 231));
- EXPECT_TRUE(checkPixel(55, 28, 35, 35, 231, 35));
- EXPECT_TRUE(checkPixel(58, 55, 35, 35, 231, 231));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
- const int texWidth = 64;
- const int texHeight = 64;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- android_native_buffer_t* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
-
- // Fill the buffer with the a checkerboard pattern
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
-
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 231, 231, 231, 231));
- EXPECT_TRUE(checkPixel(63, 0, 35, 35, 35, 35));
- EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
- EXPECT_TRUE(checkPixel( 0, 63, 35, 35, 35, 35));
-
- EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231, 35));
- EXPECT_TRUE(checkPixel(16, 1, 231, 231, 35, 231));
- EXPECT_TRUE(checkPixel(21, 12, 231, 35, 35, 231));
- EXPECT_TRUE(checkPixel(26, 51, 231, 35, 231, 35));
- EXPECT_TRUE(checkPixel( 5, 32, 35, 231, 231, 35));
- EXPECT_TRUE(checkPixel(13, 8, 35, 231, 231, 231));
- EXPECT_TRUE(checkPixel(46, 3, 35, 35, 231, 35));
- EXPECT_TRUE(checkPixel(30, 33, 35, 35, 35, 35));
- EXPECT_TRUE(checkPixel( 6, 52, 231, 231, 35, 35));
- EXPECT_TRUE(checkPixel(55, 33, 35, 231, 35, 231));
- EXPECT_TRUE(checkPixel(16, 29, 35, 35, 231, 231));
- EXPECT_TRUE(checkPixel( 1, 30, 35, 35, 35, 231));
- EXPECT_TRUE(checkPixel(41, 37, 35, 35, 231, 231));
- EXPECT_TRUE(checkPixel(46, 29, 231, 231, 35, 35));
- EXPECT_TRUE(checkPixel(15, 25, 35, 231, 35, 231));
- EXPECT_TRUE(checkPixel( 3, 52, 35, 231, 35, 35));
-}
-
-TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
- class ProducerThread : public Thread {
- public:
- ProducerThread(const sp<ANativeWindow>& anw):
- mANW(anw),
- mDequeueError(NO_ERROR) {
- }
-
- virtual ~ProducerThread() {
- }
-
- virtual bool threadLoop() {
- Mutex::Autolock lock(mMutex);
- ANativeWindowBuffer* anb;
-
- // Frame 1
- if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
- return false;
- }
- if (anb == NULL) {
- return false;
- }
- if (mANW->queueBuffer(mANW.get(), anb)
- != NO_ERROR) {
- return false;
- }
-
- // Frame 2
- if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
- return false;
- }
- if (anb == NULL) {
- return false;
- }
- if (mANW->queueBuffer(mANW.get(), anb)
- != NO_ERROR) {
- return false;
- }
-
- // Frame 3 - error expected
- mDequeueError = mANW->dequeueBuffer(mANW.get(), &anb);
- return false;
- }
-
- status_t getDequeueError() {
- Mutex::Autolock lock(mMutex);
- return mDequeueError;
- }
-
- private:
- sp<ANativeWindow> mANW;
- status_t mDequeueError;
- Mutex mMutex;
- };
-
- sp<FrameWaiter> fw(new FrameWaiter);
- mST->setFrameAvailableListener(fw);
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, mST->setBufferCountServer(2));
-
- sp<Thread> pt(new ProducerThread(mANW));
- pt->run();
-
- fw->waitForFrame();
- fw->waitForFrame();
-
- // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
- // block waiting for a buffer to become available.
- usleep(100000);
-
- mST->abandon();
-
- pt->requestExitAndWait();
- ASSERT_EQ(NO_INIT,
- reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
-}
-
-TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
- int texHeight = 16;
- ANativeWindowBuffer* anb;
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
-
- // make sure it works with small textures
- mST->setDefaultBufferSize(16, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(16, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
- // make sure it works with GL_MAX_TEXTURE_SIZE
- mST->setDefaultBufferSize(maxTextureSize, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(maxTextureSize, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
- // make sure it fails with GL_MAX_TEXTURE_SIZE+1
- mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(maxTextureSize+1, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- ASSERT_NE(NO_ERROR, mST->updateTexImage());
-}
-
-/*
- * This test fixture is for testing GL -> GL texture streaming. It creates an
- * EGLSurface and an EGLContext for the image producer to use.
- */
-class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
-protected:
- SurfaceTextureGLToGLTest():
- mProducerEglSurface(EGL_NO_SURFACE),
- mProducerEglContext(EGL_NO_CONTEXT) {
- }
-
- virtual void SetUp() {
- SurfaceTextureGLTest::SetUp();
-
- EGLConfig myConfig = {0};
- EGLint numConfigs = 0;
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
- 1, &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
- mANW.get(), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
-
- mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
- EGL_NO_CONTEXT, getContextAttribs());
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
- }
-
- virtual void TearDown() {
- if (mProducerEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mProducerEglContext);
- }
- if (mProducerEglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mProducerEglSurface);
- }
- SurfaceTextureGLTest::TearDown();
- }
-
- EGLSurface mProducerEglSurface;
- EGLContext mProducerEglContext;
-};
-
-TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
- const int texWidth = 64;
- const int texHeight = 64;
-
- mST->setDefaultBufferSize(texWidth, texHeight);
-
- // Do the producer side of things
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // This is needed to ensure we pick up a buffer of the correct size.
- eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
- glClearColor(0.6, 0.6, 0.6, 0.6);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(4, 4, 4, 4);
- glClearColor(1.0, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glScissor(24, 48, 4, 4);
- glClearColor(0.0, 1.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glScissor(37, 17, 4, 4);
- glClearColor(0.0, 0.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
- // Do the consumer side of things
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- glDisable(GL_SCISSOR_TEST);
-
- mST->updateTexImage(); // Skip the first frame, which was empty
- mST->updateTexImage();
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
-
- EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255));
- EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255));
- EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255));
- EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
- sp<GraphicBuffer> buffers[3];
-
- // This test requires async mode to run on a single thread.
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- for (int i = 0; i < 3; i++) {
- // Produce a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
- // Consume a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- mST->updateTexImage();
- buffers[i] = mST->getCurrentBuffer();
- }
-
- // Destroy the GL texture object to release its ref on buffers[2].
- GLuint texID = TEX_ID;
- glDeleteTextures(1, &texID);
-
- // Destroy the EGLSurface
- EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Release the ref that the SurfaceTexture has on buffers[2].
- mST->abandon();
-
- EXPECT_EQ(1, buffers[0]->getStrongCount());
- EXPECT_EQ(1, buffers[1]->getStrongCount());
-
- // Depending on how lazily the GL driver dequeues buffers, we may end up
- // with either two or three total buffers. If there are three, make sure
- // the last one was properly down-ref'd.
- if (buffers[2] != buffers[0]) {
- EXPECT_EQ(1, buffers[2]->getStrongCount());
- }
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
- sp<GraphicBuffer> buffers[3];
-
- // This test requires async mode to run on a single thread.
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- for (int i = 0; i < 3; i++) {
- // Produce a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- glClear(GL_COLOR_BUFFER_BIT);
- EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Consume a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_EQ(NO_ERROR, mST->updateTexImage());
- buffers[i] = mST->getCurrentBuffer();
- }
-
- // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
- // on buffers[2].
- mST->abandon();
-
- // Destroy the GL texture object to release its ref on buffers[2].
- GLuint texID = TEX_ID;
- glDeleteTextures(1, &texID);
-
- // Destroy the EGLSurface.
- EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EXPECT_EQ(1, buffers[0]->getStrongCount());
- EXPECT_EQ(1, buffers[1]->getStrongCount());
-
- // Depending on how lazily the GL driver dequeues buffers, we may end up
- // with either two or three total buffers. If there are three, make sure
- // the last one was properly down-ref'd.
- if (buffers[2] != buffers[0]) {
- EXPECT_EQ(1, buffers[2]->getStrongCount());
- }
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
- // This test requires 3 buffers to run on a single thread.
- mST->setBufferCountServer(3);
-
- ASSERT_TRUE(mST->isSynchronousMode());
-
- for (int i = 0; i < 10; i++) {
- // Produce a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- glClear(GL_COLOR_BUFFER_BIT);
- EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Consume a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_EQ(NO_ERROR, mST->updateTexImage());
- }
-
- ASSERT_TRUE(mST->isSynchronousMode());
-}
-
-/*
- * This test fixture is for testing GL -> GL texture streaming from one thread
- * to another. It contains functionality to create a producer thread that will
- * perform GL rendering to an ANativeWindow that feeds frames to a
- * SurfaceTexture. Additionally it supports interlocking the producer and
- * consumer threads so that a specific sequence of calls can be
- * deterministically created by the test.
- *
- * The intended usage is as follows:
- *
- * TEST_F(...) {
- * class PT : public ProducerThread {
- * virtual void render() {
- * ...
- * swapBuffers();
- * }
- * };
- *
- * runProducerThread(new PT());
- *
- * // The order of these calls will vary from test to test and may include
- * // multiple frames and additional operations (e.g. GL rendering from the
- * // texture).
- * fc->waitForFrame();
- * mST->updateTexImage();
- * fc->finishFrame();
- * }
- *
- */
-class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
-protected:
-
- // ProducerThread is an abstract base class to simplify the creation of
- // OpenGL ES frame producer threads.
- class ProducerThread : public Thread {
- public:
- virtual ~ProducerThread() {
- }
-
- void setEglObjects(EGLDisplay producerEglDisplay,
- EGLSurface producerEglSurface,
- EGLContext producerEglContext) {
- mProducerEglDisplay = producerEglDisplay;
- mProducerEglSurface = producerEglSurface;
- mProducerEglContext = producerEglContext;
- }
-
- virtual bool threadLoop() {
- eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
- mProducerEglSurface, mProducerEglContext);
- render();
- eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- return false;
- }
-
- protected:
- virtual void render() = 0;
-
- void swapBuffers() {
- eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
- }
-
- EGLDisplay mProducerEglDisplay;
- EGLSurface mProducerEglSurface;
- EGLContext mProducerEglContext;
- };
-
- // FrameCondition is a utility class for interlocking between the producer
- // and consumer threads. The FrameCondition object should be created and
- // destroyed in the consumer thread only. The consumer thread should set
- // the FrameCondition as the FrameAvailableListener of the SurfaceTexture,
- // and should call both waitForFrame and finishFrame once for each expected
- // frame.
- //
- // This interlocking relies on the fact that onFrameAvailable gets called
- // synchronously from SurfaceTexture::queueBuffer.
- class FrameCondition : public SurfaceTexture::FrameAvailableListener {
- public:
- FrameCondition():
- mFrameAvailable(false),
- mFrameFinished(false) {
- }
-
- // waitForFrame waits for the next frame to arrive. This should be
- // called from the consumer thread once for every frame expected by the
- // test.
- void waitForFrame() {
- Mutex::Autolock lock(mMutex);
- ALOGV("+waitForFrame");
- while (!mFrameAvailable) {
- mFrameAvailableCondition.wait(mMutex);
- }
- mFrameAvailable = false;
- ALOGV("-waitForFrame");
- }
-
- // Allow the producer to return from its swapBuffers call and continue
- // on to produce the next frame. This should be called by the consumer
- // thread once for every frame expected by the test.
- void finishFrame() {
- Mutex::Autolock lock(mMutex);
- ALOGV("+finishFrame");
- mFrameFinished = true;
- mFrameFinishCondition.signal();
- ALOGV("-finishFrame");
- }
-
- // This should be called by SurfaceTexture on the producer thread.
- virtual void onFrameAvailable() {
- Mutex::Autolock lock(mMutex);
- ALOGV("+onFrameAvailable");
- mFrameAvailable = true;
- mFrameAvailableCondition.signal();
- while (!mFrameFinished) {
- mFrameFinishCondition.wait(mMutex);
- }
- mFrameFinished = false;
- ALOGV("-onFrameAvailable");
- }
-
- protected:
- bool mFrameAvailable;
- bool mFrameFinished;
-
- Mutex mMutex;
- Condition mFrameAvailableCondition;
- Condition mFrameFinishCondition;
- };
-
- virtual void SetUp() {
- SurfaceTextureGLToGLTest::SetUp();
- mFC = new FrameCondition();
- mST->setFrameAvailableListener(mFC);
- }
-
- virtual void TearDown() {
- if (mProducerThread != NULL) {
- mProducerThread->requestExitAndWait();
- }
- mProducerThread.clear();
- mFC.clear();
- SurfaceTextureGLToGLTest::TearDown();
- }
-
- void runProducerThread(const sp<ProducerThread> producerThread) {
- ASSERT_TRUE(mProducerThread == NULL);
- mProducerThread = producerThread;
- producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
- mProducerEglContext);
- producerThread->run();
- }
-
- sp<ProducerThread> mProducerThread;
- sp<FrameCondition> mFC;
-};
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
- UpdateTexImageBeforeFrameFinishedCompletes) {
- class PT : public ProducerThread {
- virtual void render() {
- glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- swapBuffers();
- }
- };
-
- runProducerThread(new PT());
-
- mFC->waitForFrame();
- mST->updateTexImage();
- mFC->finishFrame();
-
- // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
- UpdateTexImageAfterFrameFinishedCompletes) {
- class PT : public ProducerThread {
- virtual void render() {
- glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- swapBuffers();
- }
- };
-
- runProducerThread(new PT());
-
- mFC->waitForFrame();
- mFC->finishFrame();
- mST->updateTexImage();
-
- // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
- RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
- enum { NUM_ITERATIONS = 1024 };
-
- class PT : public ProducerThread {
- virtual void render() {
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- ALOGV("+swapBuffers");
- swapBuffers();
- ALOGV("-swapBuffers");
- }
- }
- };
-
- runProducerThread(new PT());
-
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- mFC->waitForFrame();
- ALOGV("+updateTexImage");
- mST->updateTexImage();
- ALOGV("-updateTexImage");
- mFC->finishFrame();
-
- // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
- }
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
- RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
- enum { NUM_ITERATIONS = 1024 };
-
- class PT : public ProducerThread {
- virtual void render() {
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- ALOGV("+swapBuffers");
- swapBuffers();
- ALOGV("-swapBuffers");
- }
- }
- };
-
- runProducerThread(new PT());
-
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- mFC->waitForFrame();
- mFC->finishFrame();
- ALOGV("+updateTexImage");
- mST->updateTexImage();
- ALOGV("-updateTexImage");
-
- // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
- }
-}
-
-// XXX: This test is disabled because it is currently hanging on some devices.
-TEST_F(SurfaceTextureGLThreadToGLTest,
- DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
- enum { NUM_ITERATIONS = 64 };
-
- class PT : public ProducerThread {
- virtual void render() {
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- ALOGV("+swapBuffers");
- swapBuffers();
- ALOGV("-swapBuffers");
- }
- }
- };
-
- ASSERT_EQ(OK, mST->setSynchronousMode(true));
- ASSERT_EQ(OK, mST->setBufferCountServer(2));
-
- runProducerThread(new PT());
-
- // Allow three frames to be rendered and queued before starting the
- // rendering in this thread. For the latter two frames we don't call
- // updateTexImage so the next dequeue from the producer thread will block
- // waiting for a frame to become available.
- mFC->waitForFrame();
- mFC->finishFrame();
-
- // We must call updateTexImage to consume the first frame so that the
- // SurfaceTexture is able to reduce the buffer count to 2. This is because
- // the GL driver may dequeue a buffer when the EGLSurface is created, and
- // that happens before we call setBufferCountServer. It's possible that the
- // driver does not dequeue a buffer at EGLSurface creation time, so we
- // cannot rely on this to cause the second dequeueBuffer call to block.
- mST->updateTexImage();
-
- mFC->waitForFrame();
- mFC->finishFrame();
- mFC->waitForFrame();
- mFC->finishFrame();
-
- // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
- // block waiting for a buffer to become available.
- usleep(100000);
-
- // Render and present a number of images. This thread should not be blocked
- // by the fact that the producer thread is blocking in dequeue.
- for (int i = 0; i < NUM_ITERATIONS; i++) {
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(mEglDisplay, mEglSurface);
- }
-
- // Consume the two pending buffers to unblock the producer thread.
- mST->updateTexImage();
- mST->updateTexImage();
-
- // Consume the remaining buffers from the producer thread.
- for (int i = 0; i < NUM_ITERATIONS-3; i++) {
- mFC->waitForFrame();
- mFC->finishFrame();
- ALOGV("+updateTexImage");
- mST->updateTexImage();
- ALOGV("-updateTexImage");
- }
-}
-
-class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
-protected:
-
- virtual void SetUp() {
- SurfaceTextureGLTest::SetUp();
-
- glGenFramebuffers(1, &mFbo);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
- glGenTextures(1, &mFboTex);
- glBindTexture(GL_TEXTURE_2D, mFboTex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
- getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
- glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, mFboTex, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- }
-
- virtual void TearDown() {
- SurfaceTextureGLTest::TearDown();
-
- glDeleteTextures(1, &mFboTex);
- glDeleteFramebuffers(1, &mFbo);
- }
-
- GLuint mFbo;
- GLuint mFboTex;
-};
-
-// This test is intended to verify that proper synchronization is done when
-// rendering into an FBO.
-TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
- const int texWidth = 64;
- const int texHeight = 64;
-
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
- android_native_buffer_t* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
-
- // Fill the buffer with green
- uint8_t* img = NULL;
- buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
- 0, 255);
- buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
-
- ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
- glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
- drawTexture();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- for (int i = 0; i < 4; i++) {
- SCOPED_TRACE(String8::format("frame %d", i).string());
-
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- ASSERT_TRUE(anb != NULL);
-
- buf = new GraphicBuffer(anb, false);
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
- buf->getNativeBuffer()));
-
- // Fill the buffer with red
- ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
- (void**)(&img)));
- fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
- 0, 255);
- ASSERT_EQ(NO_ERROR, buf->unlock());
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
- buf->getNativeBuffer()));
-
- ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
-
- EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
-}
-
-} // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
deleted file mode 100644
index b585d68..0000000
--- a/libs/gui/tests/Surface_test.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <binder/IMemory.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-#include <utils/String8.h>
-
-#include <private/gui/ComposerService.h>
-
-namespace android {
-
-class SurfaceTest : public ::testing::Test {
-protected:
- virtual void SetUp() {
- mComposerClient = new SurfaceComposerClient;
- ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
- mSurfaceControl = mComposerClient->createSurface(
- String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGBA_8888, 0);
-
- ASSERT_TRUE(mSurfaceControl != NULL);
- ASSERT_TRUE(mSurfaceControl->isValid());
-
- SurfaceComposerClient::openGlobalTransaction();
- ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7fffffff));
- ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
- SurfaceComposerClient::closeGlobalTransaction();
-
- mSurface = mSurfaceControl->getSurface();
- ASSERT_TRUE(mSurface != NULL);
- }
-
- virtual void TearDown() {
- mComposerClient->dispose();
- }
-
- sp<Surface> mSurface;
- sp<SurfaceComposerClient> mComposerClient;
- sp<SurfaceControl> mSurfaceControl;
-};
-
-TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenVisible) {
- sp<ANativeWindow> anw(mSurface);
- int result = -123;
- int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
- &result);
- EXPECT_EQ(NO_ERROR, err);
- EXPECT_EQ(1, result);
-}
-
-TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
- mSurfaceControl.clear();
-
- sp<ANativeWindow> anw(mSurface);
- int result = -123;
- int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
- &result);
- EXPECT_EQ(NO_ERROR, err);
- EXPECT_EQ(1, result);
-}
-
-// This test probably doesn't belong here.
-TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
- sp<ANativeWindow> anw(mSurface);
-
- // Verify the screenshot works with no protected buffers.
- sp<IMemoryHeap> heap;
- uint32_t w=0, h=0;
- PixelFormat fmt=0;
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 0x7fffffff));
- ASSERT_TRUE(heap != NULL);
-
- // Set the PROTECTED usage bit and verify that the screenshot fails. Note
- // that we need to dequeue a buffer in order for it to actually get
- // allocated in SurfaceFlinger.
- ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
- GRALLOC_USAGE_PROTECTED));
- ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
- ANativeWindowBuffer* buf = 0;
-
- status_t err = anw->dequeueBuffer(anw.get(), &buf);
- if (err) {
- // we could fail if GRALLOC_USAGE_PROTECTED is not supported.
- // that's okay as long as this is the reason for the failure.
- // try again without the GRALLOC_USAGE_PROTECTED bit.
- ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
- ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
- return;
- }
- ASSERT_EQ(NO_ERROR, anw->cancelBuffer(anw.get(), buf));
-
- for (int i = 0; i < 4; i++) {
- // Loop to make sure SurfaceFlinger has retired a protected buffer.
- ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
- ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
- ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
- }
- heap = 0;
- w = h = fmt = 0;
- ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt,
- 64, 64, 0, 0x7fffffff));
- ASSERT_TRUE(heap != NULL);
-}
-
-TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
- sp<ANativeWindow> anw(mSurface);
- int result = -123;
- int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
- EXPECT_EQ(NO_ERROR, err);
- EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
-}
-
-}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
deleted file mode 100644
index 5aff7a4..0000000
--- a/libs/ui/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- FramebufferNativeWindow.cpp \
- GraphicBuffer.cpp \
- GraphicBufferAllocator.cpp \
- GraphicBufferMapper.cpp \
- PixelFormat.cpp \
- Rect.cpp \
- Region.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libhardware
-
-ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
-LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
-endif
-
-LOCAL_MODULE:= libui
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
deleted file mode 100644
index dec99b6..0000000
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
-**
-** Copyright 2007 The Android Open Source Project
-**
-** Licensed under the Apache License Version 2.0(the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing software
-** distributed under the License is distributed on an "AS IS" BASIS
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "FramebufferNativeWindow"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <utils/threads.h>
-#include <utils/RefBase.h>
-
-#include <ui/ANativeObjectBase.h>
-#include <ui/FramebufferNativeWindow.h>
-#include <ui/Rect.h>
-
-#include <EGL/egl.h>
-
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-class NativeBuffer
- : public ANativeObjectBase<
- ANativeWindowBuffer,
- NativeBuffer,
- LightRefBase<NativeBuffer> >
-{
-public:
- NativeBuffer(int w, int h, int f, int u) : BASE() {
- ANativeWindowBuffer::width = w;
- ANativeWindowBuffer::height = h;
- ANativeWindowBuffer::format = f;
- ANativeWindowBuffer::usage = u;
- }
-private:
- friend class LightRefBase<NativeBuffer>;
- ~NativeBuffer() { }; // this class cannot be overloaded
-};
-
-
-/*
- * This implements the (main) framebuffer management. This class is used
- * mostly by SurfaceFlinger, but also by command line GL application.
- *
- * In fact this is an implementation of ANativeWindow on top of
- * the framebuffer.
- *
- * Currently it is pretty simple, it manages only two buffers (the front and
- * back buffer).
- *
- */
-
-FramebufferNativeWindow::FramebufferNativeWindow()
- : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
-{
- hw_module_t const* module;
- if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
- int stride;
- int err;
- int i;
- err = framebuffer_open(module, &fbDev);
- ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
-
- err = gralloc_open(module, &grDev);
- ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
-
- // bail out if we can't initialize the modules
- if (!fbDev || !grDev)
- return;
-
- mUpdateOnDemand = (fbDev->setUpdateRect != 0);
-
- // initialize the buffer FIFO
- mNumBuffers = NUM_FRAME_BUFFERS;
- mNumFreeBuffers = NUM_FRAME_BUFFERS;
- mBufferHead = mNumBuffers-1;
-
- /*
- * This does not actually change the framebuffer format. It merely
- * fakes this format to surfaceflinger so that when it creates
- * framebuffer surfaces it will use this format. It's really a giant
- * HACK to allow interworking with buggy gralloc+GPU driver
- * implementations. You should *NEVER* need to set this for shipping
- * devices.
- */
-#ifdef FRAMEBUFFER_FORCE_FORMAT
- *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
-#endif
-
- for (i = 0; i < mNumBuffers; i++)
- {
- buffers[i] = new NativeBuffer(
- fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
- }
-
- for (i = 0; i < mNumBuffers; i++)
- {
- err = grDev->alloc(grDev,
- fbDev->width, fbDev->height, fbDev->format,
- GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
-
- ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",
- i, fbDev->width, fbDev->height, strerror(-err));
-
- if (err)
- {
- mNumBuffers = i;
- mNumFreeBuffers = i;
- mBufferHead = mNumBuffers-1;
- break;
- }
- }
-
- const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
- const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
- const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
- const_cast<int&>(ANativeWindow::minSwapInterval) =
- fbDev->minSwapInterval;
- const_cast<int&>(ANativeWindow::maxSwapInterval) =
- fbDev->maxSwapInterval;
- } else {
- ALOGE("Couldn't get gralloc module");
- }
-
- ANativeWindow::setSwapInterval = setSwapInterval;
- ANativeWindow::dequeueBuffer = dequeueBuffer;
- ANativeWindow::lockBuffer = lockBuffer;
- ANativeWindow::queueBuffer = queueBuffer;
- ANativeWindow::query = query;
- ANativeWindow::perform = perform;
-}
-
-FramebufferNativeWindow::~FramebufferNativeWindow()
-{
- if (grDev) {
- if (buffers[0] != NULL)
- grDev->free(grDev, buffers[0]->handle);
- if (buffers[1] != NULL)
- grDev->free(grDev, buffers[1]->handle);
- gralloc_close(grDev);
- }
-
- if (fbDev) {
- framebuffer_close(fbDev);
- }
-}
-
-status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r)
-{
- if (!mUpdateOnDemand) {
- return INVALID_OPERATION;
- }
- return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height());
-}
-
-status_t FramebufferNativeWindow::compositionComplete()
-{
- if (fbDev->compositionComplete) {
- return fbDev->compositionComplete(fbDev);
- }
- return INVALID_OPERATION;
-}
-
-int FramebufferNativeWindow::setSwapInterval(
- ANativeWindow* window, int interval)
-{
- framebuffer_device_t* fb = getSelf(window)->fbDev;
- return fb->setSwapInterval(fb, interval);
-}
-
-void FramebufferNativeWindow::dump(String8& result) {
- if (fbDev->common.version >= 1 && fbDev->dump) {
- const size_t SIZE = 4096;
- char buffer[SIZE];
-
- fbDev->dump(fbDev, buffer, SIZE);
- result.append(buffer);
- }
-}
-
-// only for debugging / logging
-int FramebufferNativeWindow::getCurrentBufferIndex() const
-{
- Mutex::Autolock _l(mutex);
- const int index = mCurrentBufferIndex;
- return index;
-}
-
-int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
- ANativeWindowBuffer** buffer)
-{
- FramebufferNativeWindow* self = getSelf(window);
- Mutex::Autolock _l(self->mutex);
- framebuffer_device_t* fb = self->fbDev;
-
- int index = self->mBufferHead++;
- if (self->mBufferHead >= self->mNumBuffers)
- self->mBufferHead = 0;
-
- // wait for a free buffer
- while (!self->mNumFreeBuffers) {
- self->mCondition.wait(self->mutex);
- }
- // get this buffer
- self->mNumFreeBuffers--;
- self->mCurrentBufferIndex = index;
-
- *buffer = self->buffers[index].get();
-
- return 0;
-}
-
-int FramebufferNativeWindow::lockBuffer(ANativeWindow* window,
- ANativeWindowBuffer* buffer)
-{
- FramebufferNativeWindow* self = getSelf(window);
- Mutex::Autolock _l(self->mutex);
-
- const int index = self->mCurrentBufferIndex;
-
- // wait that the buffer we're locking is not front anymore
- while (self->front == buffer) {
- self->mCondition.wait(self->mutex);
- }
-
- return NO_ERROR;
-}
-
-int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
- ANativeWindowBuffer* buffer)
-{
- FramebufferNativeWindow* self = getSelf(window);
- Mutex::Autolock _l(self->mutex);
- framebuffer_device_t* fb = self->fbDev;
- buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
-
- const int index = self->mCurrentBufferIndex;
- int res = fb->post(fb, handle);
- self->front = static_cast<NativeBuffer*>(buffer);
- self->mNumFreeBuffers++;
- self->mCondition.broadcast();
- return res;
-}
-
-int FramebufferNativeWindow::query(const ANativeWindow* window,
- int what, int* value)
-{
- const FramebufferNativeWindow* self = getSelf(window);
- Mutex::Autolock _l(self->mutex);
- framebuffer_device_t* fb = self->fbDev;
- switch (what) {
- case NATIVE_WINDOW_WIDTH:
- *value = fb->width;
- return NO_ERROR;
- case NATIVE_WINDOW_HEIGHT:
- *value = fb->height;
- return NO_ERROR;
- case NATIVE_WINDOW_FORMAT:
- *value = fb->format;
- return NO_ERROR;
- case NATIVE_WINDOW_CONCRETE_TYPE:
- *value = NATIVE_WINDOW_FRAMEBUFFER;
- return NO_ERROR;
- case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- *value = 0;
- return NO_ERROR;
- case NATIVE_WINDOW_DEFAULT_WIDTH:
- *value = fb->width;
- return NO_ERROR;
- case NATIVE_WINDOW_DEFAULT_HEIGHT:
- *value = fb->height;
- return NO_ERROR;
- case NATIVE_WINDOW_TRANSFORM_HINT:
- *value = 0;
- return NO_ERROR;
- }
- *value = 0;
- return BAD_VALUE;
-}
-
-int FramebufferNativeWindow::perform(ANativeWindow* window,
- int operation, ...)
-{
- switch (operation) {
- case NATIVE_WINDOW_CONNECT:
- case NATIVE_WINDOW_DISCONNECT:
- case NATIVE_WINDOW_SET_USAGE:
- case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
- case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
- case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
- case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
- case NATIVE_WINDOW_API_CONNECT:
- case NATIVE_WINDOW_API_DISCONNECT:
- // TODO: we should implement these
- return NO_ERROR;
-
- case NATIVE_WINDOW_LOCK:
- case NATIVE_WINDOW_UNLOCK_AND_POST:
- case NATIVE_WINDOW_SET_CROP:
- case NATIVE_WINDOW_SET_BUFFER_COUNT:
- case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
- case NATIVE_WINDOW_SET_SCALING_MODE:
- return INVALID_OPERATION;
- }
- return NAME_NOT_FOUND;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
-using namespace android;
-
-EGLNativeWindowType android_createDisplaySurface(void)
-{
- FramebufferNativeWindow* w;
- w = new FramebufferNativeWindow();
- if (w->getDevice() == NULL) {
- // get a ref so it can be destroyed when we exit this block
- sp<FramebufferNativeWindow> ref(w);
- return NULL;
- }
- return (EGLNativeWindowType)w;
-}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
deleted file mode 100644
index 57063e5..0000000
--- a/libs/ui/GraphicBuffer.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GraphicBuffer"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferAllocator.h>
-#include <ui/GraphicBufferMapper.h>
-#include <ui/PixelFormat.h>
-
-namespace android {
-
-// ===========================================================================
-// Buffer and implementation of ANativeWindowBuffer
-// ===========================================================================
-
-GraphicBuffer::GraphicBuffer()
- : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1)
-{
- width =
- height =
- stride =
- format =
- usage = 0;
- handle = NULL;
-}
-
-GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat reqFormat, uint32_t reqUsage)
- : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1)
-{
- width =
- height =
- stride =
- format =
- usage = 0;
- handle = NULL;
- mInitCheck = initSize(w, h, reqFormat, reqUsage);
-}
-
-GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat inFormat, uint32_t inUsage,
- uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
- : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
- mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1)
-{
- width = w;
- height = h;
- stride = inStride;
- format = inFormat;
- usage = inUsage;
- handle = inHandle;
-}
-
-GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
- : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
- mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer)
-{
- width = buffer->width;
- height = buffer->height;
- stride = buffer->stride;
- format = buffer->format;
- usage = buffer->usage;
- handle = buffer->handle;
-}
-
-GraphicBuffer::~GraphicBuffer()
-{
- if (handle) {
- free_handle();
- }
-}
-
-void GraphicBuffer::free_handle()
-{
- if (mOwner == ownHandle) {
- mBufferMapper.unregisterBuffer(handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
- } else if (mOwner == ownData) {
- GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
- allocator.free(handle);
- }
- mWrappedBuffer = 0;
-}
-
-status_t GraphicBuffer::initCheck() const {
- return mInitCheck;
-}
-
-void GraphicBuffer::dumpAllocationsToSystemLog()
-{
- GraphicBufferAllocator::dumpToSystemLog();
-}
-
-ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
-{
- return static_cast<ANativeWindowBuffer*>(
- const_cast<GraphicBuffer*>(this));
-}
-
-status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
- uint32_t reqUsage)
-{
- if (mOwner != ownData)
- return INVALID_OPERATION;
-
- if (handle && w==width && h==height && f==format && reqUsage==usage)
- return NO_ERROR;
-
- if (handle) {
- GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
- allocator.free(handle);
- handle = 0;
- }
- return initSize(w, h, f, reqUsage);
-}
-
-status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
- uint32_t reqUsage)
-{
- GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
- status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
- if (err == NO_ERROR) {
- this->width = w;
- this->height = h;
- this->format = format;
- this->usage = reqUsage;
- }
- return err;
-}
-
-status_t GraphicBuffer::lock(uint32_t usage, void** vaddr)
-{
- const Rect lockBounds(width, height);
- status_t res = lock(usage, lockBounds, vaddr);
- return res;
-}
-
-status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
-{
- if (rect.left < 0 || rect.right > this->width ||
- rect.top < 0 || rect.bottom > this->height) {
- ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
- rect.left, rect.top, rect.right, rect.bottom,
- this->width, this->height);
- return BAD_VALUE;
- }
- status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
- return res;
-}
-
-status_t GraphicBuffer::unlock()
-{
- status_t res = getBufferMapper().unlock(handle);
- return res;
-}
-
-size_t GraphicBuffer::getFlattenedSize() const {
- return (8 + (handle ? handle->numInts : 0))*sizeof(int);
-}
-
-size_t GraphicBuffer::getFdCount() const {
- return handle ? handle->numFds : 0;
-}
-
-status_t GraphicBuffer::flatten(void* buffer, size_t size,
- int fds[], size_t count) const
-{
- size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
- if (size < sizeNeeded) return NO_MEMORY;
-
- size_t fdCountNeeded = GraphicBuffer::getFdCount();
- if (count < fdCountNeeded) return NO_MEMORY;
-
- int* buf = static_cast<int*>(buffer);
- buf[0] = 'GBFR';
- buf[1] = width;
- buf[2] = height;
- buf[3] = stride;
- buf[4] = format;
- buf[5] = usage;
- buf[6] = 0;
- buf[7] = 0;
-
- if (handle) {
- buf[6] = handle->numFds;
- buf[7] = handle->numInts;
- native_handle_t const* const h = handle;
- memcpy(fds, h->data, h->numFds*sizeof(int));
- memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
- }
-
- return NO_ERROR;
-}
-
-status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
- int fds[], size_t count)
-{
- if (size < 8*sizeof(int)) return NO_MEMORY;
-
- int const* buf = static_cast<int const*>(buffer);
- if (buf[0] != 'GBFR') return BAD_TYPE;
-
- const size_t numFds = buf[6];
- const size_t numInts = buf[7];
-
- const size_t sizeNeeded = (8 + numInts) * sizeof(int);
- if (size < sizeNeeded) return NO_MEMORY;
-
- size_t fdCountNeeded = 0;
- if (count < fdCountNeeded) return NO_MEMORY;
-
- if (handle) {
- // free previous handle if any
- free_handle();
- }
-
- if (numFds || numInts) {
- width = buf[1];
- height = buf[2];
- stride = buf[3];
- format = buf[4];
- usage = buf[5];
- native_handle* h = native_handle_create(numFds, numInts);
- memcpy(h->data, fds, numFds*sizeof(int));
- memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
- handle = h;
- } else {
- width = height = stride = format = usage = 0;
- handle = NULL;
- }
-
- mOwner = ownHandle;
-
- if (handle != 0) {
- mBufferMapper.registerBuffer(handle);
- }
-
- return NO_ERROR;
-}
-
-
-void GraphicBuffer::setIndex(int index) {
- mIndex = index;
-}
-
-int GraphicBuffer::getIndex() const {
- return mIndex;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
deleted file mode 100644
index ff550d9..0000000
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "GraphicBufferAllocator"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include <cutils/log.h>
-
-#include <utils/Singleton.h>
-#include <utils/String8.h>
-#include <utils/Trace.h>
-
-#include <ui/GraphicBufferAllocator.h>
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator )
-
-Mutex GraphicBufferAllocator::sLock;
-KeyedVector<buffer_handle_t,
- GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
-
-GraphicBufferAllocator::GraphicBufferAllocator()
- : mAllocDev(0)
-{
- hw_module_t const* module;
- int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
- ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
- if (err == 0) {
- gralloc_open(module, &mAllocDev);
- }
-}
-
-GraphicBufferAllocator::~GraphicBufferAllocator()
-{
- gralloc_close(mAllocDev);
-}
-
-void GraphicBufferAllocator::dump(String8& result) const
-{
- Mutex::Autolock _l(sLock);
- KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
- size_t total = 0;
- const size_t SIZE = 4096;
- char buffer[SIZE];
- snprintf(buffer, SIZE, "Allocated buffers:\n");
- result.append(buffer);
- const size_t c = list.size();
- for (size_t i=0 ; i<c ; i++) {
- const alloc_rec_t& rec(list.valueAt(i));
- if (rec.size) {
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
- list.keyAt(i), rec.size/1024.0f,
- rec.w, rec.s, rec.h, rec.format, rec.usage);
- } else {
- snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
- list.keyAt(i),
- rec.w, rec.s, rec.h, rec.format, rec.usage);
- }
- result.append(buffer);
- total += rec.size;
- }
- snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
- result.append(buffer);
- if (mAllocDev->common.version >= 1 && mAllocDev->dump) {
- mAllocDev->dump(mAllocDev, buffer, SIZE);
- result.append(buffer);
- }
-}
-
-void GraphicBufferAllocator::dumpToSystemLog()
-{
- String8 s;
- GraphicBufferAllocator::getInstance().dump(s);
- ALOGD("%s", s.string());
-}
-
-status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
- int usage, buffer_handle_t* handle, int32_t* stride)
-{
- ATRACE_CALL();
- // make sure to not allocate a N x 0 or 0 x N buffer, since this is
- // allowed from an API stand-point allocate a 1x1 buffer instead.
- if (!w || !h)
- w = h = 1;
-
- // we have a h/w allocator and h/w buffer is requested
- status_t err;
-
- err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
-
- ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
- w, h, format, usage, err, strerror(-err));
-
- if (err == NO_ERROR) {
- Mutex::Autolock _l(sLock);
- KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
- int bpp = bytesPerPixel(format);
- if (bpp < 0) {
- // probably a HAL custom format. in any case, we don't know
- // what its pixel size is.
- bpp = 0;
- }
- alloc_rec_t rec;
- rec.w = w;
- rec.h = h;
- rec.s = *stride;
- rec.format = format;
- rec.usage = usage;
- rec.size = h * stride[0] * bpp;
- list.add(*handle, rec);
- }
-
- return err;
-}
-
-status_t GraphicBufferAllocator::free(buffer_handle_t handle)
-{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocDev->free(mAllocDev, handle);
-
- ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
- if (err == NO_ERROR) {
- Mutex::Autolock _l(sLock);
- KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
- list.removeItem(handle);
- }
-
- return err;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
deleted file mode 100644
index 967da98..0000000
--- a/libs/ui/GraphicBufferMapper.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "GraphicBufferMapper"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include <stdint.h>
-#include <errno.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include <ui/GraphicBufferMapper.h>
-#include <ui/Rect.h>
-
-#include <hardware/gralloc.h>
-
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
-
-GraphicBufferMapper::GraphicBufferMapper()
- : mAllocMod(0)
-{
- hw_module_t const* module;
- int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
- ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
- if (err == 0) {
- mAllocMod = (gralloc_module_t const *)module;
- }
-}
-
-status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
-{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocMod->registerBuffer(mAllocMod, handle);
-
- ALOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
- handle, err, strerror(-err));
- return err;
-}
-
-status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
-{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocMod->unregisterBuffer(mAllocMod, handle);
-
- ALOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
- handle, err, strerror(-err));
- return err;
-}
-
-status_t GraphicBufferMapper::lock(buffer_handle_t handle,
- int usage, const Rect& bounds, void** vaddr)
-{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocMod->lock(mAllocMod, handle, usage,
- bounds.left, bounds.top, bounds.width(), bounds.height(),
- vaddr);
-
- ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
- return err;
-}
-
-status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
-{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocMod->unlock(mAllocMod, handle);
-
- ALOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
- return err;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/ui/MODULE_LICENSE_APACHE2 b/libs/ui/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/ui/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/ui/NOTICE b/libs/ui/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libs/ui/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
deleted file mode 100644
index fc1d3c2..0000000
--- a/libs/ui/PixelFormat.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ui/PixelFormat.h>
-#include <hardware/hardware.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-static const int COMPONENT_YUV = 0xFF;
-
-struct Info {
- size_t size;
- size_t bitsPerPixel;
- struct {
- uint8_t ah;
- uint8_t al;
- uint8_t rh;
- uint8_t rl;
- uint8_t gh;
- uint8_t gl;
- uint8_t bh;
- uint8_t bl;
- };
- uint8_t components;
-};
-
-static Info const sPixelFormatInfos[] = {
- { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
- { 4, 32, {32,24, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGBA },
- { 4, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB },
- { 3, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB },
- { 2, 16, { 0, 0, 16,11, 11, 5, 5, 0 }, PixelFormatInfo::RGB },
- { 4, 32, {32,24, 24,16, 16, 8, 8, 0 }, PixelFormatInfo::RGBA },
- { 2, 16, { 1, 0, 16,11, 11, 6, 6, 1 }, PixelFormatInfo::RGBA },
- { 2, 16, { 4, 0, 16,12, 12, 8, 8, 4 }, PixelFormatInfo::RGBA },
- { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA},
- { 1, 8, { 0, 0, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::L },
- { 2, 16, {16, 8, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::LA },
- { 1, 8, { 0, 0, 8, 5, 5, 2, 2, 0 }, PixelFormatInfo::RGB },
-};
-
-static const Info* gGetPixelFormatTable(size_t* numEntries) {
- if (numEntries) {
- *numEntries = sizeof(sPixelFormatInfos)/sizeof(Info);
- }
- return sPixelFormatInfos;
-}
-
-// ----------------------------------------------------------------------------
-
-size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
-{
- size_t size;
- if (components == COMPONENT_YUV) {
- // YCbCr formats are different.
- size = (width * bitsPerPixel)>>3;
- } else {
- size = width * bytesPerPixel;
- }
- return size;
-}
-
-ssize_t bytesPerPixel(PixelFormat format)
-{
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- return (err < 0) ? err : info.bytesPerPixel;
-}
-
-ssize_t bitsPerPixel(PixelFormat format)
-{
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- return (err < 0) ? err : info.bitsPerPixel;
-}
-
-status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
-{
- if (format < 0)
- return BAD_VALUE;
-
- if (info->version != sizeof(PixelFormatInfo))
- return INVALID_OPERATION;
-
- // YUV format from the HAL are handled here
- switch (format) {
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- info->bitsPerPixel = 16;
- goto done;
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YV12:
- info->bitsPerPixel = 12;
- done:
- info->format = format;
- info->components = COMPONENT_YUV;
- info->bytesPerPixel = 1;
- info->h_alpha = 0;
- info->l_alpha = 0;
- info->h_red = info->h_green = info->h_blue = 8;
- info->l_red = info->l_green = info->l_blue = 0;
- return NO_ERROR;
- }
-
- size_t numEntries;
- const Info *i = gGetPixelFormatTable(&numEntries) + format;
- bool valid = uint32_t(format) < numEntries;
- if (!valid) {
- return BAD_INDEX;
- }
-
- info->format = format;
- info->bytesPerPixel = i->size;
- info->bitsPerPixel = i->bitsPerPixel;
- info->h_alpha = i->ah;
- info->l_alpha = i->al;
- info->h_red = i->rh;
- info->l_red = i->rl;
- info->h_green = i->gh;
- info->l_green = i->gl;
- info->h_blue = i->bh;
- info->l_blue = i->bl;
- info->components = i->components;
-
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
deleted file mode 100644
index 5694e00..0000000
--- a/libs/ui/Rect.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ui/Rect.h>
-
-namespace android {
-
-static inline int32_t min(int32_t a, int32_t b) {
- return (a<b) ? a : b;
-}
-
-static inline int32_t max(int32_t a, int32_t b) {
- return (a>b) ? a : b;
-}
-
-void Rect::makeInvalid() {
- left = 0;
- top = 0;
- right = -1;
- bottom = -1;
-}
-
-bool Rect::operator < (const Rect& rhs) const
-{
- if (top<rhs.top) {
- return true;
- } else if (top == rhs.top) {
- if (left < rhs.left) {
- return true;
- } else if (left == rhs.left) {
- if (bottom<rhs.bottom) {
- return true;
- } else if (bottom == rhs.bottom) {
- if (right<rhs.right) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-Rect& Rect::offsetTo(int32_t x, int32_t y)
-{
- right -= left - x;
- bottom -= top - y;
- left = x;
- top = y;
- return *this;
-}
-
-Rect& Rect::offsetBy(int32_t x, int32_t y)
-{
- left += x;
- top += y;
- right+= x;
- bottom+=y;
- return *this;
-}
-
-const Rect Rect::operator + (const Point& rhs) const
-{
- const Rect result(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y);
- return result;
-}
-
-const Rect Rect::operator - (const Point& rhs) const
-{
- const Rect result(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y);
- return result;
-}
-
-bool Rect::intersect(const Rect& with, Rect* result) const
-{
- result->left = max(left, with.left);
- result->top = max(top, with.top);
- result->right = min(right, with.right);
- result->bottom = min(bottom, with.bottom);
- return !(result->isEmpty());
-}
-
-}; // namespace android
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
deleted file mode 100644
index 6e2e731..0000000
--- a/libs/ui/Region.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Region"
-
-#include <limits.h>
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/Point.h>
-
-#include <private/ui/RegionHelper.h>
-
-// ----------------------------------------------------------------------------
-#define VALIDATE_REGIONS (false)
-#define VALIDATE_WITH_CORECG (false)
-// ----------------------------------------------------------------------------
-
-#if VALIDATE_WITH_CORECG
-#include <core/SkRegion.h>
-#endif
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-enum {
- op_nand = region_operator<Rect>::op_nand,
- op_and = region_operator<Rect>::op_and,
- op_or = region_operator<Rect>::op_or,
- op_xor = region_operator<Rect>::op_xor
-};
-
-// ----------------------------------------------------------------------------
-
-Region::Region()
- : mBounds(0,0)
-{
-}
-
-Region::Region(const Region& rhs)
- : mBounds(rhs.mBounds), mStorage(rhs.mStorage)
-{
-#if VALIDATE_REGIONS
- validate(rhs, "rhs copy-ctor");
-#endif
-}
-
-Region::Region(const Rect& rhs)
- : mBounds(rhs)
-{
-}
-
-Region::Region(const void* buffer)
-{
- status_t err = read(buffer);
- ALOGE_IF(err<0, "error %s reading Region from buffer", strerror(err));
-}
-
-Region::~Region()
-{
-}
-
-Region& Region::operator = (const Region& rhs)
-{
-#if VALIDATE_REGIONS
- validate(*this, "this->operator=");
- validate(rhs, "rhs.operator=");
-#endif
- mBounds = rhs.mBounds;
- mStorage = rhs.mStorage;
- return *this;
-}
-
-Region& Region::makeBoundsSelf()
-{
- mStorage.clear();
- return *this;
-}
-
-void Region::clear()
-{
- mBounds.clear();
- mStorage.clear();
-}
-
-void Region::set(const Rect& r)
-{
- mBounds = r;
- mStorage.clear();
-}
-
-void Region::set(uint32_t w, uint32_t h)
-{
- mBounds = Rect(int(w), int(h));
- mStorage.clear();
-}
-
-// ----------------------------------------------------------------------------
-
-void Region::addRectUnchecked(int l, int t, int r, int b)
-{
- mStorage.add(Rect(l,t,r,b));
-#if VALIDATE_REGIONS
- validate(*this, "addRectUnchecked");
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Rect& r) {
- return operationSelf(r, op_or);
-}
-Region& Region::xorSelf(const Rect& r) {
- return operationSelf(r, op_xor);
-}
-Region& Region::andSelf(const Rect& r) {
- return operationSelf(r, op_and);
-}
-Region& Region::subtractSelf(const Rect& r) {
- return operationSelf(r, op_nand);
-}
-Region& Region::operationSelf(const Rect& r, int op) {
- Region lhs(*this);
- boolean_operation(op, *this, lhs, r);
- return *this;
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Region& rhs) {
- return operationSelf(rhs, op_or);
-}
-Region& Region::xorSelf(const Region& rhs) {
- return operationSelf(rhs, op_xor);
-}
-Region& Region::andSelf(const Region& rhs) {
- return operationSelf(rhs, op_and);
-}
-Region& Region::subtractSelf(const Region& rhs) {
- return operationSelf(rhs, op_nand);
-}
-Region& Region::operationSelf(const Region& rhs, int op) {
- Region lhs(*this);
- boolean_operation(op, *this, lhs, rhs);
- return *this;
-}
-
-Region& Region::translateSelf(int x, int y) {
- if (x|y) translate(*this, x, y);
- return *this;
-}
-
-// ----------------------------------------------------------------------------
-
-const Region Region::merge(const Rect& rhs) const {
- return operation(rhs, op_or);
-}
-const Region Region::mergeExclusive(const Rect& rhs) const {
- return operation(rhs, op_xor);
-}
-const Region Region::intersect(const Rect& rhs) const {
- return operation(rhs, op_and);
-}
-const Region Region::subtract(const Rect& rhs) const {
- return operation(rhs, op_nand);
-}
-const Region Region::operation(const Rect& rhs, int op) const {
- Region result;
- boolean_operation(op, result, *this, rhs);
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-const Region Region::merge(const Region& rhs) const {
- return operation(rhs, op_or);
-}
-const Region Region::mergeExclusive(const Region& rhs) const {
- return operation(rhs, op_xor);
-}
-const Region Region::intersect(const Region& rhs) const {
- return operation(rhs, op_and);
-}
-const Region Region::subtract(const Region& rhs) const {
- return operation(rhs, op_nand);
-}
-const Region Region::operation(const Region& rhs, int op) const {
- Region result;
- boolean_operation(op, result, *this, rhs);
- return result;
-}
-
-const Region Region::translate(int x, int y) const {
- Region result;
- translate(result, *this, x, y);
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-Region& Region::orSelf(const Region& rhs, int dx, int dy) {
- return operationSelf(rhs, dx, dy, op_or);
-}
-Region& Region::xorSelf(const Region& rhs, int dx, int dy) {
- return operationSelf(rhs, dx, dy, op_xor);
-}
-Region& Region::andSelf(const Region& rhs, int dx, int dy) {
- return operationSelf(rhs, dx, dy, op_and);
-}
-Region& Region::subtractSelf(const Region& rhs, int dx, int dy) {
- return operationSelf(rhs, dx, dy, op_nand);
-}
-Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) {
- Region lhs(*this);
- boolean_operation(op, *this, lhs, rhs, dx, dy);
- return *this;
-}
-
-// ----------------------------------------------------------------------------
-
-const Region Region::merge(const Region& rhs, int dx, int dy) const {
- return operation(rhs, dx, dy, op_or);
-}
-const Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const {
- return operation(rhs, dx, dy, op_xor);
-}
-const Region Region::intersect(const Region& rhs, int dx, int dy) const {
- return operation(rhs, dx, dy, op_and);
-}
-const Region Region::subtract(const Region& rhs, int dx, int dy) const {
- return operation(rhs, dx, dy, op_nand);
-}
-const Region Region::operation(const Region& rhs, int dx, int dy, int op) const {
- Region result;
- boolean_operation(op, result, *this, rhs, dx, dy);
- return result;
-}
-
-// ----------------------------------------------------------------------------
-
-// This is our region rasterizer, which merges rects and spans together
-// to obtain an optimal region.
-class Region::rasterizer : public region_operator<Rect>::region_rasterizer
-{
- Rect& bounds;
- Vector<Rect>& storage;
- Rect* head;
- Rect* tail;
- Vector<Rect> span;
- Rect* cur;
-public:
- rasterizer(Region& reg)
- : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() {
- bounds.top = bounds.bottom = 0;
- bounds.left = INT_MAX;
- bounds.right = INT_MIN;
- storage.clear();
- }
-
- ~rasterizer() {
- if (span.size()) {
- flushSpan();
- }
- if (storage.size()) {
- bounds.top = storage.itemAt(0).top;
- bounds.bottom = storage.top().bottom;
- if (storage.size() == 1) {
- storage.clear();
- }
- } else {
- bounds.left = 0;
- bounds.right = 0;
- }
- }
-
- virtual void operator()(const Rect& rect) {
- //ALOGD(">>> %3d, %3d, %3d, %3d",
- // rect.left, rect.top, rect.right, rect.bottom);
- if (span.size()) {
- if (cur->top != rect.top) {
- flushSpan();
- } else if (cur->right == rect.left) {
- cur->right = rect.right;
- return;
- }
- }
- span.add(rect);
- cur = span.editArray() + (span.size() - 1);
- }
-private:
- template<typename T>
- static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; }
- template<typename T>
- static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; }
- void flushSpan() {
- bool merge = false;
- if (tail-head == ssize_t(span.size())) {
- Rect const* p = span.editArray();
- Rect const* q = head;
- if (p->top == q->bottom) {
- merge = true;
- while (q != tail) {
- if ((p->left != q->left) || (p->right != q->right)) {
- merge = false;
- break;
- }
- p++, q++;
- }
- }
- }
- if (merge) {
- const int bottom = span[0].bottom;
- Rect* r = head;
- while (r != tail) {
- r->bottom = bottom;
- r++;
- }
- } else {
- bounds.left = min(span.itemAt(0).left, bounds.left);
- bounds.right = max(span.top().right, bounds.right);
- storage.appendVector(span);
- tail = storage.editArray() + storage.size();
- head = tail - span.size();
- }
- span.clear();
- }
-};
-
-bool Region::validate(const Region& reg, const char* name)
-{
- bool result = true;
- const_iterator cur = reg.begin();
- const_iterator const tail = reg.end();
- const_iterator prev = cur++;
- Rect b(*prev);
- while (cur != tail) {
- b.left = b.left < cur->left ? b.left : cur->left;
- b.top = b.top < cur->top ? b.top : cur->top;
- b.right = b.right > cur->right ? b.right : cur->right;
- b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
- if (cur->top == prev->top) {
- if (cur->bottom != prev->bottom) {
- ALOGE("%s: invalid span %p", name, cur);
- result = false;
- } else if (cur->left < prev->right) {
- ALOGE("%s: spans overlap horizontally prev=%p, cur=%p",
- name, prev, cur);
- result = false;
- }
- } else if (cur->top < prev->bottom) {
- ALOGE("%s: spans overlap vertically prev=%p, cur=%p",
- name, prev, cur);
- result = false;
- }
- prev = cur;
- cur++;
- }
- if (b != reg.getBounds()) {
- result = false;
- ALOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
- b.left, b.top, b.right, b.bottom,
- reg.getBounds().left, reg.getBounds().top,
- reg.getBounds().right, reg.getBounds().bottom);
- }
- if (result == false) {
- reg.dump(name);
- }
- return result;
-}
-
-void Region::boolean_operation(int op, Region& dst,
- const Region& lhs,
- const Region& rhs, int dx, int dy)
-{
-#if VALIDATE_REGIONS
- validate(lhs, "boolean_operation (before): lhs");
- validate(rhs, "boolean_operation (before): rhs");
- validate(dst, "boolean_operation (before): dst");
-#endif
-
- size_t lhs_count;
- Rect const * const lhs_rects = lhs.getArray(&lhs_count);
-
- size_t rhs_count;
- Rect const * const rhs_rects = rhs.getArray(&rhs_count);
-
- region_operator<Rect>::region lhs_region(lhs_rects, lhs_count);
- region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy);
- region_operator<Rect> operation(op, lhs_region, rhs_region);
- { // scope for rasterizer (dtor has side effects)
- rasterizer r(dst);
- operation(r);
- }
-
-#if VALIDATE_REGIONS
- validate(lhs, "boolean_operation: lhs");
- validate(rhs, "boolean_operation: rhs");
- validate(dst, "boolean_operation: dst");
-#endif
-
-#if VALIDATE_WITH_CORECG
- SkRegion sk_lhs;
- SkRegion sk_rhs;
- SkRegion sk_dst;
-
- for (size_t i=0 ; i<lhs_count ; i++)
- sk_lhs.op(
- lhs_rects[i].left + dx,
- lhs_rects[i].top + dy,
- lhs_rects[i].right + dx,
- lhs_rects[i].bottom + dy,
- SkRegion::kUnion_Op);
-
- for (size_t i=0 ; i<rhs_count ; i++)
- sk_rhs.op(
- rhs_rects[i].left + dx,
- rhs_rects[i].top + dy,
- rhs_rects[i].right + dx,
- rhs_rects[i].bottom + dy,
- SkRegion::kUnion_Op);
-
- const char* name = "---";
- SkRegion::Op sk_op;
- switch (op) {
- case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break;
- case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break;
- case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break;
- case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break;
- }
- sk_dst.op(sk_lhs, sk_rhs, sk_op);
-
- if (sk_dst.isEmpty() && dst.isEmpty())
- return;
-
- bool same = true;
- Region::const_iterator head = dst.begin();
- Region::const_iterator const tail = dst.end();
- SkRegion::Iterator it(sk_dst);
- while (!it.done()) {
- if (head != tail) {
- if (
- head->left != it.rect().fLeft ||
- head->top != it.rect().fTop ||
- head->right != it.rect().fRight ||
- head->bottom != it.rect().fBottom
- ) {
- same = false;
- break;
- }
- } else {
- same = false;
- break;
- }
- head++;
- it.next();
- }
-
- if (head != tail) {
- same = false;
- }
-
- if(!same) {
- ALOGD("---\nregion boolean %s failed", name);
- lhs.dump("lhs");
- rhs.dump("rhs");
- dst.dump("dst");
- ALOGD("should be");
- SkRegion::Iterator it(sk_dst);
- while (!it.done()) {
- ALOGD(" [%3d, %3d, %3d, %3d]",
- it.rect().fLeft,
- it.rect().fTop,
- it.rect().fRight,
- it.rect().fBottom);
- it.next();
- }
- }
-#endif
-}
-
-void Region::boolean_operation(int op, Region& dst,
- const Region& lhs,
- const Rect& rhs, int dx, int dy)
-{
- if (!rhs.isValid()) {
- ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}",
- op, rhs.left, rhs.top, rhs.right, rhs.bottom);
- return;
- }
-
-#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS
- boolean_operation(op, dst, lhs, Region(rhs), dx, dy);
-#else
- size_t lhs_count;
- Rect const * const lhs_rects = lhs.getArray(&lhs_count);
-
- region_operator<Rect>::region lhs_region(lhs_rects, lhs_count);
- region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy);
- region_operator<Rect> operation(op, lhs_region, rhs_region);
- { // scope for rasterizer (dtor has side effects)
- rasterizer r(dst);
- operation(r);
- }
-
-#endif
-}
-
-void Region::boolean_operation(int op, Region& dst,
- const Region& lhs, const Region& rhs)
-{
- boolean_operation(op, dst, lhs, rhs, 0, 0);
-}
-
-void Region::boolean_operation(int op, Region& dst,
- const Region& lhs, const Rect& rhs)
-{
- boolean_operation(op, dst, lhs, rhs, 0, 0);
-}
-
-void Region::translate(Region& reg, int dx, int dy)
-{
- if (!reg.isEmpty()) {
-#if VALIDATE_REGIONS
- validate(reg, "translate (before)");
-#endif
- reg.mBounds.translate(dx, dy);
- size_t count = reg.mStorage.size();
- Rect* rects = reg.mStorage.editArray();
- while (count) {
- rects->translate(dx, dy);
- rects++;
- count--;
- }
-#if VALIDATE_REGIONS
- validate(reg, "translate (after)");
-#endif
- }
-}
-
-void Region::translate(Region& dst, const Region& reg, int dx, int dy)
-{
- dst = reg;
- translate(dst, dx, dy);
-}
-
-// ----------------------------------------------------------------------------
-
-ssize_t Region::write(void* buffer, size_t size) const
-{
-#if VALIDATE_REGIONS
- validate(*this, "write(buffer)");
-#endif
- const size_t count = mStorage.size();
- const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
- if (buffer != NULL) {
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- *p = count;
- memcpy(p+1, &mBounds, sizeof(Rect));
- if (count) {
- memcpy(p+5, mStorage.array(), count*sizeof(Rect));
- }
- }
- return ssize_t(sizeNeeded);
-}
-
-ssize_t Region::read(const void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- const size_t count = *p;
- memcpy(&mBounds, p+1, sizeof(Rect));
- mStorage.clear();
- if (count) {
- mStorage.insertAt(0, count);
- memcpy(mStorage.editArray(), p+5, count*sizeof(Rect));
- }
-#if VALIDATE_REGIONS
- validate(*this, "read(buffer)");
-#endif
- return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect));
-}
-
-ssize_t Region::writeEmpty(void* buffer, size_t size)
-{
- const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect);
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- memset(p, 0, sizeNeeded);
- return ssize_t(sizeNeeded);
-}
-
-bool Region::isEmpty(void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- Rect const* const b = reinterpret_cast<Rect const *>(p+1);
- return b->isEmpty();
-}
-
-// ----------------------------------------------------------------------------
-
-Region::const_iterator Region::begin() const {
- return isRect() ? &mBounds : mStorage.array();
-}
-
-Region::const_iterator Region::end() const {
- return isRect() ? ((&mBounds) + 1) : (mStorage.array() + mStorage.size());
-}
-
-Rect const* Region::getArray(size_t* count) const {
- const_iterator const b(begin());
- const_iterator const e(end());
- if (count) *count = e-b;
- return b;
-}
-
-size_t Region::getRects(Vector<Rect>& rectList) const
-{
- rectList = mStorage;
- if (rectList.isEmpty()) {
- rectList.clear();
- rectList.add(mBounds);
- }
- return rectList.size();
-}
-
-// ----------------------------------------------------------------------------
-
-void Region::dump(String8& out, const char* what, uint32_t flags) const
-{
- (void)flags;
- const_iterator head = begin();
- const_iterator const tail = end();
-
- size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n",
- what, this, tail-head);
- out.append(buffer);
- while (head != tail) {
- snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n",
- head->left, head->top, head->right, head->bottom);
- out.append(buffer);
- head++;
- }
-}
-
-void Region::dump(const char* what, uint32_t flags) const
-{
- (void)flags;
- const_iterator head = begin();
- const_iterator const tail = end();
- ALOGD(" Region %s (this=%p, count=%d)\n", what, this, tail-head);
- while (head != tail) {
- ALOGD(" [%3d, %3d, %3d, %3d]\n",
- head->left, head->top, head->right, head->bottom);
- head++;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
deleted file mode 100644
index 50cad36..0000000
--- a/libs/ui/tests/Android.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the manual test programs.
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/ui/tests/region/Android.mk b/libs/ui/tests/region/Android.mk
deleted file mode 100644
index 6cc4a5a..0000000
--- a/libs/ui/tests/region/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- region.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libui
-
-LOCAL_MODULE:= test-region
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/ui/tests/region/region.cpp b/libs/ui/tests/region/region.cpp
deleted file mode 100644
index 6347294..0000000
--- a/libs/ui/tests/region/region.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Region"
-
-#include <stdio.h>
-#include <utils/Debug.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-using namespace android;
-
-int main()
-{
- Region empty;
- Region reg0( Rect( 0, 0, 100, 100 ) );
- Region reg1 = reg0;
- Region reg2, reg3;
-
- Region reg4 = empty | reg1;
- Region reg5 = reg1 | empty;
-
- reg4.dump("reg4");
- reg5.dump("reg5");
-
- reg0.dump("reg0");
- reg1.dump("reg1");
-
- reg0 = reg0 | reg0.translate(150, 0);
- reg0.dump("reg0");
- reg1.dump("reg1");
-
- reg0 = reg0 | reg0.translate(300, 0);
- reg0.dump("reg0");
- reg1.dump("reg1");
-
- //reg2 = reg0 | reg0.translate(0, 100);
- //reg0.dump("reg0");
- //reg1.dump("reg1");
- //reg2.dump("reg2");
-
- //reg3 = reg0 | reg0.translate(0, 150);
- //reg0.dump("reg0");
- //reg1.dump("reg1");
- //reg2.dump("reg2");
- //reg3.dump("reg3");
-
- ALOGD("---");
- reg2 = reg0 | reg0.translate(100, 0);
- reg0.dump("reg0");
- reg1.dump("reg1");
- reg2.dump("reg2");
-
- return 0;
-}
-
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
deleted file mode 100644
index 57c048a..0000000
--- a/libs/utils/Android.mk
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-# libutils is a little unique: It's built twice, once for the host
-# and once for the device.
-
-commonSources:= \
- BasicHashtable.cpp \
- BlobCache.cpp \
- BufferedTextOutput.cpp \
- CallStack.cpp \
- Debug.cpp \
- FileMap.cpp \
- Flattenable.cpp \
- LinearTransform.cpp \
- PropertyMap.cpp \
- RefBase.cpp \
- SharedBuffer.cpp \
- Static.cpp \
- StopWatch.cpp \
- String8.cpp \
- String16.cpp \
- StringArray.cpp \
- SystemClock.cpp \
- TextOutput.cpp \
- Threads.cpp \
- Timers.cpp \
- Tokenizer.cpp \
- Unicode.cpp \
- VectorImpl.cpp \
- misc.cpp
-
-
-# For the host
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(commonSources)
-
-LOCAL_MODULE:= libutils
-
-LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
-
-ifeq ($(HOST_OS),windows)
-ifeq ($(strip $(USE_CYGWIN),),)
-# Under MinGW, ctype.h doesn't need multi-byte support
-LOCAL_CFLAGS += -DMB_CUR_MAX=1
-endif
-endif
-
-ifeq ($(TARGET_OS),linux)
-LOCAL_LDLIBS += -lrt -ldl
-endif
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# For the device
-# =====================================================
-include $(CLEAR_VARS)
-
-
-# we have the common sources, plus some device-specific stuff
-LOCAL_SRC_FILES:= \
- $(commonSources) \
- Looper.cpp \
- Trace.cpp
-
-ifeq ($(TARGET_OS),linux)
-LOCAL_LDLIBS += -lrt -ldl
-endif
-
-LOCAL_C_INCLUDES += \
- bionic/libc/private
-
-LOCAL_LDLIBS += -lpthread
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libdl \
- libcorkscrew
-
-LOCAL_MODULE:= libutils
-include $(BUILD_SHARED_LIBRARY)
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/utils/BasicHashtable.cpp b/libs/utils/BasicHashtable.cpp
deleted file mode 100644
index fb8ec9f..0000000
--- a/libs/utils/BasicHashtable.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BasicHashtable"
-
-#include <math.h>
-
-#include <utils/Log.h>
-#include <utils/BasicHashtable.h>
-#include <utils/misc.h>
-
-namespace android {
-
-BasicHashtableImpl::BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor,
- size_t minimumInitialCapacity, float loadFactor) :
- mBucketSize(entrySize + sizeof(Bucket)), mHasTrivialDestructor(hasTrivialDestructor),
- mLoadFactor(loadFactor), mSize(0),
- mFilledBuckets(0), mBuckets(NULL) {
- determineCapacity(minimumInitialCapacity, mLoadFactor, &mBucketCount, &mCapacity);
-}
-
-BasicHashtableImpl::BasicHashtableImpl(const BasicHashtableImpl& other) :
- mBucketSize(other.mBucketSize), mHasTrivialDestructor(other.mHasTrivialDestructor),
- mCapacity(other.mCapacity), mLoadFactor(other.mLoadFactor),
- mSize(other.mSize), mFilledBuckets(other.mFilledBuckets),
- mBucketCount(other.mBucketCount), mBuckets(other.mBuckets) {
- if (mBuckets) {
- SharedBuffer::bufferFromData(mBuckets)->acquire();
- }
-}
-
-void BasicHashtableImpl::dispose() {
- if (mBuckets) {
- releaseBuckets(mBuckets, mBucketCount);
- }
-}
-
-void BasicHashtableImpl::clone() {
- if (mBuckets) {
- void* newBuckets = allocateBuckets(mBucketCount);
- copyBuckets(mBuckets, newBuckets, mBucketCount);
- releaseBuckets(mBuckets, mBucketCount);
- mBuckets = newBuckets;
- }
-}
-
-void BasicHashtableImpl::setTo(const BasicHashtableImpl& other) {
- if (mBuckets) {
- releaseBuckets(mBuckets, mBucketCount);
- }
-
- mCapacity = other.mCapacity;
- mLoadFactor = other.mLoadFactor;
- mSize = other.mSize;
- mFilledBuckets = other.mFilledBuckets;
- mBucketCount = other.mBucketCount;
- mBuckets = other.mBuckets;
-
- if (mBuckets) {
- SharedBuffer::bufferFromData(mBuckets)->acquire();
- }
-}
-
-void BasicHashtableImpl::clear() {
- if (mBuckets) {
- if (mFilledBuckets) {
- SharedBuffer* sb = SharedBuffer::bufferFromData(mBuckets);
- if (sb->onlyOwner()) {
- destroyBuckets(mBuckets, mBucketCount);
- for (size_t i = 0; i < mSize; i++) {
- Bucket& bucket = bucketAt(mBuckets, i);
- bucket.cookie = 0;
- }
- } else {
- releaseBuckets(mBuckets, mBucketCount);
- mBuckets = NULL;
- }
- mFilledBuckets = 0;
- }
- mSize = 0;
- }
-}
-
-ssize_t BasicHashtableImpl::next(ssize_t index) const {
- if (mSize) {
- while (size_t(++index) < mBucketCount) {
- const Bucket& bucket = bucketAt(mBuckets, index);
- if (bucket.cookie & Bucket::PRESENT) {
- return index;
- }
- }
- }
- return -1;
-}
-
-ssize_t BasicHashtableImpl::find(ssize_t index, hash_t hash,
- const void* __restrict__ key) const {
- if (!mSize) {
- return -1;
- }
-
- hash = trimHash(hash);
- if (index < 0) {
- index = chainStart(hash, mBucketCount);
-
- const Bucket& bucket = bucketAt(mBuckets, size_t(index));
- if (bucket.cookie & Bucket::PRESENT) {
- if (compareBucketKey(bucket, key)) {
- return index;
- }
- } else {
- if (!(bucket.cookie & Bucket::COLLISION)) {
- return -1;
- }
- }
- }
-
- size_t inc = chainIncrement(hash, mBucketCount);
- for (;;) {
- index = chainSeek(index, inc, mBucketCount);
-
- const Bucket& bucket = bucketAt(mBuckets, size_t(index));
- if (bucket.cookie & Bucket::PRESENT) {
- if ((bucket.cookie & Bucket::HASH_MASK) == hash
- && compareBucketKey(bucket, key)) {
- return index;
- }
- }
- if (!(bucket.cookie & Bucket::COLLISION)) {
- return -1;
- }
- }
-}
-
-size_t BasicHashtableImpl::add(hash_t hash, const void* entry) {
- if (!mBuckets) {
- mBuckets = allocateBuckets(mBucketCount);
- } else {
- edit();
- }
-
- hash = trimHash(hash);
- for (;;) {
- size_t index = chainStart(hash, mBucketCount);
- Bucket* bucket = &bucketAt(mBuckets, size_t(index));
- if (bucket->cookie & Bucket::PRESENT) {
- size_t inc = chainIncrement(hash, mBucketCount);
- do {
- bucket->cookie |= Bucket::COLLISION;
- index = chainSeek(index, inc, mBucketCount);
- bucket = &bucketAt(mBuckets, size_t(index));
- } while (bucket->cookie & Bucket::PRESENT);
- }
-
- uint32_t collision = bucket->cookie & Bucket::COLLISION;
- if (!collision) {
- if (mFilledBuckets >= mCapacity) {
- rehash(mCapacity * 2, mLoadFactor);
- continue;
- }
- mFilledBuckets += 1;
- }
-
- bucket->cookie = collision | Bucket::PRESENT | hash;
- mSize += 1;
- initializeBucketEntry(*bucket, entry);
- return index;
- }
-}
-
-void BasicHashtableImpl::removeAt(size_t index) {
- edit();
-
- Bucket& bucket = bucketAt(mBuckets, index);
- bucket.cookie &= ~Bucket::PRESENT;
- if (!(bucket.cookie & Bucket::COLLISION)) {
- mFilledBuckets -= 1;
- }
- mSize -= 1;
- if (!mHasTrivialDestructor) {
- destroyBucketEntry(bucket);
- }
-}
-
-void BasicHashtableImpl::rehash(size_t minimumCapacity, float loadFactor) {
- if (minimumCapacity < mSize) {
- minimumCapacity = mSize;
- }
- size_t newBucketCount, newCapacity;
- determineCapacity(minimumCapacity, loadFactor, &newBucketCount, &newCapacity);
-
- if (newBucketCount != mBucketCount || newCapacity != mCapacity) {
- if (mBuckets) {
- void* newBuckets;
- if (mSize) {
- newBuckets = allocateBuckets(newBucketCount);
- for (size_t i = 0; i < mBucketCount; i++) {
- const Bucket& fromBucket = bucketAt(mBuckets, i);
- if (fromBucket.cookie & Bucket::PRESENT) {
- hash_t hash = fromBucket.cookie & Bucket::HASH_MASK;
- size_t index = chainStart(hash, newBucketCount);
- Bucket* toBucket = &bucketAt(newBuckets, size_t(index));
- if (toBucket->cookie & Bucket::PRESENT) {
- size_t inc = chainIncrement(hash, newBucketCount);
- do {
- toBucket->cookie |= Bucket::COLLISION;
- index = chainSeek(index, inc, newBucketCount);
- toBucket = &bucketAt(newBuckets, size_t(index));
- } while (toBucket->cookie & Bucket::PRESENT);
- }
- toBucket->cookie = Bucket::PRESENT | hash;
- initializeBucketEntry(*toBucket, fromBucket.entry);
- }
- }
- } else {
- newBuckets = NULL;
- }
- releaseBuckets(mBuckets, mBucketCount);
- mBuckets = newBuckets;
- mFilledBuckets = mSize;
- }
- mBucketCount = newBucketCount;
- mCapacity = newCapacity;
- }
- mLoadFactor = loadFactor;
-}
-
-void* BasicHashtableImpl::allocateBuckets(size_t count) const {
- size_t bytes = count * mBucketSize;
- SharedBuffer* sb = SharedBuffer::alloc(bytes);
- LOG_ALWAYS_FATAL_IF(!sb, "Could not allocate %u bytes for hashtable with %u buckets.",
- uint32_t(bytes), uint32_t(count));
- void* buckets = sb->data();
- for (size_t i = 0; i < count; i++) {
- Bucket& bucket = bucketAt(buckets, i);
- bucket.cookie = 0;
- }
- return buckets;
-}
-
-void BasicHashtableImpl::releaseBuckets(void* __restrict__ buckets, size_t count) const {
- SharedBuffer* sb = SharedBuffer::bufferFromData(buckets);
- if (sb->release(SharedBuffer::eKeepStorage) == 1) {
- destroyBuckets(buckets, count);
- SharedBuffer::dealloc(sb);
- }
-}
-
-void BasicHashtableImpl::destroyBuckets(void* __restrict__ buckets, size_t count) const {
- if (!mHasTrivialDestructor) {
- for (size_t i = 0; i < count; i++) {
- Bucket& bucket = bucketAt(buckets, i);
- if (bucket.cookie & Bucket::PRESENT) {
- destroyBucketEntry(bucket);
- }
- }
- }
-}
-
-void BasicHashtableImpl::copyBuckets(const void* __restrict__ fromBuckets,
- void* __restrict__ toBuckets, size_t count) const {
- for (size_t i = 0; i < count; i++) {
- const Bucket& fromBucket = bucketAt(fromBuckets, i);
- Bucket& toBucket = bucketAt(toBuckets, i);
- toBucket.cookie = fromBucket.cookie;
- if (fromBucket.cookie & Bucket::PRESENT) {
- initializeBucketEntry(toBucket, fromBucket.entry);
- }
- }
-}
-
-// Table of 31-bit primes where each prime is no less than twice as large
-// as the previous one. Generated by "primes.py".
-static size_t PRIMES[] = {
- 5,
- 11,
- 23,
- 47,
- 97,
- 197,
- 397,
- 797,
- 1597,
- 3203,
- 6421,
- 12853,
- 25717,
- 51437,
- 102877,
- 205759,
- 411527,
- 823117,
- 1646237,
- 3292489,
- 6584983,
- 13169977,
- 26339969,
- 52679969,
- 105359939,
- 210719881,
- 421439783,
- 842879579,
- 1685759167,
- 0,
-};
-
-void BasicHashtableImpl::determineCapacity(size_t minimumCapacity, float loadFactor,
- size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity) {
- LOG_ALWAYS_FATAL_IF(loadFactor <= 0.0f || loadFactor > 1.0f,
- "Invalid load factor %0.3f. Must be in the range (0, 1].", loadFactor);
-
- size_t count = ceilf(minimumCapacity / loadFactor) + 1;
- size_t i = 0;
- while (count > PRIMES[i] && i < NELEM(PRIMES)) {
- i++;
- }
- count = PRIMES[i];
- LOG_ALWAYS_FATAL_IF(!count, "Could not determine required number of buckets for "
- "hashtable with minimum capacity %u and load factor %0.3f.",
- uint32_t(minimumCapacity), loadFactor);
- *outBucketCount = count;
- *outCapacity = ceilf((count - 1) * loadFactor);
-}
-
-}; // namespace android
diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp
deleted file mode 100644
index be398ee..0000000
--- a/libs/utils/BlobCache.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "BlobCache"
-//#define LOG_NDEBUG 0
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <utils/BlobCache.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-namespace android {
-
-// BlobCache::Header::mMagicNumber value
-static const uint32_t blobCacheMagic = '_Bb$';
-
-// BlobCache::Header::mBlobCacheVersion value
-static const uint32_t blobCacheVersion = 1;
-
-// BlobCache::Header::mDeviceVersion value
-static const uint32_t blobCacheDeviceVersion = 1;
-
-BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize):
- mMaxKeySize(maxKeySize),
- mMaxValueSize(maxValueSize),
- mMaxTotalSize(maxTotalSize),
- mTotalSize(0) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-#ifdef _WIN32
- srand(now);
-#else
- mRandState[0] = (now >> 0) & 0xFFFF;
- mRandState[1] = (now >> 16) & 0xFFFF;
- mRandState[2] = (now >> 32) & 0xFFFF;
-#endif
- ALOGV("initializing random seed using %lld", now);
-}
-
-void BlobCache::set(const void* key, size_t keySize, const void* value,
- size_t valueSize) {
- if (mMaxKeySize < keySize) {
- ALOGV("set: not caching because the key is too large: %d (limit: %d)",
- keySize, mMaxKeySize);
- return;
- }
- if (mMaxValueSize < valueSize) {
- ALOGV("set: not caching because the value is too large: %d (limit: %d)",
- valueSize, mMaxValueSize);
- return;
- }
- if (mMaxTotalSize < keySize + valueSize) {
- ALOGV("set: not caching because the combined key/value size is too "
- "large: %d (limit: %d)", keySize + valueSize, mMaxTotalSize);
- return;
- }
- if (keySize == 0) {
- ALOGW("set: not caching because keySize is 0");
- return;
- }
- if (valueSize <= 0) {
- ALOGW("set: not caching because valueSize is 0");
- return;
- }
-
- sp<Blob> dummyKey(new Blob(key, keySize, false));
- CacheEntry dummyEntry(dummyKey, NULL);
-
- while (true) {
- ssize_t index = mCacheEntries.indexOf(dummyEntry);
- if (index < 0) {
- // Create a new cache entry.
- sp<Blob> keyBlob(new Blob(key, keySize, true));
- sp<Blob> valueBlob(new Blob(value, valueSize, true));
- size_t newTotalSize = mTotalSize + keySize + valueSize;
- if (mMaxTotalSize < newTotalSize) {
- if (isCleanable()) {
- // Clean the cache and try again.
- clean();
- continue;
- } else {
- ALOGV("set: not caching new key/value pair because the "
- "total cache size limit would be exceeded: %d "
- "(limit: %d)",
- keySize + valueSize, mMaxTotalSize);
- break;
- }
- }
- mCacheEntries.add(CacheEntry(keyBlob, valueBlob));
- mTotalSize = newTotalSize;
- ALOGV("set: created new cache entry with %d byte key and %d byte value",
- keySize, valueSize);
- } else {
- // Update the existing cache entry.
- sp<Blob> valueBlob(new Blob(value, valueSize, true));
- sp<Blob> oldValueBlob(mCacheEntries[index].getValue());
- size_t newTotalSize = mTotalSize + valueSize - oldValueBlob->getSize();
- if (mMaxTotalSize < newTotalSize) {
- if (isCleanable()) {
- // Clean the cache and try again.
- clean();
- continue;
- } else {
- ALOGV("set: not caching new value because the total cache "
- "size limit would be exceeded: %d (limit: %d)",
- keySize + valueSize, mMaxTotalSize);
- break;
- }
- }
- mCacheEntries.editItemAt(index).setValue(valueBlob);
- mTotalSize = newTotalSize;
- ALOGV("set: updated existing cache entry with %d byte key and %d byte "
- "value", keySize, valueSize);
- }
- break;
- }
-}
-
-size_t BlobCache::get(const void* key, size_t keySize, void* value,
- size_t valueSize) {
- if (mMaxKeySize < keySize) {
- ALOGV("get: not searching because the key is too large: %d (limit %d)",
- keySize, mMaxKeySize);
- return 0;
- }
- sp<Blob> dummyKey(new Blob(key, keySize, false));
- CacheEntry dummyEntry(dummyKey, NULL);
- ssize_t index = mCacheEntries.indexOf(dummyEntry);
- if (index < 0) {
- ALOGV("get: no cache entry found for key of size %d", keySize);
- return 0;
- }
-
- // The key was found. Return the value if the caller's buffer is large
- // enough.
- sp<Blob> valueBlob(mCacheEntries[index].getValue());
- size_t valueBlobSize = valueBlob->getSize();
- if (valueBlobSize <= valueSize) {
- ALOGV("get: copying %d bytes to caller's buffer", valueBlobSize);
- memcpy(value, valueBlob->getData(), valueBlobSize);
- } else {
- ALOGV("get: caller's buffer is too small for value: %d (needs %d)",
- valueSize, valueBlobSize);
- }
- return valueBlobSize;
-}
-
-static inline size_t align4(size_t size) {
- return (size + 3) & ~3;
-}
-
-size_t BlobCache::getFlattenedSize() const {
- size_t size = sizeof(Header);
- for (size_t i = 0; i < mCacheEntries.size(); i++) {
- const CacheEntry& e(mCacheEntries[i]);
- sp<Blob> keyBlob = e.getKey();
- sp<Blob> valueBlob = e.getValue();
- size = align4(size);
- size += sizeof(EntryHeader) + keyBlob->getSize() +
- valueBlob->getSize();
- }
- return size;
-}
-
-size_t BlobCache::getFdCount() const {
- return 0;
-}
-
-status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
- const {
- if (count != 0) {
- ALOGE("flatten: nonzero fd count: %zu", count);
- return BAD_VALUE;
- }
-
- // Write the cache header
- if (size < sizeof(Header)) {
- ALOGE("flatten: not enough room for cache header");
- return BAD_VALUE;
- }
- Header* header = reinterpret_cast<Header*>(buffer);
- header->mMagicNumber = blobCacheMagic;
- header->mBlobCacheVersion = blobCacheVersion;
- header->mDeviceVersion = blobCacheDeviceVersion;
- header->mNumEntries = mCacheEntries.size();
-
- // Write cache entries
- uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer);
- off_t byteOffset = align4(sizeof(Header));
- for (size_t i = 0; i < mCacheEntries.size(); i++) {
- const CacheEntry& e(mCacheEntries[i]);
- sp<Blob> keyBlob = e.getKey();
- sp<Blob> valueBlob = e.getValue();
- size_t keySize = keyBlob->getSize();
- size_t valueSize = valueBlob->getSize();
-
- size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;
- if (byteOffset + entrySize > size) {
- ALOGE("flatten: not enough room for cache entries");
- return BAD_VALUE;
- }
-
- EntryHeader* eheader = reinterpret_cast<EntryHeader*>(
- &byteBuffer[byteOffset]);
- eheader->mKeySize = keySize;
- eheader->mValueSize = valueSize;
-
- memcpy(eheader->mData, keyBlob->getData(), keySize);
- memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize);
-
- byteOffset += align4(entrySize);
- }
-
- return OK;
-}
-
-status_t BlobCache::unflatten(void const* buffer, size_t size, int fds[],
- size_t count) {
- // All errors should result in the BlobCache being in an empty state.
- mCacheEntries.clear();
-
- if (count != 0) {
- ALOGE("unflatten: nonzero fd count: %zu", count);
- return BAD_VALUE;
- }
-
- // Read the cache header
- if (size < sizeof(Header)) {
- ALOGE("unflatten: not enough room for cache header");
- return BAD_VALUE;
- }
- const Header* header = reinterpret_cast<const Header*>(buffer);
- if (header->mMagicNumber != blobCacheMagic) {
- ALOGE("unflatten: bad magic number: %d", header->mMagicNumber);
- return BAD_VALUE;
- }
- if (header->mBlobCacheVersion != blobCacheVersion ||
- header->mDeviceVersion != blobCacheDeviceVersion) {
- // We treat version mismatches as an empty cache.
- return OK;
- }
-
- // Read cache entries
- const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer);
- off_t byteOffset = align4(sizeof(Header));
- size_t numEntries = header->mNumEntries;
- for (size_t i = 0; i < numEntries; i++) {
- if (byteOffset + sizeof(EntryHeader) > size) {
- mCacheEntries.clear();
- ALOGE("unflatten: not enough room for cache entry headers");
- return BAD_VALUE;
- }
-
- const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>(
- &byteBuffer[byteOffset]);
- size_t keySize = eheader->mKeySize;
- size_t valueSize = eheader->mValueSize;
- size_t entrySize = sizeof(EntryHeader) + keySize + valueSize;
-
- if (byteOffset + entrySize > size) {
- mCacheEntries.clear();
- ALOGE("unflatten: not enough room for cache entry headers");
- return BAD_VALUE;
- }
-
- const uint8_t* data = eheader->mData;
- set(data, keySize, data + keySize, valueSize);
-
- byteOffset += align4(entrySize);
- }
-
- return OK;
-}
-
-long int BlobCache::blob_random() {
-#ifdef _WIN32
- return rand();
-#else
- return nrand48(mRandState);
-#endif
-}
-
-void BlobCache::clean() {
- // Remove a random cache entry until the total cache size gets below half
- // the maximum total cache size.
- while (mTotalSize > mMaxTotalSize / 2) {
- size_t i = size_t(blob_random() % (mCacheEntries.size()));
- const CacheEntry& entry(mCacheEntries[i]);
- mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize();
- mCacheEntries.removeAt(i);
- }
-}
-
-bool BlobCache::isCleanable() const {
- return mTotalSize > mMaxTotalSize / 2;
-}
-
-BlobCache::Blob::Blob(const void* data, size_t size, bool copyData):
- mData(copyData ? malloc(size) : data),
- mSize(size),
- mOwnsData(copyData) {
- if (data != NULL && copyData) {
- memcpy(const_cast<void*>(mData), data, size);
- }
-}
-
-BlobCache::Blob::~Blob() {
- if (mOwnsData) {
- free(const_cast<void*>(mData));
- }
-}
-
-bool BlobCache::Blob::operator<(const Blob& rhs) const {
- if (mSize == rhs.mSize) {
- return memcmp(mData, rhs.mData, mSize) < 0;
- } else {
- return mSize < rhs.mSize;
- }
-}
-
-const void* BlobCache::Blob::getData() const {
- return mData;
-}
-
-size_t BlobCache::Blob::getSize() const {
- return mSize;
-}
-
-BlobCache::CacheEntry::CacheEntry() {
-}
-
-BlobCache::CacheEntry::CacheEntry(const sp<Blob>& key, const sp<Blob>& value):
- mKey(key),
- mValue(value) {
-}
-
-BlobCache::CacheEntry::CacheEntry(const CacheEntry& ce):
- mKey(ce.mKey),
- mValue(ce.mValue) {
-}
-
-bool BlobCache::CacheEntry::operator<(const CacheEntry& rhs) const {
- return *mKey < *rhs.mKey;
-}
-
-const BlobCache::CacheEntry& BlobCache::CacheEntry::operator=(const CacheEntry& rhs) {
- mKey = rhs.mKey;
- mValue = rhs.mValue;
- return *this;
-}
-
-sp<BlobCache::Blob> BlobCache::CacheEntry::getKey() const {
- return mKey;
-}
-
-sp<BlobCache::Blob> BlobCache::CacheEntry::getValue() const {
- return mValue;
-}
-
-void BlobCache::CacheEntry::setValue(const sp<Blob>& value) {
- mValue = value;
-}
-
-} // namespace android
diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
deleted file mode 100644
index 989662e..0000000
--- a/libs/utils/BufferedTextOutput.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/BufferedTextOutput.h>
-
-#include <utils/Atomic.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <cutils/threads.h>
-
-#include <private/utils/Static.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-struct BufferedTextOutput::BufferState : public RefBase
-{
- BufferState(int32_t _seq)
- : seq(_seq)
- , buffer(NULL)
- , bufferPos(0)
- , bufferSize(0)
- , atFront(true)
- , indent(0)
- , bundle(0) {
- }
- ~BufferState() {
- free(buffer);
- }
-
- status_t append(const char* txt, size_t len) {
- if ((len+bufferPos) > bufferSize) {
- void* b = realloc(buffer, ((len+bufferPos)*3)/2);
- if (!b) return NO_MEMORY;
- buffer = (char*)b;
- }
- memcpy(buffer+bufferPos, txt, len);
- bufferPos += len;
- return NO_ERROR;
- }
-
- void restart() {
- bufferPos = 0;
- atFront = true;
- if (bufferSize > 256) {
- void* b = realloc(buffer, 256);
- if (b) {
- buffer = (char*)b;
- bufferSize = 256;
- }
- }
- }
-
- const int32_t seq;
- char* buffer;
- size_t bufferPos;
- size_t bufferSize;
- bool atFront;
- int32_t indent;
- int32_t bundle;
-};
-
-struct BufferedTextOutput::ThreadState
-{
- Vector<sp<BufferedTextOutput::BufferState> > states;
-};
-
-static mutex_t gMutex;
-
-static thread_store_t tls;
-
-BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
-{
- ThreadState* ts = (ThreadState*) thread_store_get( &tls );
- if (ts) return ts;
- ts = new ThreadState;
- thread_store_set( &tls, ts, threadDestructor );
- return ts;
-}
-
-void BufferedTextOutput::threadDestructor(void *st)
-{
- delete ((ThreadState*)st);
-}
-
-static volatile int32_t gSequence = 0;
-
-static volatile int32_t gFreeBufferIndex = -1;
-
-static int32_t allocBufferIndex()
-{
- int32_t res = -1;
-
- mutex_lock(&gMutex);
-
- if (gFreeBufferIndex >= 0) {
- res = gFreeBufferIndex;
- gFreeBufferIndex = gTextBuffers[res];
- gTextBuffers.editItemAt(res) = -1;
-
- } else {
- res = gTextBuffers.size();
- gTextBuffers.add(-1);
- }
-
- mutex_unlock(&gMutex);
-
- return res;
-}
-
-static void freeBufferIndex(int32_t idx)
-{
- mutex_lock(&gMutex);
- gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
- gFreeBufferIndex = idx;
- mutex_unlock(&gMutex);
-}
-
-// ---------------------------------------------------------------------------
-
-BufferedTextOutput::BufferedTextOutput(uint32_t flags)
- : mFlags(flags)
- , mSeq(android_atomic_inc(&gSequence))
- , mIndex(allocBufferIndex())
-{
- mGlobalState = new BufferState(mSeq);
- if (mGlobalState) mGlobalState->incStrong(this);
-}
-
-BufferedTextOutput::~BufferedTextOutput()
-{
- if (mGlobalState) mGlobalState->decStrong(this);
- freeBufferIndex(mIndex);
-}
-
-status_t BufferedTextOutput::print(const char* txt, size_t len)
-{
- //printf("BufferedTextOutput: printing %d\n", len);
-
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
-
- const char* const end = txt+len;
-
- status_t err;
-
- while (txt < end) {
- // Find the next line.
- const char* first = txt;
- while (txt < end && *txt != '\n') txt++;
-
- // Include this and all following empty lines.
- while (txt < end && *txt == '\n') txt++;
-
- // Special cases for first data on a line.
- if (b->atFront) {
- if (b->indent > 0) {
- // If this is the start of a line, add the indent.
- const char* prefix = stringForIndent(b->indent);
- err = b->append(prefix, strlen(prefix));
- if (err != NO_ERROR) return err;
-
- } else if (*(txt-1) == '\n' && !b->bundle) {
- // Fast path: if we are not indenting or bundling, and
- // have been given one or more complete lines, just write
- // them out without going through the buffer.
-
- // Slurp up all of the lines.
- const char* lastLine = txt+1;
- while (txt < end) {
- if (*txt++ == '\n') lastLine = txt;
- }
- struct iovec vec;
- vec.iov_base = (void*)first;
- vec.iov_len = lastLine-first;
- //printf("Writing %d bytes of data!\n", vec.iov_len);
- writeLines(vec, 1);
- txt = lastLine;
- continue;
- }
- }
-
- // Append the new text to the buffer.
- err = b->append(first, txt-first);
- if (err != NO_ERROR) return err;
- b->atFront = *(txt-1) == '\n';
-
- // If we have finished a line and are not bundling, write
- // it out.
- //printf("Buffer is now %d bytes\n", b->bufferPos);
- if (b->atFront && !b->bundle) {
- struct iovec vec;
- vec.iov_base = b->buffer;
- vec.iov_len = b->bufferPos;
- //printf("Writing %d bytes of data!\n", vec.iov_len);
- writeLines(vec, 1);
- b->restart();
- }
- }
-
- return NO_ERROR;
-}
-
-void BufferedTextOutput::moveIndent(int delta)
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->indent += delta;
- if (b->indent < 0) b->indent = 0;
-}
-
-void BufferedTextOutput::pushBundle()
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->bundle++;
-}
-
-void BufferedTextOutput::popBundle()
-{
- AutoMutex _l(mLock);
- BufferState* b = getBuffer();
- b->bundle--;
- LOG_FATAL_IF(b->bundle < 0,
- "TextOutput::popBundle() called more times than pushBundle()");
- if (b->bundle < 0) b->bundle = 0;
-
- if (b->bundle == 0) {
- // Last bundle, write out data if it is complete. If it is not
- // complete, don't write until the last line is done... this may
- // or may not be the write thing to do, but it's the easiest.
- if (b->bufferPos > 0 && b->atFront) {
- struct iovec vec;
- vec.iov_base = b->buffer;
- vec.iov_len = b->bufferPos;
- writeLines(vec, 1);
- b->restart();
- }
- }
-}
-
-BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
-{
- if ((mFlags&MULTITHREADED) != 0) {
- ThreadState* ts = getThreadState();
- if (ts) {
- while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
- BufferState* bs = ts->states[mIndex].get();
- if (bs != NULL && bs->seq == mSeq) return bs;
-
- ts->states.editItemAt(mIndex) = new BufferState(mIndex);
- bs = ts->states[mIndex].get();
- if (bs != NULL) return bs;
- }
- }
-
- return mGlobalState;
-}
-
-}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
deleted file mode 100644
index 18fd84f..0000000
--- a/libs/utils/CallStack.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "CallStack"
-
-#include <string.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/CallStack.h>
-#include <corkscrew/backtrace.h>
-
-/*****************************************************************************/
-namespace android {
-
-CallStack::CallStack() :
- mCount(0) {
-}
-
-CallStack::CallStack(const CallStack& rhs) :
- mCount(rhs.mCount) {
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
- }
-}
-
-CallStack::~CallStack() {
-}
-
-CallStack& CallStack::operator = (const CallStack& rhs) {
- mCount = rhs.mCount;
- if (mCount) {
- memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
- }
- return *this;
-}
-
-bool CallStack::operator == (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return false;
- return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
-}
-
-bool CallStack::operator != (const CallStack& rhs) const {
- return !operator == (rhs);
-}
-
-bool CallStack::operator < (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount < rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
-}
-
-bool CallStack::operator >= (const CallStack& rhs) const {
- return !operator < (rhs);
-}
-
-bool CallStack::operator > (const CallStack& rhs) const {
- if (mCount != rhs.mCount)
- return mCount > rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
-}
-
-bool CallStack::operator <= (const CallStack& rhs) const {
- return !operator > (rhs);
-}
-
-const void* CallStack::operator [] (int index) const {
- if (index >= int(mCount))
- return 0;
- return reinterpret_cast<const void*>(mStack[index].absolute_pc);
-}
-
-void CallStack::clear() {
- mCount = 0;
-}
-
-void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
- if (maxDepth > MAX_DEPTH) {
- maxDepth = MAX_DEPTH;
- }
- ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
- mCount = count > 0 ? count : 0;
-}
-
-void CallStack::dump(const char* prefix) const {
- backtrace_symbol_t symbols[mCount];
-
- get_backtrace_symbols(mStack, mCount, symbols);
- for (size_t i = 0; i < mCount; i++) {
- char line[MAX_BACKTRACE_LINE_LENGTH];
- format_backtrace_line(i, &mStack[i], &symbols[i],
- line, MAX_BACKTRACE_LINE_LENGTH);
- ALOGD("%s%s", prefix, line);
- }
- free_backtrace_symbols(symbols, mCount);
-}
-
-String8 CallStack::toString(const char* prefix) const {
- String8 str;
- backtrace_symbol_t symbols[mCount];
-
- get_backtrace_symbols(mStack, mCount, symbols);
- for (size_t i = 0; i < mCount; i++) {
- char line[MAX_BACKTRACE_LINE_LENGTH];
- format_backtrace_line(i, &mStack[i], &symbols[i],
- line, MAX_BACKTRACE_LINE_LENGTH);
- str.append(prefix);
- str.append(line);
- str.append("\n");
- }
- free_backtrace_symbols(symbols, mCount);
- return str;
-}
-
-}; // namespace android
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
deleted file mode 100644
index e8ac983..0000000
--- a/libs/utils/Debug.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Debug.h>
-
-#include <utils/misc.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------
-
-static const char indentStr[] =
-" "
-" ";
-
-const char* stringForIndent(int32_t indentLevel)
-{
- ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
- return indentStr + (off < 0 ? 0 : off);
-}
-
-// ---------------------------------------------------------------------
-
-static void defaultPrintFunc(void* cookie, const char* txt)
-{
- printf("%s", txt);
-}
-
-// ---------------------------------------------------------------------
-
-static inline int isident(int c)
-{
- return isalnum(c) || c == '_';
-}
-
-static inline bool isasciitype(char c)
-{
- if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
- return false;
-}
-
-static inline char makehexdigit(uint32_t val)
-{
- return "0123456789abcdef"[val&0xF];
-}
-
-static char* appendhexnum(uint32_t val, char* out)
-{
- for( int32_t i=28; i>=0; i-=4 ) {
- *out++ = makehexdigit( val>>i );
- }
- *out = 0;
- return out;
-}
-
-static inline char makeupperhexdigit(uint32_t val)
-{
- return "0123456789ABCDEF"[val&0xF];
-}
-
-static char* appendupperhexnum(uint32_t val, char* out)
-{
- for( int32_t i=28; i>=0; i-=4 ) {
- *out++ = makeupperhexdigit( val>>i );
- }
- *out = 0;
- return out;
-}
-
-static char* appendcharornum(char c, char* out, bool skipzero = true)
-{
- if (skipzero && c == 0) return out;
-
- if (isasciitype(c)) {
- *out++ = c;
- return out;
- }
-
- *out++ = '\\';
- *out++ = 'x';
- *out++ = makehexdigit(c>>4);
- *out++ = makehexdigit(c);
- return out;
-}
-
-static char* typetostring(uint32_t type, char* out,
- bool fullContext = true,
- bool strict = false)
-{
- char* pos = out;
- char c[4];
- c[0] = (char)((type>>24)&0xFF);
- c[1] = (char)((type>>16)&0xFF);
- c[2] = (char)((type>>8)&0xFF);
- c[3] = (char)(type&0xFF);
- bool valid;
- if( !strict ) {
- // now even less strict!
- // valid = isasciitype(c[3]);
- valid = true;
- int32_t i = 0;
- bool zero = true;
- while (valid && i<3) {
- if (c[i] == 0) {
- if (!zero) valid = false;
- } else {
- zero = false;
- //if (!isasciitype(c[i])) valid = false;
- }
- i++;
- }
- // if all zeros, not a valid type code.
- if (zero) valid = false;
- } else {
- valid = isident(c[3]) ? true : false;
- int32_t i = 0;
- bool zero = true;
- while (valid && i<3) {
- if (c[i] == 0) {
- if (!zero) valid = false;
- } else {
- zero = false;
- if (!isident(c[i])) valid = false;
- }
- i++;
- }
- }
- if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
- if( fullContext ) *pos++ = '\'';
- pos = appendcharornum(c[0], pos);
- pos = appendcharornum(c[1], pos);
- pos = appendcharornum(c[2], pos);
- pos = appendcharornum(c[3], pos);
- if( fullContext ) *pos++ = '\'';
- *pos = 0;
- return pos;
- }
-
- if( fullContext ) {
- *pos++ = '0';
- *pos++ = 'x';
- }
- return appendhexnum(type, pos);
-}
-
-void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
-{
- char buffer[32];
- char* end = typetostring(typeCode, buffer);
- *end = 0;
- func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
-}
-
-void printHexData(int32_t indent, const void *buf, size_t length,
- size_t bytesPerLine, int32_t singleLineBytesCutoff,
- size_t alignment, bool cStyle,
- debugPrintFunc func, void* cookie)
-{
- if (alignment == 0) {
- if (bytesPerLine >= 16) alignment = 4;
- else if (bytesPerLine >= 8) alignment = 2;
- else alignment = 1;
- }
- if (func == NULL) func = defaultPrintFunc;
-
- size_t offset;
-
- unsigned char *pos = (unsigned char *)buf;
-
- if (pos == NULL) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- func(cookie, "(NULL)");
- return;
- }
-
- if (length == 0) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- func(cookie, "(empty)");
- return;
- }
-
- if ((int32_t)length < 0) {
- if (singleLineBytesCutoff < 0) func(cookie, "\n");
- char buf[64];
- sprintf(buf, "(bad length: %zu)", length);
- func(cookie, buf);
- return;
- }
-
- char buffer[256];
- static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
-
- if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
-
- const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
- bool newLine = false;
- if (cStyle) {
- indent++;
- func(cookie, "{\n");
- newLine = true;
- } else if (!oneLine) {
- func(cookie, "\n");
- newLine = true;
- }
-
- for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
- long remain = length;
-
- char* c = buffer;
- if (!oneLine && !cStyle) {
- sprintf(c, "0x%08x: ", (int)offset);
- c += 12;
- }
-
- size_t index;
- size_t word;
-
- for (word = 0; word < bytesPerLine; ) {
-
-#ifdef HAVE_LITTLE_ENDIAN
- const size_t startIndex = word+(alignment-(alignment?1:0));
- const ssize_t dir = -1;
-#else
- const size_t startIndex = word;
- const ssize_t dir = 1;
-#endif
-
- for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
-
- if (!cStyle) {
- if (index == 0 && word > 0 && alignment > 0) {
- *c++ = ' ';
- }
-
- if (remain-- > 0) {
- const unsigned char val = *(pos+startIndex+(index*dir));
- *c++ = makehexdigit(val>>4);
- *c++ = makehexdigit(val);
- } else if (!oneLine) {
- *c++ = ' ';
- *c++ = ' ';
- }
- } else {
- if (remain > 0) {
- if (index == 0 && word > 0) {
- *c++ = ',';
- *c++ = ' ';
- }
- if (index == 0) {
- *c++ = '0';
- *c++ = 'x';
- }
- const unsigned char val = *(pos+startIndex+(index*dir));
- *c++ = makehexdigit(val>>4);
- *c++ = makehexdigit(val);
- remain--;
- }
- }
- }
-
- word += index;
- }
-
- if (!cStyle) {
- remain = length;
- *c++ = ' ';
- *c++ = '\'';
- for (index = 0; index < bytesPerLine; index++) {
-
- if (remain-- > 0) {
- const unsigned char val = pos[index];
- *c++ = (val >= ' ' && val < 127) ? val : '.';
- } else if (!oneLine) {
- *c++ = ' ';
- }
- }
-
- *c++ = '\'';
- if (length > bytesPerLine) *c++ = '\n';
- } else {
- if (remain > 0) *c++ = ',';
- *c++ = '\n';
- }
-
- if (newLine && indent) func(cookie, stringForIndent(indent));
- *c = 0;
- func(cookie, buffer);
- newLine = true;
-
- if (length <= bytesPerLine) break;
- length -= bytesPerLine;
- }
-
- if (cStyle) {
- if (indent > 0) func(cookie, stringForIndent(indent-1));
- func(cookie, "};");
- }
-}
-
-}; // namespace android
-
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
deleted file mode 100644
index 9ce370e..0000000
--- a/libs/utils/FileMap.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Shared file mapping class.
-//
-
-#define LOG_TAG "filemap"
-
-#include <utils/FileMap.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_POSIX_FILEMAP
-#include <sys/mman.h>
-#endif
-
-#include <string.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*static*/ long FileMap::mPageSize = -1;
-
-
-/*
- * Constructor. Create an empty object.
- */
-FileMap::FileMap(void)
- : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0),
- mDataPtr(NULL), mDataLength(0)
-{
-}
-
-/*
- * Destructor.
- */
-FileMap::~FileMap(void)
-{
- assert(mRefCount == 0);
-
- //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength);
-
- mRefCount = -100; // help catch double-free
- if (mFileName != NULL) {
- free(mFileName);
- }
-#ifdef HAVE_POSIX_FILEMAP
- if (mBasePtr && munmap(mBasePtr, mBaseLength) != 0) {
- ALOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
- }
-#endif
-#ifdef HAVE_WIN32_FILEMAP
- if (mBasePtr && UnmapViewOfFile(mBasePtr) == 0) {
- ALOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr,
- GetLastError() );
- }
- if (mFileMapping != INVALID_HANDLE_VALUE) {
- CloseHandle(mFileMapping);
- }
- CloseHandle(mFileHandle);
-#endif
-}
-
-
-/*
- * Create a new mapping on an open file.
- *
- * Closing the file descriptor does not unmap the pages, so we don't
- * claim ownership of the fd.
- *
- * Returns "false" on failure.
- */
-bool FileMap::create(const char* origFileName, int fd, off64_t offset, size_t length,
- bool readOnly)
-{
-#ifdef HAVE_WIN32_FILEMAP
- int adjust;
- off64_t adjOffset;
- size_t adjLength;
-
- if (mPageSize == -1) {
- SYSTEM_INFO si;
-
- GetSystemInfo( &si );
- mPageSize = si.dwAllocationGranularity;
- }
-
- DWORD protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;
-
- mFileHandle = (HANDLE) _get_osfhandle(fd);
- mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);
- if (mFileMapping == NULL) {
- ALOGE("CreateFileMapping(%p, %lx) failed with error %ld\n",
- mFileHandle, protect, GetLastError() );
- return false;
- }
-
- adjust = offset % mPageSize;
- adjOffset = offset - adjust;
- adjLength = length + adjust;
-
- mBasePtr = MapViewOfFile( mFileMapping,
- readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
- 0,
- (DWORD)(adjOffset),
- adjLength );
- if (mBasePtr == NULL) {
- ALOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n",
- adjOffset, adjLength, GetLastError() );
- CloseHandle(mFileMapping);
- mFileMapping = INVALID_HANDLE_VALUE;
- return false;
- }
-#endif
-#ifdef HAVE_POSIX_FILEMAP
- int prot, flags, adjust;
- off64_t adjOffset;
- size_t adjLength;
-
- void* ptr;
-
- assert(mRefCount == 1);
- assert(fd >= 0);
- assert(offset >= 0);
- assert(length > 0);
-
- /* init on first use */
- if (mPageSize == -1) {
-#if NOT_USING_KLIBC
- mPageSize = sysconf(_SC_PAGESIZE);
- if (mPageSize == -1) {
- ALOGE("could not get _SC_PAGESIZE\n");
- return false;
- }
-#else
- /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */
- mPageSize = 4096;
-#endif
- }
-
- adjust = offset % mPageSize;
-try_again:
- adjOffset = offset - adjust;
- adjLength = length + adjust;
-
- flags = MAP_SHARED;
- prot = PROT_READ;
- if (!readOnly)
- prot |= PROT_WRITE;
-
- ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
- if (ptr == MAP_FAILED) {
- // Cygwin does not seem to like file mapping files from an offset.
- // So if we fail, try again with offset zero
- if (adjOffset > 0) {
- adjust = offset;
- goto try_again;
- }
-
- ALOGE("mmap(%ld,%ld) failed: %s\n",
- (long) adjOffset, (long) adjLength, strerror(errno));
- return false;
- }
- mBasePtr = ptr;
-#endif /* HAVE_POSIX_FILEMAP */
-
- mFileName = origFileName != NULL ? strdup(origFileName) : NULL;
- mBaseLength = adjLength;
- mDataOffset = offset;
- mDataPtr = (char*) mBasePtr + adjust;
- mDataLength = length;
-
- assert(mBasePtr != NULL);
-
- ALOGV("MAP: base %p/%d data %p/%d\n",
- mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
-
- return true;
-}
-
-/*
- * Provide guidance to the system.
- */
-int FileMap::advise(MapAdvice advice)
-{
-#if HAVE_MADVISE
- int cc, sysAdvice;
-
- switch (advice) {
- case NORMAL: sysAdvice = MADV_NORMAL; break;
- case RANDOM: sysAdvice = MADV_RANDOM; break;
- case SEQUENTIAL: sysAdvice = MADV_SEQUENTIAL; break;
- case WILLNEED: sysAdvice = MADV_WILLNEED; break;
- case DONTNEED: sysAdvice = MADV_DONTNEED; break;
- default:
- assert(false);
- return -1;
- }
-
- cc = madvise(mBasePtr, mBaseLength, sysAdvice);
- if (cc != 0)
- ALOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno));
- return cc;
-#else
- return -1;
-#endif // HAVE_MADVISE
-}
diff --git a/libs/utils/Flattenable.cpp b/libs/utils/Flattenable.cpp
deleted file mode 100644
index 1f2ffaa..0000000
--- a/libs/utils/Flattenable.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Flattenable.h>
-
-namespace android {
-
-Flattenable::~Flattenable() {
-}
-
-}; // namespace android
diff --git a/libs/utils/LinearTransform.cpp b/libs/utils/LinearTransform.cpp
deleted file mode 100644
index d752415..0000000
--- a/libs/utils/LinearTransform.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define __STDC_LIMIT_MACROS
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <utils/LinearTransform.h>
-
-namespace android {
-
-template<class T> static inline T ABS(T x) { return (x < 0) ? -x : x; }
-
-// Static math methods involving linear transformations
-static bool scale_u64_to_u64(
- uint64_t val,
- uint32_t N,
- uint32_t D,
- uint64_t* res,
- bool round_up_not_down) {
- uint64_t tmp1, tmp2;
- uint32_t r;
-
- assert(res);
- assert(D);
-
- // Let U32(X) denote a uint32_t containing the upper 32 bits of a 64 bit
- // integer X.
- // Let L32(X) denote a uint32_t containing the lower 32 bits of a 64 bit
- // integer X.
- // Let X[A, B] with A <= B denote bits A through B of the integer X.
- // Let (A | B) denote the concatination of two 32 bit ints, A and B.
- // IOW X = (A | B) => U32(X) == A && L32(X) == B
- //
- // compute M = val * N (a 96 bit int)
- // ---------------------------------
- // tmp2 = U32(val) * N (a 64 bit int)
- // tmp1 = L32(val) * N (a 64 bit int)
- // which means
- // M = val * N = (tmp2 << 32) + tmp1
- tmp2 = (val >> 32) * N;
- tmp1 = (val & UINT32_MAX) * N;
-
- // compute M[32, 95]
- // tmp2 = tmp2 + U32(tmp1)
- // = (U32(val) * N) + U32(L32(val) * N)
- // = M[32, 95]
- tmp2 += tmp1 >> 32;
-
- // if M[64, 95] >= D, then M/D has bits > 63 set and we have
- // an overflow.
- if ((tmp2 >> 32) >= D) {
- *res = UINT64_MAX;
- return false;
- }
-
- // Divide. Going in we know
- // tmp2 = M[32, 95]
- // U32(tmp2) < D
- r = tmp2 % D;
- tmp2 /= D;
-
- // At this point
- // tmp1 = L32(val) * N
- // tmp2 = M[32, 95] / D
- // = (M / D)[32, 95]
- // r = M[32, 95] % D
- // U32(tmp2) = 0
- //
- // compute tmp1 = (r | M[0, 31])
- tmp1 = (tmp1 & UINT32_MAX) | ((uint64_t)r << 32);
-
- // Divide again. Keep the remainder around in order to round properly.
- r = tmp1 % D;
- tmp1 /= D;
-
- // At this point
- // tmp2 = (M / D)[32, 95]
- // tmp1 = (M / D)[ 0, 31]
- // r = M % D
- // U32(tmp1) = 0
- // U32(tmp2) = 0
-
- // Pack the result and deal with the round-up case (As well as the
- // remote possiblility over overflow in such a case).
- *res = (tmp2 << 32) | tmp1;
- if (r && round_up_not_down) {
- ++(*res);
- if (!(*res)) {
- *res = UINT64_MAX;
- return false;
- }
- }
-
- return true;
-}
-
-static bool linear_transform_s64_to_s64(
- int64_t val,
- int64_t basis1,
- int32_t N,
- uint32_t D,
- int64_t basis2,
- int64_t* out) {
- uint64_t scaled, res;
- uint64_t abs_val;
- bool is_neg;
-
- if (!out)
- return false;
-
- // Compute abs(val - basis_64). Keep track of whether or not this delta
- // will be negative after the scale opertaion.
- if (val < basis1) {
- is_neg = true;
- abs_val = basis1 - val;
- } else {
- is_neg = false;
- abs_val = val - basis1;
- }
-
- if (N < 0)
- is_neg = !is_neg;
-
- if (!scale_u64_to_u64(abs_val,
- ABS(N),
- D,
- &scaled,
- is_neg))
- return false; // overflow/undeflow
-
- // if scaled is >= 0x8000<etc>, then we are going to overflow or
- // underflow unless ABS(basis2) is large enough to pull us back into the
- // non-overflow/underflow region.
- if (scaled & INT64_MIN) {
- if (is_neg && (basis2 < 0))
- return false; // certain underflow
-
- if (!is_neg && (basis2 >= 0))
- return false; // certain overflow
-
- if (ABS(basis2) <= static_cast<int64_t>(scaled & INT64_MAX))
- return false; // not enough
-
- // Looks like we are OK
- *out = (is_neg ? (-scaled) : scaled) + basis2;
- } else {
- // Scaled fits within signed bounds, so we just need to check for
- // over/underflow for two signed integers. Basically, if both scaled
- // and basis2 have the same sign bit, and the result has a different
- // sign bit, then we have under/overflow. An easy way to compute this
- // is
- // (scaled_signbit XNOR basis_signbit) &&
- // (scaled_signbit XOR res_signbit)
- // ==
- // (scaled_signbit XOR basis_signbit XOR 1) &&
- // (scaled_signbit XOR res_signbit)
-
- if (is_neg)
- scaled = -scaled;
- res = scaled + basis2;
-
- if ((scaled ^ basis2 ^ INT64_MIN) & (scaled ^ res) & INT64_MIN)
- return false;
-
- *out = res;
- }
-
- return true;
-}
-
-bool LinearTransform::doForwardTransform(int64_t a_in, int64_t* b_out) const {
- if (0 == a_to_b_denom)
- return false;
-
- return linear_transform_s64_to_s64(a_in,
- a_zero,
- a_to_b_numer,
- a_to_b_denom,
- b_zero,
- b_out);
-}
-
-bool LinearTransform::doReverseTransform(int64_t b_in, int64_t* a_out) const {
- if (0 == a_to_b_numer)
- return false;
-
- return linear_transform_s64_to_s64(b_in,
- b_zero,
- a_to_b_denom,
- a_to_b_numer,
- a_zero,
- a_out);
-}
-
-template <class T> void LinearTransform::reduce(T* N, T* D) {
- T a, b;
- if (!N || !D || !(*D)) {
- assert(false);
- return;
- }
-
- a = *N;
- b = *D;
-
- if (a == 0) {
- *D = 1;
- return;
- }
-
- // This implements Euclid's method to find GCD.
- if (a < b) {
- T tmp = a;
- a = b;
- b = tmp;
- }
-
- while (1) {
- // a is now the greater of the two.
- const T remainder = a % b;
- if (remainder == 0) {
- *N /= b;
- *D /= b;
- return;
- }
- // by swapping remainder and b, we are guaranteeing that a is
- // still the greater of the two upon entrance to the loop.
- a = b;
- b = remainder;
- }
-};
-
-template void LinearTransform::reduce<uint64_t>(uint64_t* N, uint64_t* D);
-template void LinearTransform::reduce<uint32_t>(uint32_t* N, uint32_t* D);
-
-void LinearTransform::reduce(int32_t* N, uint32_t* D) {
- if (N && D && *D) {
- if (*N < 0) {
- *N = -(*N);
- reduce(reinterpret_cast<uint32_t*>(N), D);
- *N = -(*N);
- } else {
- reduce(reinterpret_cast<uint32_t*>(N), D);
- }
- }
-}
-
-} // namespace android
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
deleted file mode 100644
index d1aa664..0000000
--- a/libs/utils/Looper.cpp
+++ /dev/null
@@ -1,744 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// A looper implementation based on epoll().
-//
-#define LOG_TAG "Looper"
-
-//#define LOG_NDEBUG 0
-
-// Debugs poll and wake interactions.
-#define DEBUG_POLL_AND_WAKE 0
-
-// Debugs callback registration and invocation.
-#define DEBUG_CALLBACKS 0
-
-#include <cutils/log.h>
-#include <utils/Looper.h>
-#include <utils/Timers.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-
-
-namespace android {
-
-// --- WeakMessageHandler ---
-
-WeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
- mHandler(handler) {
-}
-
-void WeakMessageHandler::handleMessage(const Message& message) {
- sp<MessageHandler> handler = mHandler.promote();
- if (handler != NULL) {
- handler->handleMessage(message);
- }
-}
-
-
-// --- Looper ---
-
-#ifdef LOOPER_USES_EPOLL
-// Hint for number of file descriptors to be associated with the epoll instance.
-static const int EPOLL_SIZE_HINT = 8;
-
-// Maximum number of file descriptors for which to retrieve poll events each iteration.
-static const int EPOLL_MAX_EVENTS = 16;
-#endif
-
-static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
-static pthread_key_t gTLSKey = 0;
-
-Looper::Looper(bool allowNonCallbacks) :
- mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
- mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
- int wakeFds[2];
- int result = pipe(wakeFds);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
-
- mWakeReadPipeFd = wakeFds[0];
- mWakeWritePipeFd = wakeFds[1];
-
- result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d",
- errno);
-
- result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
- errno);
-
-#ifdef LOOPER_USES_EPOLL
- // Allocate the epoll instance and register the wake pipe.
- mEpollFd = epoll_create(EPOLL_SIZE_HINT);
- LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
-
- struct epoll_event eventItem;
- memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
- eventItem.events = EPOLLIN;
- eventItem.data.fd = mWakeReadPipeFd;
- result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d",
- errno);
-#else
- // Add the wake pipe to the head of the request list with a null callback.
- struct pollfd requestedFd;
- requestedFd.fd = mWakeReadPipeFd;
- requestedFd.events = POLLIN;
- mRequestedFds.push(requestedFd);
-
- Request request;
- request.fd = mWakeReadPipeFd;
- request.callback = NULL;
- request.ident = 0;
- request.data = NULL;
- mRequests.push(request);
-
- mPolling = false;
- mWaiters = 0;
-#endif
-
-#ifdef LOOPER_STATISTICS
- mPendingWakeTime = -1;
- mPendingWakeCount = 0;
- mSampledWakeCycles = 0;
- mSampledWakeCountSum = 0;
- mSampledWakeLatencySum = 0;
-
- mSampledPolls = 0;
- mSampledZeroPollCount = 0;
- mSampledZeroPollLatencySum = 0;
- mSampledTimeoutPollCount = 0;
- mSampledTimeoutPollLatencySum = 0;
-#endif
-}
-
-Looper::~Looper() {
- close(mWakeReadPipeFd);
- close(mWakeWritePipeFd);
-#ifdef LOOPER_USES_EPOLL
- close(mEpollFd);
-#endif
-}
-
-void Looper::initTLSKey() {
- int result = pthread_key_create(& gTLSKey, threadDestructor);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
-}
-
-void Looper::threadDestructor(void *st) {
- Looper* const self = static_cast<Looper*>(st);
- if (self != NULL) {
- self->decStrong((void*)threadDestructor);
- }
-}
-
-void Looper::setForThread(const sp<Looper>& looper) {
- sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
-
- if (looper != NULL) {
- looper->incStrong((void*)threadDestructor);
- }
-
- pthread_setspecific(gTLSKey, looper.get());
-
- if (old != NULL) {
- old->decStrong((void*)threadDestructor);
- }
-}
-
-sp<Looper> Looper::getForThread() {
- int result = pthread_once(& gTLSOnce, initTLSKey);
- LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
-
- return (Looper*)pthread_getspecific(gTLSKey);
-}
-
-sp<Looper> Looper::prepare(int opts) {
- bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS;
- sp<Looper> looper = Looper::getForThread();
- if (looper == NULL) {
- looper = new Looper(allowNonCallbacks);
- Looper::setForThread(looper);
- }
- if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
- ALOGW("Looper already prepared for this thread with a different value for the "
- "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
- }
- return looper;
-}
-
-bool Looper::getAllowNonCallbacks() const {
- return mAllowNonCallbacks;
-}
-
-int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
- int result = 0;
- for (;;) {
- while (mResponseIndex < mResponses.size()) {
- const Response& response = mResponses.itemAt(mResponseIndex++);
- ALooper_callbackFunc callback = response.request.callback;
- if (!callback) {
- int ident = response.request.ident;
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
- "fd=%d, events=0x%x, data=%p",
- this, ident, fd, events, data);
-#endif
- if (outFd != NULL) *outFd = fd;
- if (outEvents != NULL) *outEvents = events;
- if (outData != NULL) *outData = data;
- return ident;
- }
- }
-
- if (result != 0) {
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - returning result %d", this, result);
-#endif
- if (outFd != NULL) *outFd = 0;
- if (outEvents != NULL) *outEvents = NULL;
- if (outData != NULL) *outData = NULL;
- return result;
- }
-
- result = pollInner(timeoutMillis);
- }
-}
-
-int Looper::pollInner(int timeoutMillis) {
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
-#endif
-
- // Adjust the timeout based on when the next message is due.
- if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
- if (messageTimeoutMillis >= 0
- && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
- timeoutMillis = messageTimeoutMillis;
- }
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
- this, mNextMessageUptime - now, timeoutMillis);
-#endif
- }
-
- // Poll.
- int result = ALOOPER_POLL_WAKE;
- mResponses.clear();
- mResponseIndex = 0;
-
-#ifdef LOOPER_STATISTICS
- nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-
-#ifdef LOOPER_USES_EPOLL
- struct epoll_event eventItems[EPOLL_MAX_EVENTS];
- int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
-#else
- // Wait for wakeAndLock() waiters to run then set mPolling to true.
- mLock.lock();
- while (mWaiters != 0) {
- mResume.wait(mLock);
- }
- mPolling = true;
- mLock.unlock();
-
- size_t requestedCount = mRequestedFds.size();
- int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
-#endif
-
- // Acquire lock.
- mLock.lock();
-
- // Check for poll error.
- if (eventCount < 0) {
- if (errno == EINTR) {
- goto Done;
- }
- ALOGW("Poll failed with an unexpected error, errno=%d", errno);
- result = ALOOPER_POLL_ERROR;
- goto Done;
- }
-
- // Check for poll timeout.
- if (eventCount == 0) {
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - timeout", this);
-#endif
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
-
- // Handle all events.
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
-#endif
-
-#ifdef LOOPER_USES_EPOLL
- for (int i = 0; i < eventCount; i++) {
- int fd = eventItems[i].data.fd;
- uint32_t epollEvents = eventItems[i].events;
- if (fd == mWakeReadPipeFd) {
- if (epollEvents & EPOLLIN) {
- awoken();
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
- }
- } else {
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex >= 0) {
- int events = 0;
- if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
- if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
- if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
- pushResponse(events, mRequests.valueAt(requestIndex));
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
- "no longer registered.", epollEvents, fd);
- }
- }
- }
-Done: ;
-#else
- for (size_t i = 0; i < requestedCount; i++) {
- const struct pollfd& requestedFd = mRequestedFds.itemAt(i);
-
- short pollEvents = requestedFd.revents;
- if (pollEvents) {
- if (requestedFd.fd == mWakeReadPipeFd) {
- if (pollEvents & POLLIN) {
- awoken();
- } else {
- ALOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents);
- }
- } else {
- int events = 0;
- if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT;
- if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR;
- if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP;
- if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID;
- pushResponse(events, mRequests.itemAt(i));
- }
- if (--eventCount == 0) {
- break;
- }
- }
- }
-Done:
- // Set mPolling to false and wake up the wakeAndLock() waiters.
- mPolling = false;
- if (mWaiters != 0) {
- mAwake.broadcast();
- }
-#endif
-
-#ifdef LOOPER_STATISTICS
- nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- mSampledPolls += 1;
- if (timeoutMillis == 0) {
- mSampledZeroPollCount += 1;
- mSampledZeroPollLatencySum += pollEndTime - pollStartTime;
- } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) {
- mSampledTimeoutPollCount += 1;
- mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime
- - milliseconds_to_nanoseconds(timeoutMillis);
- }
- if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) {
- ALOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this,
- 0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount,
- 0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount);
- mSampledPolls = 0;
- mSampledZeroPollCount = 0;
- mSampledZeroPollLatencySum = 0;
- mSampledTimeoutPollCount = 0;
- mSampledTimeoutPollLatencySum = 0;
- }
-#endif
-
- // Invoke pending message callbacks.
- mNextMessageUptime = LLONG_MAX;
- while (mMessageEnvelopes.size() != 0) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
- if (messageEnvelope.uptime <= now) {
- // Remove the envelope from the list.
- // We keep a strong reference to the handler until the call to handleMessage
- // finishes. Then we drop it so that the handler can be deleted *before*
- // we reacquire our lock.
- { // obtain handler
- sp<MessageHandler> handler = messageEnvelope.handler;
- Message message = messageEnvelope.message;
- mMessageEnvelopes.removeAt(0);
- mSendingMessage = true;
- mLock.unlock();
-
-#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
- this, handler.get(), message.what);
-#endif
- handler->handleMessage(message);
- } // release handler
-
- mLock.lock();
- mSendingMessage = false;
- result = ALOOPER_POLL_CALLBACK;
- } else {
- // The last message left at the head of the queue determines the next wakeup time.
- mNextMessageUptime = messageEnvelope.uptime;
- break;
- }
- }
-
- // Release lock.
- mLock.unlock();
-
- // Invoke all response callbacks.
- for (size_t i = 0; i < mResponses.size(); i++) {
- const Response& response = mResponses.itemAt(i);
- ALooper_callbackFunc callback = response.request.callback;
- if (callback) {
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
-#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
- ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
- this, callback, fd, events, data);
-#endif
- int callbackResult = callback(fd, events, data);
- if (callbackResult == 0) {
- removeFd(fd);
- }
- result = ALOOPER_POLL_CALLBACK;
- }
- }
- return result;
-}
-
-int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
- if (timeoutMillis <= 0) {
- int result;
- do {
- result = pollOnce(timeoutMillis, outFd, outEvents, outData);
- } while (result == ALOOPER_POLL_CALLBACK);
- return result;
- } else {
- nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
- + milliseconds_to_nanoseconds(timeoutMillis);
-
- for (;;) {
- int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
- if (result != ALOOPER_POLL_CALLBACK) {
- return result;
- }
-
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
- if (timeoutMillis == 0) {
- return ALOOPER_POLL_TIMEOUT;
- }
- }
- }
-}
-
-void Looper::wake() {
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ wake", this);
-#endif
-
-#ifdef LOOPER_STATISTICS
- // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled.
- if (mPendingWakeCount++ == 0) {
- mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC);
- }
-#endif
-
- ssize_t nWrite;
- do {
- nWrite = write(mWakeWritePipeFd, "W", 1);
- } while (nWrite == -1 && errno == EINTR);
-
- if (nWrite != 1) {
- if (errno != EAGAIN) {
- ALOGW("Could not write wake signal, errno=%d", errno);
- }
- }
-}
-
-void Looper::awoken() {
-#if DEBUG_POLL_AND_WAKE
- ALOGD("%p ~ awoken", this);
-#endif
-
-#ifdef LOOPER_STATISTICS
- if (mPendingWakeCount == 0) {
- ALOGD("%p ~ awoken: spurious!", this);
- } else {
- mSampledWakeCycles += 1;
- mSampledWakeCountSum += mPendingWakeCount;
- mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime;
- mPendingWakeCount = 0;
- mPendingWakeTime = -1;
- if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) {
- ALOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this,
- 0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles,
- float(mSampledWakeCountSum) / mSampledWakeCycles);
- mSampledWakeCycles = 0;
- mSampledWakeCountSum = 0;
- mSampledWakeLatencySum = 0;
- }
- }
-#endif
-
- char buffer[16];
- ssize_t nRead;
- do {
- nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
- } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
-}
-
-void Looper::pushResponse(int events, const Request& request) {
- Response response;
- response.events = events;
- response.request = request;
- mResponses.push(response);
-}
-
-int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) {
-#if DEBUG_CALLBACKS
- ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
- events, callback, data);
-#endif
-
- if (! callback) {
- if (! mAllowNonCallbacks) {
- ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
- return -1;
- }
-
- if (ident < 0) {
- ALOGE("Invalid attempt to set NULL callback with ident <= 0.");
- return -1;
- }
- }
-
-#ifdef LOOPER_USES_EPOLL
- int epollEvents = 0;
- if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN;
- if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- Request request;
- request.fd = fd;
- request.ident = ident;
- request.callback = callback;
- request.data = data;
-
- struct epoll_event eventItem;
- memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
- eventItem.events = epollEvents;
- eventItem.data.fd = fd;
-
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex < 0) {
- int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
- if (epollResult < 0) {
- ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);
- return -1;
- }
- mRequests.add(fd, request);
- } else {
- int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
- if (epollResult < 0) {
- ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno);
- return -1;
- }
- mRequests.replaceValueAt(requestIndex, request);
- }
- } // release lock
-#else
- int pollEvents = 0;
- if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN;
- if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT;
-
- wakeAndLock(); // acquire lock
-
- struct pollfd requestedFd;
- requestedFd.fd = fd;
- requestedFd.events = pollEvents;
-
- Request request;
- request.fd = fd;
- request.ident = ident;
- request.callback = callback;
- request.data = data;
- ssize_t index = getRequestIndexLocked(fd);
- if (index < 0) {
- mRequestedFds.push(requestedFd);
- mRequests.push(request);
- } else {
- mRequestedFds.replaceAt(requestedFd, size_t(index));
- mRequests.replaceAt(request, size_t(index));
- }
-
- mLock.unlock(); // release lock
-#endif
- return 1;
-}
-
-int Looper::removeFd(int fd) {
-#if DEBUG_CALLBACKS
- ALOGD("%p ~ removeFd - fd=%d", this, fd);
-#endif
-
-#ifdef LOOPER_USES_EPOLL
- { // acquire lock
- AutoMutex _l(mLock);
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex < 0) {
- return 0;
- }
-
- int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
- if (epollResult < 0) {
- ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno);
- return -1;
- }
-
- mRequests.removeItemsAt(requestIndex);
- } // release lock
- return 1;
-#else
- wakeAndLock(); // acquire lock
-
- ssize_t index = getRequestIndexLocked(fd);
- if (index >= 0) {
- mRequestedFds.removeAt(size_t(index));
- mRequests.removeAt(size_t(index));
- }
-
- mLock.unlock(); // release lock
- return index >= 0;
-#endif
-}
-
-#ifndef LOOPER_USES_EPOLL
-ssize_t Looper::getRequestIndexLocked(int fd) {
- size_t requestCount = mRequestedFds.size();
-
- for (size_t i = 0; i < requestCount; i++) {
- if (mRequestedFds.itemAt(i).fd == fd) {
- return i;
- }
- }
-
- return -1;
-}
-
-void Looper::wakeAndLock() {
- mLock.lock();
-
- mWaiters += 1;
- while (mPolling) {
- wake();
- mAwake.wait(mLock);
- }
-
- mWaiters -= 1;
- if (mWaiters == 0) {
- mResume.signal();
- }
-}
-#endif
-
-void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sendMessageAtTime(now, handler, message);
-}
-
-void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
- const Message& message) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sendMessageAtTime(now + uptimeDelay, handler, message);
-}
-
-void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
- const Message& message) {
-#if DEBUG_CALLBACKS
- ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",
- this, uptime, handler.get(), message.what);
-#endif
-
- size_t i = 0;
- { // acquire lock
- AutoMutex _l(mLock);
-
- size_t messageCount = mMessageEnvelopes.size();
- while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
- i += 1;
- }
-
- MessageEnvelope messageEnvelope(uptime, handler, message);
- mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
-
- // Optimization: If the Looper is currently sending a message, then we can skip
- // the call to wake() because the next thing the Looper will do after processing
- // messages is to decide when the next wakeup time should be. In fact, it does
- // not even matter whether this code is running on the Looper thread.
- if (mSendingMessage) {
- return;
- }
- } // release lock
-
- // Wake the poll loop only when we enqueue a new message at the head.
- if (i == 0) {
- wake();
- }
-}
-
-void Looper::removeMessages(const sp<MessageHandler>& handler) {
-#if DEBUG_CALLBACKS
- ALOGD("%p ~ removeMessages - handler=%p", this, handler.get());
-#endif
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
- if (messageEnvelope.handler == handler) {
- mMessageEnvelopes.removeAt(i);
- }
- }
- } // release lock
-}
-
-void Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
-#if DEBUG_CALLBACKS
- ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
-#endif
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
- if (messageEnvelope.handler == handler
- && messageEnvelope.message.what == what) {
- mMessageEnvelopes.removeAt(i);
- }
- }
- } // release lock
-}
-
-} // namespace android
diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libs/utils/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libs/utils/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/libs/utils/PropertyMap.cpp b/libs/utils/PropertyMap.cpp
deleted file mode 100644
index 5520702..0000000
--- a/libs/utils/PropertyMap.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "PropertyMap"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <utils/PropertyMap.h>
-#include <utils/Log.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r=";
-
-
-// --- PropertyMap ---
-
-PropertyMap::PropertyMap() {
-}
-
-PropertyMap::~PropertyMap() {
-}
-
-void PropertyMap::clear() {
- mProperties.clear();
-}
-
-void PropertyMap::addProperty(const String8& key, const String8& value) {
- mProperties.add(key, value);
-}
-
-bool PropertyMap::hasProperty(const String8& key) const {
- return mProperties.indexOfKey(key) >= 0;
-}
-
-bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {
- ssize_t index = mProperties.indexOfKey(key);
- if (index < 0) {
- return false;
- }
-
- outValue = mProperties.valueAt(index);
- return true;
-}
-
-bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
- int32_t intValue;
- if (!tryGetProperty(key, intValue)) {
- return false;
- }
-
- outValue = intValue;
- return true;
-}
-
-bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {
- String8 stringValue;
- if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
- return false;
- }
-
- char* end;
- int value = strtol(stringValue.string(), & end, 10);
- if (*end != '\0') {
- ALOGW("Property key '%s' has invalid value '%s'. Expected an integer.",
- key.string(), stringValue.string());
- return false;
- }
- outValue = value;
- return true;
-}
-
-bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
- String8 stringValue;
- if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
- return false;
- }
-
- char* end;
- float value = strtof(stringValue.string(), & end);
- if (*end != '\0') {
- ALOGW("Property key '%s' has invalid value '%s'. Expected a float.",
- key.string(), stringValue.string());
- return false;
- }
- outValue = value;
- return true;
-}
-
-void PropertyMap::addAll(const PropertyMap* map) {
- for (size_t i = 0; i < map->mProperties.size(); i++) {
- mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));
- }
-}
-
-status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) {
- *outMap = NULL;
-
- Tokenizer* tokenizer;
- status_t status = Tokenizer::open(filename, &tokenizer);
- if (status) {
- ALOGE("Error %d opening property file %s.", status, filename.string());
- } else {
- PropertyMap* map = new PropertyMap();
- if (!map) {
- ALOGE("Error allocating property map.");
- status = NO_MEMORY;
- } else {
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
- Parser parser(map, tokenizer);
- status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
- ALOGD("Parsed property file '%s' %d lines in %0.3fms.",
- tokenizer->getFilename().string(), tokenizer->getLineNumber(),
- elapsedTime / 1000000.0);
-#endif
- if (status) {
- delete map;
- } else {
- *outMap = map;
- }
- }
- delete tokenizer;
- }
- return status;
-}
-
-
-// --- PropertyMap::Parser ---
-
-PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) :
- mMap(map), mTokenizer(tokenizer) {
-}
-
-PropertyMap::Parser::~Parser() {
-}
-
-status_t PropertyMap::Parser::parse() {
- while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
- ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
-#endif
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
- if (keyToken.isEmpty()) {
- ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- if (mTokenizer->nextChar() != '=') {
- ALOGE("%s: Expected '=' between property key and value.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- String8 valueToken = mTokenizer->nextToken(WHITESPACE);
- if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) {
- ALOGE("%s: Found reserved character '\\' or '\"' in property value.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol()) {
- ALOGE("%s: Expected end of line, got '%s'.",
- mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
- return BAD_VALUE;
- }
-
- if (mMap->hasProperty(keyToken)) {
- ALOGE("%s: Duplicate property value for key '%s'.",
- mTokenizer->getLocation().string(), keyToken.string());
- return BAD_VALUE;
- }
-
- mMap->addProperty(keyToken, valueToken);
- }
-
- mTokenizer->nextLine();
- }
- return NO_ERROR;
-}
-
-} // namespace android
diff --git a/libs/utils/README b/libs/utils/README
deleted file mode 100644
index 01741e0..0000000
--- a/libs/utils/README
+++ /dev/null
@@ -1,289 +0,0 @@
-Android Utility Function Library
-================================
-
-
-If you need a feature that is native to Linux but not present on other
-platforms, construct a platform-dependent implementation that shares
-the Linux interface. That way the actual device runs as "light" as
-possible.
-
-If that isn't feasible, create a system-independent interface and hide
-the details.
-
-The ultimate goal is *not* to create a super-duper platform abstraction
-layer. The goal is to provide an optimized solution for Linux with
-reasonable implementations for other platforms.
-
-
-
-Resource overlay
-================
-
-
-Introduction
-------------
-
-Overlay packages are special .apk files which provide no code but
-additional resource values (and possibly new configurations) for
-resources in other packages. When an application requests resources,
-the system will return values from either the application's original
-package or any associated overlay package. Any redirection is completely
-transparent to the calling application.
-
-Resource values have the following precedence table, listed in
-descending precedence.
-
- * overlay package, matching config (eg res/values-en-land)
-
- * original package, matching config
-
- * overlay package, no config (eg res/values)
-
- * original package, no config
-
-During compilation, overlay packages are differentiated from regular
-packages by passing the -o flag to aapt.
-
-
-Background
-----------
-
-This section provides generic background material on resources in
-Android.
-
-
-How resources are bundled in .apk files
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Android .apk files are .zip files, usually housing .dex code,
-certificates and resources, though packages containing resources but
-no code are possible. Resources can be divided into the following
-categories; a `configuration' indicates a set of phone language, display
-density, network operator, etc.
-
- * assets: uncompressed, raw files packaged as part of an .apk and
- explicitly referenced by filename. These files are
- independent of configuration.
-
- * res/drawable: bitmap or xml graphics. Each file may have different
- values depending on configuration.
-
- * res/values: integers, strings, etc. Each resource may have different
- values depending on configuration.
-
-Resource meta information and information proper is stored in a binary
-format in a named file resources.arsc, bundled as part of the .apk.
-
-Resource IDs and lookup
-~~~~~~~~~~~~~~~~~~~~~~~
-During compilation, the aapt tool gathers application resources and
-generates a resources.arsc file. Each resource name is assigned an
-integer ID 0xppttiii (translated to a symbolic name via R.java), where
-
- * pp: corresponds to the package namespace (details below).
-
- * tt: corresponds to the resource type (string, int, etc). Every
- resource of the same type within the same package has the same
- tt value, but depending on available types, the actual numerical
- value may be different between packages.
-
- * iiii: sequential number, assigned in the order resources are found.
-
-Resource values are specified paired with a set of configuration
-constraints (the default being the empty set), eg res/values-sv-port
-which imposes restrictions on language (Swedish) and display orientation
-(portrait). During lookup, every constraint set is matched against the
-current configuration, and the value corresponding to the best matching
-constraint set is returned (ResourceTypes.{h,cpp}).
-
-Parsing of resources.arsc is handled by ResourceTypes.cpp; this utility
-is governed by AssetManager.cpp, which tracks loaded resources per
-process.
-
-Assets are looked up by path and filename in AssetManager.cpp. The path
-to resources in res/drawable are located by ResourceTypes.cpp and then
-handled like assets by AssetManager.cpp. Other resources are handled
-solely by ResourceTypes.cpp.
-
-Package ID as namespace
-~~~~~~~~~~~~~~~~~~~~~~~
-The pp part of a resource ID defines a namespace. Android currently
-defines two namespaces:
-
- * 0x01: system resources (pre-installed in framework-res.apk)
-
- * 0x7f: application resources (bundled in the application .apk)
-
-ResourceTypes.cpp supports package IDs between 0x01 and 0x7f
-(inclusive); values outside this range are invalid.
-
-Each running (Dalvik) process is assigned a unique instance of
-AssetManager, which in turn keeps a forest structure of loaded
-resource.arsc files. Normally, this forest is structured as follows,
-where mPackageMap is the internal vector employed in ResourceTypes.cpp.
-
-mPackageMap[0x00] -> system package
-mPackageMap[0x01] -> NULL
-mPackageMap[0x02] -> NULL
-...
-mPackageMap[0x7f - 2] -> NULL
-mPackageMap[0x7f - 1] -> application package
-
-
-
-The resource overlay extension
-------------------------------
-
-The resource overlay mechanism aims to (partly) shadow and extend
-existing resources with new values for defined and new configurations.
-Technically, this is achieved by adding resource-only packages (called
-overlay packages) to existing resource namespaces, like so:
-
-mPackageMap[0x00] -> system package -> system overlay package
-mPackageMap[0x01] -> NULL
-mPackageMap[0x02] -> NULL
-...
-mPackageMap[0x7f - 2] -> NULL
-mPackageMap[0x7f - 1] -> application package -> overlay 1 -> overlay 2
-
-The use of overlay resources is completely transparent to
-applications; no additional resource identifiers are introduced, only
-configuration/value pairs. Any number of overlay packages may be loaded
-at a time; overlay packages are agnostic to what they target -- both
-system and application resources are fair game.
-
-The package targeted by an overlay package is called the target or
-original package.
-
-Resource overlay operates on symbolic resources names. Hence, to
-override the string/str1 resources in a package, the overlay package
-would include a resource also named string/str1. The end user does not
-have to worry about the numeric resources IDs assigned by aapt, as this
-is resolved automatically by the system.
-
-As of this writing, the use of resource overlay has not been fully
-explored. Until it has, only OEMs are trusted to use resource overlay.
-For this reason, overlay packages must reside in /system/overlay.
-
-
-Resource ID mapping
-~~~~~~~~~~~~~~~~~~~
-Resource identifiers must be coherent within the same namespace (ie
-PackageGroup in ResourceTypes.cpp). Calling applications will refer to
-resources using the IDs defined in the original package, but there is no
-guarantee aapt has assigned the same ID to the corresponding resource in
-an overlay package. To translate between the two, a resource ID mapping
-{original ID -> overlay ID} is created during package installation
-(PackageManagerService.java) and used during resource lookup. The
-mapping is stored in /data/resource-cache, with a @idmap file name
-suffix.
-
-The idmap file format is documented in a separate section, below.
-
-
-Package management
-~~~~~~~~~~~~~~~~~~
-Packages are managed by the PackageManagerService. Addition and removal
-of packages are monitored via the inotify framework, exposed via
-android.os.FileObserver.
-
-During initialization of a Dalvik process, ActivityThread.java requests
-the process' AssetManager (by proxy, via AssetManager.java and JNI)
-to load a list of packages. This list includes overlay packages, if
-present.
-
-When a target package or a corresponding overlay package is installed,
-the target package's process is stopped and a new idmap is generated.
-This is similar to how applications are stopped when their packages are
-upgraded.
-
-
-Creating overlay packages
--------------------------
-
-Overlay packages should contain no code, define (some) resources with
-the same type and name as in the original package, and be compiled with
-the -o flag passed to aapt.
-
-The aapt -o flag instructs aapt to create an overlay package.
-Technically, this means the package will be assigned package id 0x00.
-
-There are no restrictions on overlay packages names, though the naming
-convention <original.package.name>.overlay.<name> is recommended.
-
-
-Example overlay package
-~~~~~~~~~~~~~~~~~~~~~~~
-
-To overlay the resource bool/b in package com.foo.bar, to be applied
-when the display is in landscape mode, create a new package with
-no source code and a single .xml file under res/values-land, with
-an entry for bool/b. Compile with aapt -o and place the results in
-/system/overlay by adding the following to Android.mk:
-
-LOCAL_AAPT_FLAGS := -o com.foo.bar
-LOCAL_MODULE_PATH := $(TARGET_OUT)/overlay
-
-
-The ID map (idmap) file format
-------------------------------
-
-The idmap format is designed for lookup performance. However, leading
-and trailing undefined overlay values are discarded to reduce the memory
-footprint.
-
-
-idmap grammar
-~~~~~~~~~~~~~
-All atoms (names in square brackets) are uint32_t integers. The
-idmap-magic constant spells "idmp" in ASCII. Offsets are given relative
-to the data_header, not to the beginning of the file.
-
-map := header data
-header := idmap-magic <crc32-original-pkg> <crc32-overlay-pkg>
-idmap-magic := <0x706d6469>
-data := data_header type_block+
-data_header := <m> header_block{m}
-header_block := <0> | <type_block_offset>
-type_block := <n> <id_offset> entry{n}
-entry := <resource_id_in_target_package>
-
-
-idmap example
-~~~~~~~~~~~~~
-Given a pair of target and overlay packages with CRC sums 0x216a8fe2
-and 0x6b9beaec, each defining the following resources
-
-Name Target package Overlay package
-string/str0 0x7f010000 -
-string/str1 0x7f010001 0x7f010000
-string/str2 0x7f010002 -
-string/str3 0x7f010003 0x7f010001
-string/str4 0x7f010004 -
-bool/bool0 0x7f020000 -
-integer/int0 0x7f030000 0x7f020000
-integer/int1 0x7f030001 -
-
-the corresponding resource map is
-
-0x706d6469 0x216a8fe2 0x6b9beaec 0x00000003 \
-0x00000004 0x00000000 0x00000009 0x00000003 \
-0x00000001 0x7f010000 0x00000000 0x7f010001 \
-0x00000001 0x00000000 0x7f020000
-
-or, formatted differently
-
-0x706d6469 # magic: all idmap files begin with this constant
-0x216a8fe2 # CRC32 of the resources.arsc file in the original package
-0x6b9beaec # CRC32 of the resources.arsc file in the overlay package
-0x00000003 # header; three types (string, bool, integer) in the target package
-0x00000004 # header_block for type 0 (string) is located at offset 4
-0x00000000 # no bool type exists in overlay package -> no header_block
-0x00000009 # header_block for type 2 (integer) is located at offset 9
-0x00000003 # header_block for string; overlay IDs span 3 elements
-0x00000001 # the first string in target package is entry 1 == offset
-0x7f010000 # target 0x7f01001 -> overlay 0x7f010000
-0x00000000 # str2 not defined in overlay package
-0x7f010001 # target 0x7f010003 -> overlay 0x7f010001
-0x00000001 # header_block for integer; overlay IDs span 1 element
-0x00000000 # offset == 0
-0x7f020000 # target 0x7f030000 -> overlay 0x7f020000
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
deleted file mode 100644
index e80a795..0000000
--- a/libs/utils/RefBase.cpp
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "RefBase"
-
-#include <utils/RefBase.h>
-
-#include <utils/Atomic.h>
-#include <utils/CallStack.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/TextOutput.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <typeinfo>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-// compile with refcounting debugging enabled
-#define DEBUG_REFS 0
-#define DEBUG_REFS_FATAL_SANITY_CHECKS 0
-#define DEBUG_REFS_ENABLED_BY_DEFAULT 1
-#define DEBUG_REFS_CALLSTACK_ENABLED 1
-
-// log all reference counting operations
-#define PRINT_REFS 0
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-#define INITIAL_STRONG_VALUE (1<<28)
-
-// ---------------------------------------------------------------------------
-
-class RefBase::weakref_impl : public RefBase::weakref_type
-{
-public:
- volatile int32_t mStrong;
- volatile int32_t mWeak;
- RefBase* const mBase;
- volatile int32_t mFlags;
-
-#if !DEBUG_REFS
-
- weakref_impl(RefBase* base)
- : mStrong(INITIAL_STRONG_VALUE)
- , mWeak(0)
- , mBase(base)
- , mFlags(0)
- {
- }
-
- void addStrongRef(const void* /*id*/) { }
- void removeStrongRef(const void* /*id*/) { }
- void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
- void addWeakRef(const void* /*id*/) { }
- void removeWeakRef(const void* /*id*/) { }
- void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
- void printRefs() const { }
- void trackMe(bool, bool) { }
-
-#else
-
- weakref_impl(RefBase* base)
- : mStrong(INITIAL_STRONG_VALUE)
- , mWeak(0)
- , mBase(base)
- , mFlags(0)
- , mStrongRefs(NULL)
- , mWeakRefs(NULL)
- , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
- , mRetain(false)
- {
- }
-
- ~weakref_impl()
- {
- bool dumpStack = false;
- if (!mRetain && mStrongRefs != NULL) {
- dumpStack = true;
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
- LOG_ALWAYS_FATAL("Strong references remain!");
-#else
- ALOGE("Strong references remain:");
-#endif
- ref_entry* refs = mStrongRefs;
- while (refs) {
- char inc = refs->ref >= 0 ? '+' : '-';
- ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
-#if DEBUG_REFS_CALLSTACK_ENABLED
- refs->stack.dump();
-#endif
- refs = refs->next;
- }
- }
-
- if (!mRetain && mWeakRefs != NULL) {
- dumpStack = true;
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
- LOG_ALWAYS_FATAL("Weak references remain:");
-#else
- ALOGE("Weak references remain!");
-#endif
- ref_entry* refs = mWeakRefs;
- while (refs) {
- char inc = refs->ref >= 0 ? '+' : '-';
- ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
-#if DEBUG_REFS_CALLSTACK_ENABLED
- refs->stack.dump();
-#endif
- refs = refs->next;
- }
- }
- if (dumpStack) {
- ALOGE("above errors at:");
- CallStack stack;
- stack.update();
- stack.dump();
- }
- }
-
- void addStrongRef(const void* id) {
- //ALOGD_IF(mTrackEnabled,
- // "addStrongRef: RefBase=%p, id=%p", mBase, id);
- addRef(&mStrongRefs, id, mStrong);
- }
-
- void removeStrongRef(const void* id) {
- //ALOGD_IF(mTrackEnabled,
- // "removeStrongRef: RefBase=%p, id=%p", mBase, id);
- if (!mRetain) {
- removeRef(&mStrongRefs, id);
- } else {
- addRef(&mStrongRefs, id, -mStrong);
- }
- }
-
- void renameStrongRefId(const void* old_id, const void* new_id) {
- //ALOGD_IF(mTrackEnabled,
- // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
- // mBase, old_id, new_id);
- renameRefsId(mStrongRefs, old_id, new_id);
- }
-
- void addWeakRef(const void* id) {
- addRef(&mWeakRefs, id, mWeak);
- }
-
- void removeWeakRef(const void* id) {
- if (!mRetain) {
- removeRef(&mWeakRefs, id);
- } else {
- addRef(&mWeakRefs, id, -mWeak);
- }
- }
-
- void renameWeakRefId(const void* old_id, const void* new_id) {
- renameRefsId(mWeakRefs, old_id, new_id);
- }
-
- void trackMe(bool track, bool retain)
- {
- mTrackEnabled = track;
- mRetain = retain;
- }
-
- void printRefs() const
- {
- String8 text;
-
- {
- Mutex::Autolock _l(mMutex);
- char buf[128];
- sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
- text.append(buf);
- printRefsLocked(&text, mStrongRefs);
- sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
- text.append(buf);
- printRefsLocked(&text, mWeakRefs);
- }
-
- {
- char name[100];
- snprintf(name, 100, "/data/%p.stack", this);
- int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
- if (rc >= 0) {
- write(rc, text.string(), text.length());
- close(rc);
- ALOGD("STACK TRACE for %p saved in %s", this, name);
- }
- else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
- name, strerror(errno));
- }
- }
-
-private:
- struct ref_entry
- {
- ref_entry* next;
- const void* id;
-#if DEBUG_REFS_CALLSTACK_ENABLED
- CallStack stack;
-#endif
- int32_t ref;
- };
-
- void addRef(ref_entry** refs, const void* id, int32_t mRef)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
-
- ref_entry* ref = new ref_entry;
- // Reference count at the time of the snapshot, but before the
- // update. Positive value means we increment, negative--we
- // decrement the reference count.
- ref->ref = mRef;
- ref->id = id;
-#if DEBUG_REFS_CALLSTACK_ENABLED
- ref->stack.update(2);
-#endif
- ref->next = *refs;
- *refs = ref;
- }
- }
-
- void removeRef(ref_entry** refs, const void* id)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
-
- ref_entry* const head = *refs;
- ref_entry* ref = head;
- while (ref != NULL) {
- if (ref->id == id) {
- *refs = ref->next;
- delete ref;
- return;
- }
- refs = &ref->next;
- ref = *refs;
- }
-
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
- LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
- "(weakref_type %p) that doesn't exist!",
- id, mBase, this);
-#endif
-
- ALOGE("RefBase: removing id %p on RefBase %p"
- "(weakref_type %p) that doesn't exist!",
- id, mBase, this);
-
- ref = head;
- while (ref) {
- char inc = ref->ref >= 0 ? '+' : '-';
- ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
- ref = ref->next;
- }
-
- CallStack stack;
- stack.update();
- stack.dump();
- }
- }
-
- void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
- {
- if (mTrackEnabled) {
- AutoMutex _l(mMutex);
- ref_entry* ref = r;
- while (ref != NULL) {
- if (ref->id == old_id) {
- ref->id = new_id;
- }
- ref = ref->next;
- }
- }
- }
-
- void printRefsLocked(String8* out, const ref_entry* refs) const
- {
- char buf[128];
- while (refs) {
- char inc = refs->ref >= 0 ? '+' : '-';
- sprintf(buf, "\t%c ID %p (ref %d):\n",
- inc, refs->id, refs->ref);
- out->append(buf);
-#if DEBUG_REFS_CALLSTACK_ENABLED
- out->append(refs->stack.toString("\t\t"));
-#else
- out->append("\t\t(call stacks disabled)");
-#endif
- refs = refs->next;
- }
- }
-
- mutable Mutex mMutex;
- ref_entry* mStrongRefs;
- ref_entry* mWeakRefs;
-
- bool mTrackEnabled;
- // Collect stack traces on addref and removeref, instead of deleting the stack references
- // on removeref that match the address ones.
- bool mRetain;
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-
-void RefBase::incStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->incWeak(id);
-
- refs->addStrongRef(id);
- const int32_t c = android_atomic_inc(&refs->mStrong);
- ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
-#if PRINT_REFS
- ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
- if (c != INITIAL_STRONG_VALUE) {
- return;
- }
-
- android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
- refs->mBase->onFirstRef();
-}
-
-void RefBase::decStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->removeStrongRef(id);
- const int32_t c = android_atomic_dec(&refs->mStrong);
-#if PRINT_REFS
- ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
- ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
- if (c == 1) {
- refs->mBase->onLastStrongRef(id);
- if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
- delete this;
- }
- }
- refs->decWeak(id);
-}
-
-void RefBase::forceIncStrong(const void* id) const
-{
- weakref_impl* const refs = mRefs;
- refs->incWeak(id);
-
- refs->addStrongRef(id);
- const int32_t c = android_atomic_inc(&refs->mStrong);
- ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
- refs);
-#if PRINT_REFS
- ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
-#endif
-
- switch (c) {
- case INITIAL_STRONG_VALUE:
- android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
- // fall through...
- case 0:
- refs->mBase->onFirstRef();
- }
-}
-
-int32_t RefBase::getStrongCount() const
-{
- return mRefs->mStrong;
-}
-
-RefBase* RefBase::weakref_type::refBase() const
-{
- return static_cast<const weakref_impl*>(this)->mBase;
-}
-
-void RefBase::weakref_type::incWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
- impl->addWeakRef(id);
- const int32_t c = android_atomic_inc(&impl->mWeak);
- ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
-}
-
-
-void RefBase::weakref_type::decWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
- impl->removeWeakRef(id);
- const int32_t c = android_atomic_dec(&impl->mWeak);
- ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
- if (c != 1) return;
-
- if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
- // This is the regular lifetime case. The object is destroyed
- // when the last strong reference goes away. Since weakref_impl
- // outlive the object, it is not destroyed in the dtor, and
- // we'll have to do it here.
- if (impl->mStrong == INITIAL_STRONG_VALUE) {
- // Special case: we never had a strong reference, so we need to
- // destroy the object now.
- delete impl->mBase;
- } else {
- // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
- delete impl;
- }
- } else {
- // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
- impl->mBase->onLastWeakRef(id);
- if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
- // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
- // is gone, we can destroy the object.
- delete impl->mBase;
- }
- }
-}
-
-bool RefBase::weakref_type::attemptIncStrong(const void* id)
-{
- incWeak(id);
-
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
-
- int32_t curCount = impl->mStrong;
- ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
- this);
- while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
- if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
- break;
- }
- curCount = impl->mStrong;
- }
-
- if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
- bool allow;
- if (curCount == INITIAL_STRONG_VALUE) {
- // Attempting to acquire first strong reference... this is allowed
- // if the object does NOT have a longer lifetime (meaning the
- // implementation doesn't need to see this), or if the implementation
- // allows it to happen.
- allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
- || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
- } else {
- // Attempting to revive the object... this is allowed
- // if the object DOES have a longer lifetime (so we can safely
- // call the object with only a weak ref) and the implementation
- // allows it to happen.
- allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
- && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
- }
- if (!allow) {
- decWeak(id);
- return false;
- }
- curCount = android_atomic_inc(&impl->mStrong);
-
- // If the strong reference count has already been incremented by
- // someone else, the implementor of onIncStrongAttempted() is holding
- // an unneeded reference. So call onLastStrongRef() here to remove it.
- // (No, this is not pretty.) Note that we MUST NOT do this if we
- // are in fact acquiring the first reference.
- if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
- impl->mBase->onLastStrongRef(id);
- }
- }
-
- impl->addStrongRef(id);
-
-#if PRINT_REFS
- ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
-#endif
-
- if (curCount == INITIAL_STRONG_VALUE) {
- android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
- impl->mBase->onFirstRef();
- }
-
- return true;
-}
-
-bool RefBase::weakref_type::attemptIncWeak(const void* id)
-{
- weakref_impl* const impl = static_cast<weakref_impl*>(this);
-
- int32_t curCount = impl->mWeak;
- ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
- this);
- while (curCount > 0) {
- if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
- break;
- }
- curCount = impl->mWeak;
- }
-
- if (curCount > 0) {
- impl->addWeakRef(id);
- }
-
- return curCount > 0;
-}
-
-int32_t RefBase::weakref_type::getWeakCount() const
-{
- return static_cast<const weakref_impl*>(this)->mWeak;
-}
-
-void RefBase::weakref_type::printRefs() const
-{
- static_cast<const weakref_impl*>(this)->printRefs();
-}
-
-void RefBase::weakref_type::trackMe(bool enable, bool retain)
-{
- static_cast<weakref_impl*>(this)->trackMe(enable, retain);
-}
-
-RefBase::weakref_type* RefBase::createWeak(const void* id) const
-{
- mRefs->incWeak(id);
- return mRefs;
-}
-
-RefBase::weakref_type* RefBase::getWeakRefs() const
-{
- return mRefs;
-}
-
-RefBase::RefBase()
- : mRefs(new weakref_impl(this))
-{
-}
-
-RefBase::~RefBase()
-{
- if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
- // we never acquired a strong (and/or weak) reference on this object.
- delete mRefs;
- } else {
- // life-time of this object is extended to WEAK or FOREVER, in
- // which case weakref_impl doesn't out-live the object and we
- // can free it now.
- if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
- // It's possible that the weak count is not 0 if the object
- // re-acquired a weak reference in its destructor
- if (mRefs->mWeak == 0) {
- delete mRefs;
- }
- }
- }
- // for debugging purposes, clear this.
- const_cast<weakref_impl*&>(mRefs) = NULL;
-}
-
-void RefBase::extendObjectLifetime(int32_t mode)
-{
- android_atomic_or(mode, &mRefs->mFlags);
-}
-
-void RefBase::onFirstRef()
-{
-}
-
-void RefBase::onLastStrongRef(const void* /*id*/)
-{
-}
-
-bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
-{
- return (flags&FIRST_INC_STRONG) ? true : false;
-}
-
-void RefBase::onLastWeakRef(const void* /*id*/)
-{
-}
-
-// ---------------------------------------------------------------------------
-
-void RefBase::moveReferences(void* dst, void const* src, size_t n,
- const ReferenceConverterBase& caster)
-{
-#if DEBUG_REFS
- const size_t itemSize = caster.getReferenceTypeSize();
- for (size_t i=0 ; i<n ; i++) {
- void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize);
- void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
- RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
- ref->mRefs->renameStrongRefId(s, d);
- ref->mRefs->renameWeakRefId(s, d);
- }
-#endif
-}
-
-// ---------------------------------------------------------------------------
-
-TextOutput& printStrongPointer(TextOutput& to, const void* val)
-{
- to << "sp<>(" << val << ")";
- return to;
-}
-
-TextOutput& printWeakPointer(TextOutput& to, const void* val)
-{
- to << "wp<>(" << val << ")";
- return to;
-}
-
-
-}; // namespace android
diff --git a/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp
deleted file mode 100644
index 3555fb7..0000000
--- a/libs/utils/SharedBuffer.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <utils/SharedBuffer.h>
-#include <utils/Atomic.h>
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-SharedBuffer* SharedBuffer::alloc(size_t size)
-{
- SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
- if (sb) {
- sb->mRefs = 1;
- sb->mSize = size;
- }
- return sb;
-}
-
-
-ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
-{
- if (released->mRefs != 0) return -1; // XXX: invalid operation
- free(const_cast<SharedBuffer*>(released));
- return 0;
-}
-
-SharedBuffer* SharedBuffer::edit() const
-{
- if (onlyOwner()) {
- return const_cast<SharedBuffer*>(this);
- }
- SharedBuffer* sb = alloc(mSize);
- if (sb) {
- memcpy(sb->data(), data(), size());
- release();
- }
- return sb;
-}
-
-SharedBuffer* SharedBuffer::editResize(size_t newSize) const
-{
- if (onlyOwner()) {
- SharedBuffer* buf = const_cast<SharedBuffer*>(this);
- if (buf->mSize == newSize) return buf;
- buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
- if (buf != NULL) {
- buf->mSize = newSize;
- return buf;
- }
- }
- SharedBuffer* sb = alloc(newSize);
- if (sb) {
- const size_t mySize = mSize;
- memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);
- release();
- }
- return sb;
-}
-
-SharedBuffer* SharedBuffer::attemptEdit() const
-{
- if (onlyOwner()) {
- return const_cast<SharedBuffer*>(this);
- }
- return 0;
-}
-
-SharedBuffer* SharedBuffer::reset(size_t new_size) const
-{
- // cheap-o-reset.
- SharedBuffer* sb = alloc(new_size);
- if (sb) {
- release();
- }
- return sb;
-}
-
-void SharedBuffer::acquire() const {
- android_atomic_inc(&mRefs);
-}
-
-int32_t SharedBuffer::release(uint32_t flags) const
-{
- int32_t prev = 1;
- if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
- mRefs = 0;
- if ((flags & eKeepStorage) == 0) {
- free(const_cast<SharedBuffer*>(this));
- }
- }
- return prev;
-}
-
-
-}; // namespace android
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
deleted file mode 100644
index 624e917..0000000
--- a/libs/utils/Static.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// All static variables go here, to control initialization and
-// destruction order in the library.
-
-#include <private/utils/Static.h>
-
-#include <utils/BufferedTextOutput.h>
-#include <utils/Log.h>
-
-namespace android {
-
-class LibUtilsFirstStatics
-{
-public:
- LibUtilsFirstStatics()
- {
- initialize_string8();
- initialize_string16();
- }
-
- ~LibUtilsFirstStatics()
- {
- terminate_string16();
- terminate_string8();
- }
-};
-
-static LibUtilsFirstStatics gFirstStatics;
-int gDarwinCantLoadAllObjects = 1;
-
-// ------------ Text output streams
-
-Vector<int32_t> gTextBuffers;
-
-class LogTextOutput : public BufferedTextOutput
-{
-public:
- LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
- virtual ~LogTextOutput() { };
-
-protected:
- virtual status_t writeLines(const struct iovec& vec, size_t N)
- {
- //android_writevLog(&vec, N); <-- this is now a no-op
- if (N != 1) ALOGI("WARNING: writeLines N=%zu\n", N);
- ALOGI("%.*s", (int)vec.iov_len, (const char*) vec.iov_base);
- return NO_ERROR;
- }
-};
-
-class FdTextOutput : public BufferedTextOutput
-{
-public:
- FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
- virtual ~FdTextOutput() { };
-
-protected:
- virtual status_t writeLines(const struct iovec& vec, size_t N)
- {
- writev(mFD, &vec, N);
- return NO_ERROR;
- }
-
-private:
- int mFD;
-};
-
-static LogTextOutput gLogTextOutput;
-static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
-static FdTextOutput gStderrTextOutput(STDERR_FILENO);
-
-TextOutput& alog(gLogTextOutput);
-TextOutput& aout(gStdoutTextOutput);
-TextOutput& aerr(gStderrTextOutput);
-
-} // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
deleted file mode 100644
index b1708d6..0000000
--- a/libs/utils/StopWatch.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "StopWatch"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-/* for PRId64 */
-#define __STDC_FORMAT_MACROS 1
-#include <inttypes.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/StopWatch.h>
-
-/*****************************************************************************/
-
-namespace android {
-
-
-StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
- : mName(name), mClock(clock), mFlags(flags)
-{
- reset();
-}
-
-StopWatch::~StopWatch()
-{
- nsecs_t elapsed = elapsedTime();
- const int n = mNumLaps;
- ALOGD("StopWatch %s (us): %" PRId64 " ", mName, ns2us(elapsed));
- for (int i=0 ; i<n ; i++) {
- const nsecs_t soFar = mLaps[i].soFar;
- const nsecs_t thisLap = mLaps[i].thisLap;
- ALOGD(" [%d: %" PRId64 ", %" PRId64, i, ns2us(soFar), ns2us(thisLap));
- }
-}
-
-const char* StopWatch::name() const
-{
- return mName;
-}
-
-nsecs_t StopWatch::lap()
-{
- nsecs_t elapsed = elapsedTime();
- if (mNumLaps >= 8) {
- elapsed = 0;
- } else {
- const int n = mNumLaps;
- mLaps[n].soFar = elapsed;
- mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;
- mNumLaps = n+1;
- }
- return elapsed;
-}
-
-nsecs_t StopWatch::elapsedTime() const
-{
- return systemTime(mClock) - mStartTime;
-}
-
-void StopWatch::reset()
-{
- mNumLaps = 0;
- mStartTime = systemTime(mClock);
-}
-
-
-/*****************************************************************************/
-
-}; // namespace android
-
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
deleted file mode 100644
index 94e072f..0000000
--- a/libs/utils/String16.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/String16.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/Unicode.h>
-#include <utils/String8.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/utils/Static.h>
-
-#include <memory.h>
-#include <stdio.h>
-#include <ctype.h>
-
-
-namespace android {
-
-static SharedBuffer* gEmptyStringBuf = NULL;
-static char16_t* gEmptyString = NULL;
-
-static inline char16_t* getEmptyString()
-{
- gEmptyStringBuf->acquire();
- return gEmptyString;
-}
-
-void initialize_string16()
-{
- SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
- char16_t* str = (char16_t*)buf->data();
- *str = 0;
- gEmptyStringBuf = buf;
- gEmptyString = str;
-}
-
-void terminate_string16()
-{
- SharedBuffer::bufferFromData(gEmptyString)->release();
- gEmptyStringBuf = NULL;
- gEmptyString = NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
-{
- if (u8len == 0) return getEmptyString();
-
- const uint8_t* u8cur = (const uint8_t*) u8str;
-
- const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
- if (u16len < 0) {
- return getEmptyString();
- }
-
- const uint8_t* const u8end = u8cur + u8len;
-
- SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
- if (buf) {
- u8cur = (const uint8_t*) u8str;
- char16_t* u16str = (char16_t*)buf->data();
-
- utf8_to_utf16(u8cur, u8len, u16str);
-
- //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
- //printHexData(1, str, buf->size(), 16, 1);
- //printf("\n");
-
- return u16str;
- }
-
- return getEmptyString();
-}
-
-// ---------------------------------------------------------------------------
-
-String16::String16()
- : mString(getEmptyString())
-{
-}
-
-String16::String16(const String16& o)
- : mString(o.mString)
-{
- SharedBuffer::bufferFromData(mString)->acquire();
-}
-
-String16::String16(const String16& o, size_t len, size_t begin)
- : mString(getEmptyString())
-{
- setTo(o, len, begin);
-}
-
-String16::String16(const char16_t* o)
-{
- size_t len = strlen16(o);
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- strcpy16(str, o);
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
-
-String16::String16(const char16_t* o, size_t len)
-{
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str, o, len*sizeof(char16_t));
- str[len] = 0;
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
-
-String16::String16(const String8& o)
- : mString(allocFromUTF8(o.string(), o.size()))
-{
-}
-
-String16::String16(const char* o)
- : mString(allocFromUTF8(o, strlen(o)))
-{
-}
-
-String16::String16(const char* o, size_t len)
- : mString(allocFromUTF8(o, len))
-{
-}
-
-String16::~String16()
-{
- SharedBuffer::bufferFromData(mString)->release();
-}
-
-void String16::setTo(const String16& other)
-{
- SharedBuffer::bufferFromData(other.mString)->acquire();
- SharedBuffer::bufferFromData(mString)->release();
- mString = other.mString;
-}
-
-status_t String16::setTo(const String16& other, size_t len, size_t begin)
-{
- const size_t N = other.size();
- if (begin >= N) {
- SharedBuffer::bufferFromData(mString)->release();
- mString = getEmptyString();
- return NO_ERROR;
- }
- if ((begin+len) > N) len = N-begin;
- if (begin == 0 && len == N) {
- setTo(other);
- return NO_ERROR;
- }
-
- if (&other == this) {
- LOG_ALWAYS_FATAL("Not implemented");
- }
-
- return setTo(other.string()+begin, len);
-}
-
-status_t String16::setTo(const char16_t* other)
-{
- return setTo(other, strlen16(other));
-}
-
-status_t String16::setTo(const char16_t* other, size_t len)
-{
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memmove(str, other, len*sizeof(char16_t));
- str[len] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::append(const String16& other)
-{
- const size_t myLen = size();
- const size_t otherLen = other.size();
- if (myLen == 0) {
- setTo(other);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+otherLen+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::append(const char16_t* chrs, size_t otherLen)
-{
- const size_t myLen = size();
- if (myLen == 0) {
- setTo(chrs, otherLen);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+otherLen+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
- str[myLen+otherLen] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-status_t String16::insert(size_t pos, const char16_t* chrs)
-{
- return insert(pos, chrs, strlen16(chrs));
-}
-
-status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
-{
- const size_t myLen = size();
- if (myLen == 0) {
- return setTo(chrs, len);
- return NO_ERROR;
- } else if (len == 0) {
- return NO_ERROR;
- }
-
- if (pos > myLen) pos = myLen;
-
- #if 0
- printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
- String8(*this).string(), pos,
- len, myLen, String8(chrs, len).string());
- #endif
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((myLen+len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- if (pos < myLen) {
- memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
- }
- memcpy(str+pos, chrs, len*sizeof(char16_t));
- str[myLen+len] = 0;
- mString = str;
- #if 0
- printf("Result (%d chrs): %s\n", size(), String8(*this).string());
- #endif
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-ssize_t String16::findFirst(char16_t c) const
-{
- const char16_t* str = string();
- const char16_t* p = str;
- const char16_t* e = p + size();
- while (p < e) {
- if (*p == c) {
- return p-str;
- }
- p++;
- }
- return -1;
-}
-
-ssize_t String16::findLast(char16_t c) const
-{
- const char16_t* str = string();
- const char16_t* p = str;
- const char16_t* e = p + size();
- while (p < e) {
- e--;
- if (*e == c) {
- return e-str;
- }
- }
- return -1;
-}
-
-bool String16::startsWith(const String16& prefix) const
-{
- const size_t ps = prefix.size();
- if (ps > size()) return false;
- return strzcmp16(mString, ps, prefix.string(), ps) == 0;
-}
-
-bool String16::startsWith(const char16_t* prefix) const
-{
- const size_t ps = strlen16(prefix);
- if (ps > size()) return false;
- return strncmp16(mString, prefix, ps) == 0;
-}
-
-status_t String16::makeLower()
-{
- const size_t N = size();
- const char16_t* str = string();
- char16_t* edit = NULL;
- for (size_t i=0; i<N; i++) {
- const char16_t v = str[i];
- if (v >= 'A' && v <= 'Z') {
- if (!edit) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
- if (!buf) {
- return NO_MEMORY;
- }
- edit = (char16_t*)buf->data();
- mString = str = edit;
- }
- edit[i] = tolower((char)v);
- }
- }
- return NO_ERROR;
-}
-
-status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
-{
- const size_t N = size();
- const char16_t* str = string();
- char16_t* edit = NULL;
- for (size_t i=0; i<N; i++) {
- if (str[i] == replaceThis) {
- if (!edit) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
- if (!buf) {
- return NO_MEMORY;
- }
- edit = (char16_t*)buf->data();
- mString = str = edit;
- }
- edit[i] = withThis;
- }
- }
- return NO_ERROR;
-}
-
-status_t String16::remove(size_t len, size_t begin)
-{
- const size_t N = size();
- if (begin >= N) {
- SharedBuffer::bufferFromData(mString)->release();
- mString = getEmptyString();
- return NO_ERROR;
- }
- if ((begin+len) > N) len = N-begin;
- if (begin == 0 && len == N) {
- return NO_ERROR;
- }
-
- if (begin > 0) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((N+1)*sizeof(char16_t));
- if (!buf) {
- return NO_MEMORY;
- }
- char16_t* str = (char16_t*)buf->data();
- memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
- mString = str;
- }
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize((len+1)*sizeof(char16_t));
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- str[len] = 0;
- mString = str;
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-TextOutput& operator<<(TextOutput& to, const String16& val)
-{
- to << String8(val).string();
- return to;
-}
-
-}; // namespace android
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
deleted file mode 100644
index 562f026..0000000
--- a/libs/utils/String8.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/String8.h>
-
-#include <utils/Log.h>
-#include <utils/Unicode.h>
-#include <utils/SharedBuffer.h>
-#include <utils/String16.h>
-#include <utils/TextOutput.h>
-#include <utils/threads.h>
-
-#include <private/utils/Static.h>
-
-#include <ctype.h>
-
-/*
- * Functions outside android is below the namespace android, since they use
- * functions and constants in android namespace.
- */
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// Separator used by resource paths. This is not platform dependent contrary
-// to OS_PATH_SEPARATOR.
-#define RES_PATH_SEPARATOR '/'
-
-static SharedBuffer* gEmptyStringBuf = NULL;
-static char* gEmptyString = NULL;
-
-extern int gDarwinCantLoadAllObjects;
-int gDarwinIsReallyAnnoying;
-
-static inline char* getEmptyString()
-{
- gEmptyStringBuf->acquire();
- return gEmptyString;
-}
-
-void initialize_string8()
-{
- // HACK: This dummy dependency forces linking libutils Static.cpp,
- // which is needed to initialize String8/String16 classes.
- // These variables are named for Darwin, but are needed elsewhere too,
- // including static linking on any platform.
- gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
-
- SharedBuffer* buf = SharedBuffer::alloc(1);
- char* str = (char*)buf->data();
- *str = 0;
- gEmptyStringBuf = buf;
- gEmptyString = str;
-}
-
-void terminate_string8()
-{
- SharedBuffer::bufferFromData(gEmptyString)->release();
- gEmptyStringBuf = NULL;
- gEmptyString = NULL;
-}
-
-// ---------------------------------------------------------------------------
-
-static char* allocFromUTF8(const char* in, size_t len)
-{
- if (len > 0) {
- SharedBuffer* buf = SharedBuffer::alloc(len+1);
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char* str = (char*)buf->data();
- memcpy(str, in, len);
- str[len] = 0;
- return str;
- }
- return NULL;
- }
-
- return getEmptyString();
-}
-
-static char* allocFromUTF16(const char16_t* in, size_t len)
-{
- if (len == 0) return getEmptyString();
-
- const ssize_t bytes = utf16_to_utf8_length(in, len);
- if (bytes < 0) {
- return getEmptyString();
- }
-
- SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (!buf) {
- return getEmptyString();
- }
-
- char* str = (char*)buf->data();
- utf16_to_utf8(in, len, str);
- return str;
-}
-
-static char* allocFromUTF32(const char32_t* in, size_t len)
-{
- if (len == 0) {
- return getEmptyString();
- }
-
- const ssize_t bytes = utf32_to_utf8_length(in, len);
- if (bytes < 0) {
- return getEmptyString();
- }
-
- SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (!buf) {
- return getEmptyString();
- }
-
- char* str = (char*) buf->data();
- utf32_to_utf8(in, len, str);
-
- return str;
-}
-
-// ---------------------------------------------------------------------------
-
-String8::String8()
- : mString(getEmptyString())
-{
-}
-
-String8::String8(const String8& o)
- : mString(o.mString)
-{
- SharedBuffer::bufferFromData(mString)->acquire();
-}
-
-String8::String8(const char* o)
- : mString(allocFromUTF8(o, strlen(o)))
-{
- if (mString == NULL) {
- mString = getEmptyString();
- }
-}
-
-String8::String8(const char* o, size_t len)
- : mString(allocFromUTF8(o, len))
-{
- if (mString == NULL) {
- mString = getEmptyString();
- }
-}
-
-String8::String8(const String16& o)
- : mString(allocFromUTF16(o.string(), o.size()))
-{
-}
-
-String8::String8(const char16_t* o)
- : mString(allocFromUTF16(o, strlen16(o)))
-{
-}
-
-String8::String8(const char16_t* o, size_t len)
- : mString(allocFromUTF16(o, len))
-{
-}
-
-String8::String8(const char32_t* o)
- : mString(allocFromUTF32(o, strlen32(o)))
-{
-}
-
-String8::String8(const char32_t* o, size_t len)
- : mString(allocFromUTF32(o, len))
-{
-}
-
-String8::~String8()
-{
- SharedBuffer::bufferFromData(mString)->release();
-}
-
-String8 String8::format(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- String8 result(formatV(fmt, args));
-
- va_end(args);
- return result;
-}
-
-String8 String8::formatV(const char* fmt, va_list args)
-{
- String8 result;
- result.appendFormatV(fmt, args);
- return result;
-}
-
-void String8::clear() {
- SharedBuffer::bufferFromData(mString)->release();
- mString = getEmptyString();
-}
-
-void String8::setTo(const String8& other)
-{
- SharedBuffer::bufferFromData(other.mString)->acquire();
- SharedBuffer::bufferFromData(mString)->release();
- mString = other.mString;
-}
-
-status_t String8::setTo(const char* other)
-{
- const char *newString = allocFromUTF8(other, strlen(other));
- SharedBuffer::bufferFromData(mString)->release();
- mString = newString;
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::setTo(const char* other, size_t len)
-{
- const char *newString = allocFromUTF8(other, len);
- SharedBuffer::bufferFromData(mString)->release();
- mString = newString;
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::setTo(const char16_t* other, size_t len)
-{
- const char *newString = allocFromUTF16(other, len);
- SharedBuffer::bufferFromData(mString)->release();
- mString = newString;
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::setTo(const char32_t* other, size_t len)
-{
- const char *newString = allocFromUTF32(other, len);
- SharedBuffer::bufferFromData(mString)->release();
- mString = newString;
- if (mString) return NO_ERROR;
-
- mString = getEmptyString();
- return NO_MEMORY;
-}
-
-status_t String8::append(const String8& other)
-{
- const size_t otherLen = other.bytes();
- if (bytes() == 0) {
- setTo(other);
- return NO_ERROR;
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- return real_append(other.string(), otherLen);
-}
-
-status_t String8::append(const char* other)
-{
- return append(other, strlen(other));
-}
-
-status_t String8::append(const char* other, size_t otherLen)
-{
- if (bytes() == 0) {
- return setTo(other, otherLen);
- } else if (otherLen == 0) {
- return NO_ERROR;
- }
-
- return real_append(other, otherLen);
-}
-
-status_t String8::appendFormat(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- status_t result = appendFormatV(fmt, args);
-
- va_end(args);
- return result;
-}
-
-status_t String8::appendFormatV(const char* fmt, va_list args)
-{
- int result = NO_ERROR;
- int n = vsnprintf(NULL, 0, fmt, args);
- if (n != 0) {
- size_t oldLength = length();
- char* buf = lockBuffer(oldLength + n);
- if (buf) {
- vsnprintf(buf + oldLength, n + 1, fmt, args);
- } else {
- result = NO_MEMORY;
- }
- }
- return result;
-}
-
-status_t String8::real_append(const char* other, size_t otherLen)
-{
- const size_t myLen = bytes();
-
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(myLen+otherLen+1);
- if (buf) {
- char* str = (char*)buf->data();
- mString = str;
- str += myLen;
- memcpy(str, other, otherLen);
- str[otherLen] = '\0';
- return NO_ERROR;
- }
- return NO_MEMORY;
-}
-
-char* String8::lockBuffer(size_t size)
-{
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(size+1);
- if (buf) {
- char* str = (char*)buf->data();
- mString = str;
- return str;
- }
- return NULL;
-}
-
-void String8::unlockBuffer()
-{
- unlockBuffer(strlen(mString));
-}
-
-status_t String8::unlockBuffer(size_t size)
-{
- if (size != this->size()) {
- SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
- ->editResize(size+1);
- if (! buf) {
- return NO_MEMORY;
- }
-
- char* str = (char*)buf->data();
- str[size] = 0;
- mString = str;
- }
-
- return NO_ERROR;
-}
-
-ssize_t String8::find(const char* other, size_t start) const
-{
- size_t len = size();
- if (start >= len) {
- return -1;
- }
- const char* s = mString+start;
- const char* p = strstr(s, other);
- return p ? p-mString : -1;
-}
-
-void String8::toLower()
-{
- toLower(0, size());
-}
-
-void String8::toLower(size_t start, size_t length)
-{
- const size_t len = size();
- if (start >= len) {
- return;
- }
- if (start+length > len) {
- length = len-start;
- }
- char* buf = lockBuffer(len);
- buf += start;
- while (length > 0) {
- *buf = tolower(*buf);
- buf++;
- length--;
- }
- unlockBuffer(len);
-}
-
-void String8::toUpper()
-{
- toUpper(0, size());
-}
-
-void String8::toUpper(size_t start, size_t length)
-{
- const size_t len = size();
- if (start >= len) {
- return;
- }
- if (start+length > len) {
- length = len-start;
- }
- char* buf = lockBuffer(len);
- buf += start;
- while (length > 0) {
- *buf = toupper(*buf);
- buf++;
- length--;
- }
- unlockBuffer(len);
-}
-
-size_t String8::getUtf32Length() const
-{
- return utf8_to_utf32_length(mString, length());
-}
-
-int32_t String8::getUtf32At(size_t index, size_t *next_index) const
-{
- return utf32_from_utf8_at(mString, length(), index, next_index);
-}
-
-void String8::getUtf32(char32_t* dst) const
-{
- utf8_to_utf32(mString, length(), dst);
-}
-
-TextOutput& operator<<(TextOutput& to, const String8& val)
-{
- to << val.string();
- return to;
-}
-
-// ---------------------------------------------------------------------------
-// Path functions
-
-void String8::setPathName(const char* name)
-{
- setPathName(name, strlen(name));
-}
-
-void String8::setPathName(const char* name, size_t len)
-{
- char* buf = lockBuffer(len);
-
- memcpy(buf, name, len);
-
- // remove trailing path separator, if present
- if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
- len--;
-
- buf[len] = '\0';
-
- unlockBuffer(len);
-}
-
-String8 String8::getPathLeaf(void) const
-{
- const char* cp;
- const char*const buf = mString;
-
- cp = strrchr(buf, OS_PATH_SEPARATOR);
- if (cp == NULL)
- return String8(*this);
- else
- return String8(cp+1);
-}
-
-String8 String8::getPathDir(void) const
-{
- const char* cp;
- const char*const str = mString;
-
- cp = strrchr(str, OS_PATH_SEPARATOR);
- if (cp == NULL)
- return String8("");
- else
- return String8(str, cp - str);
-}
-
-String8 String8::walkPath(String8* outRemains) const
-{
- const char* cp;
- const char*const str = mString;
- const char* buf = str;
-
- cp = strchr(buf, OS_PATH_SEPARATOR);
- if (cp == buf) {
- // don't include a leading '/'.
- buf = buf+1;
- cp = strchr(buf, OS_PATH_SEPARATOR);
- }
-
- if (cp == NULL) {
- String8 res = buf != str ? String8(buf) : *this;
- if (outRemains) *outRemains = String8("");
- return res;
- }
-
- String8 res(buf, cp-buf);
- if (outRemains) *outRemains = String8(cp+1);
- return res;
-}
-
-/*
- * Helper function for finding the start of an extension in a pathname.
- *
- * Returns a pointer inside mString, or NULL if no extension was found.
- */
-char* String8::find_extension(void) const
-{
- const char* lastSlash;
- const char* lastDot;
- int extLen;
- const char* const str = mString;
-
- // only look at the filename
- lastSlash = strrchr(str, OS_PATH_SEPARATOR);
- if (lastSlash == NULL)
- lastSlash = str;
- else
- lastSlash++;
-
- // find the last dot
- lastDot = strrchr(lastSlash, '.');
- if (lastDot == NULL)
- return NULL;
-
- // looks good, ship it
- return const_cast<char*>(lastDot);
-}
-
-String8 String8::getPathExtension(void) const
-{
- char* ext;
-
- ext = find_extension();
- if (ext != NULL)
- return String8(ext);
- else
- return String8("");
-}
-
-String8 String8::getBasePath(void) const
-{
- char* ext;
- const char* const str = mString;
-
- ext = find_extension();
- if (ext == NULL)
- return String8(*this);
- else
- return String8(str, ext - str);
-}
-
-String8& String8::appendPath(const char* name)
-{
- // TODO: The test below will fail for Win32 paths. Fix later or ignore.
- if (name[0] != OS_PATH_SEPARATOR) {
- if (*name == '\0') {
- // nothing to do
- return *this;
- }
-
- size_t len = length();
- if (len == 0) {
- // no existing filename, just use the new one
- setPathName(name);
- return *this;
- }
-
- // make room for oldPath + '/' + newPath
- int newlen = strlen(name);
-
- char* buf = lockBuffer(len+1+newlen);
-
- // insert a '/' if needed
- if (buf[len-1] != OS_PATH_SEPARATOR)
- buf[len++] = OS_PATH_SEPARATOR;
-
- memcpy(buf+len, name, newlen+1);
- len += newlen;
-
- unlockBuffer(len);
-
- return *this;
- } else {
- setPathName(name);
- return *this;
- }
-}
-
-String8& String8::convertToResPath()
-{
-#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
- size_t len = length();
- if (len > 0) {
- char * buf = lockBuffer(len);
- for (char * end = buf + len; buf < end; ++buf) {
- if (*buf == OS_PATH_SEPARATOR)
- *buf = RES_PATH_SEPARATOR;
- }
- unlockBuffer(len);
- }
-#endif
- return *this;
-}
-
-}; // namespace android
diff --git a/libs/utils/StringArray.cpp b/libs/utils/StringArray.cpp
deleted file mode 100644
index aa42d68..0000000
--- a/libs/utils/StringArray.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Sortable array of strings. STL-ish, but STL-free.
-//
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <utils/StringArray.h>
-
-namespace android {
-
-//
-// An expanding array of strings. Add, get, sort, delete.
-//
-StringArray::StringArray()
- : mMax(0), mCurrent(0), mArray(NULL)
-{
-}
-
-StringArray:: ~StringArray() {
- for (int i = 0; i < mCurrent; i++)
- delete[] mArray[i];
- delete[] mArray;
-}
-
-//
-// Add a string. A copy of the string is made.
-//
-bool StringArray::push_back(const char* str) {
- if (mCurrent >= mMax) {
- char** tmp;
-
- if (mMax == 0)
- mMax = 16; // initial storage
- else
- mMax *= 2;
-
- tmp = new char*[mMax];
- if (tmp == NULL)
- return false;
-
- memcpy(tmp, mArray, mCurrent * sizeof(char*));
- delete[] mArray;
- mArray = tmp;
- }
-
- int len = strlen(str);
- mArray[mCurrent] = new char[len+1];
- memcpy(mArray[mCurrent], str, len+1);
- mCurrent++;
-
- return true;
-}
-
-//
-// Delete an entry.
-//
-void StringArray::erase(int idx) {
- if (idx < 0 || idx >= mCurrent)
- return;
- delete[] mArray[idx];
- if (idx < mCurrent-1) {
- memmove(&mArray[idx], &mArray[idx+1],
- (mCurrent-1 - idx) * sizeof(char*));
- }
- mCurrent--;
-}
-
-//
-// Sort the array.
-//
-void StringArray::sort(int (*compare)(const void*, const void*)) {
- qsort(mArray, mCurrent, sizeof(char*), compare);
-}
-
-//
-// Pass this to the sort routine to do an ascending alphabetical sort.
-//
-int StringArray::cmpAscendingAlpha(const void* pstr1, const void* pstr2) {
- return strcmp(*(const char**)pstr1, *(const char**)pstr2);
-}
-
-//
-// Set entry N to specified string.
-// [should use operator[] here]
-//
-void StringArray::setEntry(int idx, const char* str) {
- if (idx < 0 || idx >= mCurrent)
- return;
- delete[] mArray[idx];
- int len = strlen(str);
- mArray[idx] = new char[len+1];
- memcpy(mArray[idx], str, len+1);
-}
-
-
-}; // namespace android
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
deleted file mode 100644
index 8b8ac10..0000000
--- a/libs/utils/SystemClock.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*
- * System clock functions.
- */
-
-#ifdef HAVE_ANDROID_OS
-#include <linux/ioctl.h>
-#include <linux/rtc.h>
-#include <utils/Atomic.h>
-#include <linux/android_alarm.h>
-#endif
-
-#include <sys/time.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-#include <utils/SystemClock.h>
-#include <utils/Timers.h>
-
-#define LOG_TAG "SystemClock"
-#include "utils/Log.h"
-
-namespace android {
-
-/*
- * Set the current time. This only works when running as root.
- */
-int setCurrentTimeMillis(int64_t millis)
-{
-#if WIN32
- // not implemented
- return -1;
-#else
- struct timeval tv;
-#ifdef HAVE_ANDROID_OS
- struct timespec ts;
- int fd;
- int res;
-#endif
- int ret = 0;
-
- if (millis <= 0 || millis / 1000LL >= INT_MAX) {
- return -1;
- }
-
- tv.tv_sec = (time_t) (millis / 1000LL);
- tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
-
- ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
-
-#ifdef HAVE_ANDROID_OS
- fd = open("/dev/alarm", O_RDWR);
- if(fd < 0) {
- ALOGW("Unable to open alarm driver: %s\n", strerror(errno));
- return -1;
- }
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
- if(res < 0) {
- ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
- ret = -1;
- }
- close(fd);
-#else
- if (settimeofday(&tv, NULL) != 0) {
- ALOGW("Unable to set clock to %d.%d: %s\n",
- (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
- ret = -1;
- }
-#endif
-
- return ret;
-#endif // WIN32
-}
-
-/*
- * native public static long uptimeMillis();
- */
-int64_t uptimeMillis()
-{
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
-}
-
-/*
- * native public static long elapsedRealtime();
- */
-int64_t elapsedRealtime()
-{
-#ifdef HAVE_ANDROID_OS
- static int s_fd = -1;
-
- if (s_fd == -1) {
- int fd = open("/dev/alarm", O_RDONLY);
- if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
- close(fd);
- }
- }
-
- struct timespec ts;
- int result = ioctl(s_fd,
- ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
- if (result == 0) {
- int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- return (int64_t) nanoseconds_to_milliseconds(when);
- } else {
- // XXX: there was an error, probably because the driver didn't
- // exist ... this should return
- // a real error, like an exception!
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
- }
-#else
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
-#endif
-}
-
-}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
deleted file mode 100644
index e04823d..0000000
--- a/libs/utils/TextOutput.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/TextOutput.h>
-
-#include <utils/Debug.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-TextOutput::TextOutput() {
-}
-
-TextOutput::~TextOutput() {
-}
-
-// ---------------------------------------------------------------------------
-
-TextOutput& operator<<(TextOutput& to, bool val)
-{
- if (val) to.print("true", 4);
- else to.print("false", 5);
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, int val)
-{
- char buf[16];
- sprintf(buf, "%d", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, long val)
-{
- char buf[16];
- sprintf(buf, "%ld", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned int val)
-{
- char buf[16];
- sprintf(buf, "%u", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned long val)
-{
- char buf[16];
- sprintf(buf, "%lu", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, long long val)
-{
- char buf[32];
- sprintf(buf, "%Ld", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, unsigned long long val)
-{
- char buf[32];
- sprintf(buf, "%Lu", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-static TextOutput& print_float(TextOutput& to, double value)
-{
- char buf[64];
- sprintf(buf, "%g", value);
- if( !strchr(buf, '.') && !strchr(buf, 'e') &&
- !strchr(buf, 'E') ) {
- strncat(buf, ".0", sizeof(buf)-1);
- }
- to.print(buf, strlen(buf));
- return to;
-}
-
-TextOutput& operator<<(TextOutput& to, float val)
-{
- return print_float(to,val);
-}
-
-TextOutput& operator<<(TextOutput& to, double val)
-{
- return print_float(to,val);
-}
-
-TextOutput& operator<<(TextOutput& to, const void* val)
-{
- char buf[16];
- sprintf(buf, "%p", val);
- to.print(buf, strlen(buf));
- return to;
-}
-
-static void textOutputPrinter(void* cookie, const char* txt)
-{
- ((TextOutput*)cookie)->print(txt, strlen(txt));
-}
-
-TextOutput& operator<<(TextOutput& to, const TypeCode& val)
-{
- printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
- return to;
-}
-
-HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
- : mBuffer(buf)
- , mSize(size)
- , mBytesPerLine(bytesPerLine)
- , mSingleLineCutoff(16)
- , mAlignment(4)
- , mCArrayStyle(false)
-{
- if (bytesPerLine >= 16) mAlignment = 4;
- else if (bytesPerLine >= 8) mAlignment = 2;
- else mAlignment = 1;
-}
-
-TextOutput& operator<<(TextOutput& to, const HexDump& val)
-{
- printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
- val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
- textOutputPrinter, (void*)&to);
- return to;
-}
-
-}; // namespace android
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
deleted file mode 100644
index ab207f5..0000000
--- a/libs/utils/Threads.cpp
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "libutils.threads"
-
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-#include <cutils/sched_policy.h>
-#include <cutils/properties.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-
-#if defined(HAVE_PTHREADS)
-# include <pthread.h>
-# include <sched.h>
-# include <sys/resource.h>
-#ifdef HAVE_ANDROID_OS
-# include <bionic_pthread.h>
-#endif
-#elif defined(HAVE_WIN32_THREADS)
-# include <windows.h>
-# include <stdint.h>
-# include <process.h>
-# define HAVE_CREATETHREAD // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
-#endif
-
-#if defined(HAVE_PRCTL)
-#include <sys/prctl.h>
-#endif
-
-/*
- * ===========================================================================
- * Thread wrappers
- * ===========================================================================
- */
-
-using namespace android;
-
-// ----------------------------------------------------------------------------
-#if defined(HAVE_PTHREADS)
-// ----------------------------------------------------------------------------
-
-/*
- * Create and run a new thread.
- *
- * We create it "detached", so it cleans up after itself.
- */
-
-typedef void* (*android_pthread_entry)(void*);
-
-static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
-static bool gDoSchedulingGroup = true;
-
-static void checkDoSchedulingGroup(void) {
- char buf[PROPERTY_VALUE_MAX];
- int len = property_get("debug.sys.noschedgroups", buf, "");
- if (len > 0) {
- int temp;
- if (sscanf(buf, "%d", &temp) == 1) {
- gDoSchedulingGroup = temp == 0;
- }
- }
-}
-
-struct thread_data_t {
- thread_func_t entryFunction;
- void* userData;
- int priority;
- char * threadName;
-
- // we use this trampoline when we need to set the priority with
- // nice/setpriority, and name with prctl.
- static int trampoline(const thread_data_t* t) {
- thread_func_t f = t->entryFunction;
- void* u = t->userData;
- int prio = t->priority;
- char * name = t->threadName;
- delete t;
- setpriority(PRIO_PROCESS, 0, prio);
- pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
- if (gDoSchedulingGroup) {
- if (prio >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(androidGetTid(), SP_BACKGROUND);
- } else {
- set_sched_policy(androidGetTid(), SP_FOREGROUND);
- }
- }
-
- if (name) {
-#if defined(HAVE_PRCTL)
- // Mac OS doesn't have this, and we build libutil for the host too
- int hasAt = 0;
- int hasDot = 0;
- char *s = name;
- while (*s) {
- if (*s == '.') hasDot = 1;
- else if (*s == '@') hasAt = 1;
- s++;
- }
- int len = s - name;
- if (len < 15 || hasAt || !hasDot) {
- s = name;
- } else {
- s = name + len - 15;
- }
- prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
-#endif
- free(name);
- }
- return f(u);
- }
-};
-
-int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */
- if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
- // Now that the pthread_t has a method to find the associated
- // android_thread_id_t (pid) from pthread_t, it would be possible to avoid
- // this trampoline in some cases as the parent could set the properties
- // for the child. However, there would be a race condition because the
- // child becomes ready immediately, and it doesn't work for the name.
- // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
- // proposed but not yet accepted.
- thread_data_t* t = new thread_data_t;
- t->priority = threadPriority;
- t->threadName = threadName ? strdup(threadName) : NULL;
- t->entryFunction = entryFunction;
- t->userData = userData;
- entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
- userData = t;
- }
-#endif
-
- if (threadStackSize) {
- pthread_attr_setstacksize(&attr, threadStackSize);
- }
-
- errno = 0;
- pthread_t thread;
- int result = pthread_create(&thread, &attr,
- (android_pthread_entry)entryFunction, userData);
- pthread_attr_destroy(&attr);
- if (result != 0) {
- ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
- "(android threadPriority=%d)",
- entryFunction, result, errno, threadPriority);
- return 0;
- }
-
- // Note that *threadID is directly available to the parent only, as it is
- // assigned after the child starts. Use memory barrier / lock if the child
- // or other threads also need access.
- if (threadId != NULL) {
- *threadId = (android_thread_id_t)thread; // XXX: this is not portable
- }
- return 1;
-}
-
-#ifdef HAVE_ANDROID_OS
-static pthread_t android_thread_id_t_to_pthread(android_thread_id_t thread)
-{
- return (pthread_t) thread;
-}
-#endif
-
-android_thread_id_t androidGetThreadId()
-{
- return (android_thread_id_t)pthread_self();
-}
-
-// ----------------------------------------------------------------------------
-#elif defined(HAVE_WIN32_THREADS)
-// ----------------------------------------------------------------------------
-
-/*
- * Trampoline to make us __stdcall-compliant.
- *
- * We're expected to delete "vDetails" when we're done.
- */
-struct threadDetails {
- int (*func)(void*);
- void* arg;
-};
-static __stdcall unsigned int threadIntermediary(void* vDetails)
-{
- struct threadDetails* pDetails = (struct threadDetails*) vDetails;
- int result;
-
- result = (*(pDetails->func))(pDetails->arg);
-
- delete pDetails;
-
- ALOG(LOG_VERBOSE, "thread", "thread exiting\n");
- return (unsigned int) result;
-}
-
-/*
- * Create and run a new thread.
- */
-static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
-{
- HANDLE hThread;
- struct threadDetails* pDetails = new threadDetails; // must be on heap
- unsigned int thrdaddr;
-
- pDetails->func = fn;
- pDetails->arg = arg;
-
-#if defined(HAVE__BEGINTHREADEX)
- hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
- &thrdaddr);
- if (hThread == 0)
-#elif defined(HAVE_CREATETHREAD)
- hThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) threadIntermediary,
- (void*) pDetails, 0, (DWORD*) &thrdaddr);
- if (hThread == NULL)
-#endif
- {
- ALOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
- return false;
- }
-
-#if defined(HAVE_CREATETHREAD)
- /* close the management handle */
- CloseHandle(hThread);
-#endif
-
- if (id != NULL) {
- *id = (android_thread_id_t)thrdaddr;
- }
-
- return true;
-}
-
-int androidCreateRawThreadEtc(android_thread_func_t fn,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- return doCreateThread( fn, userData, threadId);
-}
-
-android_thread_id_t androidGetThreadId()
-{
- return (android_thread_id_t)GetCurrentThreadId();
-}
-
-// ----------------------------------------------------------------------------
-#else
-#error "Threads not supported"
-#endif
-
-// ----------------------------------------------------------------------------
-
-int androidCreateThread(android_thread_func_t fn, void* arg)
-{
- return createThreadEtc(fn, arg);
-}
-
-int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
-{
- return createThreadEtc(fn, arg, "android:unnamed_thread",
- PRIORITY_DEFAULT, 0, id);
-}
-
-static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
-
-int androidCreateThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId)
-{
- return gCreateThreadFn(entryFunction, userData, threadName,
- threadPriority, threadStackSize, threadId);
-}
-
-void androidSetCreateThreadFunc(android_create_thread_fn func)
-{
- gCreateThreadFn = func;
-}
-
-pid_t androidGetTid()
-{
-#ifdef HAVE_GETTID
- return gettid();
-#else
- return getpid();
-#endif
-}
-
-int androidSetThreadSchedulingGroup(pid_t tid, int grp)
-{
- if (grp > ANDROID_TGROUP_MAX || grp < 0) {
- return BAD_VALUE;
- }
-
-#if defined(HAVE_PTHREADS)
- pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
- if (gDoSchedulingGroup) {
- // set_sched_policy does not support tid == 0
- if (tid == 0) {
- tid = androidGetTid();
- }
- if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
- SP_BACKGROUND : SP_FOREGROUND)) {
- return PERMISSION_DENIED;
- }
- }
-#endif
-
- return NO_ERROR;
-}
-
-int androidSetThreadPriority(pid_t tid, int pri)
-{
- int rc = 0;
-
-#if defined(HAVE_PTHREADS)
- int lasterr = 0;
-
- pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
- if (gDoSchedulingGroup) {
- // set_sched_policy does not support tid == 0
- int policy_tid;
- if (tid == 0) {
- policy_tid = androidGetTid();
- } else {
- policy_tid = tid;
- }
- if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(policy_tid, SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(policy_tid, SP_FOREGROUND);
- }
- }
-
- if (rc) {
- lasterr = errno;
- }
-
- if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
- rc = INVALID_OPERATION;
- } else {
- errno = lasterr;
- }
-#endif
-
- return rc;
-}
-
-int androidGetThreadPriority(pid_t tid) {
-#if defined(HAVE_PTHREADS)
- return getpriority(PRIO_PROCESS, tid);
-#else
- return ANDROID_PRIORITY_NORMAL;
-#endif
-}
-
-int androidGetThreadSchedulingGroup(pid_t tid)
-{
- int ret = ANDROID_TGROUP_DEFAULT;
-
-#if defined(HAVE_PTHREADS)
- // convention is to not call get/set_sched_policy methods if disabled by property
- pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
- if (gDoSchedulingGroup) {
- SchedPolicy policy;
- // get_sched_policy does not support tid == 0
- if (tid == 0) {
- tid = androidGetTid();
- }
- if (get_sched_policy(tid, &policy) < 0) {
- ret = INVALID_OPERATION;
- } else {
- switch (policy) {
- case SP_BACKGROUND:
- ret = ANDROID_TGROUP_BG_NONINTERACT;
- break;
- case SP_FOREGROUND:
- ret = ANDROID_TGROUP_FG_BOOST;
- break;
- default:
- // should not happen, as enum SchedPolicy does not have any other values
- ret = INVALID_OPERATION;
- break;
- }
- }
- }
-#endif
-
- return ret;
-}
-
-namespace android {
-
-/*
- * ===========================================================================
- * Mutex class
- * ===========================================================================
- */
-
-#if defined(HAVE_PTHREADS)
-// implemented as inlines in threads.h
-#elif defined(HAVE_WIN32_THREADS)
-
-Mutex::Mutex()
-{
- HANDLE hMutex;
-
- assert(sizeof(hMutex) == sizeof(mState));
-
- hMutex = CreateMutex(NULL, FALSE, NULL);
- mState = (void*) hMutex;
-}
-
-Mutex::Mutex(const char* name)
-{
- // XXX: name not used for now
- HANDLE hMutex;
-
- assert(sizeof(hMutex) == sizeof(mState));
-
- hMutex = CreateMutex(NULL, FALSE, NULL);
- mState = (void*) hMutex;
-}
-
-Mutex::Mutex(int type, const char* name)
-{
- // XXX: type and name not used for now
- HANDLE hMutex;
-
- assert(sizeof(hMutex) == sizeof(mState));
-
- hMutex = CreateMutex(NULL, FALSE, NULL);
- mState = (void*) hMutex;
-}
-
-Mutex::~Mutex()
-{
- CloseHandle((HANDLE) mState);
-}
-
-status_t Mutex::lock()
-{
- DWORD dwWaitResult;
- dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
- return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
-}
-
-void Mutex::unlock()
-{
- if (!ReleaseMutex((HANDLE) mState))
- ALOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
-}
-
-status_t Mutex::tryLock()
-{
- DWORD dwWaitResult;
-
- dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
- if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
- ALOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
- return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
-}
-
-#else
-#error "Somebody forgot to implement threads for this platform."
-#endif
-
-
-/*
- * ===========================================================================
- * Condition class
- * ===========================================================================
- */
-
-#if defined(HAVE_PTHREADS)
-// implemented as inlines in threads.h
-#elif defined(HAVE_WIN32_THREADS)
-
-/*
- * Windows doesn't have a condition variable solution. It's possible
- * to create one, but it's easy to get it wrong. For a discussion, and
- * the origin of this implementation, see:
- *
- * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
- *
- * The implementation shown on the page does NOT follow POSIX semantics.
- * As an optimization they require acquiring the external mutex before
- * calling signal() and broadcast(), whereas POSIX only requires grabbing
- * it before calling wait(). The implementation here has been un-optimized
- * to have the correct behavior.
- */
-typedef struct WinCondition {
- // Number of waiting threads.
- int waitersCount;
-
- // Serialize access to waitersCount.
- CRITICAL_SECTION waitersCountLock;
-
- // Semaphore used to queue up threads waiting for the condition to
- // become signaled.
- HANDLE sema;
-
- // An auto-reset event used by the broadcast/signal thread to wait
- // for all the waiting thread(s) to wake up and be released from
- // the semaphore.
- HANDLE waitersDone;
-
- // This mutex wouldn't be necessary if we required that the caller
- // lock the external mutex before calling signal() and broadcast().
- // I'm trying to mimic pthread semantics though.
- HANDLE internalMutex;
-
- // Keeps track of whether we were broadcasting or signaling. This
- // allows us to optimize the code if we're just signaling.
- bool wasBroadcast;
-
- status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
- {
- // Increment the wait count, avoiding race conditions.
- EnterCriticalSection(&condState->waitersCountLock);
- condState->waitersCount++;
- //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
- // condState->waitersCount, getThreadId());
- LeaveCriticalSection(&condState->waitersCountLock);
-
- DWORD timeout = INFINITE;
- if (abstime) {
- nsecs_t reltime = *abstime - systemTime();
- if (reltime < 0)
- reltime = 0;
- timeout = reltime/1000000;
- }
-
- // Atomically release the external mutex and wait on the semaphore.
- DWORD res =
- SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
-
- //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
-
- // Reacquire lock to avoid race conditions.
- EnterCriticalSection(&condState->waitersCountLock);
-
- // No longer waiting.
- condState->waitersCount--;
-
- // Check to see if we're the last waiter after a broadcast.
- bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
-
- //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
- // lastWaiter, condState->wasBroadcast, condState->waitersCount);
-
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // If we're the last waiter thread during this particular broadcast
- // then signal broadcast() that we're all awake. It'll drop the
- // internal mutex.
- if (lastWaiter) {
- // Atomically signal the "waitersDone" event and wait until we
- // can acquire the internal mutex. We want to do this in one step
- // because it ensures that everybody is in the mutex FIFO before
- // any thread has a chance to run. Without it, another thread
- // could wake up, do work, and hop back in ahead of us.
- SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
- INFINITE, FALSE);
- } else {
- // Grab the internal mutex.
- WaitForSingleObject(condState->internalMutex, INFINITE);
- }
-
- // Release the internal and grab the external.
- ReleaseMutex(condState->internalMutex);
- WaitForSingleObject(hMutex, INFINITE);
-
- return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
- }
-} WinCondition;
-
-/*
- * Constructor. Set up the WinCondition stuff.
- */
-Condition::Condition()
-{
- WinCondition* condState = new WinCondition;
-
- condState->waitersCount = 0;
- condState->wasBroadcast = false;
- // semaphore: no security, initial value of 0
- condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
- InitializeCriticalSection(&condState->waitersCountLock);
- // auto-reset event, not signaled initially
- condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
- // used so we don't have to lock external mutex on signal/broadcast
- condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
-
- mState = condState;
-}
-
-/*
- * Destructor. Free Windows resources as well as our allocated storage.
- */
-Condition::~Condition()
-{
- WinCondition* condState = (WinCondition*) mState;
- if (condState != NULL) {
- CloseHandle(condState->sema);
- CloseHandle(condState->waitersDone);
- delete condState;
- }
-}
-
-
-status_t Condition::wait(Mutex& mutex)
-{
- WinCondition* condState = (WinCondition*) mState;
- HANDLE hMutex = (HANDLE) mutex.mState;
-
- return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
-}
-
-status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
-{
- WinCondition* condState = (WinCondition*) mState;
- HANDLE hMutex = (HANDLE) mutex.mState;
- nsecs_t absTime = systemTime()+reltime;
-
- return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
-}
-
-/*
- * Signal the condition variable, allowing one thread to continue.
- */
-void Condition::signal()
-{
- WinCondition* condState = (WinCondition*) mState;
-
- // Lock the internal mutex. This ensures that we don't clash with
- // broadcast().
- WaitForSingleObject(condState->internalMutex, INFINITE);
-
- EnterCriticalSection(&condState->waitersCountLock);
- bool haveWaiters = (condState->waitersCount > 0);
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // If no waiters, then this is a no-op. Otherwise, knock the semaphore
- // down a notch.
- if (haveWaiters)
- ReleaseSemaphore(condState->sema, 1, 0);
-
- // Release internal mutex.
- ReleaseMutex(condState->internalMutex);
-}
-
-/*
- * Signal the condition variable, allowing all threads to continue.
- *
- * First we have to wake up all threads waiting on the semaphore, then
- * we wait until all of the threads have actually been woken before
- * releasing the internal mutex. This ensures that all threads are woken.
- */
-void Condition::broadcast()
-{
- WinCondition* condState = (WinCondition*) mState;
-
- // Lock the internal mutex. This keeps the guys we're waking up
- // from getting too far.
- WaitForSingleObject(condState->internalMutex, INFINITE);
-
- EnterCriticalSection(&condState->waitersCountLock);
- bool haveWaiters = false;
-
- if (condState->waitersCount > 0) {
- haveWaiters = true;
- condState->wasBroadcast = true;
- }
-
- if (haveWaiters) {
- // Wake up all the waiters.
- ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
-
- LeaveCriticalSection(&condState->waitersCountLock);
-
- // Wait for all awakened threads to acquire the counting semaphore.
- // The last guy who was waiting sets this.
- WaitForSingleObject(condState->waitersDone, INFINITE);
-
- // Reset wasBroadcast. (No crit section needed because nobody
- // else can wake up to poke at it.)
- condState->wasBroadcast = 0;
- } else {
- // nothing to do
- LeaveCriticalSection(&condState->waitersCountLock);
- }
-
- // Release internal mutex.
- ReleaseMutex(condState->internalMutex);
-}
-
-#else
-#error "condition variables not supported on this platform"
-#endif
-
-// ----------------------------------------------------------------------------
-
-/*
- * This is our thread object!
- */
-
-Thread::Thread(bool canCallJava)
- : mCanCallJava(canCallJava),
- mThread(thread_id_t(-1)),
- mLock("Thread::mLock"),
- mStatus(NO_ERROR),
- mExitPending(false), mRunning(false)
-#ifdef HAVE_ANDROID_OS
- , mTid(-1)
-#endif
-{
-}
-
-Thread::~Thread()
-{
-}
-
-status_t Thread::readyToRun()
-{
- return NO_ERROR;
-}
-
-status_t Thread::run(const char* name, int32_t priority, size_t stack)
-{
- Mutex::Autolock _l(mLock);
-
- if (mRunning) {
- // thread already started
- return INVALID_OPERATION;
- }
-
- // reset status and exitPending to their default value, so we can
- // try again after an error happened (either below, or in readyToRun())
- mStatus = NO_ERROR;
- mExitPending = false;
- mThread = thread_id_t(-1);
-
- // hold a strong reference on ourself
- mHoldSelf = this;
-
- mRunning = true;
-
- bool res;
- if (mCanCallJava) {
- res = createThreadEtc(_threadLoop,
- this, name, priority, stack, &mThread);
- } else {
- res = androidCreateRawThreadEtc(_threadLoop,
- this, name, priority, stack, &mThread);
- }
-
- if (res == false) {
- mStatus = UNKNOWN_ERROR; // something happened!
- mRunning = false;
- mThread = thread_id_t(-1);
- mHoldSelf.clear(); // "this" may have gone away after this.
-
- return UNKNOWN_ERROR;
- }
-
- // Do not refer to mStatus here: The thread is already running (may, in fact
- // already have exited with a valid mStatus result). The NO_ERROR indication
- // here merely indicates successfully starting the thread and does not
- // imply successful termination/execution.
- return NO_ERROR;
-
- // Exiting scope of mLock is a memory barrier and allows new thread to run
-}
-
-int Thread::_threadLoop(void* user)
-{
- Thread* const self = static_cast<Thread*>(user);
-
- sp<Thread> strong(self->mHoldSelf);
- wp<Thread> weak(strong);
- self->mHoldSelf.clear();
-
-#ifdef HAVE_ANDROID_OS
- // this is very useful for debugging with gdb
- self->mTid = gettid();
-#endif
-
- bool first = true;
-
- do {
- bool result;
- if (first) {
- first = false;
- self->mStatus = self->readyToRun();
- result = (self->mStatus == NO_ERROR);
-
- if (result && !self->exitPending()) {
- // Binder threads (and maybe others) rely on threadLoop
- // running at least once after a successful ::readyToRun()
- // (unless, of course, the thread has already been asked to exit
- // at that point).
- // This is because threads are essentially used like this:
- // (new ThreadSubclass())->run();
- // The caller therefore does not retain a strong reference to
- // the thread and the thread would simply disappear after the
- // successful ::readyToRun() call instead of entering the
- // threadLoop at least once.
- result = self->threadLoop();
- }
- } else {
- result = self->threadLoop();
- }
-
- // establish a scope for mLock
- {
- Mutex::Autolock _l(self->mLock);
- if (result == false || self->mExitPending) {
- self->mExitPending = true;
- self->mRunning = false;
- // clear thread ID so that requestExitAndWait() does not exit if
- // called by a new thread using the same thread ID as this one.
- self->mThread = thread_id_t(-1);
- // note that interested observers blocked in requestExitAndWait are
- // awoken by broadcast, but blocked on mLock until break exits scope
- self->mThreadExitedCondition.broadcast();
- break;
- }
- }
-
- // Release our strong reference, to let a chance to the thread
- // to die a peaceful death.
- strong.clear();
- // And immediately, re-acquire a strong reference for the next loop
- strong = weak.promote();
- } while(strong != 0);
-
- return 0;
-}
-
-void Thread::requestExit()
-{
- Mutex::Autolock _l(mLock);
- mExitPending = true;
-}
-
-status_t Thread::requestExitAndWait()
-{
- Mutex::Autolock _l(mLock);
- if (mThread == getThreadId()) {
- ALOGW(
- "Thread (this=%p): don't call waitForExit() from this "
- "Thread object's thread. It's a guaranteed deadlock!",
- this);
-
- return WOULD_BLOCK;
- }
-
- mExitPending = true;
-
- while (mRunning == true) {
- mThreadExitedCondition.wait(mLock);
- }
- // This next line is probably not needed any more, but is being left for
- // historical reference. Note that each interested party will clear flag.
- mExitPending = false;
-
- return mStatus;
-}
-
-status_t Thread::join()
-{
- Mutex::Autolock _l(mLock);
- if (mThread == getThreadId()) {
- ALOGW(
- "Thread (this=%p): don't call join() from this "
- "Thread object's thread. It's a guaranteed deadlock!",
- this);
-
- return WOULD_BLOCK;
- }
-
- while (mRunning == true) {
- mThreadExitedCondition.wait(mLock);
- }
-
- return mStatus;
-}
-
-#ifdef HAVE_ANDROID_OS
-pid_t Thread::getTid() const
-{
- // mTid is not defined until the child initializes it, and the caller may need it earlier
- Mutex::Autolock _l(mLock);
- pid_t tid;
- if (mRunning) {
- pthread_t pthread = android_thread_id_t_to_pthread(mThread);
- tid = __pthread_gettid(pthread);
- } else {
- ALOGW("Thread (this=%p): getTid() is undefined before run()", this);
- tid = -1;
- }
- return tid;
-}
-#endif
-
-bool Thread::exitPending() const
-{
- Mutex::Autolock _l(mLock);
- return mExitPending;
-}
-
-
-
-}; // namespace android
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
deleted file mode 100644
index 64b4701..0000000
--- a/libs/utils/Timers.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Timer functions.
-//
-#include <utils/Timers.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <errno.h>
-#include <limits.h>
-
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#endif
-
-nsecs_t systemTime(int clock)
-{
-#if defined(HAVE_POSIX_CLOCKS)
- static const clockid_t clocks[] = {
- CLOCK_REALTIME,
- CLOCK_MONOTONIC,
- CLOCK_PROCESS_CPUTIME_ID,
- CLOCK_THREAD_CPUTIME_ID
- };
- struct timespec t;
- t.tv_sec = t.tv_nsec = 0;
- clock_gettime(clocks[clock], &t);
- return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
-#else
- // we don't support the clocks here.
- struct timeval t;
- t.tv_sec = t.tv_usec = 0;
- gettimeofday(&t, NULL);
- return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
-#endif
-}
-
-int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
-{
- int timeoutDelayMillis;
- if (timeoutTime > referenceTime) {
- uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
- if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
- timeoutDelayMillis = -1;
- } else {
- timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
- }
- } else {
- timeoutDelayMillis = 0;
- }
- return timeoutDelayMillis;
-}
-
-
-/*
- * ===========================================================================
- * DurationTimer
- * ===========================================================================
- */
-
-using namespace android;
-
-// Start the timer.
-void DurationTimer::start(void)
-{
- gettimeofday(&mStartWhen, NULL);
-}
-
-// Stop the timer.
-void DurationTimer::stop(void)
-{
- gettimeofday(&mStopWhen, NULL);
-}
-
-// Get the duration in microseconds.
-long long DurationTimer::durationUsecs(void) const
-{
- return (long) subtractTimevals(&mStopWhen, &mStartWhen);
-}
-
-// Subtract two timevals. Returns the difference (ptv1-ptv2) in
-// microseconds.
-/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
- const struct timeval* ptv2)
-{
- long long stop = ((long long) ptv1->tv_sec) * 1000000LL +
- ((long long) ptv1->tv_usec);
- long long start = ((long long) ptv2->tv_sec) * 1000000LL +
- ((long long) ptv2->tv_usec);
- return stop - start;
-}
-
-// Add the specified amount of time to the timeval.
-/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
-{
- if (usec < 0) {
- ALOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
- return;
- }
-
- // normalize tv_usec if necessary
- if (ptv->tv_usec >= 1000000) {
- ptv->tv_sec += ptv->tv_usec / 1000000;
- ptv->tv_usec %= 1000000;
- }
-
- ptv->tv_usec += usec % 1000000;
- if (ptv->tv_usec >= 1000000) {
- ptv->tv_usec -= 1000000;
- ptv->tv_sec++;
- }
- ptv->tv_sec += usec / 1000000;
-}
-
diff --git a/libs/utils/Tokenizer.cpp b/libs/utils/Tokenizer.cpp
deleted file mode 100644
index efda2bf..0000000
--- a/libs/utils/Tokenizer.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Tokenizer"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <utils/Log.h>
-#include <utils/Tokenizer.h>
-
-// Enables debug output for the tokenizer.
-#define DEBUG_TOKENIZER 0
-
-
-namespace android {
-
-static inline bool isDelimiter(char ch, const char* delimiters) {
- return strchr(delimiters, ch) != NULL;
-}
-
-Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length) :
- mFilename(filename), mFileMap(fileMap),
- mBuffer(buffer), mLength(length), mCurrent(buffer), mLineNumber(1) {
-}
-
-Tokenizer::~Tokenizer() {
- if (mFileMap) {
- mFileMap->release();
- } else {
- delete[] mBuffer;
- }
-}
-
-status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {
- *outTokenizer = NULL;
-
- int result = NO_ERROR;
- int fd = ::open(filename.string(), O_RDONLY);
- if (fd < 0) {
- result = -errno;
- ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
- } else {
- struct stat stat;
- if (fstat(fd, &stat)) {
- result = -errno;
- ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
- } else {
- size_t length = size_t(stat.st_size);
-
- FileMap* fileMap = new FileMap();
- char* buffer;
- if (fileMap->create(NULL, fd, 0, length, true)) {
- fileMap->advise(FileMap::SEQUENTIAL);
- buffer = static_cast<char*>(fileMap->getDataPtr());
- } else {
- fileMap->release();
- fileMap = NULL;
-
- // Fall back to reading into a buffer since we can't mmap files in sysfs.
- // The length we obtained from stat is wrong too (it will always be 4096)
- // so we must trust that read will read the entire file.
- buffer = new char[length];
- ssize_t nrd = read(fd, buffer, length);
- if (nrd < 0) {
- result = -errno;
- ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
- delete[] buffer;
- buffer = NULL;
- } else {
- length = size_t(nrd);
- }
- }
-
- if (!result) {
- *outTokenizer = new Tokenizer(filename, fileMap, buffer, length);
- }
- }
- close(fd);
- }
- return result;
-}
-
-String8 Tokenizer::getLocation() const {
- String8 result;
- result.appendFormat("%s:%d", mFilename.string(), mLineNumber);
- return result;
-}
-
-String8 Tokenizer::peekRemainderOfLine() const {
- const char* end = getEnd();
- const char* eol = mCurrent;
- while (eol != end) {
- char ch = *eol;
- if (ch == '\n') {
- break;
- }
- eol += 1;
- }
- return String8(mCurrent, eol - mCurrent);
-}
-
-String8 Tokenizer::nextToken(const char* delimiters) {
-#if DEBUG_TOKENIZER
- ALOGD("nextToken");
-#endif
- const char* end = getEnd();
- const char* tokenStart = mCurrent;
- while (mCurrent != end) {
- char ch = *mCurrent;
- if (ch == '\n' || isDelimiter(ch, delimiters)) {
- break;
- }
- mCurrent += 1;
- }
- return String8(tokenStart, mCurrent - tokenStart);
-}
-
-void Tokenizer::nextLine() {
-#if DEBUG_TOKENIZER
- ALOGD("nextLine");
-#endif
- const char* end = getEnd();
- while (mCurrent != end) {
- char ch = *(mCurrent++);
- if (ch == '\n') {
- mLineNumber += 1;
- break;
- }
- }
-}
-
-void Tokenizer::skipDelimiters(const char* delimiters) {
-#if DEBUG_TOKENIZER
- ALOGD("skipDelimiters");
-#endif
- const char* end = getEnd();
- while (mCurrent != end) {
- char ch = *mCurrent;
- if (ch == '\n' || !isDelimiter(ch, delimiters)) {
- break;
- }
- mCurrent += 1;
- }
-}
-
-} // namespace android
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
deleted file mode 100644
index c49278a..0000000
--- a/libs/utils/Trace.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-namespace android {
-
-volatile int32_t Tracer::sIsReady = 0;
-int Tracer::sTraceFD = -1;
-uint64_t Tracer::sEnabledTags = 0;
-Mutex Tracer::sMutex;
-
-void Tracer::init() {
- Mutex::Autolock lock(sMutex);
-
- if (!sIsReady) {
- const char* const traceFileName =
- "/sys/kernel/debug/tracing/trace_marker";
- sTraceFD = open(traceFileName, O_WRONLY);
- if (sTraceFD == -1) {
- ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
- } else {
- char value[PROPERTY_VALUE_MAX];
- property_get("atrace.tags.enableflags", value, "0");
- sEnabledTags = strtoll(value, NULL, 0) | ATRACE_TAG_ALWAYS;
- }
-
- android_atomic_release_store(1, &sIsReady);
- }
-}
-
-} // namespace andoid
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
deleted file mode 100644
index 41cbf03..0000000
--- a/libs/utils/Unicode.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Unicode.h>
-
-#include <stddef.h>
-
-#ifdef HAVE_WINSOCK
-# undef nhtol
-# undef htonl
-# undef nhtos
-# undef htons
-
-# ifdef HAVE_LITTLE_ENDIAN
-# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-# define htonl(x) ntohl(x)
-# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-# define htons(x) ntohs(x)
-# else
-# define ntohl(x) (x)
-# define htonl(x) (x)
-# define ntohs(x) (x)
-# define htons(x) (x)
-# endif
-#else
-# include <netinet/in.h>
-#endif
-
-extern "C" {
-
-static const char32_t kByteMask = 0x000000BF;
-static const char32_t kByteMark = 0x00000080;
-
-// Surrogates aren't valid for UTF-32 characters, so define some
-// constants that will let us screen them out.
-static const char32_t kUnicodeSurrogateHighStart = 0x0000D800;
-static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF;
-static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00;
-static const char32_t kUnicodeSurrogateLowEnd = 0x0000DFFF;
-static const char32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart;
-static const char32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd;
-static const char32_t kUnicodeMaxCodepoint = 0x0010FFFF;
-
-// Mask used to set appropriate bits in first byte of UTF-8 sequence,
-// indexed by number of bytes in the sequence.
-// 0xxxxxxx
-// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
-// 110yyyyx 10xxxxxx
-// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
-// 1110yyyy 10yxxxxx 10xxxxxx
-// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
-// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
-// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
-static const char32_t kFirstByteMark[] = {
- 0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
-};
-
-// --------------------------------------------------------------------------
-// UTF-32
-// --------------------------------------------------------------------------
-
-/**
- * Return number of UTF-8 bytes required for the character. If the character
- * is invalid, return size of 0.
- */
-static inline size_t utf32_codepoint_utf8_length(char32_t srcChar)
-{
- // Figure out how many bytes the result will require.
- if (srcChar < 0x00000080) {
- return 1;
- } else if (srcChar < 0x00000800) {
- return 2;
- } else if (srcChar < 0x00010000) {
- if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) {
- return 3;
- } else {
- // Surrogates are invalid UTF-32 characters.
- return 0;
- }
- }
- // Max code point for Unicode is 0x0010FFFF.
- else if (srcChar <= kUnicodeMaxCodepoint) {
- return 4;
- } else {
- // Invalid UTF-32 character.
- return 0;
- }
-}
-
-// Write out the source character to <dstP>.
-
-static inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
-{
- dstP += bytes;
- switch (bytes)
- { /* note: everything falls through. */
- case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
- case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
- }
-}
-
-size_t strlen32(const char32_t *s)
-{
- const char32_t *ss = s;
- while ( *ss )
- ss++;
- return ss-s;
-}
-
-size_t strnlen32(const char32_t *s, size_t maxlen)
-{
- const char32_t *ss = s;
- while ((maxlen > 0) && *ss) {
- ss++;
- maxlen--;
- }
- return ss-s;
-}
-
-static inline int32_t utf32_at_internal(const char* cur, size_t *num_read)
-{
- const char first_char = *cur;
- if ((first_char & 0x80) == 0) { // ASCII
- *num_read = 1;
- return *cur;
- }
- cur++;
- char32_t mask, to_ignore_mask;
- size_t num_to_read = 0;
- char32_t utf32 = first_char;
- for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
- (first_char & mask);
- num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
- // 0x3F == 00111111
- utf32 = (utf32 << 6) + (*cur++ & 0x3F);
- }
- to_ignore_mask |= mask;
- utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
-
- *num_read = num_to_read;
- return static_cast<int32_t>(utf32);
-}
-
-int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index)
-{
- if (index >= src_len) {
- return -1;
- }
- size_t dummy_index;
- if (next_index == NULL) {
- next_index = &dummy_index;
- }
- size_t num_read;
- int32_t ret = utf32_at_internal(src + index, &num_read);
- if (ret >= 0) {
- *next_index = index + num_read;
- }
-
- return ret;
-}
-
-ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return -1;
- }
-
- size_t ret = 0;
- const char32_t *end = src + src_len;
- while (src < end) {
- ret += utf32_codepoint_utf8_length(*src++);
- }
- return ret;
-}
-
-void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
-{
- if (src == NULL || src_len == 0 || dst == NULL) {
- return;
- }
-
- const char32_t *cur_utf32 = src;
- const char32_t *end_utf32 = src + src_len;
- char *cur = dst;
- while (cur_utf32 < end_utf32) {
- size_t len = utf32_codepoint_utf8_length(*cur_utf32);
- utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);
- cur += len;
- }
- *cur = '\0';
-}
-
-// --------------------------------------------------------------------------
-// UTF-16
-// --------------------------------------------------------------------------
-
-int strcmp16(const char16_t *s1, const char16_t *s2)
-{
- char16_t ch;
- int d = 0;
-
- while ( 1 ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
-{
- char16_t ch;
- int d = 0;
-
- while ( n-- ) {
- d = (int)(ch = *s1++) - (int)*s2++;
- if ( d || !ch )
- break;
- }
-
- return d;
-}
-
-char16_t *strcpy16(char16_t *dst, const char16_t *src)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char16_t ch;
-
- do {
- *q++ = ch = *p++;
- } while ( ch );
-
- return dst;
-}
-
-size_t strlen16(const char16_t *s)
-{
- const char16_t *ss = s;
- while ( *ss )
- ss++;
- return ss-s;
-}
-
-
-char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
-{
- char16_t *q = dst;
- const char16_t *p = src;
- char ch;
-
- while (n) {
- n--;
- *q++ = ch = *p++;
- if ( !ch )
- break;
- }
-
- *q = 0;
-
- return dst;
-}
-
-size_t strnlen16(const char16_t *s, size_t maxlen)
-{
- const char16_t *ss = s;
-
- /* Important: the maxlen test must precede the reference through ss;
- since the byte beyond the maximum may segfault */
- while ((maxlen > 0) && *ss) {
- ss++;
- maxlen--;
- }
- return ss-s;
-}
-
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
-{
- const char16_t* e1 = s1+n1;
- const char16_t* e2 = s2+n2;
-
- while (s1 < e1 && s2 < e2) {
- const int d = (int)*s1++ - (int)*s2++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)*s2)
- : (n1 > n2
- ? ((int)*s1 - 0)
- : 0);
-}
-
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
-{
- const char16_t* e1 = s1H+n1;
- const char16_t* e2 = s2N+n2;
-
- while (s1H < e1 && s2N < e2) {
- const char16_t c2 = ntohs(*s2N);
- const int d = (int)*s1H++ - (int)c2;
- s2N++;
- if (d) {
- return d;
- }
- }
-
- return n1 < n2
- ? (0 - (int)ntohs(*s2N))
- : (n1 > n2
- ? ((int)*s1H - 0)
- : 0);
-}
-
-void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
-{
- if (src == NULL || src_len == 0 || dst == NULL) {
- return;
- }
-
- const char16_t* cur_utf16 = src;
- const char16_t* const end_utf16 = src + src_len;
- char *cur = dst;
- while (cur_utf16 < end_utf16) {
- char32_t utf32;
- // surrogate pairs
- if ((*cur_utf16 & 0xFC00) == 0xD800) {
- utf32 = (*cur_utf16++ - 0xD800) << 10;
- utf32 |= *cur_utf16++ - 0xDC00;
- utf32 += 0x10000;
- } else {
- utf32 = (char32_t) *cur_utf16++;
- }
- const size_t len = utf32_codepoint_utf8_length(utf32);
- utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);
- cur += len;
- }
- *cur = '\0';
-}
-
-// --------------------------------------------------------------------------
-// UTF-8
-// --------------------------------------------------------------------------
-
-ssize_t utf8_length(const char *src)
-{
- const char *cur = src;
- size_t ret = 0;
- while (*cur != '\0') {
- const char first_char = *cur++;
- if ((first_char & 0x80) == 0) { // ASCII
- ret += 1;
- continue;
- }
- // (UTF-8's character must not be like 10xxxxxx,
- // but 110xxxxx, 1110xxxx, ... or 1111110x)
- if ((first_char & 0x40) == 0) {
- return -1;
- }
-
- int32_t mask, to_ignore_mask;
- size_t num_to_read = 0;
- char32_t utf32 = 0;
- for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
- num_to_read < 5 && (first_char & mask);
- num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
- if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
- return -1;
- }
- // 0x3F == 00111111
- utf32 = (utf32 << 6) + (*cur++ & 0x3F);
- }
- // "first_char" must be (110xxxxx - 11110xxx)
- if (num_to_read == 5) {
- return -1;
- }
- to_ignore_mask |= mask;
- utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
- if (utf32 > kUnicodeMaxCodepoint) {
- return -1;
- }
-
- ret += num_to_read;
- }
- return ret;
-}
-
-ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return -1;
- }
-
- size_t ret = 0;
- const char16_t* const end = src + src_len;
- while (src < end) {
- if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
- && (*++src & 0xFC00) == 0xDC00) {
- // surrogate pairs are always 4 bytes.
- ret += 4;
- src++;
- } else {
- ret += utf32_codepoint_utf8_length((char32_t) *src++);
- }
- }
- return ret;
-}
-
-/**
- * Returns 1-4 based on the number of leading bits.
- *
- * 1111 -> 4
- * 1110 -> 3
- * 110x -> 2
- * 10xx -> 1
- * 0xxx -> 1
- */
-static inline size_t utf8_codepoint_len(uint8_t ch)
-{
- return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
-}
-
-static inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte)
-{
- *codePoint <<= 6;
- *codePoint |= 0x3F & byte;
-}
-
-size_t utf8_to_utf32_length(const char *src, size_t src_len)
-{
- if (src == NULL || src_len == 0) {
- return 0;
- }
- size_t ret = 0;
- const char* cur;
- const char* end;
- size_t num_to_skip;
- for (cur = src, end = src + src_len, num_to_skip = 1;
- cur < end;
- cur += num_to_skip, ret++) {
- const char first_char = *cur;
- num_to_skip = 1;
- if ((first_char & 0x80) == 0) { // ASCII
- continue;
- }
- int32_t mask;
-
- for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
- }
- }
- return ret;
-}
-
-void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)
-{
- if (src == NULL || src_len == 0 || dst == NULL) {
- return;
- }
-
- const char* cur = src;
- const char* const end = src + src_len;
- char32_t* cur_utf32 = dst;
- while (cur < end) {
- size_t num_read;
- *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));
- cur += num_read;
- }
- *cur_utf32 = 0;
-}
-
-static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)
-{
- uint32_t unicode;
-
- switch (length)
- {
- case 1:
- return src[0];
- case 2:
- unicode = src[0] & 0x1f;
- utf8_shift_and_mask(&unicode, src[1]);
- return unicode;
- case 3:
- unicode = src[0] & 0x0f;
- utf8_shift_and_mask(&unicode, src[1]);
- utf8_shift_and_mask(&unicode, src[2]);
- return unicode;
- case 4:
- unicode = src[0] & 0x07;
- utf8_shift_and_mask(&unicode, src[1]);
- utf8_shift_and_mask(&unicode, src[2]);
- utf8_shift_and_mask(&unicode, src[3]);
- return unicode;
- default:
- return 0xffff;
- }
-
- //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
-}
-
-ssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len)
-{
- const uint8_t* const u8end = u8str + u8len;
- const uint8_t* u8cur = u8str;
-
- /* Validate that the UTF-8 is the correct len */
- size_t u16measuredLen = 0;
- while (u8cur < u8end) {
- u16measuredLen++;
- int u8charLen = utf8_codepoint_len(*u8cur);
- uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen);
- if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16
- u8cur += u8charLen;
- }
-
- /**
- * Make sure that we ended where we thought we would and the output UTF-16
- * will be exactly how long we were told it would be.
- */
- if (u8cur != u8end) {
- return -1;
- }
-
- return u16measuredLen;
-}
-
-char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* u8str, size_t u8len, char16_t* u16str)
-{
- const uint8_t* const u8end = u8str + u8len;
- const uint8_t* u8cur = u8str;
- char16_t* u16cur = u16str;
-
- while (u8cur < u8end) {
- size_t u8len = utf8_codepoint_len(*u8cur);
- uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);
-
- // Convert the UTF32 codepoint to one or more UTF16 codepoints
- if (codepoint <= 0xFFFF) {
- // Single UTF16 character
- *u16cur++ = (char16_t) codepoint;
- } else {
- // Multiple UTF16 characters with surrogates
- codepoint = codepoint - 0x10000;
- *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
- *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
- }
-
- u8cur += u8len;
- }
- return u16cur;
-}
-
-void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) {
- char16_t* end = utf8_to_utf16_no_null_terminator(u8str, u8len, u16str);
- *end = 0;
-}
-
-}
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
deleted file mode 100644
index 220ae3e..0000000
--- a/libs/utils/VectorImpl.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Vector"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/SharedBuffer.h>
-#include <utils/VectorImpl.h>
-
-/*****************************************************************************/
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-const size_t kMinVectorCapacity = 4;
-
-static inline size_t max(size_t a, size_t b) {
- return a>b ? a : b;
-}
-
-// ----------------------------------------------------------------------------
-
-VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
- : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)
-{
-}
-
-VectorImpl::VectorImpl(const VectorImpl& rhs)
- : mStorage(rhs.mStorage), mCount(rhs.mCount),
- mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
-{
- if (mStorage) {
- SharedBuffer::sharedBuffer(mStorage)->acquire();
- }
-}
-
-VectorImpl::~VectorImpl()
-{
- ALOG_ASSERT(!mCount,
- "[%p] "
- "subclasses of VectorImpl must call finish_vector()"
- " in their destructor. Leaking %d bytes.",
- this, (int)(mCount*mItemSize));
- // We can't call _do_destroy() here because the vtable is already gone.
-}
-
-VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
-{
- ALOG_ASSERT(mItemSize == rhs.mItemSize,
- "Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
- if (this != &rhs) {
- release_storage();
- if (rhs.mCount) {
- mStorage = rhs.mStorage;
- mCount = rhs.mCount;
- SharedBuffer::sharedBuffer(mStorage)->acquire();
- } else {
- mStorage = 0;
- mCount = 0;
- }
- }
- return *this;
-}
-
-void* VectorImpl::editArrayImpl()
-{
- if (mStorage) {
- SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit();
- if (sb == 0) {
- sb = SharedBuffer::alloc(capacity() * mItemSize);
- if (sb) {
- _do_copy(sb->data(), mStorage, mCount);
- release_storage();
- mStorage = sb->data();
- }
- }
- }
- return mStorage;
-}
-
-size_t VectorImpl::capacity() const
-{
- if (mStorage) {
- return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize;
- }
- return 0;
-}
-
-ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
-{
- return insertArrayAt(vector.arrayImpl(), index, vector.size());
-}
-
-ssize_t VectorImpl::appendVector(const VectorImpl& vector)
-{
- return insertVectorAt(vector, size());
-}
-
-ssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length)
-{
- if (index > size())
- return BAD_INDEX;
- void* where = _grow(index, length);
- if (where) {
- _do_copy(where, array, length);
- }
- return where ? index : (ssize_t)NO_MEMORY;
-}
-
-ssize_t VectorImpl::appendArray(const void* array, size_t length)
-{
- return insertArrayAt(array, size(), length);
-}
-
-ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
-{
- return insertAt(0, index, numItems);
-}
-
-ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
-{
- if (index > size())
- return BAD_INDEX;
- void* where = _grow(index, numItems);
- if (where) {
- if (item) {
- _do_splat(where, item, numItems);
- } else {
- _do_construct(where, numItems);
- }
- }
- return where ? index : (ssize_t)NO_MEMORY;
-}
-
-static int sortProxy(const void* lhs, const void* rhs, void* func)
-{
- return (*(VectorImpl::compar_t)func)(lhs, rhs);
-}
-
-status_t VectorImpl::sort(VectorImpl::compar_t cmp)
-{
- return sort(sortProxy, (void*)cmp);
-}
-
-status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
-{
- // the sort must be stable. we're using insertion sort which
- // is well suited for small and already sorted arrays
- // for big arrays, it could be better to use mergesort
- const ssize_t count = size();
- if (count > 1) {
- void* array = const_cast<void*>(arrayImpl());
- void* temp = 0;
- ssize_t i = 1;
- while (i < count) {
- void* item = reinterpret_cast<char*>(array) + mItemSize*(i);
- void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
- if (cmp(curr, item, state) > 0) {
-
- if (!temp) {
- // we're going to have to modify the array...
- array = editArrayImpl();
- if (!array) return NO_MEMORY;
- temp = malloc(mItemSize);
- if (!temp) return NO_MEMORY;
- item = reinterpret_cast<char*>(array) + mItemSize*(i);
- curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
- } else {
- _do_destroy(temp, 1);
- }
-
- _do_copy(temp, item, 1);
-
- ssize_t j = i-1;
- void* next = reinterpret_cast<char*>(array) + mItemSize*(i);
- do {
- _do_destroy(next, 1);
- _do_copy(next, curr, 1);
- next = curr;
- --j;
- curr = reinterpret_cast<char*>(array) + mItemSize*(j);
- } while (j>=0 && (cmp(curr, temp, state) > 0));
-
- _do_destroy(next, 1);
- _do_copy(next, temp, 1);
- }
- i++;
- }
-
- if (temp) {
- _do_destroy(temp, 1);
- free(temp);
- }
- }
- return NO_ERROR;
-}
-
-void VectorImpl::pop()
-{
- if (size())
- removeItemsAt(size()-1, 1);
-}
-
-void VectorImpl::push()
-{
- push(0);
-}
-
-void VectorImpl::push(const void* item)
-{
- insertAt(item, size());
-}
-
-ssize_t VectorImpl::add()
-{
- return add(0);
-}
-
-ssize_t VectorImpl::add(const void* item)
-{
- return insertAt(item, size());
-}
-
-ssize_t VectorImpl::replaceAt(size_t index)
-{
- return replaceAt(0, index);
-}
-
-ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
-{
- ALOG_ASSERT(index<size(),
- "[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
-
- void* item = editItemLocation(index);
- if (item != prototype) {
- if (item == 0)
- return NO_MEMORY;
- _do_destroy(item, 1);
- if (prototype == 0) {
- _do_construct(item, 1);
- } else {
- _do_copy(item, prototype, 1);
- }
- }
- return ssize_t(index);
-}
-
-ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
-{
- ALOG_ASSERT((index+count)<=size(),
- "[%p] remove: index=%d, count=%d, size=%d",
- this, (int)index, (int)count, (int)size());
-
- if ((index+count) > size())
- return BAD_VALUE;
- _shrink(index, count);
- return index;
-}
-
-void VectorImpl::finish_vector()
-{
- release_storage();
- mStorage = 0;
- mCount = 0;
-}
-
-void VectorImpl::clear()
-{
- _shrink(0, mCount);
-}
-
-void* VectorImpl::editItemLocation(size_t index)
-{
- ALOG_ASSERT(index<capacity(),
- "[%p] editItemLocation: index=%d, capacity=%d, count=%d",
- this, (int)index, (int)capacity(), (int)mCount);
-
- void* buffer = editArrayImpl();
- if (buffer)
- return reinterpret_cast<char*>(buffer) + index*mItemSize;
- return 0;
-}
-
-const void* VectorImpl::itemLocation(size_t index) const
-{
- ALOG_ASSERT(index<capacity(),
- "[%p] itemLocation: index=%d, capacity=%d, count=%d",
- this, (int)index, (int)capacity(), (int)mCount);
-
- const void* buffer = arrayImpl();
- if (buffer)
- return reinterpret_cast<const char*>(buffer) + index*mItemSize;
- return 0;
-}
-
-ssize_t VectorImpl::setCapacity(size_t new_capacity)
-{
- size_t current_capacity = capacity();
- ssize_t amount = new_capacity - size();
- if (amount <= 0) {
- // we can't reduce the capacity
- return current_capacity;
- }
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- _do_copy(array, mStorage, size());
- release_storage();
- mStorage = const_cast<void*>(array);
- } else {
- return NO_MEMORY;
- }
- return new_capacity;
-}
-
-void VectorImpl::release_storage()
-{
- if (mStorage) {
- const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage);
- if (sb->release(SharedBuffer::eKeepStorage) == 1) {
- _do_destroy(mStorage, mCount);
- SharedBuffer::dealloc(sb);
- }
- }
-}
-
-void* VectorImpl::_grow(size_t where, size_t amount)
-{
-// ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
-// this, (int)where, (int)amount, (int)mCount, (int)capacity());
-
- ALOG_ASSERT(where <= mCount,
- "[%p] _grow: where=%d, amount=%d, count=%d",
- this, (int)where, (int)amount, (int)mCount); // caller already checked
-
- const size_t new_size = mCount + amount;
- if (capacity() < new_size) {
- const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
-// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((mStorage) &&
- (mCount==where) &&
- (mFlags & HAS_TRIVIAL_COPY) &&
- (mFlags & HAS_TRIVIAL_DTOR))
- {
- const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
- SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
- mStorage = sb->data();
- } else {
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- if (where != 0) {
- _do_copy(array, mStorage, where);
- }
- if (where != mCount) {
- const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
- void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_copy(dest, from, mCount-where);
- }
- release_storage();
- mStorage = const_cast<void*>(array);
- }
- }
- } else {
- if (where != mCount) {
- void* array = editArrayImpl();
- const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
- void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_move_forward(to, from, mCount - where);
- }
- }
- mCount = new_size;
- void* free_space = const_cast<void*>(itemLocation(where));
- return free_space;
-}
-
-void VectorImpl::_shrink(size_t where, size_t amount)
-{
- if (!mStorage)
- return;
-
-// ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
-// this, (int)where, (int)amount, (int)mCount, (int)capacity());
-
- ALOG_ASSERT(where + amount <= mCount,
- "[%p] _shrink: where=%d, amount=%d, count=%d",
- this, (int)where, (int)amount, (int)mCount); // caller already checked
-
- const size_t new_size = mCount - amount;
- if (new_size*3 < capacity()) {
- const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
-// ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((where == new_size) &&
- (mFlags & HAS_TRIVIAL_COPY) &&
- (mFlags & HAS_TRIVIAL_DTOR))
- {
- const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
- SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
- mStorage = sb->data();
- } else {
- SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
- if (sb) {
- void* array = sb->data();
- if (where != 0) {
- _do_copy(array, mStorage, where);
- }
- if (where != new_size) {
- const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
- void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_copy(dest, from, new_size - where);
- }
- release_storage();
- mStorage = const_cast<void*>(array);
- }
- }
- } else {
- void* array = editArrayImpl();
- void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_destroy(to, amount);
- if (where != new_size) {
- const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_move_backward(to, from, new_size - where);
- }
- }
- mCount = new_size;
-}
-
-size_t VectorImpl::itemSize() const {
- return mItemSize;
-}
-
-void VectorImpl::_do_construct(void* storage, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_CTOR)) {
- do_construct(storage, num);
- }
-}
-
-void VectorImpl::_do_destroy(void* storage, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_DTOR)) {
- do_destroy(storage, num);
- }
-}
-
-void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
-{
- if (!(mFlags & HAS_TRIVIAL_COPY)) {
- do_copy(dest, from, num);
- } else {
- memcpy(dest, from, num*itemSize());
- }
-}
-
-void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
- do_splat(dest, item, num);
-}
-
-void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
- do_move_forward(dest, from, num);
-}
-
-void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
- do_move_backward(dest, from, num);
-}
-
-void VectorImpl::reservedVectorImpl1() { }
-void VectorImpl::reservedVectorImpl2() { }
-void VectorImpl::reservedVectorImpl3() { }
-void VectorImpl::reservedVectorImpl4() { }
-void VectorImpl::reservedVectorImpl5() { }
-void VectorImpl::reservedVectorImpl6() { }
-void VectorImpl::reservedVectorImpl7() { }
-void VectorImpl::reservedVectorImpl8() { }
-
-/*****************************************************************************/
-
-SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
- : VectorImpl(itemSize, flags)
-{
-}
-
-SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
-: VectorImpl(rhs)
-{
-}
-
-SortedVectorImpl::~SortedVectorImpl()
-{
-}
-
-SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)
-{
- return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );
-}
-
-ssize_t SortedVectorImpl::indexOf(const void* item) const
-{
- return _indexOrderOf(item);
-}
-
-size_t SortedVectorImpl::orderOf(const void* item) const
-{
- size_t o;
- _indexOrderOf(item, &o);
- return o;
-}
-
-ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
-{
- // binary search
- ssize_t err = NAME_NOT_FOUND;
- ssize_t l = 0;
- ssize_t h = size()-1;
- ssize_t mid;
- const void* a = arrayImpl();
- const size_t s = itemSize();
- while (l <= h) {
- mid = l + (h - l)/2;
- const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
- const int c = do_compare(curr, item);
- if (c == 0) {
- err = l = mid;
- break;
- } else if (c < 0) {
- l = mid + 1;
- } else {
- h = mid - 1;
- }
- }
- if (order) *order = l;
- return err;
-}
-
-ssize_t SortedVectorImpl::add(const void* item)
-{
- size_t order;
- ssize_t index = _indexOrderOf(item, &order);
- if (index < 0) {
- index = VectorImpl::insertAt(item, order, 1);
- } else {
- index = VectorImpl::replaceAt(item, index);
- }
- return index;
-}
-
-ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
-{
- // naive merge...
- if (!vector.isEmpty()) {
- const void* buffer = vector.arrayImpl();
- const size_t is = itemSize();
- size_t s = vector.size();
- for (size_t i=0 ; i<s ; i++) {
- ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );
- if (err<0) {
- return err;
- }
- }
- }
- return NO_ERROR;
-}
-
-ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
-{
- // we've merging a sorted vector... nice!
- ssize_t err = NO_ERROR;
- if (!vector.isEmpty()) {
- // first take care of the case where the vectors are sorted together
- if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {
- err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);
- } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {
- err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));
- } else {
- // this could be made a little better
- err = merge(static_cast<const VectorImpl&>(vector));
- }
- }
- return err;
-}
-
-ssize_t SortedVectorImpl::remove(const void* item)
-{
- ssize_t i = indexOf(item);
- if (i>=0) {
- VectorImpl::removeItemsAt(i, 1);
- }
- return i;
-}
-
-void SortedVectorImpl::reservedSortedVectorImpl1() { };
-void SortedVectorImpl::reservedSortedVectorImpl2() { };
-void SortedVectorImpl::reservedSortedVectorImpl3() { };
-void SortedVectorImpl::reservedSortedVectorImpl4() { };
-void SortedVectorImpl::reservedSortedVectorImpl5() { };
-void SortedVectorImpl::reservedSortedVectorImpl6() { };
-void SortedVectorImpl::reservedSortedVectorImpl7() { };
-void SortedVectorImpl::reservedSortedVectorImpl8() { };
-
-
-/*****************************************************************************/
-
-}; // namespace android
-
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
deleted file mode 100644
index dc89d15..0000000
--- a/libs/utils/misc.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Miscellaneous utility functions.
-//
-#include <utils/misc.h>
-
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-
-/*
- * Like strdup(), but uses C++ "new" operator instead of malloc.
- */
-char* strdupNew(const char* str)
-{
- char* newStr;
- int len;
-
- if (str == NULL)
- return NULL;
-
- len = strlen(str);
- newStr = new char[len+1];
- memcpy(newStr, str, len+1);
-
- return newStr;
-}
-
-/*
- * Concatenate an argument vector.
- */
-char* concatArgv(int argc, const char* const argv[])
-{
- char* newStr = NULL;
- int len, totalLen, posn, idx;
-
- /*
- * First, figure out the total length.
- */
- totalLen = idx = 0;
- while (1) {
- if (idx == argc || argv[idx] == NULL)
- break;
- if (idx)
- totalLen++; // leave a space between args
- totalLen += strlen(argv[idx]);
- idx++;
- }
-
- /*
- * Alloc the string.
- */
- newStr = new char[totalLen +1];
- if (newStr == NULL)
- return NULL;
-
- /*
- * Finally, allocate the string and copy data over.
- */
- idx = posn = 0;
- while (1) {
- if (idx == argc || argv[idx] == NULL)
- break;
- if (idx)
- newStr[posn++] = ' ';
-
- len = strlen(argv[idx]);
- memcpy(&newStr[posn], argv[idx], len);
- posn += len;
-
- idx++;
- }
-
- assert(posn == totalLen);
- newStr[posn] = '\0';
-
- return newStr;
-}
-
-/*
- * Count the #of args in an argument vector. Don't count the final NULL.
- */
-int countArgv(const char* const argv[])
-{
- int count = 0;
-
- while (argv[count] != NULL)
- count++;
-
- return count;
-}
-
-
-#include <stdio.h>
-/*
- * Get a file's type.
- */
-FileType getFileType(const char* fileName)
-{
- struct stat sb;
-
- if (stat(fileName, &sb) < 0) {
- if (errno == ENOENT || errno == ENOTDIR)
- return kFileTypeNonexistent;
- else {
- fprintf(stderr, "getFileType got errno=%d on '%s'\n",
- errno, fileName);
- return kFileTypeUnknown;
- }
- } else {
- if (S_ISREG(sb.st_mode))
- return kFileTypeRegular;
- else if (S_ISDIR(sb.st_mode))
- return kFileTypeDirectory;
- else if (S_ISCHR(sb.st_mode))
- return kFileTypeCharDev;
- else if (S_ISBLK(sb.st_mode))
- return kFileTypeBlockDev;
- else if (S_ISFIFO(sb.st_mode))
- return kFileTypeFifo;
-#ifdef HAVE_SYMLINKS
- else if (S_ISLNK(sb.st_mode))
- return kFileTypeSymlink;
- else if (S_ISSOCK(sb.st_mode))
- return kFileTypeSocket;
-#endif
- else
- return kFileTypeUnknown;
- }
-}
-
-/*
- * Get a file's modification date.
- */
-time_t getFileModDate(const char* fileName)
-{
- struct stat sb;
-
- if (stat(fileName, &sb) < 0)
- return (time_t) -1;
-
- return sb.st_mtime;
-}
-
-/*
- * Round up to the next highest power of 2.
- *
- * Found on http://graphics.stanford.edu/~seander/bithacks.html.
- */
-unsigned int roundUpPower2(unsigned int val)
-{
- val--;
- val |= val >> 1;
- val |= val >> 2;
- val |= val >> 4;
- val |= val >> 8;
- val |= val >> 16;
- val++;
-
- return val;
-}
-
-}; // namespace android
-
diff --git a/libs/utils/primes.py b/libs/utils/primes.py
deleted file mode 100755
index e161dd8..0000000
--- a/libs/utils/primes.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python2.6
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Generates a table of prime numbers for use in BasicHashtable.cpp.
-#
-# Each prime is chosen such that it is a little more than twice as large as
-# the previous prime in the table. This makes it easier to choose a new
-# hashtable size when the underlying array is grown by as nominal factor
-# of two each time.
-#
-
-def is_odd_prime(n):
- limit = (n - 1) / 2
- d = 3
- while d <= limit:
- if n % d == 0:
- return False
- d += 2
- return True
-
-print "static size_t PRIMES[] = {"
-
-n = 5
-max = 2**31 - 1
-while n < max:
- print " %d," % (n)
- n = n * 2 + 1
- while not is_odd_prime(n):
- n += 2
-
-print " 0,"
-print "};"
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
deleted file mode 100644
index a6811fc..0000000
--- a/libs/utils/tests/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the unit tests.
-test_src_files := \
- BasicHashtable_test.cpp \
- BlobCache_test.cpp \
- Looper_test.cpp \
- String8_test.cpp \
- Unicode_test.cpp \
-
-shared_libraries := \
- libz \
- liblog \
- libcutils \
- libutils \
- libstlport
-
-static_libraries := \
- libgtest \
- libgtest_main
-
-c_includes := \
- external/zlib \
- external/icu4c/common \
- bionic \
- bionic/libstdc++/include \
- external/gtest/include \
- external/stlport/stlport
-
-module_tags := eng tests
-
-$(foreach file,$(test_src_files), \
- $(eval include $(CLEAR_VARS)) \
- $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
- $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
- $(eval LOCAL_C_INCLUDES := $(c_includes)) \
- $(eval LOCAL_SRC_FILES := $(file)) \
- $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
- $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
- $(eval include $(BUILD_EXECUTABLE)) \
-)
diff --git a/libs/utils/tests/BasicHashtable_test.cpp b/libs/utils/tests/BasicHashtable_test.cpp
deleted file mode 100644
index 7dcf750..0000000
--- a/libs/utils/tests/BasicHashtable_test.cpp
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BasicHashtable_test"
-
-#include <utils/BasicHashtable.h>
-#include <cutils/log.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-
-namespace android {
-
-typedef int SimpleKey;
-typedef int SimpleValue;
-typedef key_value_pair_t<SimpleKey, SimpleValue> SimpleEntry;
-typedef BasicHashtable<SimpleKey, SimpleEntry> SimpleHashtable;
-
-struct ComplexKey {
- int k;
-
- explicit ComplexKey(int k) : k(k) {
- instanceCount += 1;
- }
-
- ComplexKey(const ComplexKey& other) : k(other.k) {
- instanceCount += 1;
- }
-
- ~ComplexKey() {
- instanceCount -= 1;
- }
-
- bool operator ==(const ComplexKey& other) const {
- return k == other.k;
- }
-
- bool operator !=(const ComplexKey& other) const {
- return k != other.k;
- }
-
- static ssize_t instanceCount;
-};
-
-ssize_t ComplexKey::instanceCount = 0;
-
-template<> inline hash_t hash_type(const ComplexKey& value) {
- return hash_type(value.k);
-}
-
-struct ComplexValue {
- int v;
-
- explicit ComplexValue(int v) : v(v) {
- instanceCount += 1;
- }
-
- ComplexValue(const ComplexValue& other) : v(other.v) {
- instanceCount += 1;
- }
-
- ~ComplexValue() {
- instanceCount -= 1;
- }
-
- static ssize_t instanceCount;
-};
-
-ssize_t ComplexValue::instanceCount = 0;
-
-typedef key_value_pair_t<ComplexKey, ComplexValue> ComplexEntry;
-typedef BasicHashtable<ComplexKey, ComplexEntry> ComplexHashtable;
-
-class BasicHashtableTest : public testing::Test {
-protected:
- virtual void SetUp() {
- ComplexKey::instanceCount = 0;
- ComplexValue::instanceCount = 0;
- }
-
- virtual void TearDown() {
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
- }
-
- void assertInstanceCount(ssize_t keys, ssize_t values) {
- if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) {
- FAIL() << "Expected " << keys << " keys and " << values << " values "
- "but there were actually " << ComplexKey::instanceCount << " keys and "
- << ComplexValue::instanceCount << " values";
- }
- }
-
-public:
- template <typename TKey, typename TEntry>
- static void cookieAt(const BasicHashtable<TKey, TEntry>& h, size_t index,
- bool* collision, bool* present, hash_t* hash) {
- uint32_t cookie = h.cookieAt(index);
- *collision = cookie & BasicHashtable<TKey, TEntry>::Bucket::COLLISION;
- *present = cookie & BasicHashtable<TKey, TEntry>::Bucket::PRESENT;
- *hash = cookie & BasicHashtable<TKey, TEntry>::Bucket::HASH_MASK;
- }
-
- template <typename TKey, typename TEntry>
- static const void* getBuckets(const BasicHashtable<TKey, TEntry>& h) {
- return h.mBuckets;
- }
-};
-
-template <typename TKey, typename TValue>
-static size_t add(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
- const TKey& key, const TValue& value) {
- return h.add(hash_type(key), key_value_pair_t<TKey, TValue>(key, value));
-}
-
-template <typename TKey, typename TValue>
-static ssize_t find(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
- ssize_t index, const TKey& key) {
- return h.find(index, hash_type(key), key);
-}
-
-template <typename TKey, typename TValue>
-static bool remove(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
- const TKey& key) {
- ssize_t index = find(h, -1, key);
- if (index >= 0) {
- h.removeAt(index);
- return true;
- }
- return false;
-}
-
-template <typename TEntry>
-static void getKeyValue(const TEntry& entry, int* key, int* value);
-
-template <> void getKeyValue(const SimpleEntry& entry, int* key, int* value) {
- *key = entry.key;
- *value = entry.value;
-}
-
-template <> void getKeyValue(const ComplexEntry& entry, int* key, int* value) {
- *key = entry.key.k;
- *value = entry.value.v;
-}
-
-template <typename TKey, typename TValue>
-static void dump(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h) {
- ALOGD("hashtable %p, size=%u, capacity=%u, bucketCount=%u",
- &h, h.size(), h.capacity(), h.bucketCount());
- for (size_t i = 0; i < h.bucketCount(); i++) {
- bool collision, present;
- hash_t hash;
- BasicHashtableTest::cookieAt(h, i, &collision, &present, &hash);
- if (present) {
- int key, value;
- getKeyValue(h.entryAt(i), &key, &value);
- ALOGD(" [%3u] = collision=%d, present=%d, hash=0x%08x, key=%3d, value=%3d, "
- "hash_type(key)=0x%08x",
- i, collision, present, hash, key, value, hash_type(key));
- } else {
- ALOGD(" [%3u] = collision=%d, present=%d",
- i, collision, present);
- }
- }
-}
-
-TEST_F(BasicHashtableTest, DefaultConstructor_WithDefaultProperties) {
- SimpleHashtable h;
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Constructor_WithNonUnityLoadFactor) {
- SimpleHashtable h(52, 0.8f);
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(77U, h.capacity());
- EXPECT_EQ(97U, h.bucketCount());
- EXPECT_EQ(0.8f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndExactCapacity) {
- SimpleHashtable h(46, 1.0f);
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
- EXPECT_EQ(47U, h.bucketCount());
- EXPECT_EQ(1.0f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndInexactCapacity) {
- SimpleHashtable h(42, 1.0f);
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
- EXPECT_EQ(47U, h.bucketCount());
- EXPECT_EQ(1.0f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, FindAddFindRemoveFind_OneEntry) {
- SimpleHashtable h;
- ssize_t index = find(h, -1, 8);
- ASSERT_EQ(-1, index);
-
- index = add(h, 8, 1);
- ASSERT_EQ(1U, h.size());
-
- ASSERT_EQ(index, find(h, -1, 8));
- ASSERT_EQ(8, h.entryAt(index).key);
- ASSERT_EQ(1, h.entryAt(index).value);
-
- index = find(h, index, 8);
- ASSERT_EQ(-1, index);
-
- ASSERT_TRUE(remove(h, 8));
- ASSERT_EQ(0U, h.size());
-
- index = find(h, -1, 8);
- ASSERT_EQ(-1, index);
-}
-
-TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithUniqueKey) {
- const size_t N = 11;
-
- SimpleHashtable h;
- for (size_t i = 0; i < N; i++) {
- ssize_t index = find(h, -1, int(i));
- ASSERT_EQ(-1, index);
-
- index = add(h, int(i), int(i * 10));
- ASSERT_EQ(i + 1, h.size());
-
- ASSERT_EQ(index, find(h, -1, int(i)));
- ASSERT_EQ(int(i), h.entryAt(index).key);
- ASSERT_EQ(int(i * 10), h.entryAt(index).value);
-
- index = find(h, index, int(i));
- ASSERT_EQ(-1, index);
- }
-
- for (size_t i = N; --i > 0; ) {
- ASSERT_TRUE(remove(h, int(i))) << "i = " << i;
- ASSERT_EQ(i, h.size());
-
- ssize_t index = find(h, -1, int(i));
- ASSERT_EQ(-1, index);
- }
-}
-
-TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithDuplicateKey) {
- const size_t N = 11;
- const int K = 1;
-
- SimpleHashtable h;
- for (size_t i = 0; i < N; i++) {
- ssize_t index = find(h, -1, K);
- if (i == 0) {
- ASSERT_EQ(-1, index);
- } else {
- ASSERT_NE(-1, index);
- }
-
- add(h, K, int(i));
- ASSERT_EQ(i + 1, h.size());
-
- index = -1;
- int values = 0;
- for (size_t j = 0; j <= i; j++) {
- index = find(h, index, K);
- ASSERT_GE(index, 0);
- ASSERT_EQ(K, h.entryAt(index).key);
- values |= 1 << h.entryAt(index).value;
- }
- ASSERT_EQ(values, (1 << (i + 1)) - 1);
-
- index = find(h, index, K);
- ASSERT_EQ(-1, index);
- }
-
- for (size_t i = N; --i > 0; ) {
- ASSERT_TRUE(remove(h, K)) << "i = " << i;
- ASSERT_EQ(i, h.size());
-
- ssize_t index = -1;
- for (size_t j = 0; j < i; j++) {
- index = find(h, index, K);
- ASSERT_GE(index, 0);
- ASSERT_EQ(K, h.entryAt(index).key);
- }
-
- index = find(h, index, K);
- ASSERT_EQ(-1, index);
- }
-}
-
-TEST_F(BasicHashtableTest, Clear_WhenAlreadyEmpty_DoesNothing) {
- SimpleHashtable h;
- h.clear();
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_RemovesThem) {
- SimpleHashtable h;
- add(h, 0, 0);
- add(h, 1, 0);
- h.clear();
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_DestroysThem) {
- ComplexHashtable h;
- add(h, ComplexKey(0), ComplexValue(0));
- add(h, ComplexKey(1), ComplexValue(0));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
-
- h.clear();
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Remove_AfterElementsAdded_DestroysThem) {
- ComplexHashtable h;
- add(h, ComplexKey(0), ComplexValue(0));
- add(h, ComplexKey(1), ComplexValue(0));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
-
- ASSERT_TRUE(remove(h, ComplexKey(0)));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
-
- ASSERT_TRUE(remove(h, ComplexKey(1)));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
-}
-
-TEST_F(BasicHashtableTest, Destructor_AfterElementsAdded_DestroysThem) {
- {
- ComplexHashtable h;
- add(h, ComplexKey(0), ComplexValue(0));
- add(h, ComplexKey(1), ComplexValue(0));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- } // h is destroyed here
-
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-}
-
-TEST_F(BasicHashtableTest, Next_WhenEmpty_ReturnsMinusOne) {
- SimpleHashtable h;
-
- ASSERT_EQ(-1, h.next(-1));
-}
-
-TEST_F(BasicHashtableTest, Next_WhenNonEmpty_IteratesOverAllEntries) {
- const int N = 88;
-
- SimpleHashtable h;
- for (int i = 0; i < N; i++) {
- add(h, i, i * 10);
- }
-
- bool set[N];
- memset(set, 0, sizeof(bool) * N);
- int count = 0;
- for (ssize_t index = -1; (index = h.next(index)) != -1; ) {
- ASSERT_GE(index, 0);
- ASSERT_LT(size_t(index), h.bucketCount());
-
- const SimpleEntry& entry = h.entryAt(index);
- ASSERT_GE(entry.key, 0);
- ASSERT_LT(entry.key, N);
- ASSERT_EQ(false, set[entry.key]);
- ASSERT_EQ(entry.key * 10, entry.value);
-
- set[entry.key] = true;
- count += 1;
- }
- ASSERT_EQ(N, count);
-}
-
-TEST_F(BasicHashtableTest, Add_RehashesOnDemand) {
- SimpleHashtable h;
- size_t initialCapacity = h.capacity();
- size_t initialBucketCount = h.bucketCount();
-
- for (size_t i = 0; i < initialCapacity; i++) {
- add(h, int(i), 0);
- }
-
- EXPECT_EQ(initialCapacity, h.size());
- EXPECT_EQ(initialCapacity, h.capacity());
- EXPECT_EQ(initialBucketCount, h.bucketCount());
-
- add(h, -1, -1);
-
- EXPECT_EQ(initialCapacity + 1, h.size());
- EXPECT_GT(h.capacity(), initialCapacity);
- EXPECT_GT(h.bucketCount(), initialBucketCount);
- EXPECT_GT(h.bucketCount(), h.capacity());
-}
-
-TEST_F(BasicHashtableTest, Rehash_WhenCapacityAndBucketCountUnchanged_DoesNothing) {
- ComplexHashtable h;
- add(h, ComplexKey(0), ComplexValue(0));
- const void* oldBuckets = getBuckets(h);
- ASSERT_NE((void*)NULL, oldBuckets);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
-
- h.rehash(h.capacity(), h.loadFactor());
-
- ASSERT_EQ(oldBuckets, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
-}
-
-TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasNoBuckets_ButDoesNotAllocateBuckets) {
- ComplexHashtable h;
- ASSERT_EQ((void*)NULL, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-
- h.rehash(9, 1.0f);
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(10U, h.capacity());
- EXPECT_EQ(11U, h.bucketCount());
- EXPECT_EQ(1.0f, h.loadFactor());
- EXPECT_EQ((void*)NULL, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-}
-
-TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasBuckets_ReleasesBucketsAndSetsCapacity) {
- ComplexHashtable h(10);
- add(h, ComplexKey(0), ComplexValue(0));
- ASSERT_TRUE(remove(h, ComplexKey(0)));
- ASSERT_NE((void*)NULL, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-
- h.rehash(0, 0.75f);
-
- EXPECT_EQ(0U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
- EXPECT_EQ((void*)NULL, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
-}
-
-TEST_F(BasicHashtableTest, Rehash_WhenLessThanCurrentCapacity_ShrinksBuckets) {
- ComplexHashtable h(10);
- add(h, ComplexKey(0), ComplexValue(0));
- add(h, ComplexKey(1), ComplexValue(1));
- const void* oldBuckets = getBuckets(h);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
-
- h.rehash(0, 0.75f);
-
- EXPECT_EQ(2U, h.size());
- EXPECT_EQ(3U, h.capacity());
- EXPECT_EQ(5U, h.bucketCount());
- EXPECT_EQ(0.75f, h.loadFactor());
- EXPECT_NE(oldBuckets, getBuckets(h));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
-}
-
-TEST_F(BasicHashtableTest, CopyOnWrite) {
- ComplexHashtable h1;
- add(h1, ComplexKey(0), ComplexValue(0));
- add(h1, ComplexKey(1), ComplexValue(1));
- const void* originalBuckets = getBuckets(h1);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ssize_t index0 = find(h1, -1, ComplexKey(0));
- EXPECT_GE(index0, 0);
-
- // copy constructor acquires shared reference
- ComplexHashtable h2(h1);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ASSERT_EQ(originalBuckets, getBuckets(h2));
- EXPECT_EQ(h1.size(), h2.size());
- EXPECT_EQ(h1.capacity(), h2.capacity());
- EXPECT_EQ(h1.bucketCount(), h2.bucketCount());
- EXPECT_EQ(h1.loadFactor(), h2.loadFactor());
- EXPECT_EQ(index0, find(h2, -1, ComplexKey(0)));
-
- // operator= acquires shared reference
- ComplexHashtable h3;
- h3 = h2;
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ASSERT_EQ(originalBuckets, getBuckets(h3));
- EXPECT_EQ(h1.size(), h3.size());
- EXPECT_EQ(h1.capacity(), h3.capacity());
- EXPECT_EQ(h1.bucketCount(), h3.bucketCount());
- EXPECT_EQ(h1.loadFactor(), h3.loadFactor());
- EXPECT_EQ(index0, find(h3, -1, ComplexKey(0)));
-
- // editEntryAt copies shared contents
- h1.editEntryAt(index0).value.v = 42;
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
- ASSERT_NE(originalBuckets, getBuckets(h1));
- EXPECT_EQ(42, h1.entryAt(index0).value.v);
- EXPECT_EQ(0, h2.entryAt(index0).value.v);
- EXPECT_EQ(0, h3.entryAt(index0).value.v);
-
- // clear releases reference to shared contents
- h2.clear();
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
- EXPECT_EQ(0U, h2.size());
- ASSERT_NE(originalBuckets, getBuckets(h2));
-
- // operator= acquires shared reference, destroys unshared contents
- h1 = h3;
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ASSERT_EQ(originalBuckets, getBuckets(h1));
- EXPECT_EQ(h3.size(), h1.size());
- EXPECT_EQ(h3.capacity(), h1.capacity());
- EXPECT_EQ(h3.bucketCount(), h1.bucketCount());
- EXPECT_EQ(h3.loadFactor(), h1.loadFactor());
- EXPECT_EQ(index0, find(h1, -1, ComplexKey(0)));
-
- // add copies shared contents
- add(h1, ComplexKey(2), ComplexValue(2));
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(5, 5));
- ASSERT_NE(originalBuckets, getBuckets(h1));
- EXPECT_EQ(3U, h1.size());
- EXPECT_EQ(0U, h2.size());
- EXPECT_EQ(2U, h3.size());
-
- // remove copies shared contents
- h1 = h3;
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ASSERT_EQ(originalBuckets, getBuckets(h1));
- h1.removeAt(index0);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(3, 3));
- ASSERT_NE(originalBuckets, getBuckets(h1));
- EXPECT_EQ(1U, h1.size());
- EXPECT_EQ(0U, h2.size());
- EXPECT_EQ(2U, h3.size());
-
- // rehash copies shared contents
- h1 = h3;
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
- ASSERT_EQ(originalBuckets, getBuckets(h1));
- h1.rehash(10, 1.0f);
- ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
- ASSERT_NE(originalBuckets, getBuckets(h1));
- EXPECT_EQ(2U, h1.size());
- EXPECT_EQ(0U, h2.size());
- EXPECT_EQ(2U, h3.size());
-}
-
-} // namespace android
diff --git a/libs/utils/tests/BlobCache_test.cpp b/libs/utils/tests/BlobCache_test.cpp
deleted file mode 100644
index b64cc39..0000000
--- a/libs/utils/tests/BlobCache_test.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-
-#include <gtest/gtest.h>
-
-#include <utils/BlobCache.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class BlobCacheTest : public ::testing::Test {
-protected:
- enum {
- MAX_KEY_SIZE = 6,
- MAX_VALUE_SIZE = 8,
- MAX_TOTAL_SIZE = 13,
- };
-
- virtual void SetUp() {
- mBC = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE);
- }
-
- virtual void TearDown() {
- mBC.clear();
- }
-
- sp<BlobCache> mBC;
-};
-
-TEST_F(BlobCacheTest, CacheSingleValueSucceeds) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
- ASSERT_EQ('e', buf[0]);
- ASSERT_EQ('f', buf[1]);
- ASSERT_EQ('g', buf[2]);
- ASSERT_EQ('h', buf[3]);
-}
-
-TEST_F(BlobCacheTest, CacheTwoValuesSucceeds) {
- char buf[2] = { 0xee, 0xee };
- mBC->set("ab", 2, "cd", 2);
- mBC->set("ef", 2, "gh", 2);
- ASSERT_EQ(size_t(2), mBC->get("ab", 2, buf, 2));
- ASSERT_EQ('c', buf[0]);
- ASSERT_EQ('d', buf[1]);
- ASSERT_EQ(size_t(2), mBC->get("ef", 2, buf, 2));
- ASSERT_EQ('g', buf[0]);
- ASSERT_EQ('h', buf[1]);
-}
-
-TEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) {
- char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf+1, 4));
- ASSERT_EQ(0xee, buf[0]);
- ASSERT_EQ('e', buf[1]);
- ASSERT_EQ('f', buf[2]);
- ASSERT_EQ('g', buf[3]);
- ASSERT_EQ('h', buf[4]);
- ASSERT_EQ(0xee, buf[5]);
-}
-
-TEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {
- char buf[3] = { 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 3));
- ASSERT_EQ(0xee, buf[0]);
- ASSERT_EQ(0xee, buf[1]);
- ASSERT_EQ(0xee, buf[2]);
-}
-
-TEST_F(BlobCacheTest, GetDoesntAccessNullBuffer) {
- mBC->set("abcd", 4, "efgh", 4);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, NULL, 0));
-}
-
-TEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- mBC->set("abcd", 4, "ijkl", 4);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
- ASSERT_EQ('i', buf[0]);
- ASSERT_EQ('j', buf[1]);
- ASSERT_EQ('k', buf[2]);
- ASSERT_EQ('l', buf[3]);
-}
-
-TEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {
- char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
- ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
- ASSERT_EQ('e', buf[0]);
- ASSERT_EQ('f', buf[1]);
- ASSERT_EQ('g', buf[2]);
- ASSERT_EQ('h', buf[3]);
-}
-
-TEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) {
- char key[MAX_KEY_SIZE+1];
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- for (int i = 0; i < MAX_KEY_SIZE+1; i++) {
- key[i] = 'a';
- }
- mBC->set(key, MAX_KEY_SIZE+1, "bbbb", 4);
- ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE+1, buf, 4));
- ASSERT_EQ(0xee, buf[0]);
- ASSERT_EQ(0xee, buf[1]);
- ASSERT_EQ(0xee, buf[2]);
- ASSERT_EQ(0xee, buf[3]);
-}
-
-TEST_F(BlobCacheTest, DoesntCacheIfValueIsTooBig) {
- char buf[MAX_VALUE_SIZE+1];
- for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
- buf[i] = 'b';
- }
- mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
- for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
- buf[i] = 0xee;
- }
- ASSERT_EQ(size_t(0), mBC->get("abcd", 4, buf, MAX_VALUE_SIZE+1));
- for (int i = 0; i < MAX_VALUE_SIZE+1; i++) {
- SCOPED_TRACE(i);
- ASSERT_EQ(0xee, buf[i]);
- }
-}
-
-TEST_F(BlobCacheTest, DoesntCacheIfKeyValuePairIsTooBig) {
- // Check a testing assumptions
- ASSERT_TRUE(MAX_TOTAL_SIZE < MAX_KEY_SIZE + MAX_VALUE_SIZE);
- ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
-
- enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE + 1 };
-
- char key[MAX_KEY_SIZE];
- char buf[bufSize];
- for (int i = 0; i < MAX_KEY_SIZE; i++) {
- key[i] = 'a';
- }
- for (int i = 0; i < bufSize; i++) {
- buf[i] = 'b';
- }
-
- mBC->set(key, MAX_KEY_SIZE, buf, MAX_VALUE_SIZE);
- ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
-}
-
-TEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) {
- char key[MAX_KEY_SIZE];
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- for (int i = 0; i < MAX_KEY_SIZE; i++) {
- key[i] = 'a';
- }
- mBC->set(key, MAX_KEY_SIZE, "wxyz", 4);
- ASSERT_EQ(size_t(4), mBC->get(key, MAX_KEY_SIZE, buf, 4));
- ASSERT_EQ('w', buf[0]);
- ASSERT_EQ('x', buf[1]);
- ASSERT_EQ('y', buf[2]);
- ASSERT_EQ('z', buf[3]);
-}
-
-TEST_F(BlobCacheTest, CacheMaxValueSizeSucceeds) {
- char buf[MAX_VALUE_SIZE];
- for (int i = 0; i < MAX_VALUE_SIZE; i++) {
- buf[i] = 'b';
- }
- mBC->set("abcd", 4, buf, MAX_VALUE_SIZE);
- for (int i = 0; i < MAX_VALUE_SIZE; i++) {
- buf[i] = 0xee;
- }
- ASSERT_EQ(size_t(MAX_VALUE_SIZE), mBC->get("abcd", 4, buf,
- MAX_VALUE_SIZE));
- for (int i = 0; i < MAX_VALUE_SIZE; i++) {
- SCOPED_TRACE(i);
- ASSERT_EQ('b', buf[i]);
- }
-}
-
-TEST_F(BlobCacheTest, CacheMaxKeyValuePairSizeSucceeds) {
- // Check a testing assumption
- ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE);
-
- enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE };
-
- char key[MAX_KEY_SIZE];
- char buf[bufSize];
- for (int i = 0; i < MAX_KEY_SIZE; i++) {
- key[i] = 'a';
- }
- for (int i = 0; i < bufSize; i++) {
- buf[i] = 'b';
- }
-
- mBC->set(key, MAX_KEY_SIZE, buf, bufSize);
- ASSERT_EQ(size_t(bufSize), mBC->get(key, MAX_KEY_SIZE, NULL, 0));
-}
-
-TEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
- char buf[1] = { 0xee };
- mBC->set("x", 1, "y", 1);
- ASSERT_EQ(size_t(1), mBC->get("x", 1, buf, 1));
- ASSERT_EQ('y', buf[0]);
-}
-
-TEST_F(BlobCacheTest, CacheSizeDoesntExceedTotalLimit) {
- for (int i = 0; i < 256; i++) {
- uint8_t k = i;
- mBC->set(&k, 1, "x", 1);
- }
- int numCached = 0;
- for (int i = 0; i < 256; i++) {
- uint8_t k = i;
- if (mBC->get(&k, 1, NULL, 0) == 1) {
- numCached++;
- }
- }
- ASSERT_GE(MAX_TOTAL_SIZE / 2, numCached);
-}
-
-TEST_F(BlobCacheTest, ExceedingTotalLimitHalvesCacheSize) {
- // Fill up the entire cache with 1 char key/value pairs.
- const int maxEntries = MAX_TOTAL_SIZE / 2;
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- mBC->set(&k, 1, "x", 1);
- }
- // Insert one more entry, causing a cache overflow.
- {
- uint8_t k = maxEntries;
- mBC->set(&k, 1, "x", 1);
- }
- // Count the number of entries in the cache.
- int numCached = 0;
- for (int i = 0; i < maxEntries+1; i++) {
- uint8_t k = i;
- if (mBC->get(&k, 1, NULL, 0) == 1) {
- numCached++;
- }
- }
- ASSERT_EQ(maxEntries/2 + 1, numCached);
-}
-
-class BlobCacheFlattenTest : public BlobCacheTest {
-protected:
- virtual void SetUp() {
- BlobCacheTest::SetUp();
- mBC2 = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE);
- }
-
- virtual void TearDown() {
- mBC2.clear();
- BlobCacheTest::TearDown();
- }
-
- void roundTrip() {
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
- ASSERT_EQ(OK, mBC2->unflatten(flat, size, NULL, 0));
- delete[] flat;
- }
-
- sp<BlobCache> mBC2;
-};
-
-TEST_F(BlobCacheFlattenTest, FlattenOneValue) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
- roundTrip();
- ASSERT_EQ(size_t(4), mBC2->get("abcd", 4, buf, 4));
- ASSERT_EQ('e', buf[0]);
- ASSERT_EQ('f', buf[1]);
- ASSERT_EQ('g', buf[2]);
- ASSERT_EQ('h', buf[3]);
-}
-
-TEST_F(BlobCacheFlattenTest, FlattenFullCache) {
- // Fill up the entire cache with 1 char key/value pairs.
- const int maxEntries = MAX_TOTAL_SIZE / 2;
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- mBC->set(&k, 1, &k, 1);
- }
-
- roundTrip();
-
- // Verify the deserialized cache
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- uint8_t v = 0xee;
- ASSERT_EQ(size_t(1), mBC2->get(&k, 1, &v, 1));
- ASSERT_EQ(k, v);
- }
-}
-
-TEST_F(BlobCacheFlattenTest, FlattenDoesntChangeCache) {
- // Fill up the entire cache with 1 char key/value pairs.
- const int maxEntries = MAX_TOTAL_SIZE / 2;
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- mBC->set(&k, 1, &k, 1);
- }
-
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
- delete[] flat;
-
- // Verify the cache that we just serialized
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- uint8_t v = 0xee;
- ASSERT_EQ(size_t(1), mBC->get(&k, 1, &v, 1));
- ASSERT_EQ(k, v);
- }
-}
-
-TEST_F(BlobCacheFlattenTest, FlattenCatchesBufferTooSmall) {
- // Fill up the entire cache with 1 char key/value pairs.
- const int maxEntries = MAX_TOTAL_SIZE / 2;
- for (int i = 0; i < maxEntries; i++) {
- uint8_t k = i;
- mBC->set(&k, 1, &k, 1);
- }
-
- size_t size = mBC->getFlattenedSize() - 1;
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(BAD_VALUE, mBC->flatten(flat, size, NULL, 0));
- delete[] flat;
-}
-
-TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadMagic) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
-
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
- flat[1] = ~flat[1];
-
- // Bad magic should cause an error.
- ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size, NULL, 0));
- delete[] flat;
-
- // The error should cause the unflatten to result in an empty cache
- ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
-}
-
-TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheVersion) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
-
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
- flat[5] = ~flat[5];
-
- // Version mismatches shouldn't cause errors, but should not use the
- // serialized entries
- ASSERT_EQ(OK, mBC2->unflatten(flat, size, NULL, 0));
- delete[] flat;
-
- // The version mismatch should cause the unflatten to result in an empty
- // cache
- ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
-}
-
-TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheDeviceVersion) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
-
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
- flat[10] = ~flat[10];
-
- // Version mismatches shouldn't cause errors, but should not use the
- // serialized entries
- ASSERT_EQ(OK, mBC2->unflatten(flat, size, NULL, 0));
- delete[] flat;
-
- // The version mismatch should cause the unflatten to result in an empty
- // cache
- ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
-}
-
-TEST_F(BlobCacheFlattenTest, UnflattenCatchesBufferTooSmall) {
- char buf[4] = { 0xee, 0xee, 0xee, 0xee };
- mBC->set("abcd", 4, "efgh", 4);
-
- size_t size = mBC->getFlattenedSize();
- uint8_t* flat = new uint8_t[size];
- ASSERT_EQ(OK, mBC->flatten(flat, size, NULL, 0));
-
- // A buffer truncation shouldt cause an error
- ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size-1, NULL, 0));
- delete[] flat;
-
- // The error should cause the unflatten to result in an empty cache
- ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4));
-}
-
-} // namespace android
diff --git a/libs/utils/tests/Looper_test.cpp b/libs/utils/tests/Looper_test.cpp
deleted file mode 100644
index 8bf2ba2..0000000
--- a/libs/utils/tests/Looper_test.cpp
+++ /dev/null
@@ -1,693 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-
-#include <utils/Looper.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "TestHelpers.h"
-
-// # of milliseconds to fudge stopwatch measurements
-#define TIMING_TOLERANCE_MS 25
-
-namespace android {
-
-enum {
- MSG_TEST1 = 1,
- MSG_TEST2 = 2,
- MSG_TEST3 = 3,
- MSG_TEST4 = 4,
-};
-
-class DelayedWake : public DelayedTask {
- sp<Looper> mLooper;
-
-public:
- DelayedWake(int delayMillis, const sp<Looper> looper) :
- DelayedTask(delayMillis), mLooper(looper) {
- }
-
-protected:
- virtual void doTask() {
- mLooper->wake();
- }
-};
-
-class DelayedWriteSignal : public DelayedTask {
- Pipe* mPipe;
-
-public:
- DelayedWriteSignal(int delayMillis, Pipe* pipe) :
- DelayedTask(delayMillis), mPipe(pipe) {
- }
-
-protected:
- virtual void doTask() {
- mPipe->writeSignal();
- }
-};
-
-class CallbackHandler {
-public:
- void setCallback(const sp<Looper>& looper, int fd, int events) {
- looper->addFd(fd, 0, events, staticHandler, this);
- }
-
-protected:
- virtual ~CallbackHandler() { }
-
- virtual int handler(int fd, int events) = 0;
-
-private:
- static int staticHandler(int fd, int events, void* data) {
- return static_cast<CallbackHandler*>(data)->handler(fd, events);
- }
-};
-
-class StubCallbackHandler : public CallbackHandler {
-public:
- int nextResult;
- int callbackCount;
-
- int fd;
- int events;
-
- StubCallbackHandler(int nextResult) : nextResult(nextResult),
- callbackCount(0), fd(-1), events(-1) {
- }
-
-protected:
- virtual int handler(int fd, int events) {
- callbackCount += 1;
- this->fd = fd;
- this->events = events;
- return nextResult;
- }
-};
-
-class StubMessageHandler : public MessageHandler {
-public:
- Vector<Message> messages;
-
- virtual void handleMessage(const Message& message) {
- messages.push(message);
- }
-};
-
-class LooperTest : public testing::Test {
-protected:
- sp<Looper> mLooper;
-
- virtual void SetUp() {
- mLooper = new Looper(true);
- }
-
- virtual void TearDown() {
- mLooper.clear();
- }
-};
-
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) {
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal timeout";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) {
- mLooper->wake();
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because wake() was called before waiting";
- EXPECT_EQ(ALOOPER_POLL_WAKE, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {
- sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);
- delayedWake->run();
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal wake delay";
- EXPECT_EQ(ALOOPER_POLL_WAKE, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
-}
-
-TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) {
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should be approx. zero";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
-}
-
-TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {
- Pipe pipe;
- StubCallbackHandler handler(true);
-
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should be approx. zero";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
- EXPECT_EQ(0, handler.callbackCount)
- << "callback should not have been invoked because FD was not signalled";
-}
-
-TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {
- Pipe pipe;
- StubCallbackHandler handler(true);
-
- ASSERT_EQ(OK, pipe.writeSignal());
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should be approx. zero";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
- EXPECT_EQ(1, handler.callbackCount)
- << "callback should be invoked exactly once";
- EXPECT_EQ(pipe.receiveFd, handler.fd)
- << "callback should have received pipe fd as parameter";
- EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
- << "callback should have received ALOOPER_EVENT_INPUT as events";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {
- Pipe pipe;
- StubCallbackHandler handler(true);
-
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal timeout";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
- EXPECT_EQ(0, handler.callbackCount)
- << "callback should not have been invoked because FD was not signalled";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {
- Pipe pipe;
- StubCallbackHandler handler(true);
-
- pipe.writeSignal();
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should be approx. zero";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
- EXPECT_EQ(1, handler.callbackCount)
- << "callback should be invoked exactly once";
- EXPECT_EQ(pipe.receiveFd, handler.fd)
- << "callback should have received pipe fd as parameter";
- EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
- << "callback should have received ALOOPER_EVENT_INPUT as events";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {
- Pipe pipe;
- StubCallbackHandler handler(true);
- sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
-
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
- delayedWriteSignal->run();
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal signal delay";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
- EXPECT_EQ(1, handler.callbackCount)
- << "callback should be invoked exactly once";
- EXPECT_EQ(pipe.receiveFd, handler.fd)
- << "callback should have received pipe fd as parameter";
- EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
- << "callback should have received ALOOPER_EVENT_INPUT as events";
-}
-
-TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
- Pipe pipe;
- StubCallbackHandler handler(true);
-
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
- pipe.writeSignal(); // would cause FD to be considered signalled
- mLooper->removeFd(pipe.receiveFd);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal timeout because FD was no longer registered";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
- EXPECT_EQ(0, handler.callbackCount)
- << "callback should not be invoked";
-}
-
-TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
- Pipe pipe;
- StubCallbackHandler handler(false);
-
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- // First loop: Callback is registered and FD is signalled.
- pipe.writeSignal();
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal zero because FD was already signalled";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
- EXPECT_EQ(1, handler.callbackCount)
- << "callback should be invoked";
-
- // Second loop: Callback is no longer registered and FD is signalled.
- pipe.writeSignal();
-
- stopWatch.reset();
- result = mLooper->pollOnce(0);
- elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. equal zero because timeout was zero";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
- EXPECT_EQ(1, handler.callbackCount)
- << "callback should not be invoked this time";
-}
-
-TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {
- const int expectedIdent = 5;
- void* expectedData = this;
-
- Pipe pipe;
-
- pipe.writeSignal();
- mLooper->addFd(pipe.receiveFd, expectedIdent, ALOOPER_EVENT_INPUT, NULL, expectedData);
-
- StopWatch stopWatch("pollOnce");
- int fd;
- int events;
- void* data;
- int result = mLooper->pollOnce(100, &fd, &events, &data);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should be approx. zero";
- EXPECT_EQ(expectedIdent, result)
- << "pollOnce result should be the ident of the FD that was signalled";
- EXPECT_EQ(pipe.receiveFd, fd)
- << "pollOnce should have returned the received pipe fd";
- EXPECT_EQ(ALOOPER_EVENT_INPUT, events)
- << "pollOnce should have returned ALOOPER_EVENT_INPUT as events";
- EXPECT_EQ(expectedData, data)
- << "pollOnce should have returned the data";
-}
-
-TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {
- Pipe pipe;
- int result = mLooper->addFd(pipe.receiveFd, 0, ALOOPER_EVENT_INPUT, NULL, NULL);
-
- EXPECT_EQ(1, result)
- << "addFd should return 1 because FD was added";
-}
-
-TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {
- Pipe pipe;
- int result = mLooper->addFd(pipe.receiveFd, -1, ALOOPER_EVENT_INPUT, NULL, NULL);
-
- EXPECT_EQ(-1, result)
- << "addFd should return -1 because arguments were invalid";
-}
-
-TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {
- Pipe pipe;
- sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);
- int result = looper->addFd(pipe.receiveFd, 0, 0, NULL, NULL);
-
- EXPECT_EQ(-1, result)
- << "addFd should return -1 because arguments were invalid";
-}
-
-TEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) {
- int result = mLooper->removeFd(1);
-
- EXPECT_EQ(0, result)
- << "removeFd should return 0 because FD not registered";
-}
-
-TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {
- Pipe pipe;
- StubCallbackHandler handler(false);
- handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
-
- // First time.
- int result = mLooper->removeFd(pipe.receiveFd);
-
- EXPECT_EQ(1, result)
- << "removeFd should return 1 first time because FD was registered";
-
- // Second time.
- result = mLooper->removeFd(pipe.receiveFd);
-
- EXPECT_EQ(0, result)
- << "removeFd should return 0 second time because FD was no longer registered";
-}
-
-TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
- Pipe pipe;
- StubCallbackHandler handler1(true);
- StubCallbackHandler handler2(true);
-
- handler1.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
- handler2.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); // replace it
- pipe.writeSignal(); // would cause FD to be considered signalled
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- ASSERT_EQ(OK, pipe.readSignal())
- << "signal should actually have been written";
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because FD was already signalled";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
- EXPECT_EQ(0, handler1.callbackCount)
- << "original handler callback should not be invoked because it was replaced";
- EXPECT_EQ(1, handler2.callbackCount)
- << "replacement handler callback should be invoked";
-}
-
-TEST_F(LooperTest, SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessage(handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll) {
- sp<StubMessageHandler> handler1 = new StubMessageHandler();
- sp<StubMessageHandler> handler2 = new StubMessageHandler();
- mLooper->sendMessage(handler1, Message(MSG_TEST1));
- mLooper->sendMessage(handler2, Message(MSG_TEST2));
- mLooper->sendMessage(handler1, Message(MSG_TEST3));
- mLooper->sendMessage(handler1, Message(MSG_TEST4));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(3), handler1->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler1->messages[0].what)
- << "handled message";
- EXPECT_EQ(MSG_TEST3, handler1->messages[1].what)
- << "handled message";
- EXPECT_EQ(MSG_TEST4, handler1->messages[2].what)
- << "handled message";
- EXPECT_EQ(size_t(1), handler2->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST2, handler2->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageDelayed(ms2ns(100), handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "first poll should end quickly because next message timeout was computed";
- EXPECT_EQ(ALOOPER_POLL_WAKE, result)
- << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup";
- EXPECT_EQ(size_t(0), handler->messages.size())
- << "no message handled yet";
-
- result = mLooper->pollOnce(1000);
- elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "second poll should end around the time of the delayed message dispatch";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
-
- result = mLooper->pollOnce(100);
- elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "third poll should timeout";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left";
-}
-
-TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageDelayed(ms2ns(-1000), handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageDelayed(0, handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageAtTime(now + ms2ns(100), handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(1000);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "first poll should end quickly because next message timeout was computed";
- EXPECT_EQ(ALOOPER_POLL_WAKE, result)
- << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup";
- EXPECT_EQ(size_t(0), handler->messages.size())
- << "no message handled yet";
-
- result = mLooper->pollOnce(1000);
- elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
- EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "second poll should end around the time of the delayed message dispatch";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
-
- result = mLooper->pollOnce(100);
- elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
- << "third poll should timeout";
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left";
-}
-
-TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageAtTime(now - ms2ns(1000), handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessageAtTime(now, handler, Message(MSG_TEST1));
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(100);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was already sent";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
- EXPECT_EQ(size_t(1), handler->messages.size())
- << "handled message";
- EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
- << "handled message";
-}
-
-TEST_F(LooperTest, RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessage(handler, Message(MSG_TEST1));
- mLooper->sendMessage(handler, Message(MSG_TEST2));
- mLooper->sendMessage(handler, Message(MSG_TEST3));
- mLooper->removeMessages(handler);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was sent so looper was awoken";
- EXPECT_EQ(ALOOPER_POLL_WAKE, result)
- << "pollOnce result should be ALOOPER_POLL_WAKE because looper was awoken";
- EXPECT_EQ(size_t(0), handler->messages.size())
- << "no messages to handle";
-
- result = mLooper->pollOnce(0);
-
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do";
- EXPECT_EQ(size_t(0), handler->messages.size())
- << "no messages to handle";
-}
-
-TEST_F(LooperTest, RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage) {
- sp<StubMessageHandler> handler = new StubMessageHandler();
- mLooper->sendMessage(handler, Message(MSG_TEST1));
- mLooper->sendMessage(handler, Message(MSG_TEST2));
- mLooper->sendMessage(handler, Message(MSG_TEST3));
- mLooper->sendMessage(handler, Message(MSG_TEST4));
- mLooper->removeMessages(handler, MSG_TEST3);
- mLooper->removeMessages(handler, MSG_TEST1);
-
- StopWatch stopWatch("pollOnce");
- int result = mLooper->pollOnce(0);
- int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
-
- EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
- << "elapsed time should approx. zero because message was sent so looper was awoken";
- EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
- << "pollOnce result should be ALOOPER_POLL_CALLBACK because two messages were sent";
- EXPECT_EQ(size_t(2), handler->messages.size())
- << "no messages to handle";
- EXPECT_EQ(MSG_TEST2, handler->messages[0].what)
- << "handled message";
- EXPECT_EQ(MSG_TEST4, handler->messages[1].what)
- << "handled message";
-
- result = mLooper->pollOnce(0);
-
- EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
- << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do";
- EXPECT_EQ(size_t(2), handler->messages.size())
- << "no more messages to handle";
-}
-
-} // namespace android
diff --git a/libs/utils/tests/String8_test.cpp b/libs/utils/tests/String8_test.cpp
deleted file mode 100644
index c42c68d..0000000
--- a/libs/utils/tests/String8_test.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "String8_test"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-
-class String8Test : public testing::Test {
-protected:
- virtual void SetUp() {
- }
-
- virtual void TearDown() {
- }
-};
-
-TEST_F(String8Test, Cstr) {
- String8 tmp("Hello, world!");
-
- EXPECT_STREQ(tmp.string(), "Hello, world!");
-}
-
-TEST_F(String8Test, OperatorPlus) {
- String8 src1("Hello, ");
-
- // Test adding String8 + const char*
- const char* ccsrc2 = "world!";
- String8 dst1 = src1 + ccsrc2;
- EXPECT_STREQ(dst1.string(), "Hello, world!");
- EXPECT_STREQ(src1.string(), "Hello, ");
- EXPECT_STREQ(ccsrc2, "world!");
-
- // Test adding String8 + String8
- String8 ssrc2("world!");
- String8 dst2 = src1 + ssrc2;
- EXPECT_STREQ(dst2.string(), "Hello, world!");
- EXPECT_STREQ(src1.string(), "Hello, ");
- EXPECT_STREQ(ssrc2.string(), "world!");
-}
-
-TEST_F(String8Test, OperatorPlusEquals) {
- String8 src1("My voice");
-
- // Testing String8 += String8
- String8 src2(" is my passport.");
- src1 += src2;
- EXPECT_STREQ(src1.string(), "My voice is my passport.");
- EXPECT_STREQ(src2.string(), " is my passport.");
-
- // Adding const char* to the previous string.
- const char* src3 = " Verify me.";
- src1 += src3;
- EXPECT_STREQ(src1.string(), "My voice is my passport. Verify me.");
- EXPECT_STREQ(src2.string(), " is my passport.");
- EXPECT_STREQ(src3, " Verify me.");
-}
-
-}
diff --git a/libs/utils/tests/TestHelpers.h b/libs/utils/tests/TestHelpers.h
deleted file mode 100644
index d8e985e..0000000
--- a/libs/utils/tests/TestHelpers.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TESTHELPERS_H
-#define TESTHELPERS_H
-
-#include <utils/threads.h>
-
-namespace android {
-
-class Pipe {
-public:
- int sendFd;
- int receiveFd;
-
- Pipe() {
- int fds[2];
- ::pipe(fds);
-
- receiveFd = fds[0];
- sendFd = fds[1];
- }
-
- ~Pipe() {
- if (sendFd != -1) {
- ::close(sendFd);
- }
-
- if (receiveFd != -1) {
- ::close(receiveFd);
- }
- }
-
- status_t writeSignal() {
- ssize_t nWritten = ::write(sendFd, "*", 1);
- return nWritten == 1 ? 0 : -errno;
- }
-
- status_t readSignal() {
- char buf[1];
- ssize_t nRead = ::read(receiveFd, buf, 1);
- return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
- }
-};
-
-class DelayedTask : public Thread {
- int mDelayMillis;
-
-public:
- DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
-
-protected:
- virtual ~DelayedTask() { }
-
- virtual void doTask() = 0;
-
- virtual bool threadLoop() {
- usleep(mDelayMillis * 1000);
- doTask();
- return false;
- }
-};
-
-} // namespace android
-
-#endif // TESTHELPERS_H
diff --git a/libs/utils/tests/Unicode_test.cpp b/libs/utils/tests/Unicode_test.cpp
deleted file mode 100644
index 18c130c..0000000
--- a/libs/utils/tests/Unicode_test.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Unicode_test"
-#include <utils/Log.h>
-#include <utils/Unicode.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-
-class UnicodeTest : public testing::Test {
-protected:
- virtual void SetUp() {
- }
-
- virtual void TearDown() {
- }
-};
-
-TEST_F(UnicodeTest, UTF8toUTF16ZeroLength) {
- ssize_t measured;
-
- const uint8_t str[] = { };
-
- measured = utf8_to_utf16_length(str, 0);
- EXPECT_EQ(0, measured)
- << "Zero length input should return zero length output.";
-}
-
-TEST_F(UnicodeTest, UTF8toUTF16ASCIILength) {
- ssize_t measured;
-
- // U+0030 or ASCII '0'
- const uint8_t str[] = { 0x30 };
-
- measured = utf8_to_utf16_length(str, sizeof(str));
- EXPECT_EQ(1, measured)
- << "ASCII glyphs should have a length of 1 char16_t";
-}
-
-TEST_F(UnicodeTest, UTF8toUTF16Plane1Length) {
- ssize_t measured;
-
- // U+2323 SMILE
- const uint8_t str[] = { 0xE2, 0x8C, 0xA3 };
-
- measured = utf8_to_utf16_length(str, sizeof(str));
- EXPECT_EQ(1, measured)
- << "Plane 1 glyphs should have a length of 1 char16_t";
-}
-
-TEST_F(UnicodeTest, UTF8toUTF16SurrogateLength) {
- ssize_t measured;
-
- // U+10000
- const uint8_t str[] = { 0xF0, 0x90, 0x80, 0x80 };
-
- measured = utf8_to_utf16_length(str, sizeof(str));
- EXPECT_EQ(2, measured)
- << "Surrogate pairs should have a length of 2 char16_t";
-}
-
-TEST_F(UnicodeTest, UTF8toUTF16TruncatedUTF8) {
- ssize_t measured;
-
- // Truncated U+2323 SMILE
- // U+2323 SMILE
- const uint8_t str[] = { 0xE2, 0x8C };
-
- measured = utf8_to_utf16_length(str, sizeof(str));
- EXPECT_EQ(-1, measured)
- << "Truncated UTF-8 should return -1 to indicate invalid";
-}
-
-TEST_F(UnicodeTest, UTF8toUTF16Normal) {
- const uint8_t str[] = {
- 0x30, // U+0030, 1 UTF-16 character
- 0xC4, 0x80, // U+0100, 1 UTF-16 character
- 0xE2, 0x8C, 0xA3, // U+2323, 1 UTF-16 character
- 0xF0, 0x90, 0x80, 0x80, // U+10000, 2 UTF-16 character
- };
-
- char16_t output[1 + 1 + 1 + 2 + 1]; // Room for NULL
-
- utf8_to_utf16(str, sizeof(str), output);
-
- EXPECT_EQ(0x0030, output[0])
- << "should be U+0030";
- EXPECT_EQ(0x0100, output[1])
- << "should be U+0100";
- EXPECT_EQ(0x2323, output[2])
- << "should be U+2323";
- EXPECT_EQ(0xD800, output[3])
- << "should be first half of surrogate U+10000";
- EXPECT_EQ(0xDC00, output[4])
- << "should be second half of surrogate U+10000";
- EXPECT_EQ(NULL, output[5])
- << "should be NULL terminated";
-}
-
-}