am 455d4100: Merge "Initial checkin of "foundation" library for future stagefright development." into kraken

This commit is contained in:
Andreas Huber
2010-06-07 12:51:16 -07:00
committed by Android Git Automerger
21 changed files with 2036 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
/*
* 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 A_ATOMIZER_H_
#define A_ATOMIZER_H_
#include <stdint.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
#include <utils/List.h>
#include <utils/Vector.h>
#include <utils/threads.h>
namespace android {
struct AAtomizer {
static const char *Atomize(const char *name);
private:
static AAtomizer gAtomizer;
Mutex mLock;
Vector<List<AString> > mAtoms;
AAtomizer();
const char *atomize(const char *name);
static uint32_t Hash(const char *s);
DISALLOW_EVIL_CONSTRUCTORS(AAtomizer);
};
} // namespace android
#endif // A_ATOMIZER_H_

View File

@@ -0,0 +1,25 @@
/*
* 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 A_BASE_H_
#define A_BASE_H_
#define DISALLOW_EVIL_CONSTRUCTORS(name) \
name(const name &); \
name &operator=(const name &)
#endif // A_BASE_H_

View File

@@ -0,0 +1,71 @@
/*
* 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 A_BUFFER_H_
#define A_BUFFER_H_
#include <sys/types.h>
#include <stdint.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/RefBase.h>
namespace android {
struct AMessage;
struct ABuffer : public RefBase {
ABuffer(size_t capacity);
ABuffer(void *data, size_t capacity);
void setFarewellMessage(const sp<AMessage> msg);
uint8_t *base() { return (uint8_t *)mData; }
uint8_t *data() { return (uint8_t *)mData + mRangeOffset; }
size_t capacity() const { return mCapacity; }
size_t size() const { return mRangeLength; }
size_t offset() const { return mRangeOffset; }
void setRange(size_t offset, size_t size);
void setInt32Data(int32_t data) { mInt32Data = data; }
int32_t int32Data() const { return mInt32Data; }
sp<AMessage> meta();
protected:
virtual ~ABuffer();
private:
sp<AMessage> mFarewell;
sp<AMessage> mMeta;
void *mData;
size_t mCapacity;
size_t mRangeOffset;
size_t mRangeLength;
int32_t mInt32Data;
bool mOwnsData;
DISALLOW_EVIL_CONSTRUCTORS(ABuffer);
};
} // namespace android
#endif // A_BUFFER_H_

View File

@@ -0,0 +1,105 @@
/*
* 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 A_DEBUG_H_
#define A_DEBUG_H_
#include <string.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
namespace android {
enum LogType {
VERBOSE,
INFO,
WARNING,
ERROR,
FATAL,
};
struct Logger {
Logger(LogType type);
virtual ~Logger();
template<class T> Logger &operator<<(const T &x) {
mMessage.append(x);
return *this;
}
private:
android::AString mMessage;
LogType mLogType;
DISALLOW_EVIL_CONSTRUCTORS(Logger);
};
const char *LeafName(const char *s);
#undef LOG
#define LOG(type) Logger(type) << LeafName(__FILE__) << ":" << __LINE__ << " "
#define CHECK(condition) \
do { \
if (!(condition)) { \
LOG(FATAL) << "CHECK(" #condition ") failed."; \
} \
} while (false)
#define MAKE_COMPARATOR(suffix,op) \
template<class A, class B> \
AString Compare_##suffix(const A &a, const B &b) { \
AString res; \
if (!(a op b)) { \
res.append(a); \
res.append(" vs. "); \
res.append(b); \
} \
return res; \
}
MAKE_COMPARATOR(EQ,==)
MAKE_COMPARATOR(NE,!=)
MAKE_COMPARATOR(LE,<=)
MAKE_COMPARATOR(GE,>=)
MAKE_COMPARATOR(LT,<)
MAKE_COMPARATOR(GT,>)
#define CHECK_OP(x,y,suffix,op) \
do { \
AString ___res = Compare_##suffix(x, y); \
if (!___res.empty()) { \
LOG(FATAL) << "CHECK_" #suffix "(" #x "," #y ") failed: " \
<< ___res; \
} \
} while (false)
#define CHECK_EQ(x,y) CHECK_OP(x,y,EQ,==)
#define CHECK_NE(x,y) CHECK_OP(x,y,NE,!=)
#define CHECK_LE(x,y) CHECK_OP(x,y,LE,<=)
#define CHECK_LT(x,y) CHECK_OP(x,y,LT,<)
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
#define TRESPASS() LOG(FATAL) << "Should not be here."
} // namespace android
#endif // A_DEBUG_H_

View File

@@ -0,0 +1,54 @@
/*
* 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 A_HANDLER_H_
#define A_HANDLER_H_
#include <media/stagefright/foundation/ALooper.h>
#include <utils/RefBase.h>
namespace android {
struct AMessage;
struct AHandler : public RefBase {
AHandler()
: mID(0) {
}
ALooper::handler_id id() const {
return mID;
}
protected:
virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
private:
friend struct ALooperRoster;
ALooper::handler_id mID;
void setID(ALooper::handler_id id) {
mID = id;
}
DISALLOW_EVIL_CONSTRUCTORS(AHandler);
};
} // namespace android
#endif // A_HANDLER_H_

View File

@@ -0,0 +1,75 @@
/*
* 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 A_LOOPER_H_
#define A_LOOPER_H_
#include <media/stagefright/foundation/ABase.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
namespace android {
struct AHandler;
struct AMessage;
struct ALooper : public RefBase {
typedef int32_t event_id;
typedef int32_t handler_id;
ALooper();
handler_id registerHandler(const sp<AHandler> &handler);
void unregisterHandler(handler_id handlerID);
status_t start(bool runOnCallingThread = false);
status_t stop();
static int64_t GetNowUs();
protected:
virtual ~ALooper();
private:
friend struct ALooperRoster;
struct Event {
int64_t mWhenUs;
sp<AMessage> mMessage;
};
Mutex mLock;
Condition mQueueChangedCondition;
List<Event> mEventQueue;
struct LooperThread;
sp<LooperThread> mThread;
bool mRunningLocally;
void post(const sp<AMessage> &msg, int64_t delayUs);
bool loop();
DISALLOW_EVIL_CONSTRUCTORS(ALooper);
};
} // namespace android
#endif // A_LOOPER_H_

View File

@@ -0,0 +1,52 @@
/*
* 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 A_LOOPER_ROSTER_H_
#define A_LOOPER_ROSTER_H_
#include <media/stagefright/foundation/ALooper.h>
#include <utils/KeyedVector.h>
namespace android {
struct ALooperRoster {
ALooperRoster();
ALooper::handler_id registerHandler(
const sp<ALooper> looper, const sp<AHandler> &handler);
void unregisterHandler(ALooper::handler_id handlerID);
void postMessage(const sp<AMessage> &msg, int64_t delayUs = 0);
void deliverMessage(const sp<AMessage> &msg);
private:
struct HandlerInfo {
sp<ALooper> mLooper;
sp<AHandler> mHandler;
};
Mutex mLock;
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
ALooper::handler_id mNextHandlerID;
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
};
} // namespace android
#endif // A_LOOPER_ROSTER_H_

View File

@@ -0,0 +1,113 @@
/*
* 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 A_MESSAGE_H_
#define A_MESSAGE_H_
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/ALooper.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
namespace android {
struct AString;
struct AMessage : public RefBase {
AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
void setWhat(uint32_t what);
uint32_t what() const;
void setTarget(ALooper::handler_id target);
ALooper::handler_id target() const;
void setInt32(const char *name, int32_t value);
void setInt64(const char *name, int64_t value);
void setSize(const char *name, size_t value);
void setFloat(const char *name, float value);
void setDouble(const char *name, double value);
void setPointer(const char *name, void *value);
void setString(const char *name, const char *s, ssize_t len = -1);
void setObject(const char *name, const sp<RefBase> &obj);
void setMessage(const char *name, const sp<AMessage> &obj);
bool findInt32(const char *name, int32_t *value) const;
bool findInt64(const char *name, int64_t *value) const;
bool findSize(const char *name, size_t *value) const;
bool findFloat(const char *name, float *value) const;
bool findDouble(const char *name, double *value) const;
bool findPointer(const char *name, void **value) const;
bool findString(const char *name, AString *value) const;
bool findObject(const char *name, sp<RefBase> *obj) const;
bool findMessage(const char *name, sp<AMessage> *obj) const;
void post(int64_t delayUs = 0);
sp<AMessage> dup() const;
protected:
virtual ~AMessage();
private:
enum Type {
kTypeInt32,
kTypeInt64,
kTypeSize,
kTypeFloat,
kTypeDouble,
kTypePointer,
kTypeString,
kTypeObject,
kTypeMessage,
};
uint32_t mWhat;
ALooper::handler_id mTarget;
struct Item {
union {
int32_t int32Value;
int64_t int64Value;
size_t sizeValue;
float floatValue;
double doubleValue;
void *ptrValue;
RefBase *refValue;
AString *stringValue;
} u;
const char *mName;
Type mType;
};
enum {
kMaxNumItems = 16
};
Item mItems[kMaxNumItems];
size_t mNumItems;
void clear();
Item *allocateItem(const char *name);
void freeItem(Item *item);
const Item *findItem(const char *name, Type type) const;
DISALLOW_EVIL_CONSTRUCTORS(AMessage);
};
} // namespace android
#endif // A_MESSAGE_H_

View File

@@ -0,0 +1,94 @@
/*
* 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 A_STRING_H_
#define A_STRING_H_
#include <sys/types.h>
namespace android {
struct AString {
AString();
AString(const char *s);
AString(const char *s, size_t size);
AString(const AString &from);
AString(const AString &from, size_t offset, size_t n);
~AString();
AString &operator=(const AString &from);
void setTo(const char *s);
void setTo(const char *s, size_t size);
void setTo(const AString &from, size_t offset, size_t n);
size_t size() const;
const char *c_str() const;
bool empty() const;
void clear();
void trim();
void erase(size_t start, size_t n);
void append(char c) { append(&c, 1); }
void append(const char *s);
void append(const char *s, size_t size);
void append(const AString &from);
void append(const AString &from, size_t offset, size_t n);
void append(int x);
void append(unsigned x);
void append(long x);
void append(unsigned long x);
void append(long long x);
void append(unsigned long long x);
void append(float x);
void append(double x);
void append(void *x);
void insert(const AString &from, size_t insertionPos);
void insert(const char *from, size_t size, size_t insertionPos);
ssize_t find(const char *substring, size_t start = 0) const;
size_t hash() const;
bool operator==(const AString &other) const;
bool operator<(const AString &other) const;
bool operator>(const AString &other) const;
int compare(const AString &other) const;
bool startsWith(const char *prefix) const;
void tolower();
private:
static const char *kEmptyString;
char *mData;
size_t mSize;
size_t mAllocSize;
void makeMutable();
};
AString StringPrintf(const char *format, ...);
} // namespace android
#endif // A_STRING_H_

View File

@@ -0,0 +1,33 @@
/*
* 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 BASE_64_H_
#define BASE_64_H_
#include <utils/RefBase.h>
namespace android {
struct ABuffer;
struct AString;
sp<ABuffer> decodeBase64(const AString &s);
void encodeBase64(const void *data, size_t size, AString *out);
} // namespace android
#endif // BASE_64_H_

View File

@@ -0,0 +1,29 @@
/*
* 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 HEXDUMP_H_
#define HEXDUMP_H_
#include <sys/types.h>
namespace android {
void hexdump(const void *_data, size_t size);
} // namespace android
#endif // HEXDUMP_H_

View File

@@ -0,0 +1,67 @@
/*
* 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 <sys/types.h>
#include "AAtomizer.h"
namespace android {
// static
AAtomizer AAtomizer::gAtomizer;
// static
const char *AAtomizer::Atomize(const char *name) {
return gAtomizer.atomize(name);
}
AAtomizer::AAtomizer() {
for (size_t i = 0; i < 128; ++i) {
mAtoms.push(List<AString>());
}
}
const char *AAtomizer::atomize(const char *name) {
Mutex::Autolock autoLock(mLock);
const size_t n = mAtoms.size();
size_t index = AAtomizer::Hash(name) % n;
List<AString> &entry = mAtoms.editItemAt(index);
List<AString>::iterator it = entry.begin();
while (it != entry.end()) {
if ((*it) == name) {
return (*it).c_str();
}
++it;
}
entry.push_back(AString(name));
return (*--entry.end()).c_str();
}
// static
uint32_t AAtomizer::Hash(const char *s) {
uint32_t sum = 0;
while (*s != '\0') {
sum = (sum * 31) + *s;
++s;
}
return sum;
}
} // namespace android

View File

@@ -0,0 +1,76 @@
/*
* 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 "ABuffer.h"
#include "ADebug.h"
#include "ALooper.h"
#include "AMessage.h"
namespace android {
ABuffer::ABuffer(size_t capacity)
: mData(malloc(capacity)),
mCapacity(capacity),
mRangeOffset(0),
mRangeLength(capacity),
mInt32Data(0),
mOwnsData(true) {
}
ABuffer::ABuffer(void *data, size_t capacity)
: mData(data),
mCapacity(capacity),
mRangeOffset(0),
mRangeLength(capacity),
mInt32Data(0),
mOwnsData(false) {
}
ABuffer::~ABuffer() {
if (mOwnsData) {
if (mData != NULL) {
free(mData);
mData = NULL;
}
}
if (mFarewell != NULL) {
mFarewell->post();
}
}
void ABuffer::setRange(size_t offset, size_t size) {
CHECK_LE(offset, mCapacity);
CHECK_LE(offset + size, mCapacity);
mRangeOffset = offset;
mRangeLength = size;
}
void ABuffer::setFarewellMessage(const sp<AMessage> msg) {
mFarewell = msg;
}
sp<AMessage> ABuffer::meta() {
if (mMeta == NULL) {
mMeta = new AMessage;
}
return mMeta;
}
} // namespace android

View File

@@ -0,0 +1,76 @@
/*
* 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 "ADebug.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef ANDROID
#include <cutils/log.h>
#endif
namespace android {
Logger::Logger(LogType type)
: mLogType(type) {
switch (mLogType) {
case VERBOSE:
mMessage = "V ";
break;
case INFO:
mMessage = "I ";
break;
case WARNING:
mMessage = "W ";
break;
case ERROR:
mMessage = "E ";
break;
case FATAL:
mMessage = "F ";
break;
default:
break;
}
}
Logger::~Logger() {
if (mLogType == VERBOSE) {
return;
}
mMessage.append("\n");
#if defined(ANDROID) && 1
LOG_PRI(ANDROID_LOG_INFO, "ADebug", "%s", mMessage.c_str());
#else
fprintf(stderr, mMessage.c_str());
fflush(stderr);
#endif
if (mLogType == FATAL) {
abort();
}
}
const char *LeafName(const char *s) {
const char *lastSlash = strrchr(s, '/');
return lastSlash != NULL ? lastSlash + 1 : s;
}
} // namespace android

View File

@@ -0,0 +1,196 @@
/*
* 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_NDEBUG 0
#define LOG_TAG "ALooper"
#include <utils/Log.h>
#include <sys/time.h>
#include "ALooper.h"
#include "AHandler.h"
#include "ALooperRoster.h"
#include "AMessage.h"
namespace android {
ALooperRoster gLooperRoster;
struct ALooper::LooperThread : public Thread {
LooperThread(ALooper *looper)
: mLooper(looper) {
}
virtual bool threadLoop() {
return mLooper->loop();
}
protected:
virtual ~LooperThread() {}
private:
ALooper *mLooper;
DISALLOW_EVIL_CONSTRUCTORS(LooperThread);
};
// static
int64_t ALooper::GetNowUs() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec;
}
ALooper::ALooper()
: mRunningLocally(false) {
}
ALooper::~ALooper() {
stop();
}
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
return gLooperRoster.registerHandler(this, handler);
}
void ALooper::unregisterHandler(handler_id handlerID) {
gLooperRoster.unregisterHandler(handlerID);
}
status_t ALooper::start(bool runOnCallingThread) {
if (runOnCallingThread) {
{
Mutex::Autolock autoLock(mLock);
if (mThread != NULL || mRunningLocally) {
return INVALID_OPERATION;
}
mRunningLocally = true;
}
do {
} while (loop());
return OK;
}
Mutex::Autolock autoLock(mLock);
if (mThread != NULL || mRunningLocally) {
return INVALID_OPERATION;
}
mThread = new LooperThread(this);
status_t err = mThread->run("ALooper");
if (err != OK) {
mThread.clear();
}
return err;
}
status_t ALooper::stop() {
sp<LooperThread> thread;
bool runningLocally;
{
Mutex::Autolock autoLock(mLock);
thread = mThread;
runningLocally = mRunningLocally;
mThread.clear();
mRunningLocally = false;
}
if (thread == NULL && !runningLocally) {
return INVALID_OPERATION;
}
if (thread != NULL) {
thread->requestExit();
}
mQueueChangedCondition.signal();
if (!runningLocally) {
thread->requestExitAndWait();
}
return OK;
}
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
Mutex::Autolock autoLock(mLock);
int64_t whenUs;
if (delayUs > 0) {
whenUs = GetNowUs() + delayUs;
} else {
whenUs = GetNowUs();
}
List<Event>::iterator it = mEventQueue.begin();
while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
++it;
}
Event event;
event.mWhenUs = whenUs;
event.mMessage = msg;
if (it == mEventQueue.begin()) {
mQueueChangedCondition.signal();
}
mEventQueue.insert(it, event);
}
bool ALooper::loop() {
Event event;
{
Mutex::Autolock autoLock(mLock);
if (mThread == NULL && !mRunningLocally) {
return false;
}
if (mEventQueue.empty()) {
mQueueChangedCondition.wait(mLock);
return true;
}
int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
int64_t nowUs = GetNowUs();
if (whenUs > nowUs) {
int64_t delayUs = whenUs - nowUs;
mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
return true;
}
event = *mEventQueue.begin();
mEventQueue.erase(mEventQueue.begin());
}
gLooperRoster.deliverMessage(event.mMessage);
return true;
}
} // namespace android

View File

@@ -0,0 +1,100 @@
/*
* 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_NDEBUG 0
#define LOG_TAG "ALooperRoster"
#include <utils/Log.h>
#include "ALooperRoster.h"
#include "ADebug.h"
#include "AHandler.h"
#include "AMessage.h"
namespace android {
ALooperRoster::ALooperRoster()
: mNextHandlerID(1) {
}
ALooper::handler_id ALooperRoster::registerHandler(
const sp<ALooper> looper, const sp<AHandler> &handler) {
Mutex::Autolock autoLock(mLock);
if (handler->id() != 0) {
CHECK(!"A handler must only be registered once.");
return INVALID_OPERATION;
}
HandlerInfo info;
info.mLooper = looper;
info.mHandler = handler;
ALooper::handler_id handlerID = mNextHandlerID++;
mHandlers.add(handlerID, info);
handler->setID(handlerID);
return handlerID;
}
void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
Mutex::Autolock autoLock(mLock);
ssize_t index = mHandlers.indexOfKey(handlerID);
CHECK(index >= 0);
const HandlerInfo &info = mHandlers.valueAt(index);
info.mHandler->setID(0);
mHandlers.removeItemsAt(index);
}
void ALooperRoster::postMessage(
const sp<AMessage> &msg, int64_t delayUs) {
Mutex::Autolock autoLock(mLock);
ssize_t index = mHandlers.indexOfKey(msg->target());
if (index < 0) {
LOG(WARNING) << "failed to post message. Target handler not registered.";
return;
}
const HandlerInfo &info = mHandlers.valueAt(index);
info.mLooper->post(msg, delayUs);
}
void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
sp<AHandler> handler;
{
Mutex::Autolock autoLock(mLock);
ssize_t index = mHandlers.indexOfKey(msg->target());
if (index < 0) {
LOG(WARNING) << "failed to deliver message. Target handler not registered.";
return;
}
const HandlerInfo &info = mHandlers.valueAt(index);
handler = info.mHandler;
}
handler->onMessageReceived(msg);
}
} // namespace android

View File

@@ -0,0 +1,241 @@
/*
* 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 "AMessage.h"
#include "AAtomizer.h"
#include "ADebug.h"
#include "ALooperRoster.h"
#include "AString.h"
namespace android {
AMessage::AMessage(uint32_t what, ALooper::handler_id target)
: mWhat(what),
mTarget(target),
mNumItems(0) {
}
AMessage::~AMessage() {
clear();
}
void AMessage::setWhat(uint32_t what) {
mWhat = what;
}
uint32_t AMessage::what() const {
return mWhat;
}
void AMessage::setTarget(ALooper::handler_id handlerID) {
mTarget = handlerID;
}
ALooper::handler_id AMessage::target() const {
return mTarget;
}
void AMessage::clear() {
for (size_t i = 0; i < mNumItems; ++i) {
Item *item = &mItems[i];
freeItem(item);
}
mNumItems = 0;
}
void AMessage::freeItem(Item *item) {
switch (item->mType) {
case kTypeString:
{
delete item->u.stringValue;
break;
}
case kTypeObject:
case kTypeMessage:
{
if (item->u.refValue != NULL) {
item->u.refValue->decStrong(this);
}
break;
}
default:
break;
}
}
AMessage::Item *AMessage::allocateItem(const char *name) {
name = AAtomizer::Atomize(name);
size_t i = 0;
while (i < mNumItems && mItems[i].mName != name) {
++i;
}
Item *item;
if (i < mNumItems) {
item = &mItems[i];
freeItem(item);
} else {
CHECK(mNumItems < kMaxNumItems);
i = mNumItems++;
item = &mItems[i];
item->mName = name;
}
return item;
}
const AMessage::Item *AMessage::findItem(
const char *name, Type type) const {
name = AAtomizer::Atomize(name);
for (size_t i = 0; i < mNumItems; ++i) {
const Item *item = &mItems[i];
if (item->mName == name) {
return item->mType == type ? item : NULL;
}
}
return NULL;
}
#define BASIC_TYPE(NAME,FIELDNAME,TYPENAME) \
void AMessage::set##NAME(const char *name, TYPENAME value) { \
Item *item = allocateItem(name); \
\
item->mType = kType##NAME; \
item->u.FIELDNAME = value; \
} \
\
bool AMessage::find##NAME(const char *name, TYPENAME *value) const { \
const Item *item = findItem(name, kType##NAME); \
if (item) { \
*value = item->u.FIELDNAME; \
return true; \
} \
return false; \
}
BASIC_TYPE(Int32,int32Value,int32_t)
BASIC_TYPE(Int64,int64Value,int64_t)
BASIC_TYPE(Size,sizeValue,size_t)
BASIC_TYPE(Float,floatValue,float)
BASIC_TYPE(Double,doubleValue,double)
BASIC_TYPE(Pointer,ptrValue,void *)
#undef BASIC_TYPE
void AMessage::setString(
const char *name, const char *s, ssize_t len) {
Item *item = allocateItem(name);
item->mType = kTypeString;
item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
}
void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
Item *item = allocateItem(name);
item->mType = kTypeObject;
if (obj != NULL) { obj->incStrong(this); }
item->u.refValue = obj.get();
}
void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
Item *item = allocateItem(name);
item->mType = kTypeMessage;
if (obj != NULL) { obj->incStrong(this); }
item->u.refValue = obj.get();
}
bool AMessage::findString(const char *name, AString *value) const {
const Item *item = findItem(name, kTypeString);
if (item) {
*value = *item->u.stringValue;
return true;
}
return false;
}
bool AMessage::findObject(const char *name, sp<RefBase> *obj) const {
const Item *item = findItem(name, kTypeObject);
if (item) {
*obj = item->u.refValue;
return true;
}
return false;
}
bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
const Item *item = findItem(name, kTypeMessage);
if (item) {
*obj = static_cast<AMessage *>(item->u.refValue);
return true;
}
return false;
}
void AMessage::post(int64_t delayUs) {
extern ALooperRoster gLooperRoster;
gLooperRoster.postMessage(this, delayUs);
}
sp<AMessage> AMessage::dup() const {
sp<AMessage> msg = new AMessage(mWhat, mTarget);
msg->mNumItems = mNumItems;
for (size_t i = 0; i < mNumItems; ++i) {
const Item *from = &mItems[i];
Item *to = &msg->mItems[i];
to->mName = from->mName;
to->mType = from->mType;
switch (from->mType) {
case kTypeString:
{
to->u.stringValue =
new AString(*from->u.stringValue);
break;
}
case kTypeObject:
case kTypeMessage:
{
to->u.refValue = from->u.refValue;
to->u.refValue->incStrong(msg.get());
break;
}
default:
{
to->u = from->u;
break;
}
}
}
return msg;
}
} // namespace android

View File

@@ -0,0 +1,331 @@
/*
* 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 <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ADebug.h"
#include "AString.h"
namespace android {
// static
const char *AString::kEmptyString = "";
AString::AString()
: mData((char *)kEmptyString),
mSize(0),
mAllocSize(1) {
}
AString::AString(const char *s)
: mData(NULL),
mSize(0),
mAllocSize(1) {
setTo(s);
}
AString::AString(const char *s, size_t size)
: mData(NULL),
mSize(0),
mAllocSize(1) {
setTo(s, size);
}
AString::AString(const AString &from)
: mData(NULL),
mSize(0),
mAllocSize(1) {
setTo(from, 0, from.size());
}
AString::AString(const AString &from, size_t offset, size_t n)
: mData(NULL),
mSize(0),
mAllocSize(1) {
setTo(from, offset, n);
}
AString::~AString() {
clear();
}
AString &AString::operator=(const AString &from) {
if (&from != this) {
setTo(from, 0, from.size());
}
return *this;
}
size_t AString::size() const {
return mSize;
}
const char *AString::c_str() const {
return mData;
}
bool AString::empty() const {
return mSize == 0;
}
void AString::setTo(const char *s) {
setTo(s, strlen(s));
}
void AString::setTo(const char *s, size_t size) {
clear();
append(s, size);
}
void AString::setTo(const AString &from, size_t offset, size_t n) {
CHECK(&from != this);
clear();
setTo(from.mData + offset, n);
}
void AString::clear() {
if (mData && mData != kEmptyString) {
free(mData);
mData = NULL;
}
mData = (char *)kEmptyString;
mSize = 0;
mAllocSize = 1;
}
size_t AString::hash() const {
size_t x = 0;
for (size_t i = 0; i < mSize; ++i) {
x = (x * 31) + mData[i];
}
return x;
}
bool AString::operator==(const AString &other) const {
return mSize == other.mSize && !memcmp(mData, other.mData, mSize);
}
void AString::trim() {
makeMutable();
size_t i = 0;
while (i < mSize && isspace(mData[i])) {
++i;
}
size_t j = mSize;
while (j > i && isspace(mData[j - 1])) {
--j;
}
memmove(mData, &mData[i], j - i);
mSize = j - i;
mData[mSize] = '\0';
}
void AString::erase(size_t start, size_t n) {
CHECK_LT(start, mSize);
CHECK_LE(start + n, mSize);
makeMutable();
memmove(&mData[start], &mData[start + n], mSize - start - n);
mSize -= n;
mData[mSize] = '\0';
}
void AString::makeMutable() {
if (mData == kEmptyString) {
mData = strdup(kEmptyString);
}
}
void AString::append(const char *s) {
append(s, strlen(s));
}
void AString::append(const char *s, size_t size) {
makeMutable();
if (mSize + size + 1 > mAllocSize) {
mAllocSize = (mAllocSize + size + 31) & -32;
mData = (char *)realloc(mData, mAllocSize);
CHECK(mData != NULL);
}
memcpy(&mData[mSize], s, size);
mSize += size;
mData[mSize] = '\0';
}
void AString::append(const AString &from) {
append(from.c_str(), from.size());
}
void AString::append(const AString &from, size_t offset, size_t n) {
append(from.c_str() + offset, n);
}
void AString::append(int x) {
char s[16];
sprintf(s, "%d", x);
append(s);
}
void AString::append(unsigned x) {
char s[16];
sprintf(s, "%u", x);
append(s);
}
void AString::append(long x) {
char s[16];
sprintf(s, "%ld", x);
append(s);
}
void AString::append(unsigned long x) {
char s[16];
sprintf(s, "%lu", x);
append(s);
}
void AString::append(long long x) {
char s[32];
sprintf(s, "%lld", x);
append(s);
}
void AString::append(unsigned long long x) {
char s[32];
sprintf(s, "%llu", x);
append(s);
}
void AString::append(float x) {
char s[16];
sprintf(s, "%f", x);
append(s);
}
void AString::append(double x) {
char s[16];
sprintf(s, "%f", x);
append(s);
}
void AString::append(void *x) {
char s[16];
sprintf(s, "%p", x);
append(s);
}
ssize_t AString::find(const char *substring, size_t start) const {
CHECK_LE(start, size());
const char *match = strstr(mData + start, substring);
if (match == NULL) {
return -1;
}
return match - mData;
}
void AString::insert(const AString &from, size_t insertionPos) {
insert(from.c_str(), from.size(), insertionPos);
}
void AString::insert(const char *from, size_t size, size_t insertionPos) {
CHECK_GE(insertionPos, 0u);
CHECK_LE(insertionPos, mSize);
makeMutable();
if (mSize + size + 1 > mAllocSize) {
mAllocSize = (mAllocSize + size + 31) & -32;
mData = (char *)realloc(mData, mAllocSize);
CHECK(mData != NULL);
}
memmove(&mData[insertionPos + size],
&mData[insertionPos], mSize - insertionPos + 1);
memcpy(&mData[insertionPos], from, size);
mSize += size;
}
bool AString::operator<(const AString &other) const {
return compare(other) < 0;
}
bool AString::operator>(const AString &other) const {
return compare(other) > 0;
}
int AString::compare(const AString &other) const {
return strcmp(mData, other.mData);
}
void AString::tolower() {
makeMutable();
for (size_t i = 0; i < mSize; ++i) {
mData[i] = ::tolower(mData[i]);
}
}
bool AString::startsWith(const char *prefix) const {
return !strncmp(mData, prefix, strlen(prefix));
}
AString StringPrintf(const char *format, ...) {
va_list ap;
va_start(ap, format);
char *buffer;
vasprintf(&buffer, format, ap);
va_end(ap);
AString result(buffer);
free(buffer);
buffer = NULL;
return result;
}
} // namespace android

View File

@@ -0,0 +1,35 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
AAtomizer.cpp \
ABuffer.cpp \
ADebug.cpp \
ALooper.cpp \
ALooperRoster.cpp \
AMessage.cpp \
AString.cpp \
base64.cpp \
hexdump.cpp
LOCAL_C_INCLUDES:= \
frameworks/base/include/media/stagefright/foundation
LOCAL_SHARED_LIBRARIES := \
libbinder \
libmedia \
libutils \
libcutils \
libui \
libsonivox \
libvorbisidec \
libsurfaceflinger_client \
libcamera_client
LOCAL_CFLAGS += -Wno-multichar
LOCAL_MODULE:= libstagefright_foundation
LOCAL_PRELINK_MODULE:= false
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,139 @@
/*
* 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 "base64.h"
#include "ABuffer.h"
#include "ADebug.h"
namespace android {
sp<ABuffer> decodeBase64(const AString &s) {
if ((s.size() % 4) != 0) {
return NULL;
}
size_t n = s.size();
size_t padding = 0;
if (n >= 1 && s.c_str()[n - 1] == '=') {
padding = 1;
if (n >= 2 && s.c_str()[n - 2] == '=') {
padding = 2;
}
}
size_t outLen = 3 * s.size() / 4 - padding;
sp<ABuffer> buffer = new ABuffer(outLen);
uint8_t *out = buffer->data();
size_t j = 0;
uint32_t accum = 0;
for (size_t i = 0; i < n; ++i) {
char c = s.c_str()[i];
unsigned value;
if (c >= 'A' && c <= 'Z') {
value = c - 'A';
} else if (c >= 'a' && c <= 'z') {
value = 26 + c - 'a';
} else if (c >= '0' && c <= '9') {
value = 52 + c - '0';
} else if (c == '+') {
value = 62;
} else if (c == '/') {
value = 63;
} else if (c != '=') {
return NULL;
} else {
if (i < n - padding) {
return NULL;
}
value = 0;
}
accum = (accum << 6) | value;
if (((i + 1) % 4) == 0) {
out[j++] = (accum >> 16);
if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
if (j < outLen) { out[j++] = accum & 0xff; }
accum = 0;
}
}
return buffer;
}
static char encode6Bit(unsigned x) {
if (x <= 25) {
return 'A' + x;
} else if (x <= 51) {
return 'a' + x - 26;
} else if (x <= 61) {
return '0' + x - 52;
} else if (x == 62) {
return '+';
} else {
return '/';
}
}
void encodeBase64(
const void *_data, size_t size, AString *out) {
out->clear();
const uint8_t *data = (const uint8_t *)_data;
size_t i;
for (i = 0; i < (size / 3) * 3; i += 3) {
uint8_t x1 = data[i];
uint8_t x2 = data[i + 1];
uint8_t x3 = data[i + 2];
out->append(encode6Bit(x1 >> 2));
out->append(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
out->append(encode6Bit((x2 << 2 | x3 >> 6) & 0x3f));
out->append(encode6Bit(x3 & 0x3f));
}
switch (size % 3) {
case 0:
break;
case 2:
{
uint8_t x1 = data[i];
uint8_t x2 = data[i + 1];
out->append(encode6Bit(x1 >> 2));
out->append(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
out->append(encode6Bit((x2 << 2) & 0x3f));
out->append('=');
break;
}
default:
{
uint8_t x1 = data[i];
out->append(encode6Bit(x1 >> 2));
out->append(encode6Bit((x1 << 4) & 0x3f));
out->append("==");
break;
}
}
}
} // namespace android

View File

@@ -0,0 +1,73 @@
/*
* 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 "hexdump.h"
#include "ADebug.h"
#include "AString.h"
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
namespace android {
void hexdump(const void *_data, size_t size) {
const uint8_t *data = (const uint8_t *)_data;
size_t offset = 0;
while (offset < size) {
AString line;
char tmp[32];
sprintf(tmp, "%08lx: ", (unsigned long)offset);
line.append(tmp);
for (size_t i = 0; i < 16; ++i) {
if (i == 8) {
line.append(' ');
}
if (offset + i >= size) {
line.append(" ");
} else {
sprintf(tmp, "%02x ", data[offset + i]);
line.append(tmp);
}
}
line.append(' ');
for (size_t i = 0; i < 16; ++i) {
if (offset + i >= size) {
break;
}
if (isprint(data[offset + i])) {
line.append((char)data[offset + i]);
} else {
line.append('.');
}
}
LOG(INFO) << line;
offset += 16;
}
}
} // namespace android