diff options
author | 2009-05-27 14:34:50 -0700 | |
---|---|---|
committer | 2009-05-27 14:34:50 -0700 | |
commit | 723ec00af46d1f95d69fe5af53e0a5d09f01a7d6 (patch) | |
tree | ef596c117b8f11f8025770c52baeac04b2e4551a | |
parent | 310f8da0c3122ed5419db8f12a6e98d3188325b2 (diff) | |
parent | 39afd5f7daaa525adaf38caf4a48d2cb22e0a41d (diff) |
Merge commit 'goog/master' into merge_master
Conflicts:
include/ui/Rect.h
libs/ui/ISurfaceComposer.cpp
45 files changed, 961 insertions, 220 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 404512e129..453dc29369 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -1052,12 +1052,6 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) } -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t CameraService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h index d09cec8dda..090ca6de64 100644 --- a/cmds/runtime/ServiceManager.h +++ b/cmds/runtime/ServiceManager.h @@ -4,7 +4,7 @@ #ifndef ANDROID_SERVICE_MANAGER_H #define ANDROID_SERVICE_MANAGER_H -#include <utils/IServiceManager.h> +#include <binder/IServiceManager.h> #include <utils/KeyedVector.h> #include <utils/threads.h> diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp index 718ea67e01..6ae3a5c0a9 100644 --- a/cmds/runtime/main_runtime.cpp +++ b/cmds/runtime/main_runtime.cpp @@ -45,9 +45,9 @@ static const char* ZYGOTE_ARGV[] = { "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003", /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST & * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE & CAP_KILL & - * CAP_SYS_BOOT + * CAP_SYS_BOOT CAP_SYS_NICE */ - "--capabilities=88161312,88161312", + "--capabilities=96549920,96549920", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer" diff --git a/include/binder/Binder.h b/include/binder/Binder.h index c9b71fd486..47b2bb9b2c 100644 --- a/include/binder/Binder.h +++ b/include/binder/Binder.h @@ -27,7 +27,7 @@ class BBinder : public IBinder public: BBinder(); - virtual String16 getInterfaceDescriptor() const; + virtual const String16& getInterfaceDescriptor() const; virtual bool isBinderAlive() const; virtual status_t pingBinder(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -71,6 +71,7 @@ private: Extras* mExtras; void* mReserved0; + static String16 sEmptyDescriptor; }; // --------------------------------------------------------------------------- diff --git a/include/binder/BpBinder.h b/include/binder/BpBinder.h index 067637eaea..7ef93aa390 100644 --- a/include/binder/BpBinder.h +++ b/include/binder/BpBinder.h @@ -31,7 +31,7 @@ public: inline int32_t handle() const { return mHandle; } - virtual String16 getInterfaceDescriptor() const; + virtual const String16& getInterfaceDescriptor() const; virtual bool isBinderAlive() const; virtual status_t pingBinder(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -106,6 +106,7 @@ private: }; void reportOneDeath(const Obituary& obit); + bool isDescriptorCached() const; mutable Mutex mLock; volatile int32_t mAlive; @@ -113,6 +114,7 @@ private: Vector<Obituary>* mObituaries; ObjectManager mObjects; Parcel* mConstantData; + mutable String16 mDescriptorCache; }; }; // namespace android diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h index 737033090f..884b5c1237 100644 --- a/include/binder/IBinder.h +++ b/include/binder/IBinder.h @@ -56,7 +56,7 @@ public: FLAG_ONEWAY = 0x00000001 }; - inline IBinder() { } + IBinder(); /** * Check if this IBinder implements the interface named by @@ -69,7 +69,7 @@ public: * Return the canonical name of the interface provided by this IBinder * object. */ - virtual String16 getInterfaceDescriptor() const = 0; + virtual const String16& getInterfaceDescriptor() const = 0; virtual bool isBinderAlive() const = 0; virtual status_t pingBinder() = 0; @@ -147,7 +147,7 @@ public: virtual BpBinder* remoteBinder(); protected: - inline virtual ~IBinder() { } + virtual ~IBinder(); private: }; diff --git a/include/binder/IInterface.h b/include/binder/IInterface.h index 3b1e33bda1..273d92231f 100644 --- a/include/binder/IInterface.h +++ b/include/binder/IInterface.h @@ -27,10 +27,12 @@ namespace android { class IInterface : public virtual RefBase { public: + IInterface(); sp<IBinder> asBinder(); sp<const IBinder> asBinder() const; - + protected: + virtual ~IInterface(); virtual IBinder* onAsBinder() = 0; }; @@ -49,7 +51,7 @@ class BnInterface : public INTERFACE, public BBinder { public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); - virtual String16 getInterfaceDescriptor() const; + virtual const String16& getInterfaceDescriptor() const; protected: virtual IBinder* onAsBinder(); @@ -72,11 +74,14 @@ protected: #define DECLARE_META_INTERFACE(INTERFACE) \ static const String16 descriptor; \ static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \ - virtual String16 getInterfaceDescriptor() const; \ + virtual const String16& getInterfaceDescriptor() const; \ + I##INTERFACE(); \ + virtual ~I##INTERFACE(); \ + #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const String16 I##INTERFACE::descriptor(NAME); \ - String16 I##INTERFACE::getInterfaceDescriptor() const { \ + const String16& I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ @@ -92,9 +97,16 @@ protected: } \ return intr; \ } \ + I##INTERFACE::I##INTERFACE() { } \ + I##INTERFACE::~I##INTERFACE() { } \ + + +#define CHECK_INTERFACE(interface, data, reply) \ + if (!data.checkInterface(this)) { return PERMISSION_DENIED; } \ + // ---------------------------------------------------------------------- -// No user-servicable parts after this... +// No user-serviceable parts after this... template<typename INTERFACE> inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( @@ -105,7 +117,7 @@ inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( } template<typename INTERFACE> -inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const +inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const { return INTERFACE::getInterfaceDescriptor(); } diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h index 182792cf06..ae042cba55 100644 --- a/include/binder/IMemory.h +++ b/include/binder/IMemory.h @@ -59,6 +59,10 @@ public: const Parcel& data, Parcel* reply, uint32_t flags = 0); + + BnMemoryHeap(); +protected: + virtual ~BnMemoryHeap(); }; // ---------------------------------------------------------------------------- @@ -85,6 +89,10 @@ public: const Parcel& data, Parcel* reply, uint32_t flags = 0); + + BnMemory(); +protected: + virtual ~BnMemory(); }; // ---------------------------------------------------------------------------- diff --git a/include/binder/MemoryDealer.h b/include/binder/MemoryDealer.h index 2080ea64d1..6628f751b6 100644 --- a/include/binder/MemoryDealer.h +++ b/include/binder/MemoryDealer.h @@ -39,6 +39,10 @@ class HeapInterface : public virtual BnMemoryHeap public: // all values must be page-aligned virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0; + + HeapInterface(); +protected: + virtual ~HeapInterface(); }; // ---------------------------------------------------------------------------- @@ -61,6 +65,10 @@ public: virtual void dump(const char* what, uint32_t flags = 0) const = 0; virtual void dump(String8& res, const char* what, uint32_t flags = 0) const = 0; + + AllocatorInterface(); +protected: + virtual ~AllocatorInterface(); }; // ---------------------------------------------------------------------------- @@ -71,6 +79,7 @@ public: class SharedHeap : public HeapInterface, public MemoryHeapBase { public: + SharedHeap(); SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL); virtual ~SharedHeap(); virtual sp<IMemory> mapMemory(size_t offset, size_t size); diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index af1490a029..58c2d9ad76 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -57,7 +57,8 @@ public: status_t writeInterfaceToken(const String16& interface); bool enforceInterface(const String16& interface) const; - + bool checkInterface(IBinder*) const; + void freeData(); const size_t* objects() const; @@ -147,7 +148,7 @@ public: release_func relFunc, void* relCookie); void print(TextOutput& to, uint32_t flags = 0) const; - + private: Parcel(const Parcel& o); Parcel& operator=(const Parcel& o); diff --git a/include/ui/Point.h b/include/ui/Point.h index dbbad1ecc2..1653120a6d 100644 --- a/include/ui/Point.h +++ b/include/ui/Point.h @@ -31,12 +31,9 @@ public: // because we want the compiler generated versions // Default constructor doesn't initialize the Point - inline Point() - { + inline Point() { } - - inline Point(int _x, int _y) : x(_x), y(_y) - { + inline Point(int x, int y) : x(x), y(y) { } inline bool operator == (const Point& rhs) const { @@ -57,8 +54,8 @@ public: } inline Point& operator - () { - x=-x; - y=-y; + x = -x; + y = -y; return *this; } @@ -73,11 +70,13 @@ public: return *this; } - Point operator + (const Point& rhs) const { - return Point(x+rhs.x, y+rhs.y); + const Point operator + (const Point& rhs) const { + const Point result(x+rhs.x, y+rhs.y); + return result; } - Point operator - (const Point& rhs) const { - return Point(x-rhs.x, y-rhs.y); + const Point operator - (const Point& rhs) const { + const Point result(x-rhs.x, y-rhs.y); + return result; } }; diff --git a/include/ui/Rect.h b/include/ui/Rect.h index 902324d511..da72944762 100644 --- a/include/ui/Rect.h +++ b/include/ui/Rect.h @@ -30,36 +30,23 @@ public: int right; int bottom; - typedef int value_type; - // we don't provide copy-ctor and operator= on purpose // because we want the compiler generated versions - inline Rect() - { + inline Rect() { } - inline Rect(int w, int h) - : left(0), top(0), right(w), bottom(h) - { + : left(0), top(0), right(w), bottom(h) { } - inline Rect(int l, int t, int r, int b) - : left(l), top(t), right(r), bottom(b) - { + : left(l), top(t), right(r), bottom(b) { } - inline Rect(const Point& lt, const Point& rb) - : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) - { + : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) { } void makeInvalid(); - inline void clear() { - left = top = right = bottom = 0; - } - // a valid rectangle has a non negative width and height inline bool isValid() const { return (width()>=0) && (height()>=0); @@ -84,29 +71,29 @@ public: return bottom-top; } + void setLeftTop(const Point& lt) { + left = lt.x; + top = lt.y; + } + + void setRightBottom(const Point& rb) { + right = rb.x; + bottom = rb.y; + } + // the following 4 functions return the 4 corners of the rect as Point - inline Point leftTop() const { + Point leftTop() const { return Point(left, top); } - inline Point rightBottom() const { + Point rightBottom() const { return Point(right, bottom); } - inline Point rightTop() const { + Point rightTop() const { return Point(right, top); } - inline Point leftBottom() const { + Point leftBottom() const { return Point(left, bottom); } - - inline void setLeftTop(const Point& p) { - left = p.x; - top = p.y; - } - - inline void setRightBottom(const Point& p) { - right = p.x; - bottom = p.y; - } // comparisons inline bool operator == (const Rect& rhs) const { @@ -140,8 +127,8 @@ public: Rect& operator -= (const Point& rhs) { return offsetBy(-rhs.x, -rhs.y); } - Rect operator + (const Point& rhs) const; - Rect operator - (const Point& rhs) const; + const Rect operator + (const Point& rhs) const; + const Rect operator - (const Point& rhs) const; void translate(int dx, int dy) { // legacy, don't use. offsetBy(dx, dy); diff --git a/include/utils/TextOutput.h b/include/utils/TextOutput.h index d8d86ba82c..de2fbbee1f 100644 --- a/include/utils/TextOutput.h +++ b/include/utils/TextOutput.h @@ -28,8 +28,8 @@ namespace android { class TextOutput { public: - TextOutput() { } - virtual ~TextOutput() { } + TextOutput(); + virtual ~TextOutput(); virtual status_t print(const char* txt, size_t len) = 0; virtual void moveIndent(int delta) = 0; diff --git a/include/utils/Timers.h b/include/utils/Timers.h index 96103995bb..577325f5c4 100644 --- a/include/utils/Timers.h +++ b/include/utils/Timers.h @@ -108,15 +108,15 @@ namespace android { */ class DurationTimer { public: - DurationTimer(void) {} - ~DurationTimer(void) {} + DurationTimer() {} + ~DurationTimer() {} // Start the timer. - void start(void); + void start(); // Stop the timer. - void stop(void); + void stop(); // Get the duration in microseconds. - long long durationUsecs(void) const; + long long durationUsecs() const; // Subtract two timevals. Returns the difference (ptv1-ptv2) in // microseconds. diff --git a/include/utils/threads.h b/include/utils/threads.h index b3209156bc..e0cb664233 100644 --- a/include/utils/threads.h +++ b/include/utils/threads.h @@ -199,11 +199,11 @@ public: // constructed and released when Autolock goes out of scope. class Autolock { public: - inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); } - inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); } - inline ~Autolock() { mpMutex->unlock(); } + inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } + inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } + inline ~Autolock() { mLock.unlock(); } private: - Mutex* mpMutex; + Mutex& mLock; }; private: @@ -291,7 +291,7 @@ protected: bool exitPending() const; private: - // Derived class must implemtent threadLoop(). The thread starts its life + // Derived class must implement threadLoop(). The thread starts its life // here. There are two ways of using the Thread object: // 1) loop: if threadLoop() returns true, it will be called again if // requestExit() wasn't called. diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index 4b4fa5e295..49b01293fe 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -1560,7 +1560,6 @@ size_t AudioFlinger::MixerThread::getOutputFrameCount() AudioFlinger::MixerThread::TrackBase::TrackBase( const sp<MixerThread>& mixerThread, const sp<Client>& client, - int streamType, uint32_t sampleRate, int format, int channelCount, @@ -1570,7 +1569,6 @@ AudioFlinger::MixerThread::TrackBase::TrackBase( : RefBase(), mMixerThread(mixerThread), mClient(client), - mStreamType(streamType), mFrameCount(0), mState(IDLE), mClientTid(-1), @@ -1720,12 +1718,13 @@ AudioFlinger::MixerThread::Track::Track( int channelCount, int frameCount, const sp<IMemory>& sharedBuffer) - : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer) + : TrackBase(mixerThread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer) { mVolume[0] = 1.0f; mVolume[1] = 1.0f; mMute = false; mSharedBuffer = sharedBuffer; + mStreamType = streamType; } AudioFlinger::MixerThread::Track::~Track() @@ -1909,15 +1908,15 @@ void AudioFlinger::MixerThread::Track::setVolume(float left, float right) AudioFlinger::MixerThread::RecordTrack::RecordTrack( const sp<MixerThread>& mixerThread, const sp<Client>& client, - int streamType, + int inputSource, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags) - : TrackBase(mixerThread, client, streamType, sampleRate, format, + : TrackBase(mixerThread, client, sampleRate, format, channelCount, frameCount, flags, 0), - mOverflow(false) + mOverflow(false), mInputSource(inputSource) { } @@ -2242,7 +2241,7 @@ status_t AudioFlinger::TrackHandle::onTransact( sp<IAudioRecord> AudioFlinger::openRecord( pid_t pid, - int streamType, + int inputSource, uint32_t sampleRate, int format, int channelCount, @@ -2265,7 +2264,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( goto Exit; } - if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) { + if (uint32_t(inputSource) >= AudioRecord::NUM_INPUT_SOURCES) { LOGE("invalid stream type"); lStatus = BAD_VALUE; goto Exit; @@ -2308,7 +2307,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount; // create new record track. The record track uses one track in mHardwareMixerThread by convention. - recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate, + recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, inputSource, sampleRate, format, channelCount, frameCount, flags); } if (recordTrack->getCblk() == NULL) { @@ -2415,7 +2414,7 @@ bool AudioFlinger::AudioRecordThread::threadLoop() LOGV("AudioRecordThread: loop starting"); if (mRecordTrack != 0) { input = mAudioHardware->openInputStream( - mRecordTrack->type(), + mRecordTrack->inputSource(), mRecordTrack->format(), mRecordTrack->channelCount(), mRecordTrack->sampleRate(), diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h index f3e6dc1eda..cc3d6c24ba 100644 --- a/libs/audioflinger/AudioFlinger.h +++ b/libs/audioflinger/AudioFlinger.h @@ -139,7 +139,7 @@ public: // record interface virtual sp<IAudioRecord> openRecord( pid_t pid, - int streamType, + int inputSource, uint32_t sampleRate, int format, int channelCount, @@ -232,7 +232,6 @@ private: TrackBase(const sp<MixerThread>& mixerThread, const sp<Client>& client, - int streamType, uint32_t sampleRate, int format, int channelCount, @@ -260,10 +259,6 @@ private: return mCblk; } - int type() const { - return mStreamType; - } - int format() const { return mFormat; } @@ -293,7 +288,6 @@ private: sp<Client> mClient; sp<IMemory> mCblkMemory; audio_track_cblk_t* mCblk; - int mStreamType; void* mBuffer; void* mBufferEnd; uint32_t mFrameCount; @@ -328,6 +322,11 @@ private: void mute(bool); void setVolume(float left, float right); + int type() const { + return mStreamType; + } + + protected: friend class MixerThread; friend class AudioFlinger; @@ -364,6 +363,7 @@ private: int8_t mRetryCount; sp<IMemory> mSharedBuffer; bool mResetDone; + int mStreamType; }; // end of Track // record track @@ -371,7 +371,7 @@ private: public: RecordTrack(const sp<MixerThread>& mixerThread, const sp<Client>& client, - int streamType, + int inputSource, uint32_t sampleRate, int format, int channelCount, @@ -385,6 +385,8 @@ private: bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; } bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; } + int inputSource() const { return mInputSource; } + private: friend class AudioFlinger; friend class AudioFlinger::RecordHandle; @@ -397,6 +399,7 @@ private: virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer); bool mOverflow; + int mInputSource; }; // playback track diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp index a97c0bcb9a..1e159b814f 100644 --- a/libs/audioflinger/AudioHardwareGeneric.cpp +++ b/libs/audioflinger/AudioHardwareGeneric.cpp @@ -98,8 +98,8 @@ AudioStreamIn* AudioHardwareGeneric::openInputStream( status_t *status, AudioSystem::audio_in_acoustics acoustics) { // check for valid input source - if ((inputSource != AudioRecord::DEFAULT_INPUT) && - (inputSource != AudioRecord::MIC_INPUT)) { + if ((inputSource < AudioRecord::DEFAULT_INPUT) || + (inputSource >= AudioRecord::NUM_INPUT_SOURCES)) { return 0; } diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp index c61e6e654e..0ab4c60e53 100644 --- a/libs/audioflinger/AudioHardwareStub.cpp +++ b/libs/audioflinger/AudioHardwareStub.cpp @@ -61,8 +61,8 @@ AudioStreamIn* AudioHardwareStub::openInputStream( status_t *status, AudioSystem::audio_in_acoustics acoustics) { // check for valid input source - if ((inputSource != AudioRecord::DEFAULT_INPUT) && - (inputSource != AudioRecord::MIC_INPUT)) { + if ((inputSource < AudioRecord::DEFAULT_INPUT) || + (inputSource >= AudioRecord::NUM_INPUT_SOURCES)) { return 0; } diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index 26f29f8e98..0dd762212f 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -27,6 +27,17 @@ namespace android { // --------------------------------------------------------------------------- +IBinder::IBinder() + : RefBase() +{ +} + +IBinder::~IBinder() +{ +} + +// --------------------------------------------------------------------------- + sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) { return NULL; @@ -58,6 +69,8 @@ public: // --------------------------------------------------------------------------- +String16 BBinder::sEmptyDescriptor; + BBinder::BBinder() : mExtras(NULL) { @@ -73,10 +86,10 @@ status_t BBinder::pingBinder() return NO_ERROR; } -String16 BBinder::getInterfaceDescriptor() const +const String16& BBinder::getInterfaceDescriptor() const { LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this); - return String16(); + return sEmptyDescriptor; } status_t BBinder::transact( diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 56bf413c29..5de87ec769 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -98,16 +98,33 @@ BpBinder::BpBinder(int32_t handle) IPCThreadState::self()->incWeakHandle(handle); } -String16 BpBinder::getInterfaceDescriptor() const +bool BpBinder::isDescriptorCached() const { + Mutex::Autolock _l(mLock); + return mDescriptorCache.size() ? true : false; +} + +const String16& BpBinder::getInterfaceDescriptor() const { - String16 res; - Parcel send, reply; - status_t err = const_cast<BpBinder*>(this)->transact( - INTERFACE_TRANSACTION, send, &reply); - if (err == NO_ERROR) { - res = reply.readString16(); + if (isDescriptorCached() == false) { + Parcel send, reply; + // do the IPC without a lock held. + status_t err = const_cast<BpBinder*>(this)->transact( + INTERFACE_TRANSACTION, send, &reply); + if (err == NO_ERROR) { + String16 res(reply.readString16()); + Mutex::Autolock _l(mLock); + // mDescriptorCache could have been assigned while the lock was + // released. + if (mDescriptorCache.size() == 0) + mDescriptorCache = res; + } } - return res; + + // we're returning a reference to a non-static object here. Usually this + // is not something smart to do, however, with binder objects it is + // (usually) safe because they are reference-counted. + + return mDescriptorCache; } bool BpBinder::isBinderAlive() const diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp index 9f1192f011..29acf5ddd1 100644 --- a/libs/binder/IInterface.cpp +++ b/libs/binder/IInterface.cpp @@ -20,6 +20,13 @@ namespace android { // --------------------------------------------------------------------------- +IInterface::IInterface() + : RefBase() { +} + +IInterface::~IInterface() { +} + sp<IBinder> IInterface::asBinder() { return this ? onAsBinder() : NULL; diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp index 13d67c07de..6c1d2253b6 100644 --- a/libs/binder/IMemory.cpp +++ b/libs/binder/IMemory.cpp @@ -205,11 +205,11 @@ sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory"); -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) +BnMemory::BnMemory() { +} + +BnMemory::~BnMemory() { +} status_t BnMemory::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) @@ -299,11 +299,11 @@ void BpMemoryHeap::assertReallyMapped() const ssize_t size = reply.readInt32(); uint32_t flags = reply.readInt32(); - LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)", + LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)", asBinder().get(), parcel_fd, size, err, strerror(-err)); int fd = dup( parcel_fd ); - LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)", + LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)", parcel_fd, size, err, strerror(errno)); int access = PROT_READ; @@ -316,7 +316,7 @@ void BpMemoryHeap::assertReallyMapped() const mRealHeap = true; mBase = mmap(0, size, access, MAP_SHARED, fd, 0); if (mBase == MAP_FAILED) { - LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)", + LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)", asBinder().get(), size, fd, strerror(errno)); close(fd); } else { @@ -357,8 +357,14 @@ uint32_t BpMemoryHeap::getFlags() const { IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap"); +BnMemoryHeap::BnMemoryHeap() { +} + +BnMemoryHeap::~BnMemoryHeap() { +} + status_t BnMemoryHeap::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case HEAP_ID: { diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp index a61debf3d5..bff4c9bd7d 100644 --- a/libs/binder/IPermissionController.cpp +++ b/libs/binder/IPermissionController.cpp @@ -55,12 +55,6 @@ IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnPermissionController::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 2f265b8595..88774e79b9 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -178,12 +178,6 @@ IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnServiceManager::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp index fd6ab7ae88..d5ffe7f6d3 100644 --- a/libs/binder/MemoryDealer.cpp +++ b/libs/binder/MemoryDealer.cpp @@ -38,7 +38,15 @@ #include <sys/file.h> namespace android { +// ---------------------------------------------------------------------------- +HeapInterface::HeapInterface() { } +HeapInterface::~HeapInterface() { } + +// ---------------------------------------------------------------------------- + +AllocatorInterface::AllocatorInterface() { } +AllocatorInterface::~AllocatorInterface() { } // ---------------------------------------------------------------------------- @@ -107,7 +115,7 @@ sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags) if (new_memory != 0) { memory = new Allocation(this, offset, size, new_memory); } else { - LOGE("couldn't map [%8x, %d]", offset, size); + LOGE("couldn't map [%8lx, %u]", offset, size); if (size) { /* NOTE: it's VERY important to not free allocations of size 0 * because they're special as they don't have any record in the @@ -339,6 +347,10 @@ void SimpleBestFitAllocator::dump_l(String8& result, // ---------------------------------------------------------------------------- +SharedHeap::SharedHeap() + : HeapInterface(), MemoryHeapBase() +{ +} SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name) : MemoryHeapBase(size, flags, name) diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp index 599c9aecd9..3806a42d37 100644 --- a/libs/binder/MemoryHeapPmem.cpp +++ b/libs/binder/MemoryHeapPmem.cpp @@ -108,7 +108,7 @@ void SubRegionMemory::revoke() // promote() it. #if HAVE_ANDROID_OS - if (mSize != NULL) { + if (mSize != 0) { const sp<MemoryHeapPmem>& heap(getHeap()); int our_fd = heap->heapID(); struct pmem_region sub; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 0819c29154..f40e4bdc3e 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -409,12 +409,16 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len) mObjects[idx++] = off; mObjectsSize++; - const flat_binder_object* flat + flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(mData + off); acquire_object(proc, *flat, this); - // take note if the object is a file descriptor 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; } } @@ -437,9 +441,14 @@ status_t Parcel::writeInterfaceToken(const String16& interface) return writeString16(interface); } +bool Parcel::checkInterface(IBinder* binder) const +{ + return enforceInterface(binder->getInterfaceDescriptor()); +} + bool Parcel::enforceInterface(const String16& interface) const { - String16 str = readString16(); + const String16 str(readString16()); if (str == interface) { return true; } else { diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index bf886a4104..38ef8b9b90 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -20,7 +20,6 @@ LOCAL_SRC_FILES:= \ LayerState.cpp \ Overlay.cpp \ PixelFormat.cpp \ - Point.cpp \ Rect.cpp \ Region.cpp \ Surface.cpp \ diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp index cbe8798e74..805c2ca2be 100644 --- a/libs/ui/ICamera.cpp +++ b/libs/ui/ICamera.cpp @@ -221,12 +221,6 @@ IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnCamera::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp index c6cf75c5e9..a88fd48b58 100644 --- a/libs/ui/ICameraClient.cpp +++ b/libs/ui/ICameraClient.cpp @@ -66,12 +66,6 @@ IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnCameraClient::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp index 1adb4aa2cb..84986c65c2 100644 --- a/libs/ui/ICameraService.cpp +++ b/libs/ui/ICameraService.cpp @@ -49,12 +49,6 @@ IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnCameraService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp index a20b36c51f..65e6b4f376 100644 --- a/libs/ui/IOverlay.cpp +++ b/libs/ui/IOverlay.cpp @@ -49,12 +49,6 @@ IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnOverlay::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index fcc0303302..9fbae1ebaf 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -129,12 +129,6 @@ IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnSurface::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp index 869e4281a2..2aa1405b0c 100644 --- a/libs/ui/ISurfaceComposer.cpp +++ b/libs/ui/ISurfaceComposer.cpp @@ -126,60 +126,57 @@ IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags); - if (err == NO_ERROR) - return err; - - CHECK_INTERFACE(ISurfaceComposer, data, reply); - switch(code) { case CREATE_CONNECTION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = createConnection()->asBinder(); reply->writeStrongBinder(b); } break; case OPEN_GLOBAL_TRANSACTION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); openGlobalTransaction(); } break; case CLOSE_GLOBAL_TRANSACTION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); closeGlobalTransaction(); } break; case SET_ORIENTATION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); DisplayID dpy = data.readInt32(); int orientation = data.readInt32(); uint32_t flags = data.readInt32(); reply->writeInt32( setOrientation(dpy, orientation, flags) ); } break; case FREEZE_DISPLAY: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); DisplayID dpy = data.readInt32(); uint32_t flags = data.readInt32(); reply->writeInt32( freezeDisplay(dpy, flags) ); } break; case UNFREEZE_DISPLAY: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); DisplayID dpy = data.readInt32(); uint32_t flags = data.readInt32(); reply->writeInt32( unfreezeDisplay(dpy, flags) ); } break; case BOOT_FINISHED: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); bootFinished(); } break; case SIGNAL: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); signal(); } break; case GET_CBLK: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> b = getCblk()->asBinder(); reply->writeStrongBinder(b); } break; default: - return UNKNOWN_TRANSACTION; + return BBinder::onTransact(code, data, reply, flags); } return NO_ERROR; } diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp index c2f6f8340c..46c12afe89 100644 --- a/libs/ui/ISurfaceFlingerClient.cpp +++ b/libs/ui/ISurfaceFlingerClient.cpp @@ -118,12 +118,6 @@ IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient // ---------------------------------------------------------------------- -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - LOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - status_t BnSurfaceFlingerClient::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/ui/Point.cpp b/libs/ui/Point.cpp deleted file mode 100644 index 438d49fa4f..0000000000 --- a/libs/ui/Point.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Point.cpp - * Android - * - * Created on 11/16/2006. - * Copyright 2005 The Android Open Source Project - * - */ - -#include <ui/Point.h> - diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp index 99e68bb171..66b95762d0 100644 --- a/libs/ui/Rect.cpp +++ b/libs/ui/Rect.cpp @@ -1,21 +1,28 @@ /* - * Rect.cpp - * Android + * Copyright (C) 2009 The Android Open Source Project * - * Created on 10/14/05. - * Copyright 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 <ui/Rect.h> namespace android { -inline int min(int a, int b) { +static inline int min(int a, int b) { return (a<b) ? a : b; } -inline int max(int a, int b) { +static inline int max(int a, int b) { return (a>b) ? a : b; } @@ -64,14 +71,16 @@ Rect& Rect::offsetBy(int x, int y) return *this; } -Rect Rect::operator + (const Point& rhs) const +const Rect Rect::operator + (const Point& rhs) const { - return Rect(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y); + const Rect result(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y); + return result; } -Rect Rect::operator - (const Point& rhs) const +const Rect Rect::operator - (const Point& rhs) const { - return Rect(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y); + 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 diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp index 2fdaa71186..55b6024f63 100644 --- a/libs/utils/CallStack.cpp +++ b/libs/utils/CallStack.cpp @@ -311,7 +311,8 @@ String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const } else { void const* start = 0; name = MapInfo::mapAddressToName(ip, "<unknown>", &start); - snprintf(tmp, 256, "pc %08lx %s", uintptr_t(ip)-uintptr_t(start), name); + snprintf(tmp, 256, "pc %08lx %s", + long(uintptr_t(ip)-uintptr_t(start)), name); res.append(tmp); } res.append("\n"); diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp index cebee99e5b..e04823d2b5 100644 --- a/libs/utils/TextOutput.cpp +++ b/libs/utils/TextOutput.cpp @@ -22,9 +22,17 @@ #include <stdlib.h> #include <string.h> +namespace android { + // --------------------------------------------------------------------------- -namespace android { +TextOutput::TextOutput() { +} + +TextOutput::~TextOutput() { +} + +// --------------------------------------------------------------------------- TextOutput& operator<<(TextOutput& to, bool val) { diff --git a/libs/utils/backup_helper_file.cpp b/libs/utils/backup_helper_file.cpp index 8efb3eb8b7..7ec2ce8653 100644 --- a/libs/utils/backup_helper_file.cpp +++ b/libs/utils/backup_helper_file.cpp @@ -26,6 +26,7 @@ #include <sys/types.h> #include <sys/uio.h> #include <sys/stat.h> +#include <sys/time.h> // for utimes #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -607,14 +608,14 @@ backup_helper_test_four() 0x11, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x33, 0xab, 0xab, 0xab, - + // bytes of padding2 0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde, 0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01, 0x12, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x32, 0xab, 0xab, - + // bytes of padding3 0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde, 0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01, @@ -627,7 +628,7 @@ backup_helper_test_four() if (err != 0) { return err; } - + // read fd = open(filename, O_RDONLY); if (fd == -1) { @@ -665,7 +666,7 @@ backup_helper_test_four() matched = false; } } - + return matched ? 0 : 1; } @@ -746,7 +747,7 @@ backup_helper_test_data_writer() system("rm -r " SCRATCH_DIR); mkdir(SCRATCH_DIR, 0777); mkdir(SCRATCH_DIR "data", 0777); - + fd = creat(filename, 0666); if (fd == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); @@ -863,7 +864,7 @@ backup_helper_test_data_reader() system("rm -r " SCRATCH_DIR); mkdir(SCRATCH_DIR, 0777); mkdir(SCRATCH_DIR "data", 0777); - + fd = creat(filename, 0666); if (fd == -1) { fprintf(stderr, "error creating: %s\n", strerror(errno)); @@ -940,9 +941,23 @@ get_mod_time(const char* filename, struct timeval times[2]) return errno; } times[0].tv_sec = st.st_atime; - times[0].tv_usec = st.st_atime_nsec / 1000; times[1].tv_sec = st.st_mtime; + + // If st_atime is a macro then struct stat64 uses struct timespec + // to store the access and modif time values and typically + // st_*time_nsec is not defined. In glibc, this is controlled by + // __USE_MISC. +#ifdef __USE_MISC +#if !defined(st_atime) || defined(st_atime_nsec) +#error "Check if this __USE_MISC conditional is still needed." +#endif + times[0].tv_usec = st.st_atim.tv_nsec / 1000; + times[1].tv_usec = st.st_mtim.tv_nsec / 1000; +#else + times[0].tv_usec = st.st_atime_nsec / 1000; times[1].tv_usec = st.st_mtime_nsec / 1000; +#endif + return 0; } @@ -987,7 +1002,7 @@ backup_helper_test_files() { BackupDataWriter dataStream(dataStreamFD); - + err = back_up_files(-1, &dataStream, newSnapshotFD, SCRATCH_DIR, files_before, 5); if (err != 0) { return err; @@ -1017,7 +1032,7 @@ backup_helper_test_files() utimes(SCRATCH_DIR "data/e", e_times); write_text_file(SCRATCH_DIR "data/g", "g\ngg\n"); unlink(SCRATCH_DIR "data/f"); - + char const* files_after[] = { "data/a", // added "data/b", // same @@ -1047,7 +1062,7 @@ backup_helper_test_files() { BackupDataWriter dataStream(dataStreamFD); - + err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, SCRATCH_DIR, files_after, 6); if (err != 0) { @@ -1058,7 +1073,7 @@ backup_helper_test_files() close(oldSnapshotFD); close(dataStreamFD); close(newSnapshotFD); - + return 0; } diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c index ba19520339..ab48c69218 100644 --- a/libs/utils/futex_synchro.c +++ b/libs/utils/futex_synchro.c @@ -28,6 +28,7 @@ // This futex glue code is need on desktop linux, but is already part of bionic. #if !defined(HAVE_FUTEX_WRAPPERS) +#include <unistd.h> #include <sys/syscall.h> typedef unsigned int u32; #define asmlinkage diff --git a/tts/java/android/tts/ITts.aidl b/tts/java/android/tts/ITts.aidl new file mode 100755 index 0000000000..1fe4a6a17b --- /dev/null +++ b/tts/java/android/tts/ITts.aidl @@ -0,0 +1,59 @@ +/* + * 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. + */ + +package android.tts; + +import android.tts.ITtsCallback; + +import android.content.Intent; + +/** + * AIDL for the TTS Service + * ITts.java is autogenerated from this. + * + * {@hide} + */ +interface ITts { + void setEngine(in String engineName, in String[] requestedLanguages, in int strictness); + + void setEngineWithIntent(in Intent engineIntent); + + void setSpeechRate(in int speechRate); + + void speak(in String text, in int queueMode, in String[] params); + + boolean isSpeaking(); + + void stop(); + + void addSpeech(in String text, in String packageName, in int resId); + + void addSpeechFile(in String text, in String filename); + + void setLanguage(in String language); + + boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory); + + void playEarcon(in String earcon, in int queueMode, in String[] params); + + void addEarcon(in String earcon, in String packageName, in int resId); + + void addEarconFile(in String earcon, in String filename); + + void registerCallback(ITtsCallback cb); + + void unregisterCallback(ITtsCallback cb); +} diff --git a/tts/java/android/tts/ITtsCallback.aidl b/tts/java/android/tts/ITtsCallback.aidl new file mode 100755 index 0000000000..131401025b --- /dev/null +++ b/tts/java/android/tts/ITtsCallback.aidl @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package android.tts; + +/** + * AIDL for the callback from the TTS Service + * ITtsCallback.java is autogenerated from this. + * + * {@hide} + */ +oneway interface ITtsCallback { + void markReached(String mark); +} diff --git a/tts/java/android/tts/Tts.java b/tts/java/android/tts/Tts.java new file mode 100755 index 0000000000..6c8b36d658 --- /dev/null +++ b/tts/java/android/tts/Tts.java @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * 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. + */ +package android.tts; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +/** + * @hide + * + * Synthesizes speech from text. This abstracts away the complexities of using + * the TTS service such as setting up the IBinder connection and handling + * RemoteExceptions, etc. + * + * The TTS should always be safe the use; if the user does not have the + * necessary TTS apk installed, the behavior is that all calls to the TTS act as + * no-ops. + * + */ +//FIXME #TTS# review + complete javadoc +public class Tts { + + + /** + * Called when the TTS has initialized + * + * The InitListener must implement the onInit function. onInit is passed the + * version number of the TTS library that the user has installed; since this + * is called when the TTS has started, it is a good time to make sure that + * the user's TTS library is up to date. + */ + public interface OnInitListener { + public void onInit(int version); + } + + /** + * Called when the TTS has finished speaking by itself (speaking + * finished without being canceled). + * + */ + public interface OnSpeechCompletedListener { + public void onSpeechCompleted(); + } + + /** + * Connection needed for the TTS + */ + private ServiceConnection serviceConnection; + + private ITts itts = null; + private Context ctx = null; + private OnInitListener cb = null; + private int version = -1; + private boolean started = false; + private final Object startLock = new Object(); + private boolean showInstaller = false; + private ITtsCallback ittscallback; + private OnSpeechCompletedListener speechCompletedCallback = null; + + + /** + * The constructor for the TTS. + * + * @param context + * The context + * @param callback + * The InitListener that should be called when the TTS has + * initialized successfully. + * @param displayInstallMessage + * Boolean indicating whether or not an installation prompt + * should be displayed to users who do not have the TTS library. + * If this is true, a generic alert asking the user to install + * the TTS will be used. If you wish to specify the exact message + * of that prompt, please use TTS(Context context, InitListener + * callback, TTSVersionAlert alert) as the constructor instead. + */ + public Tts(Context context, OnInitListener callback, + boolean displayInstallMessage) { + showInstaller = displayInstallMessage; + ctx = context; + cb = callback; + if (dataFilesCheck()) { + initTts(); + } + } + + /** + * The constructor for the TTS. + * + * @param context + * The context + * @param callback + * The InitListener that should be called when the TTS has + * initialized successfully. + */ + public Tts(Context context, OnInitListener callback) { + // FIXME #TTS# support TtsVersionAlert + // showInstaller = true; + // versionAlert = alert; + ctx = context; + cb = callback; + if (dataFilesCheck()) { + initTts(); + } + } + + + public void setOnSpeechCompletedListener( + final OnSpeechCompletedListener listener) { + speechCompletedCallback = listener; + } + + + private boolean dataFilesCheck() { + // FIXME #TTS# config manager will be in settings + Log.i("TTS_FIXME", "FIXME in Tts: config manager will be in settings"); + // FIXME #TTS# implement checking of the correct installation of + // the data files. + + return true; + } + + + private void initTts() { + started = false; + + // Initialize the TTS, run the callback after the binding is successful + serviceConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName name, IBinder service) { + synchronized(startLock) { + itts = ITts.Stub.asInterface(service); + try { + ittscallback = new ITtsCallback.Stub() { + //@Override + public void markReached(String mark) + throws RemoteException { + if (speechCompletedCallback != null) { + speechCompletedCallback.onSpeechCompleted(); + } + } + }; + itts.registerCallback(ittscallback); + + } catch (RemoteException e) { + initTts(); + return; + } + + started = true; + // The callback can become null if the Android OS decides to + // restart the TTS process as well as whatever is using it. + // In such cases, do nothing - the error handling from the + // speaking calls will kick in and force a proper restart of + // the TTS. + if (cb != null) { + cb.onInit(version); + } + } + } + + public void onServiceDisconnected(ComponentName name) { + synchronized(startLock) { + itts = null; + cb = null; + started = false; + } + } + }; + + Intent intent = new Intent("android.intent.action.USE_TTS"); + intent.addCategory("android.intent.category.TTS"); + // Binding will fail only if the TTS doesn't exist; + // the TTSVersionAlert will give users a chance to install + // the needed TTS. + if (!ctx.bindService(intent, serviceConnection, + Context.BIND_AUTO_CREATE)) { + if (showInstaller) { + // FIXME #TTS# show version alert + } + } + } + + + /** + * Shuts down the TTS. It is good practice to call this in the onDestroy + * method of the Activity that is using the TTS so that the TTS is stopped + * cleanly. + */ + public void shutdown() { + try { + ctx.unbindService(serviceConnection); + } catch (IllegalArgumentException e) { + // Do nothing and fail silently since an error here indicates that + // binding never succeeded in the first place. + } + } + + + /** + * Adds a mapping between a string of text and a sound resource in a + * package. + * + * @see #TTS.speak(String text, int queueMode, String[] params) + * + * @param text + * Example: <b><code>"south_south_east"</code></b><br/> + * + * @param packagename + * Pass the packagename of the application that contains the + * resource. If the resource is in your own application (this is + * the most common case), then put the packagename of your + * application here.<br/> + * Example: <b>"com.google.marvin.compass"</b><br/> + * The packagename can be found in the AndroidManifest.xml of + * your application. + * <p> + * <code><manifest xmlns:android="..." + * package="<b>com.google.marvin.compass</b>"></code> + * </p> + * + * @param resourceId + * Example: <b><code>R.raw.south_south_east</code></b> + */ + public void addSpeech(String text, String packagename, int resourceId) { + synchronized(startLock) { + if (!started) { + return; + } + try { + itts.addSpeech(text, packagename, resourceId); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Adds a mapping between a string of text and a sound file. Using this, it + * is possible to add custom pronounciations for text. + * + * @param text + * The string of text + * @param filename + * The full path to the sound file (for example: + * "/sdcard/mysounds/hello.wav") + */ + public void addSpeech(String text, String filename) { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.addSpeechFile(text, filename); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Speaks the string using the specified queuing strategy and speech + * parameters. Note that the speech parameters are not universally supported + * by all engines and will be treated as a hint. The TTS library will try to + * fulfill these parameters as much as possible, but there is no guarantee + * that the voice used will have the properties specified. + * + * @param text + * The string of text to be spoken. + * @param queueMode + * The queuing strategy to use. Use 0 for no queuing, and 1 for + * queuing. + * @param params + * The array of speech parameters to be used. Currently, only + * params[0] is defined - it is for setting the type of voice if + * the engine allows it. Possible values are "VOICE_MALE", + * "VOICE_FEMALE", and "VOICE_ROBOT". Note that right now only + * the pre-recorded voice has this support - this setting has no + * effect on eSpeak. + */ + public void speak(String text, int queueMode, String[] params) { + synchronized (startLock) { + Log.i("TTS received: ", text); + if (!started) { + return; + } + try { + itts.speak(text, queueMode, params); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Plays the earcon using the specified queueing mode and parameters. + * + * @param earcon + * The earcon that should be played + * @param queueMode + * 0 for no queue (interrupts all previous utterances), 1 for + * queued + * @param params + * An ArrayList of parameters. + */ + public void playEarcon(String earcon, int queueMode, String[] params) { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.playEarcon(earcon, queueMode, params); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Returns whether or not the TTS is busy speaking. + * + * @return Whether or not the TTS is busy speaking. + */ + public boolean isSpeaking() { + synchronized (startLock) { + if (!started) { + return false; + } + try { + return itts.isSpeaking(); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + return false; + } + } + + + /** + * Stops speech from the TTS. + */ + public void stop() { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.stop(); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Returns the version number of the TTS library that the user has + * installed. + * + * @return The version number of the TTS library that the user has + * installed. + */ + public int getVersion() { + return version; + } + + + /** + * Sets the TTS engine to be used. + * + * @param selectedEngine + * The TTS engine that should be used. + */ + public void setEngine(String engineName, String[] requestedLanguages, int strictness) { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.setEngine(engineName, requestedLanguages, strictness); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Sets the speech rate for the TTS engine. + * + * Note that the speech rate is not universally supported by all engines and + * will be treated as a hint. The TTS library will try to use the specified + * speech rate, but there is no guarantee. + * + * Currently, this will change the speech rate for the espeak engine, but it + * has no effect on any pre-recorded speech. + * + * @param speechRate + * The speech rate for the TTS engine. + */ + public void setSpeechRate(int speechRate) { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.setSpeechRate(speechRate); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Sets the language for the TTS engine. + * + * Note that the language is not universally supported by all engines and + * will be treated as a hint. The TTS library will try to use the specified + * language, but there is no guarantee. + * + * Currently, this will change the language for the espeak engine, but it + * has no effect on any pre-recorded speech. + * + * @param language + * The language to be used. The languages are specified by their + * IETF language tags as defined by BCP 47. This is the same + * standard used for the lang attribute in HTML. See: + * http://en.wikipedia.org/wiki/IETF_language_tag + */ + public void setLanguage(String language) { + synchronized (startLock) { + if (!started) { + return; + } + try { + itts.setLanguage(language); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } + } + } + + + /** + * Speaks the given text using the specified queueing mode and parameters. + * + * @param text + * The String of text that should be synthesized + * @param params + * An ArrayList of parameters. The first element of this array + * controls the type of voice to use. + * @param filename + * The string that gives the full output filename; it should be + * something like "/sdcard/myappsounds/mysound.wav". + * @return A boolean that indicates if the synthesis succeeded + */ + public boolean synthesizeToFile(String text, String[] params, + String filename) { + synchronized (startLock) { + if (!started) { + return false; + } + try { + return itts.synthesizeToFile(text, params, filename); + } catch (RemoteException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + started = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + started = false; + initTts(); + } + return false; + } + } + + + /** + * Displays an alert that prompts users to install the TTS engine. + * This is useful if the application expects a newer version + * of the TTS than what the user has. + */ + public void showVersionAlert() { + if (!started) { + return; + } + // FIXME #TTS# implement show version alert + } + + + /** + * Checks if the TTS service is installed or not + * + * @return A boolean that indicates whether the TTS service is installed + */ + // TODO: TTS Service itself will always be installed. Factor this out + // (may need to add another method to see if there are any working + // TTS engines on the device). + public static boolean isInstalled(Context ctx) { + PackageManager pm = ctx.getPackageManager(); + Intent intent = new Intent("android.intent.action.USE_TTS"); + intent.addCategory("android.intent.category.TTS"); + ResolveInfo info = pm.resolveService(intent, 0); + if (info == null) { + return false; + } + return true; + } + +} |