diff options
Diffstat (limited to 'include')
122 files changed, 17783 insertions, 0 deletions
diff --git a/include/android_runtime/ActivityManager.h b/include/android_runtime/ActivityManager.h new file mode 100644 index 0000000..451a004 --- /dev/null +++ b/include/android_runtime/ActivityManager.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ActivityManager_H +#define ActivityManager_H + +#include <utils/String16.h> + +namespace android { + +// Perform a ContentProvider.openFile() call for the given URI. +// +// Returns the native file descriptor for the opened stream, < 0 on error. +extern int openContentProviderFile(const String16& uri); + +} + +#endif diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h new file mode 100644 index 0000000..78bef91 --- /dev/null +++ b/include/android_runtime/AndroidRuntime.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +#ifndef _RUNTIME_ANDROID_RUNTIME_H +#define _RUNTIME_ANDROID_RUNTIME_H + +#include <utils/Errors.h> +#include <utils/IBinder.h> +#include <utils/String8.h> +#include <utils/String16.h> +#include <utils/Vector.h> +#include <utils/threads.h> +#include <pthread.h> +#include <nativehelper/jni.h> + + +namespace android { + +class AndroidRuntime +{ +public: + AndroidRuntime(); + virtual ~AndroidRuntime(); + + /** + * Register a set of methods in the specified class. + */ + static int registerNativeMethods(JNIEnv* env, + const char* className, const JNINativeMethod* gMethods, int numMethods); + + /** + * Call a static Java function that takes no arguments and returns void. + */ + status_t callStatic(const char* className, const char* methodName); + + /** + * Call a class's static main method with the given arguments, + */ + status_t callMain(const char* className, int argc, const char* const argv[]); + + /** + * Find a class, with the input either of the form + * "package/class" or "package.class". + */ + static jclass findClass(JNIEnv* env, const char* className); + + int addVmArguments(int argc, const char* const argv[]); + + void start(const char *classname, const bool startSystemServer); + void start(); // start in android.util.RuntimeInit + + static AndroidRuntime* getRuntime(); + + /** + * This gets called after the JavaVM has initialized. Override it + * with the system's native entry point. + */ + virtual void onStarted() = 0; + + /** + * This gets called after the JavaVM has initialized after a Zygote + * fork. Override it to initialize threads, etc. Upon return, the + * correct static main will be invoked. + */ + virtual void onZygoteInit() {}; + + + /** + * Called when the Java application exits. The default + * implementation calls exit(code). + */ + virtual void onExit(int code); + + /** create a new thread that is visible from Java */ + static void createJavaThread(const char* name, void (*start)(void *), + void* arg); + + /** return a pointer to the VM running in this process */ + static JavaVM* getJavaVM() { return mJavaVM; } + + /** return a pointer to the JNIEnv pointer for this thread */ + static JNIEnv* getJNIEnv(); + +private: + static int startReg(JNIEnv* env); + + Vector<JavaVMOption> mOptions; + + /* JNI JavaVM pointer */ + static JavaVM* mJavaVM; + + /* + * Thread creation helpers. + */ + static int javaCreateThreadEtc( + android_thread_func_t entryFunction, + void* userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t* threadId); + static int javaThreadShell(void* args); +}; + +// Returns the Unix file descriptor for a ParcelFileDescriptor object +extern int getParcelFileDescriptorFD(JNIEnv* env, jobject object); + +} + +#endif diff --git a/include/android_runtime/android_util_AssetManager.h b/include/android_runtime/android_util_AssetManager.h new file mode 100644 index 0000000..b6dd9c9 --- /dev/null +++ b/include/android_runtime/android_util_AssetManager.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_util_AssetManager_H +#define android_util_AssetManager_H + +#include <utils/AssetManager.h> + +#include "jni.h" + +namespace android { + +extern AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject assetMgr); + +} + +#endif diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h new file mode 100644 index 0000000..ff64855 --- /dev/null +++ b/include/media/AudioRecord.h @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIORECORD_H_ +#define AUDIORECORD_H_ + +#include <stdint.h> +#include <sys/types.h> + +#include <media/IAudioFlinger.h> +#include <media/IAudioRecord.h> +#include <media/AudioTrack.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/IMemory.h> +#include <utils/threads.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class AudioRecord +{ +public: + + enum stream_type { + DEFAULT_INPUT =-1, + MIC_INPUT = 0, + NUM_STREAM_TYPES + }; + + static const int DEFAULT_SAMPLE_RATE = 8000; + + /* Events used by AudioRecord callback function (callback_t). + * + * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java + */ + enum event_type { + EVENT_MORE_DATA = 0, // Request to reqd more data from PCM buffer. + EVENT_OVERRUN = 1, // PCM buffer overrun occured. + EVENT_MARKER = 2, // Record head is at the specified marker position + // (See setMarkerPosition()). + EVENT_NEW_POS = 3, // Record head is at a new position + // (See setPositionUpdatePeriod()). + }; + + /* Create Buffer on the stack and pass it to obtainBuffer() + * and releaseBuffer(). + */ + + class Buffer + { + public: + enum { + MUTE = 0x00000001 + }; + uint32_t flags; + int channelCount; + int format; + size_t frameCount; + size_t size; + union { + void* raw; + short* i16; + int8_t* i8; + }; + }; + + /* These are static methods to control the system-wide AudioFlinger + * only privileged processes can have access to them + */ + +// static status_t setMasterMute(bool mute); + + /* As a convenience, if a callback is supplied, a handler thread + * is automatically created with the appropriate priority. This thread + * invokes the callback when a new buffer becomes ready or an overrun condition occurs. + * Parameters: + * + * event: type of event notified (see enum AudioRecord::event_type). + * user: Pointer to context for use by the callback receiver. + * info: Pointer to optional parameter according to event type: + * - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read + * more bytes than indicated by 'size' field and update 'size' if less bytes are + * read. + * - EVENT_OVERRUN: unused. + * - EVENT_MARKER: pointer to an uin32_t containing the marker position in frames. + * - EVENT_NEW_POS: pointer to an uin32_t containing the new position in frames. + */ + + typedef void (*callback_t)(int event, void* user, void *info); + + /* Constructs an uninitialized AudioRecord. No connection with + * AudioFlinger takes place. + */ + AudioRecord(); + + /* Creates an AudioRecord track and registers it with AudioFlinger. + * Once created, the track needs to be started before it can be used. + * Unspecified values are set to the audio hardware's current + * values. + * + * Parameters: + * + * streamType: Select the audio input to record to (e.g. AudioRecord::MIC_INPUT). + * sampleRate: Track sampling rate in Hz. + * format: PCM sample format (e.g AudioSystem::PCM_16_BIT for signed + * 16 bits per sample). + * channelCount: Number of PCM channels (e.g 2 for stereo). + * frameCount: Total size of track PCM buffer in frames. This defines the + * latency of the track. + * flags: A bitmask of acoustic values from enum record_flags. It enables + * AGC, NS, and IIR. + * cbf: Callback function. If not null, this function is called periodically + * to provide new PCM data. + * notificationFrames: The callback function is called each time notificationFrames PCM + * frames are ready in record track output buffer. + * user Context for use by the callback receiver. + */ + + enum record_flags { + RECORD_AGC_ENABLE = AudioSystem::AGC_ENABLE, + RECORD_NS_ENABLE = AudioSystem::NS_ENABLE, + RECORD_IIR_ENABLE = AudioSystem::TX_IIR_ENABLE + }; + + AudioRecord(int streamType, + uint32_t sampleRate = 0, + int format = 0, + int channelCount = 0, + int frameCount = 0, + uint32_t flags = 0, + callback_t cbf = 0, + void* user = 0, + int notificationFrames = 0); + + + /* Terminates the AudioRecord and unregisters it from AudioFlinger. + * Also destroys all resources assotiated with the AudioRecord. + */ + ~AudioRecord(); + + + /* Initialize an uninitialized AudioRecord. + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful intialization + * - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use + * - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...) + * - NO_INIT: audio server or audio hardware not initialized + * - PERMISSION_DENIED: recording is not allowed for the requesting process + * */ + status_t set(int streamType = 0, + uint32_t sampleRate = 0, + int format = 0, + int channelCount = 0, + int frameCount = 0, + uint32_t flags = 0, + callback_t cbf = 0, + void* user = 0, + int notificationFrames = 0, + bool threadCanCallJava = false); + + + /* Result of constructing the AudioRecord. This must be checked + * before using any AudioRecord API (except for set()), using + * an uninitialized AudioRecord produces undefined results. + * See set() method above for possible return codes. + */ + status_t initCheck() const; + + /* Returns this track's latency in milliseconds. + * This includes the latency due to AudioRecord buffer size + * and audio hardware driver. + */ + uint32_t latency() const; + + /* getters, see constructor */ + + uint32_t sampleRate() const; + int format() const; + int channelCount() const; + uint32_t frameCount() const; + int frameSize() const; + + + /* After it's created the track is not active. Call start() to + * make it active. If set, the callback will start being called. + */ + status_t start(); + + /* Stop a track. If set, the callback will cease being called and + * obtainBuffer returns STOPPED. Note that obtainBuffer() still works + * and will fill up buffers until the pool is exhausted. + */ + status_t stop(); + bool stopped() const; + + /* get sample rate for this track + */ + uint32_t getSampleRate(); + + /* Sets marker position. When record reaches the number of frames specified, + * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition + * with marker == 0 cancels marker notification callback. + * If the AudioRecord has been opened with no callback function associated, + * the operation will fail. + * + * Parameters: + * + * marker: marker position expressed in frames. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioRecord has no callback installed. + */ + status_t setMarkerPosition(uint32_t marker); + status_t getMarkerPosition(uint32_t *marker); + + + /* Sets position update period. Every time the number of frames specified has been recorded, + * a callback with event type EVENT_NEW_POS is called. + * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification + * callback. + * If the AudioRecord has been opened with no callback function associated, + * the operation will fail. + * + * Parameters: + * + * updatePeriod: position update notification period expressed in frames. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioRecord has no callback installed. + */ + status_t setPositionUpdatePeriod(uint32_t updatePeriod); + status_t getPositionUpdatePeriod(uint32_t *updatePeriod); + + + /* Gets record head position. The position is the total number of frames + * recorded since record start. + * + * Parameters: + * + * position: Address where to return record head position within AudioRecord buffer. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - BAD_VALUE: position is NULL + */ + status_t getPosition(uint32_t *position); + + + + /* obtains a buffer of "frameCount" frames. The buffer must be + * filled entirely. If the track is stopped, obtainBuffer() returns + * STOPPED instead of NO_ERROR as long as there are buffers availlable, + * at which point NO_MORE_BUFFERS is returned. + * Buffers will be returned until the pool (buffercount()) + * is exhausted, at which point obtainBuffer() will either block + * or return WOULD_BLOCK depending on the value of the "blocking" + * parameter. + */ + + enum { + NO_MORE_BUFFERS = 0x80000001, + STOPPED = 1 + }; + + status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); + void releaseBuffer(Buffer* audioBuffer); + + + /* As a convenience we provide a read() interface to the audio buffer. + * This is implemented on top of lockBuffer/unlockBuffer. + */ + ssize_t read(void* buffer, size_t size); + +private: + /* copying audio tracks is not allowed */ + AudioRecord(const AudioRecord& other); + AudioRecord& operator = (const AudioRecord& other); + + /* a small internal class to handle the callback */ + class ClientRecordThread : public Thread + { + public: + ClientRecordThread(AudioRecord& receiver, bool bCanCallJava = false); + private: + friend class AudioRecord; + virtual bool threadLoop(); + virtual status_t readyToRun() { return NO_ERROR; } + virtual void onFirstRef() {} + AudioRecord& mReceiver; + Mutex mLock; + }; + + bool processAudioBuffer(const sp<ClientRecordThread>& thread); + + sp<IAudioFlinger> mAudioFlinger; + sp<IAudioRecord> mAudioRecord; + sp<IMemory> mCblkMemory; + sp<ClientRecordThread> mClientRecordThread; + Mutex mRecordThreadLock; + + uint32_t mSampleRate; + uint32_t mFrameCount; + + audio_track_cblk_t* mCblk; + uint8_t mFormat; + uint8_t mChannelCount; + uint8_t mReserved[2]; + status_t mStatus; + uint32_t mLatency; + + volatile int32_t mActive; + + callback_t mCbf; + void* mUserData; + uint32_t mNotificationFrames; + uint32_t mRemainingFrames; + uint32_t mMarkerPosition; + uint32_t mNewPosition; + uint32_t mUpdatePeriod; +}; + +}; // namespace android + +#endif /*AUDIORECORD_H_*/ diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h new file mode 100644 index 0000000..77c90ba --- /dev/null +++ b/include/media/AudioSystem.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIOSYSTEM_H_ +#define ANDROID_AUDIOSYSTEM_H_ + +#include <utils/RefBase.h> +#include <utils/threads.h> +#include <media/IAudioFlinger.h> + +namespace android { + +typedef void (*audio_error_callback)(status_t err); + +class AudioSystem +{ +public: + + enum stream_type { + DEFAULT =-1, + VOICE_CALL = 0, + SYSTEM = 1, + RING = 2, + MUSIC = 3, + ALARM = 4, + NOTIFICATION = 5, + BLUETOOTH_SCO = 6, + NUM_STREAM_TYPES + }; + + enum audio_output_type { + AUDIO_OUTPUT_DEFAULT =-1, + AUDIO_OUTPUT_HARDWARE = 0, + AUDIO_OUTPUT_A2DP = 1, + NUM_AUDIO_OUTPUT_TYPES + }; + + enum audio_format { + FORMAT_DEFAULT = 0, + PCM_16_BIT, + PCM_8_BIT, + INVALID_FORMAT + }; + + enum audio_mode { + MODE_INVALID = -2, + MODE_CURRENT = -1, + MODE_NORMAL = 0, + MODE_RINGTONE, + MODE_IN_CALL, + NUM_MODES // not a valid entry, denotes end-of-list + }; + + enum audio_routes { + ROUTE_EARPIECE = (1 << 0), + ROUTE_SPEAKER = (1 << 1), + ROUTE_BLUETOOTH_SCO = (1 << 2), + ROUTE_HEADSET = (1 << 3), + ROUTE_BLUETOOTH_A2DP = (1 << 4), + ROUTE_ALL = -1UL, + }; + + enum audio_in_acoustics { + AGC_ENABLE = 0x0001, + AGC_DISABLE = 0, + NS_ENABLE = 0x0002, + NS_DISABLE = 0, + TX_IIR_ENABLE = 0x0004, + TX_DISABLE = 0 + }; + + /* These are static methods to control the system-wide AudioFlinger + * only privileged processes can have access to them + */ + + // routing helper functions + static status_t speakerphone(bool state); + static status_t isSpeakerphoneOn(bool* state); + static status_t bluetoothSco(bool state); + static status_t isBluetoothScoOn(bool* state); + static status_t muteMicrophone(bool state); + static status_t isMicrophoneMuted(bool *state); + + static status_t setMasterVolume(float value); + static status_t setMasterMute(bool mute); + static status_t getMasterVolume(float* volume); + static status_t getMasterMute(bool* mute); + + static status_t setStreamVolume(int stream, float value); + static status_t setStreamMute(int stream, bool mute); + static status_t getStreamVolume(int stream, float* volume); + static status_t getStreamMute(int stream, bool* mute); + + static status_t setMode(int mode); + static status_t getMode(int* mode); + + static status_t setRouting(int mode, uint32_t routes, uint32_t mask); + static status_t getRouting(int mode, uint32_t* routes); + + static status_t isMusicActive(bool *state); + + // Temporary interface, do not use + // TODO: Replace with a more generic key:value get/set mechanism + static status_t setParameter(const char* key, const char* value); + + static void setErrorCallback(audio_error_callback cb); + + // helper function to obtain AudioFlinger service handle + static const sp<IAudioFlinger>& get_audio_flinger(); + + static float linearToLog(int volume); + static int logToLinear(float volume); + + static status_t getOutputSamplingRate(int* samplingRate, int stream = DEFAULT); + static status_t getOutputFrameCount(int* frameCount, int stream = DEFAULT); + static status_t getOutputLatency(uint32_t* latency, int stream = DEFAULT); + + static bool routedToA2dpOutput(int streamType); + + static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, + size_t* buffSize); + + // ---------------------------------------------------------------------------- + +private: + + class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient + { + public: + AudioFlingerClient() { + } + + // DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + + // IAudioFlingerClient + virtual void a2dpEnabledChanged(bool enabled); + + }; + static int getOutput(int streamType); + + static sp<AudioFlingerClient> gAudioFlingerClient; + + friend class AudioFlingerClient; + + static Mutex gLock; + static sp<IAudioFlinger> gAudioFlinger; + static audio_error_callback gAudioErrorCallback; + static int gOutSamplingRate[NUM_AUDIO_OUTPUT_TYPES]; + static int gOutFrameCount[NUM_AUDIO_OUTPUT_TYPES]; + static uint32_t gOutLatency[NUM_AUDIO_OUTPUT_TYPES]; + static bool gA2dpEnabled; + + static size_t gInBuffSize; + // previous parameters for recording buffer size queries + static uint32_t gPrevInSamplingRate; + static int gPrevInFormat; + static int gPrevInChannelCount; + +}; + +}; // namespace android + +#endif /*ANDROID_AUDIOSYSTEM_H_*/ diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h new file mode 100644 index 0000000..659f5f8 --- /dev/null +++ b/include/media/AudioTrack.h @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIOTRACK_H +#define ANDROID_AUDIOTRACK_H + +#include <stdint.h> +#include <sys/types.h> + +#include <media/IAudioFlinger.h> +#include <media/IAudioTrack.h> +#include <media/AudioSystem.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/IMemory.h> +#include <utils/threads.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class audio_track_cblk_t; + +// ---------------------------------------------------------------------------- + +class AudioTrack +{ +public: + enum channel_index { + MONO = 0, + LEFT = 0, + RIGHT = 1 + }; + + /* Events used by AudioTrack callback function (audio_track_cblk_t). + */ + enum event_type { + EVENT_MORE_DATA = 0, // Request to write more data to PCM buffer. + EVENT_UNDERRUN = 1, // PCM buffer underrun occured. + EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from loop start if loop count was not 0. + EVENT_MARKER = 3, // Playback head is at the specified marker position (See setMarkerPosition()). + EVENT_NEW_POS = 4, // Playback head is at a new position (See setPositionUpdatePeriod()). + EVENT_BUFFER_END = 5 // Playback head is at the end of the buffer. + }; + + /* Create Buffer on the stack and pass it to obtainBuffer() + * and releaseBuffer(). + */ + + class Buffer + { + public: + enum { + MUTE = 0x00000001 + }; + uint32_t flags; + int channelCount; + int format; + size_t frameCount; + size_t size; + union { + void* raw; + short* i16; + int8_t* i8; + }; + }; + + + /* As a convenience, if a callback is supplied, a handler thread + * is automatically created with the appropriate priority. This thread + * invokes the callback when a new buffer becomes availlable or an underrun condition occurs. + * Parameters: + * + * event: type of event notified (see enum AudioTrack::event_type). + * user: Pointer to context for use by the callback receiver. + * info: Pointer to optional parameter according to event type: + * - EVENT_MORE_DATA: pointer to AudioTrack::Buffer struct. The callback must not write + * more bytes than indicated by 'size' field and update 'size' if less bytes are + * written. + * - EVENT_UNDERRUN: unused. + * - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining. + * - EVENT_MARKER: pointer to an uin32_t containing the marker position in frames. + * - EVENT_NEW_POS: pointer to an uin32_t containing the new position in frames. + * - EVENT_BUFFER_END: unused. + */ + + typedef void (*callback_t)(int event, void* user, void *info); + + /* Constructs an uninitialized AudioTrack. No connection with + * AudioFlinger takes place. + */ + AudioTrack(); + + /* Creates an audio track and registers it with AudioFlinger. + * Once created, the track needs to be started before it can be used. + * Unspecified values are set to the audio hardware's current + * values. + * + * Parameters: + * + * streamType: Select the type of audio stream this track is attached to + * (e.g. AudioSystem::MUSIC). + * sampleRate: Track sampling rate in Hz. + * format: PCM sample format (e.g AudioSystem::PCM_16_BIT for signed + * 16 bits per sample). + * channelCount: Number of PCM channels (e.g 2 for stereo). + * frameCount: Total size of track PCM buffer in frames. This defines the + * latency of the track. + * flags: Reserved for future use. + * cbf: Callback function. If not null, this function is called periodically + * to request new PCM data. + * notificationFrames: The callback function is called each time notificationFrames PCM + * frames have been comsumed from track input buffer. + * user Context for use by the callback receiver. + */ + + AudioTrack( int streamType, + uint32_t sampleRate = 0, + int format = 0, + int channelCount = 0, + int frameCount = 0, + uint32_t flags = 0, + callback_t cbf = 0, + void* user = 0, + int notificationFrames = 0); + + /* Creates an audio track and registers it with AudioFlinger. With this constructor, + * The PCM data to be rendered by AudioTrack is passed in a shared memory buffer + * identified by the argument sharedBuffer. This prototype is for static buffer playback. + * PCM data must be present into memory before the AudioTrack is started. + * The Write() and Flush() methods are not supported in this case. + * It is recommented to pass a callback function to be notified of playback end by an + * EVENT_UNDERRUN event. + */ + + AudioTrack( int streamType, + uint32_t sampleRate = 0, + int format = 0, + int channelCount = 0, + const sp<IMemory>& sharedBuffer = 0, + uint32_t flags = 0, + callback_t cbf = 0, + void* user = 0, + int notificationFrames = 0); + + /* Terminates the AudioTrack and unregisters it from AudioFlinger. + * Also destroys all resources assotiated with the AudioTrack. + */ + ~AudioTrack(); + + + /* Initialize an uninitialized AudioTrack. + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful intialization + * - INVALID_OPERATION: AudioTrack is already intitialized + * - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...) + * - NO_INIT: audio server or audio hardware not initialized + * */ + status_t set(int streamType =-1, + uint32_t sampleRate = 0, + int format = 0, + int channelCount = 0, + int frameCount = 0, + uint32_t flags = 0, + callback_t cbf = 0, + void* user = 0, + int notificationFrames = 0, + const sp<IMemory>& sharedBuffer = 0, + bool threadCanCallJava = false); + + + /* Result of constructing the AudioTrack. This must be checked + * before using any AudioTrack API (except for set()), using + * an uninitialized AudioTrack produces undefined results. + * See set() method above for possible return codes. + */ + status_t initCheck() const; + + /* Returns this track's latency in milliseconds. + * This includes the latency due to AudioTrack buffer size, AudioMixer (if any) + * and audio hardware driver. + */ + uint32_t latency() const; + + /* getters, see constructor */ + + int streamType() const; + uint32_t sampleRate() const; + int format() const; + int channelCount() const; + uint32_t frameCount() const; + int frameSize() const; + sp<IMemory>& sharedBuffer(); + + + /* After it's created the track is not active. Call start() to + * make it active. If set, the callback will start being called. + */ + void start(); + + /* Stop a track. If set, the callback will cease being called and + * obtainBuffer returns STOPPED. Note that obtainBuffer() still works + * and will fill up buffers until the pool is exhausted. + */ + void stop(); + bool stopped() const; + + /* flush a stopped track. All pending buffers are discarded. + * This function has no effect if the track is not stoped. + */ + void flush(); + + /* Pause a track. If set, the callback will cease being called and + * obtainBuffer returns STOPPED. Note that obtainBuffer() still works + * and will fill up buffers until the pool is exhausted. + */ + void pause(); + + /* mute or unmutes this track. + * While mutted, the callback, if set, is still called. + */ + void mute(bool); + bool muted() const; + + + /* set volume for this track, mostly used for games' sound effects + */ + void setVolume(float left, float right); + void getVolume(float* left, float* right); + + /* set sample rate for this track, mostly used for games' sound effects + */ + void setSampleRate(int sampleRate); + uint32_t getSampleRate(); + + /* Enables looping and sets the start and end points of looping. + * + * Parameters: + * + * loopStart: loop start expressed as the number of PCM frames played since AudioTrack start. + * loopEnd: loop end expressed as the number of PCM frames played since AudioTrack start. + * loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any pending or + * active loop. loopCount = -1 means infinite looping. + * + * For proper operation the following condition must be respected: + * (loopEnd-loopStart) <= framecount() + */ + status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount); + status_t getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount); + + + /* Sets marker position. When playback reaches the number of frames specified, a callback with event + * type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker notification + * callback. + * If the AudioTrack has been opened with no callback function associated, the operation will fail. + * + * Parameters: + * + * marker: marker position expressed in frames. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioTrack has no callback installed. + */ + status_t setMarkerPosition(uint32_t marker); + status_t getMarkerPosition(uint32_t *marker); + + + /* Sets position update period. Every time the number of frames specified has been played, + * a callback with event type EVENT_NEW_POS is called. + * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification + * callback. + * If the AudioTrack has been opened with no callback function associated, the operation will fail. + * + * Parameters: + * + * updatePeriod: position update notification period expressed in frames. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioTrack has no callback installed. + */ + status_t setPositionUpdatePeriod(uint32_t updatePeriod); + status_t getPositionUpdatePeriod(uint32_t *updatePeriod); + + + /* Sets playback head position within AudioTrack buffer. The new position is specified + * in number of frames. + * This method must be called with the AudioTrack in paused or stopped state. + * Note that the actual position set is <position> modulo the AudioTrack buffer size in frames. + * Therefore using this method makes sense only when playing a "static" audio buffer + * as opposed to streaming. + * The getPosition() method on the other hand returns the total number of frames played since + * playback start. + * + * Parameters: + * + * position: New playback head position within AudioTrack buffer. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioTrack is not stopped. + * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack buffer + */ + status_t setPosition(uint32_t position); + status_t getPosition(uint32_t *position); + + /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids + * rewriting the buffer before restarting playback after a stop. + * This method must be called with the AudioTrack in paused or stopped state. + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the AudioTrack is not stopped. + */ + status_t reload(); + + /* obtains a buffer of "frameCount" frames. The buffer must be + * filled entirely. If the track is stopped, obtainBuffer() returns + * STOPPED instead of NO_ERROR as long as there are buffers availlable, + * at which point NO_MORE_BUFFERS is returned. + * Buffers will be returned until the pool (buffercount()) + * is exhausted, at which point obtainBuffer() will either block + * or return WOULD_BLOCK depending on the value of the "blocking" + * parameter. + */ + + enum { + NO_MORE_BUFFERS = 0x80000001, + STOPPED = 1 + }; + + status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); + void releaseBuffer(Buffer* audioBuffer); + + + /* As a convenience we provide a write() interface to the audio buffer. + * This is implemented on top of lockBuffer/unlockBuffer. For best + * performance + * + */ + ssize_t write(const void* buffer, size_t size); + + /* + * Dumps the state of an audio track. + */ + status_t dump(int fd, const Vector<String16>& args) const; + +private: + /* copying audio tracks is not allowed */ + AudioTrack(const AudioTrack& other); + AudioTrack& operator = (const AudioTrack& other); + + /* a small internal class to handle the callback */ + class AudioTrackThread : public Thread + { + public: + AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false); + private: + friend class AudioTrack; + virtual bool threadLoop(); + virtual status_t readyToRun(); + virtual void onFirstRef(); + AudioTrack& mReceiver; + Mutex mLock; + }; + + bool processAudioBuffer(const sp<AudioTrackThread>& thread); + + sp<IAudioFlinger> mAudioFlinger; + sp<IAudioTrack> mAudioTrack; + sp<IMemory> mCblkMemory; + sp<AudioTrackThread> mAudioTrackThread; + + float mVolume[2]; + uint32_t mSampleRate; + uint32_t mFrameCount; + + audio_track_cblk_t* mCblk; + uint8_t mStreamType; + uint8_t mFormat; + uint8_t mChannelCount; + uint8_t mMuted; + status_t mStatus; + uint32_t mLatency; + + volatile int32_t mActive; + + callback_t mCbf; + void* mUserData; + uint32_t mNotificationFrames; + sp<IMemory> mSharedBuffer; + int mLoopCount; + uint32_t mRemainingFrames; + uint32_t mMarkerPosition; + uint32_t mNewPosition; + uint32_t mUpdatePeriod; +}; + + +}; // namespace android + +#endif // ANDROID_AUDIOTRACK_H diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h new file mode 100644 index 0000000..6f13fe0 --- /dev/null +++ b/include/media/IAudioFlinger.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IAUDIOFLINGER_H +#define ANDROID_IAUDIOFLINGER_H + +#include <stdint.h> +#include <sys/types.h> +#include <unistd.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <media/IAudioTrack.h> +#include <media/IAudioRecord.h> +#include <media/IAudioFlingerClient.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioFlinger : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioFlinger); + + /* create an audio track and registers it with AudioFlinger. + * return null if the track cannot be created. + */ + virtual sp<IAudioTrack> createTrack( + pid_t pid, + int streamType, + uint32_t sampleRate, + int format, + int channelCount, + int frameCount, + uint32_t flags, + const sp<IMemory>& sharedBuffer, + status_t *status) = 0; + + virtual sp<IAudioRecord> openRecord( + pid_t pid, + int streamType, + uint32_t sampleRate, + int format, + int channelCount, + int frameCount, + uint32_t flags, + status_t *status) = 0; + + /* query the audio hardware state. This state never changes, + * and therefore can be cached. + */ + virtual uint32_t sampleRate(int output) const = 0; + virtual int channelCount(int output) const = 0; + virtual int format(int output) const = 0; + virtual size_t frameCount(int output) const = 0; + virtual uint32_t latency(int output) const = 0; + + /* set/get the audio hardware state. This will probably be used by + * the preference panel, mostly. + */ + virtual status_t setMasterVolume(float value) = 0; + virtual status_t setMasterMute(bool muted) = 0; + + virtual float masterVolume() const = 0; + virtual bool masterMute() const = 0; + + /* set/get stream type state. This will probably be used by + * the preference panel, mostly. + */ + virtual status_t setStreamVolume(int stream, float value) = 0; + virtual status_t setStreamMute(int stream, bool muted) = 0; + + virtual float streamVolume(int stream) const = 0; + virtual bool streamMute(int stream) const = 0; + + // set/get audio routing + virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask) = 0; + virtual uint32_t getRouting(int mode) const = 0; + + // set/get audio mode + virtual status_t setMode(int mode) = 0; + virtual int getMode() const = 0; + + // mic mute/state + virtual status_t setMicMute(bool state) = 0; + virtual bool getMicMute() const = 0; + + // is a music stream active? + virtual bool isMusicActive() const = 0; + + // pass a generic configuration parameter to libaudio + // Temporary interface, do not use + // TODO: Replace with a more generic key:value get/set mechanism + virtual status_t setParameter(const char* key, const char* value) = 0; + + // register a current process for audio output change notifications + virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0; + + // retrieve the audio recording buffer size + virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0; + + // force AudioFlinger thread out of standby + virtual void wakeUp() = 0; + + // is A2DP output enabled + virtual bool isA2dpEnabled() const = 0; +}; + + +// ---------------------------------------------------------------------------- + +class BnAudioFlinger : public BnInterface<IAudioFlinger> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOFLINGER_H diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h new file mode 100644 index 0000000..c3deb0b --- /dev/null +++ b/include/media/IAudioFlingerClient.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef ANDROID_IAUDIOFLINGERCLIENT_H +#define ANDROID_IAUDIOFLINGERCLIENT_H + + +#include <utils/RefBase.h> +#include <utils/IInterface.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioFlingerClient : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioFlingerClient); + + // Notifies a change of audio output from/to hardware to/from A2DP. + virtual void a2dpEnabledChanged(bool enabled) = 0; + +}; + + +// ---------------------------------------------------------------------------- + +class BnAudioFlingerClient : public BnInterface<IAudioFlingerClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOFLINGERCLIENT_H diff --git a/include/media/IAudioRecord.h b/include/media/IAudioRecord.h new file mode 100644 index 0000000..9d45d2d --- /dev/null +++ b/include/media/IAudioRecord.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IAUDIORECORD_H_ +#define IAUDIORECORD_H_ + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/IMemory.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioRecord : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioRecord); + + /* After it's created the track is not active. Call start() to + * make it active. If set, the callback will start being called. + */ + virtual status_t start() = 0; + + /* Stop a track. If set, the callback will cease being called and + * obtainBuffer will return an error. Buffers that are already released + * will be processed, unless flush() is called. + */ + virtual void stop() = 0; + + /* get this tracks control block */ + virtual sp<IMemory> getCblk() const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnAudioRecord : public BnInterface<IAudioRecord> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif /*IAUDIORECORD_H_*/ diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h new file mode 100644 index 0000000..12f2111 --- /dev/null +++ b/include/media/IAudioTrack.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IAUDIOTRACK_H +#define ANDROID_IAUDIOTRACK_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/IMemory.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioTrack : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioTrack); + + /* After it's created the track is not active. Call start() to + * make it active. If set, the callback will start being called. + */ + virtual status_t start() = 0; + + /* Stop a track. If set, the callback will cease being called and + * obtainBuffer will return an error. Buffers that are already released + * will be processed, unless flush() is called. + */ + virtual void stop() = 0; + + /* flush a stopped track. All pending buffers are discarded. + * This function has no effect if the track is not stoped. + */ + virtual void flush() = 0; + + /* mute or unmutes this track. + * While mutted, the callback, if set, is still called. + */ + virtual void mute(bool) = 0; + + /* Pause a track. If set, the callback will cease being called and + * obtainBuffer will return an error. Buffers that are already released + * will be processed, unless flush() is called. + */ + virtual void pause() = 0; + + /* get this tracks control block */ + virtual sp<IMemory> getCblk() const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnAudioTrack : public BnInterface<IAudioTrack> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOTRACK_H diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h new file mode 100644 index 0000000..c677e83 --- /dev/null +++ b/include/media/IMediaMetadataRetriever.h @@ -0,0 +1,56 @@ +/* +** +** Copyright (C) 2008 The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_IMEDIAMETADATARETRIEVER_H +#define ANDROID_IMEDIAMETADATARETRIEVER_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> +#include <utils/IMemory.h> + +namespace android { + +class IMediaMetadataRetriever: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaMetadataRetriever); + virtual void disconnect() = 0; + virtual status_t setDataSource(const char* srcUrl) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setMode(int mode) = 0; + virtual status_t getMode(int* mode) const = 0; + virtual sp<IMemory> captureFrame() = 0; + virtual sp<IMemory> extractAlbumArt() = 0; + virtual const char* extractMetadata(int keyCode) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaMetadataRetriever: public BnInterface<IMediaMetadataRetriever> +{ +public: + virtual status_t onTransact(uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIAMETADATARETRIEVER_H + diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h new file mode 100644 index 0000000..a683e74 --- /dev/null +++ b/include/media/IMediaPlayer.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEDIAPLAYER_H +#define ANDROID_IMEDIAPLAYER_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> + +namespace android { + +class ISurface; + +class IMediaPlayer: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaPlayer); + + virtual void disconnect() = 0; + + virtual status_t setVideoSurface(const sp<ISurface>& surface) = 0; + virtual status_t prepareAsync() = 0; + virtual status_t start() = 0; + virtual status_t stop() = 0; + virtual status_t pause() = 0; + virtual status_t isPlaying(bool* state) = 0; + virtual status_t seekTo(int msec) = 0; + virtual status_t getCurrentPosition(int* msec) = 0; + virtual status_t getDuration(int* msec) = 0; + virtual status_t reset() = 0; + virtual status_t setAudioStreamType(int type) = 0; + virtual status_t setLooping(int loop) = 0; + virtual status_t setVolume(float leftVolume, float rightVolume) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaPlayer: public BnInterface<IMediaPlayer> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIAPLAYER_H + diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h new file mode 100644 index 0000000..5d32811 --- /dev/null +++ b/include/media/IMediaPlayerClient.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEDIAPLAYERCLIENT_H +#define ANDROID_IMEDIAPLAYERCLIENT_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> + +namespace android { + +class IMediaPlayerClient: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaPlayerClient); + + virtual void notify(int msg, int ext1, int ext2) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIAPLAYERCLIENT_H + diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h new file mode 100644 index 0000000..8125cc9 --- /dev/null +++ b/include/media/IMediaPlayerService.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEDIAPLAYERSERVICE_H +#define ANDROID_IMEDIAPLAYERSERVICE_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> + +#include <media/IMediaPlayerClient.h> +#include <media/IMediaPlayer.h> +#include <media/IMediaMetadataRetriever.h> + +namespace android { + +class IMediaRecorder; + +class IMediaPlayerService: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaPlayerService); + + virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0; + virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0; + + virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0; + virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0; + virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; + virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaPlayerService: public BnInterface<IMediaPlayerService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIAPLAYERSERVICE_H + diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h new file mode 100644 index 0000000..eace996 --- /dev/null +++ b/include/media/IMediaRecorder.h @@ -0,0 +1,70 @@ +/* + ** + ** Copyright 2008, HTC 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. + */ + +#ifndef ANDROID_IMEDIARECORDER_H +#define ANDROID_IMEDIARECORDER_H + +#include <utils/IInterface.h> + +namespace android { + +class ISurface; +class ICamera; +class IMediaPlayerClient; + +class IMediaRecorder: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaRecorder); + + virtual status_t setCamera(const sp<ICamera>& camera) = 0; + virtual status_t setPreviewSurface(const sp<ISurface>& surface) = 0; + virtual status_t setVideoSource(int vs) = 0; + virtual status_t setAudioSource(int as) = 0; + virtual status_t setOutputFormat(int of) = 0; + virtual status_t setVideoEncoder(int ve) = 0; + virtual status_t setAudioEncoder(int ae) = 0; + virtual status_t setOutputFile(const char* path) = 0; + virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setVideoSize(int width, int height) = 0; + virtual status_t setVideoFrameRate(int frames_per_second) = 0; + virtual status_t setListener(const sp<IMediaPlayerClient>& listener) = 0; + virtual status_t prepare() = 0; + virtual status_t getMaxAmplitude(int* max) = 0; + virtual status_t start() = 0; + virtual status_t stop() = 0; + virtual status_t reset() = 0; + virtual status_t init() = 0; + virtual status_t close() = 0; + virtual status_t release() = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaRecorder: public BnInterface<IMediaRecorder> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIARECORDER_H + diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h new file mode 100644 index 0000000..16764a9 --- /dev/null +++ b/include/media/JetPlayer.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JETPLAYER_H_ +#define JETPLAYER_H_ + +#include <utils/threads.h> +#include <nativehelper/jni.h> + +#include <libsonivox/jet.h> +#include <libsonivox/eas_types.h> +#include "AudioTrack.h" + + +namespace android { + +typedef void (*jetevent_callback)(int eventType, int val1, int val2, void *cookie); + +class JetPlayer { + +public: + + // to keep in sync with the JetPlayer class constants + // defined in frameworks/base/media/java/android/media/JetPlayer.java + static const int JET_EVENT = 1; + static const int JET_USERID_UPDATE = 2; + static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3; + static const int JET_PAUSE_UPDATE = 4; + + JetPlayer(jobject javaJetPlayer, + int maxTracks = 32, + int trackBufferSize = 1200); + ~JetPlayer(); + int init(); + int release(); + + int loadFromFile(const char* url); + int loadFromFD(const int fd, const long long offset, const long long length); + int closeFile(); + int play(); + int pause(); + int queueSegment(int segmentNum, int libNum, int repeatCount, int transpose, + EAS_U32 muteFlags, EAS_U8 userID); + int setMuteFlags(EAS_U32 muteFlags, bool sync); + int setMuteFlag(int trackNum, bool muteFlag, bool sync); + int triggerClip(int clipId); + int clearQueue(); + + void setEventCallback(jetevent_callback callback); + + int getMaxTracks() { return mMaxTracks; }; + + +private: + static int renderThread(void*); + int render(); + void fireUpdateOnStatusChange(); + void fireEventsFromJetQueue(); + + JetPlayer() {} // no default constructor + void dump(); + void dumpJetStatus(S_JET_STATUS* pJetStatus); + + jetevent_callback mEventCallback; + + jobject mJavaJetPlayerRef; + Mutex mMutex; // mutex to sync the render and playback thread with the JET calls + pid_t mTid; + Condition mCondition; + volatile bool mRender; + bool mPaused; + + EAS_STATE mState; + int* mMemFailedVar; + + int mMaxTracks; // max number of MIDI tracks, usually 32 + EAS_DATA_HANDLE mEasData; + EAS_FILE_LOCATOR mEasJetFileLoc; + EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer, + AudioTrack* mAudioTrack; // and we play it in this audio track + int mTrackBufferSize; + S_JET_STATUS mJetStatus; + S_JET_STATUS mPreviousJetStatus; + + char mJetFilePath[256]; + + +}; // end class JetPlayer + +} // end namespace android + + + +#endif /*JETPLAYER_H_*/ diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h new file mode 100644 index 0000000..b178836 --- /dev/null +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -0,0 +1,52 @@ +/* +** +** Copyright (C) 2008 The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_MEDIAMETADATARETRIEVERINTERFACE_H +#define ANDROID_MEDIAMETADATARETRIEVERINTERFACE_H + +#include <utils/RefBase.h> +#include <media/mediametadataretriever.h> +#include <private/media/VideoFrame.h> + +namespace android { + +// Abstract base class +class MediaMetadataRetrieverBase : public RefBase +{ +public: + MediaMetadataRetrieverBase() {} + virtual ~MediaMetadataRetrieverBase() {} + virtual status_t setDataSource(const char *url) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setMode(int mode) = 0; + virtual status_t getMode(int* mode) const = 0; + virtual VideoFrame* captureFrame() = 0; + virtual MediaAlbumArt* extractAlbumArt() = 0; + virtual const char* extractMetadata(int keyCode) = 0; +}; + +// MediaMetadataRetrieverInterface +class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase +{ +public: + virtual ~MediaMetadataRetrieverInterface() {} +}; + +}; // namespace android + +#endif // ANDROID_MEDIAMETADATARETRIEVERINTERFACE_H + diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h new file mode 100644 index 0000000..7f0e7b3 --- /dev/null +++ b/include/media/MediaPlayerInterface.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEDIAPLAYERINTERFACE_H +#define ANDROID_MEDIAPLAYERINTERFACE_H + +#ifdef __cplusplus + +#include <ui/ISurface.h> +#include <utils/RefBase.h> + +#include <media/mediaplayer.h> +#include <media/AudioSystem.h> + +namespace android { + +enum player_type { + PV_PLAYER = 1, + SONIVOX_PLAYER = 2, + VORBIS_PLAYER = 3 +}; + +#define DEFAULT_AUDIOSINK_BUFFERCOUNT 4 +#define DEFAULT_AUDIOSINK_BUFFERSIZE 1200 +#define DEFAULT_AUDIOSINK_SAMPLERATE 44100 + + +// callback mechanism for passing messages to MediaPlayer object +typedef void (*notify_callback_f)(void* cookie, int msg, int ext1, int ext2); + +// abstract base class - use MediaPlayerInterface +class MediaPlayerBase : public RefBase +{ +public: + + // AudioSink: abstraction layer for audio output + class AudioSink : public RefBase { + public: + virtual ~AudioSink() {} + virtual bool ready() const = 0; // audio output is open and ready + virtual bool realtime() const = 0; // audio output is real-time output + virtual ssize_t bufferSize() const = 0; + virtual ssize_t frameCount() const = 0; + virtual ssize_t channelCount() const = 0; + virtual ssize_t frameSize() const = 0; + virtual uint32_t latency() const = 0; + virtual float msecsPerFrame() const = 0; + virtual status_t open(uint32_t sampleRate, int channelCount, int format=AudioSystem::PCM_16_BIT, int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT) = 0; + virtual void start() = 0; + virtual ssize_t write(const void* buffer, size_t size) = 0; + virtual void stop() = 0; + virtual void flush() = 0; + virtual void pause() = 0; + virtual void close() = 0; + }; + + MediaPlayerBase() : mCookie(0), mNotify(0) {} + virtual ~MediaPlayerBase() {} + virtual status_t initCheck() = 0; + virtual bool hardwareOutput() = 0; + virtual status_t setDataSource(const char *url) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setVideoSurface(const sp<ISurface>& surface) = 0; + virtual status_t prepare() = 0; + virtual status_t prepareAsync() = 0; + virtual status_t start() = 0; + virtual status_t stop() = 0; + virtual status_t pause() = 0; + virtual bool isPlaying() = 0; + virtual status_t seekTo(int msec) = 0; + virtual status_t getCurrentPosition(int *msec) = 0; + virtual status_t getDuration(int *msec) = 0; + virtual status_t reset() = 0; + virtual status_t setLooping(int loop) = 0; + virtual player_type playerType() = 0; + virtual void setNotifyCallback(void* cookie, notify_callback_f notifyFunc) { + mCookie = cookie; mNotify = notifyFunc; } + +protected: + virtual void sendEvent(int msg, int ext1=0, int ext2=0) { if (mNotify) mNotify(mCookie, msg, ext1, ext2); } + + void* mCookie; + notify_callback_f mNotify; +}; + +// Implement this class for media players that use the AudioFlinger software mixer +class MediaPlayerInterface : public MediaPlayerBase +{ +public: + virtual ~MediaPlayerInterface() { } + virtual bool hardwareOutput() { return false; } + virtual void setAudioSink(const sp<AudioSink>& audioSink) { mAudioSink = audioSink; } +protected: + sp<AudioSink> mAudioSink; +}; + +// Implement this class for media players that output directo to hardware +class MediaPlayerHWInterface : public MediaPlayerBase +{ +public: + virtual ~MediaPlayerHWInterface() {} + virtual bool hardwareOutput() { return true; } + virtual status_t setVolume(float leftVolume, float rightVolume) = 0; + virtual status_t setAudioStreamType(int streamType) = 0; +}; + +}; // namespace android + +#endif // __cplusplus + + +#endif // ANDROID_MEDIAPLAYERINTERFACE_H + diff --git a/include/media/PVMediaRecorder.h b/include/media/PVMediaRecorder.h new file mode 100644 index 0000000..3315c59 --- /dev/null +++ b/include/media/PVMediaRecorder.h @@ -0,0 +1,65 @@ +/* + ** + ** Copyright 2008, HTC 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. + */ + +#ifndef ANDROID_PVMEDIARECORDER_H +#define ANDROID_PVMEDIARECORDER_H + +#include <media/mediarecorder.h> +#include <media/IMediaPlayerClient.h> + +namespace android { + +class ISurface; +class ICamera; +class AuthorDriverWrapper; + +class PVMediaRecorder +{ +public: + PVMediaRecorder(); + ~PVMediaRecorder(); + + status_t init(); + status_t setAudioSource(audio_source as); + status_t setVideoSource(video_source vs); + status_t setOutputFormat(output_format of); + status_t setAudioEncoder(audio_encoder ae); + status_t setVideoEncoder(video_encoder ve); + status_t setVideoSize(int width, int height); + status_t setVideoFrameRate(int frames_per_second); + status_t setCamera(const sp<ICamera>& camera); + status_t setPreviewSurface(const sp<ISurface>& surface); + status_t setOutputFile(const char *path); + status_t setOutputFile(int fd, int64_t offset, int64_t length); + status_t setListener(const sp<IMediaPlayerClient>& listener); + status_t prepare(); + status_t start(); + status_t stop(); + status_t close(); + status_t reset(); + status_t getMaxAmplitude(int *max); + +private: + status_t doStop(); + + AuthorDriverWrapper* mAuthorDriverWrapper; +}; + +}; // namespace android + +#endif // ANDROID_PVMEDIARECORDER_H + diff --git a/include/media/PVMetadataRetriever.h b/include/media/PVMetadataRetriever.h new file mode 100644 index 0000000..c202dfe --- /dev/null +++ b/include/media/PVMetadataRetriever.h @@ -0,0 +1,51 @@ +/* +** +** Copyright (C) 2008 The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_PVMETADATARETRIEVER_H +#define ANDROID_PVMETADATARETRIEVER_H + +#include <utils/Errors.h> +#include <media/MediaMetadataRetrieverInterface.h> +#include <private/media/VideoFrame.h> + +namespace android { + +class MetadataDriver; + +class PVMetadataRetriever : public MediaMetadataRetrieverInterface +{ +public: + PVMetadataRetriever(); + virtual ~PVMetadataRetriever(); + + virtual status_t setDataSource(const char *url); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); + virtual status_t setMode(int mode); + virtual status_t getMode(int* mode) const; + virtual VideoFrame* captureFrame(); + virtual MediaAlbumArt* extractAlbumArt(); + virtual const char* extractMetadata(int keyCode); + +private: + mutable Mutex mLock; + MetadataDriver* mMetadataDriver; + char* mDataSourcePath; +}; + +}; // namespace android + +#endif // ANDROID_PVMETADATARETRIEVER_H diff --git a/include/media/PVPlayer.h b/include/media/PVPlayer.h new file mode 100644 index 0000000..6d98852 --- /dev/null +++ b/include/media/PVPlayer.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PVPLAYER_H +#define ANDROID_PVPLAYER_H + +#include <utils/Errors.h> +#include <media/MediaPlayerInterface.h> + +#define MAX_OPENCORE_INSTANCES 25 + +#ifdef MAX_OPENCORE_INSTANCES +#include <cutils/atomic.h> +#endif + +class PlayerDriver; + +namespace android { + +class PVPlayer : public MediaPlayerInterface +{ +public: + PVPlayer(); + virtual ~PVPlayer(); + + virtual status_t initCheck(); + virtual status_t setDataSource(const char *url); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); + virtual status_t setVideoSurface(const sp<ISurface>& surface); + virtual status_t prepare(); + virtual status_t prepareAsync(); + virtual status_t start(); + virtual status_t stop(); + virtual status_t pause(); + virtual bool isPlaying(); + virtual status_t seekTo(int msec); + virtual status_t getCurrentPosition(int *msec); + virtual status_t getDuration(int *msec); + virtual status_t reset(); + virtual status_t setLooping(int loop); + virtual player_type playerType() { return PV_PLAYER; } + + // make available to PlayerDriver + void sendEvent(int msg, int ext1=0, int ext2=0) { MediaPlayerBase::sendEvent(msg, ext1, ext2); } + +private: + static void do_nothing(status_t s, void *cookie, bool cancelled) { } + static void run_init(status_t s, void *cookie, bool cancelled); + static void run_set_video_surface(status_t s, void *cookie, bool cancelled); + static void run_set_audio_output(status_t s, void *cookie, bool cancelled); + static void run_prepare(status_t s, void *cookie, bool cancelled); + + PlayerDriver* mPlayerDriver; + char * mDataSourcePath; + bool mIsDataSourceSet; + sp<ISurface> mSurface; + int mSharedFd; + status_t mInit; + int mDuration; + +#ifdef MAX_OPENCORE_INSTANCES + static volatile int32_t sNumInstances; +#endif +}; + +}; // namespace android + +#endif // ANDROID_PVPLAYER_H diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h new file mode 100644 index 0000000..ec64e4d --- /dev/null +++ b/include/media/ToneGenerator.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TONEGENERATOR_H_ +#define ANDROID_TONEGENERATOR_H_ + +#include <utils/RefBase.h> +#include <utils/Vector.h> +#include <utils/threads.h> +#include <media/AudioSystem.h> +#include <media/AudioTrack.h> + +namespace android { + +class ToneGenerator { +public: + + // List of all available tones + // This enum must be kept consistant with constants in ToneGenerator JAVA class + enum tone_type { + // DTMF tones ITU-T Recommendation Q.23 + TONE_DTMF_0 = 0, // 0 key: 1336Hz, 941Hz + TONE_DTMF_1, // 1 key: 1209Hz, 697Hz + TONE_DTMF_2, // 2 key: 1336Hz, 697Hz + TONE_DTMF_3, // 3 key: 1477Hz, 697Hz + TONE_DTMF_4, // 4 key: 1209Hz, 770Hz + TONE_DTMF_5, // 5 key: 1336Hz, 770Hz + TONE_DTMF_6, // 6 key: 1477Hz, 770Hz + TONE_DTMF_7, // 7 key: 1209Hz, 852Hz + TONE_DTMF_8, // 8 key: 1336Hz, 852Hz + TONE_DTMF_9, // 9 key: 1477Hz, 852Hz + TONE_DTMF_S, // * key: 1209Hz, 941Hz + TONE_DTMF_P, // # key: 1477Hz, 941Hz + TONE_DTMF_A, // A key: 1633Hz, 697Hz + TONE_DTMF_B, // B key: 1633Hz, 770Hz + TONE_DTMF_C, // C key: 1633Hz, 852Hz + TONE_DTMF_D, // D key: 1633Hz, 941Hz + // Call supervisory tones: 3GPP TS 22.001 (CEPT) + TONE_SUP_DIAL, // Dial tone: 425Hz, continuous + TONE_SUP_BUSY, // Busy tone: 425Hz, 500ms ON, 500ms OFF... + TONE_SUP_CONGESTION, // Congestion tone: 425Hz, 200ms ON, 200ms OFF... + TONE_SUP_RADIO_ACK, // Radio path acknowlegment: 425Hz, 200ms ON + TONE_SUP_RADIO_NOTAVAIL, // Radio path not available: 425Hz, 200ms ON, 200 OFF 3 bursts + TONE_SUP_ERROR, // Error/Special info: 950Hz+1400Hz+1800Hz, 330ms ON, 1s OFF... + TONE_SUP_CALL_WAITING, // Call Waiting: 425Hz, 200ms ON, 600ms OFF, 200ms ON, 3s OFF... + TONE_SUP_RINGTONE, // Ring Tone: 425Hz, 1s ON, 4s OFF... + // Proprietary tones: 3GPP TS 31.111 + TONE_PROP_BEEP, // General beep: 400Hz+1200Hz, 35ms ON + TONE_PROP_ACK, // Positive Acknowlgement: 1200Hz, 100ms ON, 100ms OFF 2 bursts + TONE_PROP_NACK, // Negative Acknowlgement: 300Hz+400Hz+500Hz, 400ms ON + TONE_PROP_PROMPT, // Prompt tone: 400Hz+1200Hz, 200ms ON + TONE_PROP_BEEP2, // General double beep: 400Hz+1200Hz, 35ms ON, 200ms OFF, 35ms on + NUM_TONES + }; + + ToneGenerator(int streamType, float volume); + ~ToneGenerator(); + + bool startTone(int toneType); + void stopTone(); + + bool isInited() { return (mState == TONE_IDLE)?false:true;} + +private: + + enum tone_state { + TONE_IDLE, // ToneGenerator is being initialized or initialization failed + TONE_INIT, // ToneGenerator has been successfully initialized and is not playing + TONE_STARTING, // ToneGenerator is starting playing + TONE_PLAYING, // ToneGenerator is playing + TONE_STOPPING, // ToneGenerator is stoping + TONE_RESTARTING // + }; + + static const unsigned int TONEGEN_MAX_WAVES = 3; + static const unsigned int TONEGEN_MAX_SEGMENTS = 4; // Maximun number of elenemts in + static const unsigned int TONEGEN_INF = 0xFFFFFFFF; // Represents infinite time duration + static const float TONEGEN_GAIN = 0.9; // Default gain passed to WaveGenerator(). + + // ToneDescriptor class contains all parameters needed to generate a tone: + // - The array waveFreq[] contains the frequencies of all individual waves making the multi-tone. + // The number of sine waves varies from 1 to TONEGEN_MAX_WAVES. + // The first null value indicates that no more waves are needed. + // - The array segments[] is used to generate the tone pulses. A segment is a period of time + // during which the tone is ON or OFF. Segments with even index (starting from 0) + // correspond to tone ON state and segments with odd index to OFF state. + // The data stored in segments[] is the duration of the corresponding period in ms. + // The first segment encountered with a 0 duration indicates that no more segment follows. + // - repeatCnt indicates the number of times the sequence described by segments[] array must be repeated. + // When the tone generator encounters the first 0 duration segment, it will compare repeatCnt to mCurCount. + // If mCurCount > repeatCnt, the tone is stopped automatically. + + class ToneDescriptor { + public: + unsigned short waveFreq[TONEGEN_MAX_WAVES+1]; + unsigned long segments[TONEGEN_MAX_SEGMENTS+1]; + unsigned long repeatCnt; + }; + + static const ToneDescriptor toneDescriptors[NUM_TONES]; + + unsigned int mTotalSmp; // Total number of audio samples played (gives current time) + unsigned int mNextSegSmp; // Position of next segment transition expressed in samples + // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly + // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded, + // no crash will occur but tone sequence will show a glitch. + + unsigned short mCurSegment; // Current segment index in ToneDescriptor segments[] + unsigned short mCurCount; // Current sequence repeat count + volatile unsigned short mState; // ToneGenerator state (tone_state) + const ToneDescriptor *mpToneDesc; // pointer to active tone descriptor + const ToneDescriptor *mpNewToneDesc; // pointer to next active tone descriptor + + int mSamplingRate; // AudioFlinger Sampling rate + AudioTrack *mpAudioTrack; // Pointer to audio track used for playback + Mutex mLock; // Mutex to control concurent access to ToneGenerator object from audio callback and application API + Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond + Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested + float mVolume; // Volume applied to audio track + int mStreamType; // Audio stream used for output + unsigned int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). + + bool initAudioTrack(); + static void audioCallback(int event, void* user, void *info); + bool prepareWave(); + unsigned int numWaves(); + void clearWaveGens(); + + // WaveGenerator generates a single sine wave + class WaveGenerator { + public: + enum gen_command { + WAVEGEN_START, // Start/restart wave from phase 0 + WAVEGEN_CONT, // Continue wave from current phase + WAVEGEN_STOP // Stop wave on zero crossing + }; + + WaveGenerator(unsigned short samplingRate, unsigned short frequency, + float volume); + ~WaveGenerator(); + + void getSamples(short *outBuffer, unsigned int count, + unsigned int command); + + private: + static const short GEN_AMP = 32000; // amplitude of generator + static const short S_Q14 = 14; // shift for Q14 + static const short S_Q15 = 15; // shift for Q15 + + short mA1_Q14; // Q14 coefficient + // delay line of full amplitude generator + short mS1, mS2; // delay line S2 oldest + short mS2_0; // saved value for reinitialisation + short mAmplitude_Q15; // Q15 amplitude + }; + + Vector<WaveGenerator *> mWaveGens; // list of active wave generators. +}; + +} +; // namespace android + +#endif /*ANDROID_TONEGENERATOR_H_*/ diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h new file mode 100644 index 0000000..f2719d3 --- /dev/null +++ b/include/media/mediametadataretriever.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef MEDIAMETADATARETRIEVER_H +#define MEDIAMETADATARETRIEVER_H + +#include <utils/Errors.h> // for status_t +#include <utils/threads.h> +#include <utils/IMemory.h> +#include <media/IMediaMetadataRetriever.h> + +namespace android { + +class IMediaPlayerService; +class IMediaMetadataRetriever; + +// Keep these in synch with the constants defined in MediaMetadataRetriever.java +// class. +enum { + METADATA_KEY_CD_TRACK_NUMBER = 0, + METADATA_KEY_ALBUM = 1, + METADATA_KEY_ARTIST = 2, + METADATA_KEY_AUTHOR = 3, + METADATA_KEY_COMPOSER = 4, + METADATA_KEY_DATE = 5, + METADATA_KEY_GENRE = 6, + METADATA_KEY_TITLE = 7, + METADATA_KEY_YEAR = 8, + METADATA_KEY_DURATION = 9, + METADATA_KEY_NUM_TRACKS = 10, + METADATA_KEY_IS_DRM_CRIPPLED = 11, + METADATA_KEY_CODEC = 12, + METADATA_KEY_RATING = 13, + METADATA_KEY_COMMENT = 14, + METADATA_KEY_COPYRIGHT = 15, + METADATA_KEY_BIT_RATE = 16, + METADATA_KEY_FRAME_RATE = 17, + METADATA_KEY_VIDEO_FORMAT = 18, + METADATA_KEY_VIDEO_HEIGHT = 19, + METADATA_KEY_VIDEO_WIDTH = 20, + // Add more here... +}; + + +class MediaMetadataRetriever: public RefBase +{ +public: + MediaMetadataRetriever(); + ~MediaMetadataRetriever(); + void disconnect(); + status_t setDataSource(const char* dataSourceUrl); + status_t setDataSource(int fd, int64_t offset, int64_t length); + status_t setMode(int mode); + status_t getMode(int* mode); + sp<IMemory> captureFrame(); + sp<IMemory> extractAlbumArt(); + const char* extractMetadata(int keyCode); + +private: + static const sp<IMediaPlayerService>& getService(); + + class DeathNotifier: public IBinder::DeathRecipient + { + public: + DeathNotifier() {} + virtual ~DeathNotifier(); + virtual void binderDied(const wp<IBinder>& who); + }; + + static sp<DeathNotifier> sDeathNotifier; + static Mutex sServiceLock; + static sp<IMediaPlayerService> sService; + + Mutex mLock; + sp<IMediaMetadataRetriever> mRetriever; + +}; + +}; // namespace android + +#endif // MEDIAMETADATARETRIEVER_H diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h new file mode 100644 index 0000000..7288445 --- /dev/null +++ b/include/media/mediaplayer.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEDIAPLAYER_H +#define ANDROID_MEDIAPLAYER_H + +#include <utils/IMemory.h> +#include <ui/Surface.h> +#include <media/IMediaPlayerClient.h> +#include <media/IMediaPlayer.h> +#include <media/IMediaPlayerService.h> +#include <utils/SortedVector.h> + +namespace android { + +enum media_event_type { + MEDIA_NOP = 0, // interface test message + MEDIA_PREPARED = 1, + MEDIA_PLAYBACK_COMPLETE = 2, + MEDIA_BUFFERING_UPDATE = 3, + MEDIA_SEEK_COMPLETE = 4, + MEDIA_SET_VIDEO_SIZE = 5, + MEDIA_ERROR = 100, +}; + +typedef int media_error_type; +const media_error_type MEDIA_ERROR_UNKNOWN = 1; +const media_error_type MEDIA_ERROR_SERVER_DIED = 100; + +enum media_player_states { + MEDIA_PLAYER_STATE_ERROR = 0, + MEDIA_PLAYER_IDLE = 1 << 0, + MEDIA_PLAYER_INITIALIZED = 1 << 1, + MEDIA_PLAYER_PREPARING = 1 << 2, + MEDIA_PLAYER_PREPARED = 1 << 3, + MEDIA_PLAYER_STARTED = 1 << 4, + MEDIA_PLAYER_PAUSED = 1 << 5, + MEDIA_PLAYER_STOPPED = 1 << 6, + MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7 +}; + +// ---------------------------------------------------------------------------- +// ref-counted object for callbacks +class MediaPlayerListener: virtual public RefBase +{ +public: + virtual void notify(int msg, int ext1, int ext2) = 0; +}; + +class MediaPlayer : public BnMediaPlayerClient +{ +public: + MediaPlayer(); + ~MediaPlayer(); + void onFirstRef(); + void disconnect(); + status_t setDataSource(const char *url); + status_t setDataSource(int fd, int64_t offset, int64_t length); + status_t setVideoSurface(const sp<Surface>& surface); + status_t setListener(const sp<MediaPlayerListener>& listener); + status_t prepare(); + status_t prepareAsync(); + status_t start(); + status_t stop(); + status_t pause(); + bool isPlaying(); + status_t getVideoWidth(int *w); + status_t getVideoHeight(int *h); + status_t seekTo(int msec); + status_t getCurrentPosition(int *msec); + status_t getDuration(int *msec); + status_t reset(); + status_t setAudioStreamType(int type); + status_t setLooping(int loop); + bool isLooping(); + status_t setVolume(float leftVolume, float rightVolume); + void notify(int msg, int ext1, int ext2); + static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); + static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); + +private: + void clear_l(); + status_t seekTo_l(int msec); + status_t prepareAsync_l(); + status_t getDuration_l(int *msec); + status_t setDataSource(const sp<IMediaPlayer>& player); + + static const sp<IMediaPlayerService>& getMediaPlayerService(); + static void addObitRecipient(const wp<MediaPlayer>& recipient); + static void removeObitRecipient(const wp<MediaPlayer>& recipient); + + class DeathNotifier: public IBinder::DeathRecipient + { + public: + DeathNotifier() {} + virtual ~DeathNotifier(); + + virtual void binderDied(const wp<IBinder>& who); + }; + + sp<IMediaPlayer> mPlayer; + Mutex mLock; + Mutex mNotifyLock; + Condition mSignal; + sp<MediaPlayerListener> mListener; + void* mCookie; + media_player_states mCurrentState; + int mDuration; + int mCurrentPosition; + int mSeekPosition; + bool mPrepareSync; + status_t mPrepareStatus; + int mStreamType; + bool mLoop; + float mLeftVolume; + float mRightVolume; + int mVideoWidth; + int mVideoHeight; + + friend class DeathNotifier; + + static Mutex sServiceLock; + static sp<IMediaPlayerService> sMediaPlayerService; + static sp<DeathNotifier> sDeathNotifier; + static SortedVector< wp<MediaPlayer> > sObitRecipients; +}; + +}; // namespace android + +#endif // ANDROID_MEDIAPLAYER_H + diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h new file mode 100644 index 0000000..8991f08 --- /dev/null +++ b/include/media/mediarecorder.h @@ -0,0 +1,155 @@ +/* + ** Copyright (C) 2008 The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** + ** limitations under the License. + */ + +#ifndef ANDROID_MEDIARECORDER_H +#define ANDROID_MEDIARECORDER_H + +#include <utils.h> +#include <media/IMediaPlayerClient.h> + +namespace android { + +class Surface; +class IMediaRecorder; +class ICamera; + +typedef void (*media_completion_f)(status_t status, void *cookie); + +/* Do not change these values without updating their counterparts + * in java/android/android/media/MediaRecorder.java! + */ +enum audio_source { + AUDIO_SOURCE_DEFAULT = 0, + AUDIO_SOURCE_MIC = 1, +}; + +enum video_source { + VIDEO_SOURCE_DEFAULT = 0, + VIDEO_SOURCE_CAMERA = 1, +}; + +//Please update java/android/android/media/MediaRecorder.java if the following is updated. +enum output_format { + OUTPUT_FORMAT_DEFAULT = 0, + OUTPUT_FORMAT_THREE_GPP, + OUTPUT_FORMAT_MPEG_4, + OUTPUT_FORMAT_RAW_AMR, + OUTPUT_FORMAT_LIST_END // must be last - used to validate format type +}; + +enum audio_encoder { + AUDIO_ENCODER_DEFAULT = 0, + AUDIO_ENCODER_AMR_NB = 1, +}; + +enum video_encoder { + VIDEO_ENCODER_DEFAULT = 0, + VIDEO_ENCODER_H263 = 1, + VIDEO_ENCODER_H264 = 2, + VIDEO_ENCODER_MPEG_4_SP = 3, +}; + +// Maximum frames per second is 24 +#define MEDIA_RECORDER_MAX_FRAME_RATE 24 + +/* + * The state machine of the media_recorder uses a set of different state names. + * The mapping between the media_recorder and the pvauthorengine is shown below: + * + * mediarecorder pvauthorengine + * ---------------------------------------------------------------- + * MEDIA_RECORDER_ERROR ERROR + * MEDIA_RECORDER_IDLE IDLE + * MEDIA_RECORDER_INITIALIZED OPENED + * MEDIA_RECORDER_DATASOURCE_CONFIGURED + * MEDIA_RECORDER_PREPARED INITIALIZED + * MEDIA_RECORDER_RECORDING RECORDING + */ +enum media_recorder_states { + MEDIA_RECORDER_ERROR = 0, + MEDIA_RECORDER_IDLE = 1 << 0, + MEDIA_RECORDER_INITIALIZED = 1 << 1, + MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2, + MEDIA_RECORDER_PREPARED = 1 << 3, + MEDIA_RECORDER_RECORDING = 1 << 4, +}; + +// The "msg" code passed to the listener in notify. +enum { + MEDIA_RECORDER_EVENT_ERROR = 1 +}; + +enum { + MEDIA_RECORDER_ERROR_UNKNOWN = 1 +}; + +// ---------------------------------------------------------------------------- +// ref-counted object for callbacks +class MediaRecorderListener: virtual public RefBase +{ +public: + virtual void notify(int msg, int ext1, int ext2) = 0; +}; + +class MediaRecorder : public BnMediaPlayerClient +{ +public: + MediaRecorder(); + ~MediaRecorder(); + + status_t initCheck(); + status_t setCamera(const sp<ICamera>& camera); + status_t setPreviewSurface(const sp<Surface>& surface); + status_t setVideoSource(int vs); + status_t setAudioSource(int as); + status_t setOutputFormat(int of); + status_t setVideoEncoder(int ve); + status_t setAudioEncoder(int ae); + status_t setOutputFile(const char* path); + status_t setOutputFile(int fd, int64_t offset, int64_t length); + status_t setVideoSize(int width, int height); + status_t setVideoFrameRate(int frames_per_second); + status_t setListener(const sp<MediaRecorderListener>& listener); + status_t prepare(); + status_t getMaxAmplitude(int* max); + status_t start(); + status_t stop(); + status_t reset(); + status_t init(); + status_t close(); + status_t release(); + void notify(int msg, int ext1, int ext2); + +private: + void doCleanUp(); + status_t doReset(); + + sp<IMediaRecorder> mMediaRecorder; + sp<MediaRecorderListener> mListener; + media_recorder_states mCurrentState; + bool mIsAudioSourceSet; + bool mIsVideoSourceSet; + bool mIsAudioEncoderSet; + bool mIsVideoEncoderSet; + bool mIsOutputFileSet; + Mutex mLock; + Mutex mNotifyLock; +}; + +}; // namespace android + +#endif // ANDROID_MEDIARECORDER_H diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h new file mode 100644 index 0000000..fbef1db --- /dev/null +++ b/include/media/mediascanner.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIASCANNER_H +#define MEDIASCANNER_H + +#include <utils.h> +#include <pthread.h> + +namespace android { + +class MediaScannerClient; +class StringArray; + +class MediaScanner +{ +public: + MediaScanner(); + ~MediaScanner(); + + typedef bool (*ExceptionCheck)(void* env); + + status_t processFile(const char *path, const char *mimeType, MediaScannerClient& client); + status_t processDirectory(const char *path, const char* extensions, + MediaScannerClient& client, ExceptionCheck exceptionCheck, void* exceptionEnv); + void setLocale(const char* locale); + + // extracts album art as a block of data + char* extractAlbumArt(int fd); + + static void uninitializeForThread(); + +private: + status_t doProcessDirectory(char *path, int pathRemaining, const char* extensions, + MediaScannerClient& client, ExceptionCheck exceptionCheck, void* exceptionEnv); + void initializeForThread(); + + // current locale (like "ja_JP"), created/destroyed with strdup()/free() + char* mLocale; +}; + + +class MediaScannerClient +{ +public: + MediaScannerClient(); + virtual ~MediaScannerClient(); + void setLocale(const char* locale); + void beginFile(); + bool addStringTag(const char* name, const char* value); + void endFile(); + + virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; + virtual bool handleStringTag(const char* name, const char* value) = 0; + virtual bool setMimeType(const char* mimeType) = 0; + +protected: + void convertValues(uint32_t encoding); + +protected: + // cached name and value strings, for native encoding support. + StringArray* mNames; + StringArray* mValues; + + // default encoding based on MediaScanner::mLocale string + uint32_t mLocaleEncoding; +}; + +}; // namespace android + +#endif // MEDIASCANNER_H + diff --git a/include/media/thread_init.h b/include/media/thread_init.h new file mode 100644 index 0000000..2c0c1f1 --- /dev/null +++ b/include/media/thread_init.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef THREAD_INIT_H +#define THREAD_INIT_H + +bool InitializeForThread(); +void UninitializeForThread(); +void keydestructor(void*); + +#endif /* THREAD_INIT_H*/ + diff --git a/include/pim/EventRecurrence.h b/include/pim/EventRecurrence.h new file mode 100644 index 0000000..1ceda41 --- /dev/null +++ b/include/pim/EventRecurrence.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef _PIM_EVENT_RECURRENCE_H +#define _PIM_EVENT_RECURRENCE_H + +#include <utils/String16.h> + +namespace android { + +struct EventRecurrence +{ +public: + EventRecurrence(); + ~EventRecurrence(); + + status_t parse(const String16&); + + + enum freq_t { + SECONDLY = 1, + MINUTELY = 2, + HOURLY = 3, + DAILY = 4, + WEEKLY = 5, + MONTHLY = 6, + YEARLY = 7 + }; + + enum { + SU = 0x00010000, + MO = 0x00020000, + TU = 0x00040000, + WE = 0x00080000, + TH = 0x00100000, + FR = 0x00200000, + SA = 0x00400000 + }; + + freq_t freq; + String16 until; + int count; + int interval; + int* bysecond; + int bysecondCount; + int* byminute; + int byminuteCount; + int* byhour; + int byhourCount; + int* byday; + int* bydayNum; + int bydayCount; + int* bymonthday; + int bymonthdayCount; + int* byyearday; + int byyeardayCount; + int* byweekno; + int byweeknoCount; + int* bymonth; + int bymonthCount; + int* bysetpos; + int bysetposCount; + int wkst; +}; + +}; // namespace android + +#endif // _PIM_EVENT_RECURRENCE_H diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h new file mode 100644 index 0000000..1991aa7 --- /dev/null +++ b/include/private/media/AudioTrackShared.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIO_TRACK_SHARED_H +#define ANDROID_AUDIO_TRACK_SHARED_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/threads.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +#define MAX_SAMPLE_RATE 65535 +#define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO) +// Maximum cumulated timeout milliseconds before restarting audioflinger thread +#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time +#define MAX_RUN_TIMEOUT_MS 1000 +#define WAIT_PERIOD_MS 10 + + +struct audio_track_cblk_t +{ + + // The data members are grouped so that members accessed frequently and in the same context + // are in the same line of data cache. + Mutex lock; + Condition cv; + volatile uint32_t user; + volatile uint32_t server; + uint32_t userBase; + uint32_t serverBase; + void* buffers; + uint32_t frameCount; + // Cache line boundary + uint32_t loopStart; + uint32_t loopEnd; + int loopCount; + volatile union { + uint16_t volume[2]; + uint32_t volumeLR; + }; + uint16_t sampleRate; + uint16_t channels; + int16_t flowControlFlag; // underrun (out) or overrrun (in) indication + uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord + uint8_t forceReady; + uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger + uint16_t waitTimeMs; // Cumulated wait time + // Padding ensuring that data buffer starts on a cache line boundary (32 bytes). + // See AudioFlinger::TrackBase constructor + int32_t Padding[3]; + + audio_track_cblk_t(); + uint32_t stepUser(uint32_t frameCount); + bool stepServer(uint32_t frameCount); + void* buffer(uint32_t offset) const; + uint32_t framesAvailable(); + uint32_t framesAvailable_l(); + uint32_t framesReady(); +}; + + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_AUDIO_TRACK_SHARED_H diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h new file mode 100644 index 0000000..9c35274ba --- /dev/null +++ b/include/private/media/VideoFrame.h @@ -0,0 +1,127 @@ +/* +** +** Copyright (C) 2008 The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_VIDEO_FRAME_H +#define ANDROID_VIDEO_FRAME_H + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <utils/Log.h> + +namespace android { + +// A simple buffer to hold binary data +class MediaAlbumArt +{ +public: + MediaAlbumArt(): mSize(0), mData(0) {} + + explicit MediaAlbumArt(const char* url) { + mSize = 0; + mData = NULL; + FILE *in = fopen(url, "r"); + if (!in) { + return; + } + fseek(in, 0, SEEK_END); + mSize = ftell(in); // Allocating buffer of size equals to the external file size. + if (mSize == 0 || (mData = new uint8_t[mSize]) == NULL) { + fclose(in); + if (mSize != 0) { + mSize = 0; + } + return; + } + rewind(in); + if (fread(mData, 1, mSize, in) != mSize) { // Read failed. + delete[] mData; + mData = NULL; + mSize = 0; + return; + } + fclose(in); + } + + MediaAlbumArt(const MediaAlbumArt& copy) { + mSize = copy.mSize; + mData = NULL; // initialize it first + if (mSize > 0 && copy.mData != NULL) { + mData = new uint8_t[copy.mSize]; + if (mData != NULL) { + memcpy(mData, copy.mData, mSize); + } else { + mSize = 0; + } + } + } + + ~MediaAlbumArt() { + if (mData != 0) { + delete[] mData; + } + } + + // Intentional public access modifier: + // We have to know the internal structure in order to share it between + // processes? + uint32_t mSize; // Number of bytes in mData + uint8_t* mData; // Actual binary data +}; + +// Represents a color converted (RGB-based) video frame +// with bitmap pixels stored in FrameBuffer +class VideoFrame +{ +public: + VideoFrame(): mWidth(0), mHeight(0), mDisplayWidth(0), mDisplayHeight(0), mSize(0), mData(0) {} + + VideoFrame(const VideoFrame& copy) { + mWidth = copy.mWidth; + mHeight = copy.mHeight; + mDisplayWidth = copy.mDisplayWidth; + mDisplayHeight = copy.mDisplayHeight; + mSize = copy.mSize; + mData = NULL; // initialize it first + if (mSize > 0 && copy.mData != NULL) { + mData = new uint8_t[mSize]; + if (mData != NULL) { + memcpy(mData, copy.mData, mSize); + } else { + mSize = 0; + } + } + } + + ~VideoFrame() { + if (mData != 0) { + delete[] mData; + } + } + + // Intentional public access modifier: + uint32_t mWidth; + uint32_t mHeight; + uint32_t mDisplayWidth; + uint32_t mDisplayHeight; + uint32_t mSize; // Number of bytes in mData + uint8_t* mData; // Actual binary data +}; + +}; // namespace android + +#endif // ANDROID_VIDEO_FRAME_H diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h new file mode 100644 index 0000000..0c7ad46 --- /dev/null +++ b/include/private/opengles/gl_context.h @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_OPENGLES_CONTEXT_H +#define ANDROID_OPENGLES_CONTEXT_H + +#include <stdint.h> +#include <stddef.h> +#include <sys/types.h> +#include <pthread.h> +#ifdef HAVE_ANDROID_OS +#include <bionic_tls.h> +#endif + +#include <private/pixelflinger/ggl_context.h> + +#include <GLES/gl.h> +#include <GLES/glext.h> + +namespace android { + +const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10; + +class EGLTextureObject; +class EGLSurfaceManager; +class EGLBufferObjectManager; + +namespace gl { + +struct ogles_context_t; +struct matrixx_t; +struct transform_t; +struct buffer_t; + +ogles_context_t* getGlContext(); + +template<typename T> +static inline void swap(T& a, T& b) { + T t(a); a = b; b = t; +} +template<typename T> +inline T max(T a, T b) { + return a<b ? b : a; +} +template<typename T> +inline T max(T a, T b, T c) { + return max(a, max(b, c)); +} +template<typename T> +inline T min(T a, T b) { + return a<b ? a : b; +} +template<typename T> +inline T min(T a, T b, T c) { + return min(a, min(b, c)); +} +template<typename T> +inline T min(T a, T b, T c, T d) { + return min(min(a,b), min(c,d)); +} + +// ---------------------------------------------------------------------------- +// vertices +// ---------------------------------------------------------------------------- + +struct vec3_t { + union { + struct { GLfixed x, y, z; }; + struct { GLfixed r, g, b; }; + struct { GLfixed S, T, R; }; + GLfixed v[3]; + }; +}; + +struct vec4_t { + union { + struct { GLfixed x, y, z, w; }; + struct { GLfixed r, g, b, a; }; + struct { GLfixed S, T, R, Q; }; + GLfixed v[4]; + }; +}; + +struct vertex_t { + enum { + // these constant matter for our clipping + CLIP_L = 0x0001, // clipping flags + CLIP_R = 0x0002, + CLIP_B = 0x0004, + CLIP_T = 0x0008, + CLIP_N = 0x0010, + CLIP_F = 0x0020, + + EYE = 0x0040, + RESERVED = 0x0080, + + USER_CLIP_0 = 0x0100, // user clipping flags + USER_CLIP_1 = 0x0200, + USER_CLIP_2 = 0x0400, + USER_CLIP_3 = 0x0800, + USER_CLIP_4 = 0x1000, + USER_CLIP_5 = 0x2000, + + LIT = 0x4000, // lighting has been applied + TT = 0x8000, // texture coords transformed + + FRUSTUM_CLIP_ALL= 0x003F, + USER_CLIP_ALL = 0x3F00, + CLIP_ALL = 0x3F3F, + }; + + // the fields below are arranged to minimize d-cache usage + // we group together, by cache-line, the fields most likely to be used + + union { + vec4_t obj; + vec4_t eye; + }; + vec4_t clip; + + uint32_t flags; + size_t index; // cache tag, and vertex index + GLfixed fog; + uint8_t locked; + uint8_t mru; + uint8_t reserved[2]; + vec4_t window; + + vec4_t color; + vec4_t texture[GGL_TEXTURE_UNIT_COUNT]; + uint32_t reserved1[4]; + + inline void clear() { + flags = index = locked = mru = 0; + } +}; + +struct point_size_t { + GGLcoord size; + GLboolean smooth; +}; + +struct line_width_t { + GGLcoord width; + GLboolean smooth; +}; + +struct polygon_offset_t { + GLfixed factor; + GLfixed units; + GLboolean enable; +}; + +// ---------------------------------------------------------------------------- +// arrays +// ---------------------------------------------------------------------------- + +struct array_t { + typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*); + fetcher_t fetch; + GLvoid const* physical_pointer; + GLint size; + GLsizei stride; + GLvoid const* pointer; + buffer_t const* bo; + uint16_t type; + GLboolean enable; + GLboolean pad; + GLsizei bounds; + void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei); + inline void resolve(); + inline const GLubyte* element(GLint i) const { + return (const GLubyte*)physical_pointer + i * stride; + } +}; + +struct array_machine_t { + array_t vertex; + array_t normal; + array_t color; + array_t texture[GGL_TEXTURE_UNIT_COUNT]; + uint8_t activeTexture; + uint8_t tmu; + uint16_t cull; + uint32_t flags; + GLenum indicesType; + buffer_t const* array_buffer; + buffer_t const* element_array_buffer; + + void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei); + void (*compileElement)(ogles_context_t*, vertex_t*, GLint); + + void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*); + void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*); + void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*); + void (*perspective)(ogles_context_t*c, vertex_t* v); + void (*clipVertex)(ogles_context_t* c, vertex_t* nv, + GGLfixed t, const vertex_t* s, const vertex_t* p); + void (*clipEye)(ogles_context_t* c, vertex_t* nv, + GGLfixed t, const vertex_t* s, const vertex_t* p); +}; + +struct vertex_cache_t { + enum { + // must be at least 4 + // 3 vertice for triangles + // or 2 + 2 for indexed triangles w/ cache contention + VERTEX_BUFFER_SIZE = 8, + // must be a power of two and at least 3 + VERTEX_CACHE_SIZE = 64, // 8 KB + + INDEX_BITS = 16, + INDEX_MASK = ((1LU<<INDEX_BITS)-1), + INDEX_SEQ = 1LU<<INDEX_BITS, + }; + vertex_t* vBuffer; + vertex_t* vCache; + uint32_t sequence; + void* base; + uint32_t total; + uint32_t misses; + int64_t startTime; + void init(); + void uninit(); + void clear(); + void dump_stats(GLenum mode); +}; + +// ---------------------------------------------------------------------------- +// fog +// ---------------------------------------------------------------------------- + +struct fog_t { + GLfixed density; + GLfixed start; + GLfixed end; + GLfixed invEndMinusStart; + GLenum mode; + GLfixed (*fog)(ogles_context_t* c, GLfixed z); +}; + +// ---------------------------------------------------------------------------- +// user clip planes +// ---------------------------------------------------------------------------- + +const unsigned int OGLES_MAX_CLIP_PLANES = 6; + +struct clip_plane_t { + vec4_t equation; +}; + +struct user_clip_planes_t { + clip_plane_t plane[OGLES_MAX_CLIP_PLANES]; + uint32_t enable; +}; + +// ---------------------------------------------------------------------------- +// lighting +// ---------------------------------------------------------------------------- + +const unsigned int OGLES_MAX_LIGHTS = 8; + +struct light_t { + vec4_t ambient; + vec4_t diffuse; + vec4_t specular; + vec4_t implicitAmbient; + vec4_t implicitDiffuse; + vec4_t implicitSpecular; + vec4_t position; // position in eye space + vec4_t objPosition; + vec4_t normalizedObjPosition; + vec4_t spotDir; + vec4_t normalizedSpotDir; + GLfixed spotExp; + GLfixed spotCutoff; + GLfixed spotCutoffCosine; + GLfixed attenuation[3]; + GLfixed rConstAttenuation; + GLboolean enable; +}; + +struct material_t { + vec4_t ambient; + vec4_t diffuse; + vec4_t specular; + vec4_t emission; + GLfixed shininess; +}; + +struct light_model_t { + vec4_t ambient; + GLboolean twoSide; +}; + +struct color_material_t { + GLenum face; + GLenum mode; + GLboolean enable; +}; + +struct lighting_t { + light_t lights[OGLES_MAX_LIGHTS]; + material_t front; + light_model_t lightModel; + color_material_t colorMaterial; + uint32_t enabledLights; + GLboolean enable; + vec4_t implicitSceneEmissionAndAmbient; + GLenum shadeModel; + typedef void (*light_fct_t)(ogles_context_t*, vertex_t*); + void (*lightVertex)(ogles_context_t* c, vertex_t* v); + void (*lightTriangle)(ogles_context_t* c, + vertex_t* v0, vertex_t* v1, vertex_t* v2); +}; + +struct culling_t { + GLenum cullFace; + GLenum frontFace; + GLboolean enable; +}; + +// ---------------------------------------------------------------------------- +// textures +// ---------------------------------------------------------------------------- + +struct texture_unit_t { + GLuint name; + EGLTextureObject* texture; + uint8_t dirty; +}; + +struct texture_state_t +{ + texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT]; + int active; // active tmu + EGLTextureObject* defaultTexture; + GGLContext* ggl; + uint8_t packAlignment; + uint8_t unpackAlignment; +}; + +// ---------------------------------------------------------------------------- +// transformation and matrices +// ---------------------------------------------------------------------------- + +struct matrixf_t; + +struct matrixx_t { + GLfixed m[16]; + void load(const matrixf_t& rhs); +}; + +struct matrix_stack_t; + + +struct matrixf_t { + void loadIdentity(); + void load(const matrixf_t& rhs); + + inline GLfloat* editElements() { return m; } + inline GLfloat const* elements() const { return m; } + + void set(const GLfixed* rhs); + void set(const GLfloat* rhs); + + static void multiply(matrixf_t& r, + const matrixf_t& lhs, const matrixf_t& rhs); + + void dump(const char* what); + +private: + friend struct matrix_stack_t; + GLfloat m[16]; + void load(const GLfixed* rhs); + void load(const GLfloat* rhs); + void multiply(const matrixf_t& rhs); + void translate(GLfloat x, GLfloat y, GLfloat z); + void scale(GLfloat x, GLfloat y, GLfloat z); + void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z); +}; + +enum { + OP_IDENTITY = 0x00, + OP_TRANSLATE = 0x01, + OP_UNIFORM_SCALE = 0x02, + OP_SCALE = 0x05, + OP_ROTATE = 0x08, + OP_SKEW = 0x10, + OP_ALL = 0x1F +}; + +struct transform_t { + enum { + FLAGS_2D_PROJECTION = 0x1 + }; + matrixx_t matrix; + uint32_t flags; + uint32_t ops; + + union { + struct { + void (*point2)(transform_t const* t, vec4_t*, vec4_t const*); + void (*point3)(transform_t const* t, vec4_t*, vec4_t const*); + void (*point4)(transform_t const* t, vec4_t*, vec4_t const*); + }; + void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*); + }; + + void loadIdentity(); + void picker(); + void dump(const char* what); +}; + +struct mvui_transform_t : public transform_t +{ + void picker(); +}; + +struct matrix_stack_t { + enum { + DO_PICKER = 0x1, + DO_FLOAT_TO_FIXED = 0x2 + }; + transform_t transform; + uint8_t maxDepth; + uint8_t depth; + uint8_t dirty; + uint8_t reserved; + matrixf_t *stack; + uint8_t *ops; + void init(int depth); + void uninit(); + void loadIdentity(); + void load(const GLfixed* rhs); + void load(const GLfloat* rhs); + void multiply(const matrixf_t& rhs); + void translate(GLfloat x, GLfloat y, GLfloat z); + void scale(GLfloat x, GLfloat y, GLfloat z); + void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z); + GLint push(); + GLint pop(); + void validate(); + matrixf_t& top() { return stack[depth]; } + const matrixf_t& top() const { return stack[depth]; } + const uint32_t top_ops() const { return ops[depth]; } + inline bool isRigidBody() const { + return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE)); + } +}; + +struct vp_transform_t { + transform_t transform; + matrixf_t matrix; + GLfloat zNear; + GLfloat zFar; + void loadIdentity(); +}; + +struct transform_state_t { + enum { + MODELVIEW = 0x01, + PROJECTION = 0x02, + VIEWPORT = 0x04, + TEXTURE = 0x08, + MVUI = 0x10, + MVIT = 0x20, + MVP = 0x40, + }; + matrix_stack_t *current; + matrix_stack_t modelview; + matrix_stack_t projection; + matrix_stack_t texture[GGL_TEXTURE_UNIT_COUNT]; + + // modelview * projection + transform_t mvp __attribute__((aligned(32))); + // viewport transformation + vp_transform_t vpt __attribute__((aligned(32))); + // same for 4-D vertices + transform_t mvp4; + // full modelview inverse transpose + transform_t mvit4; + // upper 3x3 of mv-inverse-transpose (for normals) + mvui_transform_t mvui; + + GLenum matrixMode; + GLenum rescaleNormals; + uint32_t dirty; + void invalidate(); + void update_mvp(); + void update_mvit(); + void update_mvui(); +}; + +struct viewport_t { + GLint x; + GLint y; + GLsizei w; + GLsizei h; + struct { + GLint x; + GLint y; + } surfaceport; + struct { + GLint x; + GLint y; + GLsizei w; + GLsizei h; + } scissor; +}; + +// ---------------------------------------------------------------------------- +// Lerping +// ---------------------------------------------------------------------------- + +struct compute_iterators_t +{ + void initTriangle( + vertex_t const* v0, + vertex_t const* v1, + vertex_t const* v2); + + void initLine( + vertex_t const* v0, + vertex_t const* v1); + + inline void initLerp(vertex_t const* v0, uint32_t enables); + + int iteratorsScale(int32_t it[3], + int32_t c0, int32_t c1, int32_t c2) const; + + void iterators1616(GGLfixed it[3], + GGLfixed c0, GGLfixed c1, GGLfixed c2) const; + + void iterators0032(int32_t it[3], + int32_t c0, int32_t c1, int32_t c2) const; + + void iterators0032(int64_t it[3], + int32_t c0, int32_t c1, int32_t c2) const; + + GGLcoord area() const { return m_area; } + +private: + // don't change order of members here -- used by iterators.S + GGLcoord m_dx01, m_dy10, m_dx20, m_dy02; + GGLcoord m_x0, m_y0; + GGLcoord m_area; + uint8_t m_scale; + uint8_t m_area_scale; + uint8_t m_reserved[2]; + +}; + +// ---------------------------------------------------------------------------- +// state +// ---------------------------------------------------------------------------- + +#ifdef HAVE_ANDROID_OS + // We have a dedicated TLS slot in bionic + inline void setGlThreadSpecific(ogles_context_t *value) { + ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value; + } + inline ogles_context_t* getGlThreadSpecific() { + return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]); + } +#else + extern pthread_key_t gGLKey; + inline void setGlThreadSpecific(ogles_context_t *value) { + pthread_setspecific(gGLKey, value); + } + inline ogles_context_t* getGlThreadSpecific() { + return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey)); + } +#endif + + +struct prims_t { + typedef ogles_context_t* GL; + void (*renderPoint)(GL, vertex_t*); + void (*renderLine)(GL, vertex_t*, vertex_t*); + void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*); +}; + +struct ogles_context_t { + context_t rasterizer; + array_machine_t arrays __attribute__((aligned(32))); + texture_state_t textures; + transform_state_t transforms; + vertex_cache_t vc; + prims_t prims; + culling_t cull; + lighting_t lighting; + user_clip_planes_t clipPlanes; + compute_iterators_t lerp; __attribute__((aligned(32))); + vertex_t current; + vec4_t currentColorClamped; + vec3_t currentNormal; + viewport_t viewport; + point_size_t point; + line_width_t line; + polygon_offset_t polygonOffset; + fog_t fog; + uint32_t perspective : 1; + uint32_t transformTextures : 1; + EGLSurfaceManager* surfaceManager; + EGLBufferObjectManager* bufferObjectManager; + GLenum error; + + static inline ogles_context_t* get() { + return getGlThreadSpecific(); + } + +}; + +}; // namespace gl +}; // namespace android + +#endif // ANDROID_OPENGLES_CONTEXT_H + diff --git a/include/private/ui/LayerState.h b/include/private/ui/LayerState.h new file mode 100644 index 0000000..b6fcd80 --- /dev/null +++ b/include/private/ui/LayerState.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_COMPOSER_LAYER_STATE_H +#define ANDROID_COMPOSER_LAYER_STATE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> + +#include <ui/ISurfaceFlingerClient.h> +#include <ui/Region.h> + +#include <private/ui/SharedState.h> + +namespace android { + +class Parcel; + +struct layer_state_t { + + layer_state_t() + : surface(0), what(0), + x(0), y(0), z(0), w(0), h(0), + alpha(0), tint(0), flags(0), mask(0), + reserved(0) + { + matrix.dsdx = matrix.dtdy = 1.0f; + matrix.dsdy = matrix.dtdx = 0.0f; + } + + status_t write(Parcel& output) const; + status_t read(const Parcel& input); + + struct matrix22_t { + float dsdx; + float dtdx; + float dsdy; + float dtdy; + }; + SurfaceID surface; + uint32_t what; + int32_t x; + int32_t y; + uint32_t z; + uint32_t w; + uint32_t h; + float alpha; + uint32_t tint; + uint8_t flags; + uint8_t mask; + uint8_t reserved; + matrix22_t matrix; + // non POD must be last. see write/read + Region transparentRegion; +}; + +}; // namespace android + +#endif // ANDROID_COMPOSER_LAYER_STATE_H + diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h new file mode 100644 index 0000000..546d0ad --- /dev/null +++ b/include/private/ui/SharedState.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_SHARED_STATE_H +#define ANDROID_UI_SHARED_STATE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/threads.h> + +namespace android { + +/* + * These structures are shared between the composer process and its clients + */ + +// --------------------------------------------------------------------------- + +struct surface_info_t { // 4 longs, 16 bytes + enum { + eBufferDirty = 0x01 + }; + uint16_t w; + uint16_t h; + uint16_t stride; + uint16_t bpr; + uint16_t reserved; + uint8_t format; + uint8_t flags; + ssize_t bits_offset; +}; + +// --------------------------------------------------------------------------- + +const uint32_t NUM_LAYERS_MAX = 31; + +enum { // layer_cblk_t swapState + eIndex = 0x00000001, + eFlipRequested = 0x00000002, + + eResizeBuffer0 = 0x00000004, + eResizeBuffer1 = 0x00000008, + eResizeRequested = eResizeBuffer0 | eResizeBuffer1, + + eBusy = 0x00000010, + eLocked = 0x00000020, + eNextFlipPending = 0x00000040, + eInvalidSurface = 0x00000080 +}; + +enum { // layer_cblk_t flags + eLayerNotPosted = 0x00000001, + eNoCopyBack = 0x00000002, + eReserved = 0x0000007C, + eBufferIndexShift = 7, + eBufferIndex = 1<<eBufferIndexShift, +}; + +struct flat_region_t // 40 bytes +{ + int32_t count; + int16_t l; + int16_t t; + int16_t r; + int16_t b; + uint16_t runs[14]; +}; + +struct layer_cblk_t // (128 bytes) +{ + volatile int32_t swapState; // 4 + volatile int32_t flags; // 4 + volatile int32_t identity; // 4 + int32_t reserved; // 4 + surface_info_t surface[2]; // 32 + flat_region_t region[2]; // 80 + + static inline int backBuffer(uint32_t state) { + return ((state & eIndex) ^ ((state & eFlipRequested)>>1)); + } + static inline int frontBuffer(uint32_t state) { + return 1 - backBuffer(state); + } +}; + +// --------------------------------------------------------------------------- + +struct per_client_cblk_t // 4KB max +{ + Mutex lock; + Condition cv; + layer_cblk_t layers[NUM_LAYERS_MAX] __attribute__((aligned(32))); + + enum { + BLOCKING = 0x00000001, + INSPECT = 0x00000002 + }; + + per_client_cblk_t(); + + // these functions are used by the clients + status_t validate(size_t i) const; + int32_t lock_layer(size_t i, uint32_t flags); + uint32_t unlock_layer_and_post(size_t i); + void unlock_layer(size_t i); +}; +// --------------------------------------------------------------------------- + +const uint32_t NUM_DISPLAY_MAX = 4; + +struct display_cblk_t +{ + uint16_t w; + uint16_t h; + uint8_t format; + uint8_t orientation; + uint8_t reserved[2]; + float fps; + float density; + float xdpi; + float ydpi; + uint32_t pad[2]; +}; + +struct surface_flinger_cblk_t // 4KB max +{ + surface_flinger_cblk_t(); + + uint8_t connected; + uint8_t reserved[3]; + uint32_t pad[7]; + + display_cblk_t displays[NUM_DISPLAY_MAX]; +}; + +// --------------------------------------------------------------------------- + +template<bool> struct CTA; +template<> struct CTA<true> { }; + +// compile-time assertions. just to avoid catastrophes. +inline void compile_time_asserts() { + CTA<sizeof(layer_cblk_t) == 128> sizeof__layer_cblk_t__eq_128; + (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning + CTA<sizeof(per_client_cblk_t) <= 4096> sizeof__per_client_cblk_t__le_4096; + (void)sizeof__per_client_cblk_t__le_4096; // we don't want a warning + CTA<sizeof(surface_flinger_cblk_t) <= 4096> sizeof__surface_flinger_cblk_t__le_4096; + (void)sizeof__surface_flinger_cblk_t__le_4096; // we don't want a warning +} + +}; // namespace android + +#endif // ANDROID_UI_SHARED_STATE_H + diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h new file mode 100644 index 0000000..ff91b61 --- /dev/null +++ b/include/private/ui/SurfaceFlingerSynchro.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_SURFACE_FLINGER_SYNCHRO_H +#define ANDROID_SURFACE_FLINGER_SYNCHRO_H + +#include <stdint.h> +#include <sys/types.h> +#include <utils/Errors.h> +#include <utils/threads.h> +#include <ui/ISurfaceComposer.h> + +namespace android { + +class SurfaceFlinger; + +class SurfaceFlingerSynchro +{ +public: + + // client constructor + SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger); + ~SurfaceFlingerSynchro(); + + // signal surfaceflinger for some work + status_t signal(); + +private: + class Barrier { + public: + Barrier(); + ~Barrier(); + void open(); + void close(); + void waitAndClose(); + status_t waitAndClose(nsecs_t timeout); + private: + enum { OPENED, CLOSED }; + mutable Mutex lock; + mutable Condition cv; + volatile int state; + }; + + friend class SurfaceFlinger; + + // server constructor + SurfaceFlingerSynchro(); + + void open(); + + // wait until there is some work to do + status_t wait(); + status_t wait(nsecs_t timeout); + + sp<ISurfaceComposer> mSurfaceComposer; + Barrier mBarrier; +}; + +}; // namespace android + +#endif // ANDROID_SURFACE_FLINGER_SYNCHRO_H + diff --git a/include/private/utils/Static.h b/include/private/utils/Static.h new file mode 100644 index 0000000..f1439b7 --- /dev/null +++ b/include/private/utils/Static.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// All static variables go here, to control initialization and +// destruction order in the library. + +#include <utils/threads.h> +#include <utils/KeyedVector.h> + +#ifndef LIBUTILS_NATIVE +#include <utils/IBinder.h> +#include <utils/IMemory.h> +#include <utils/ProcessState.h> +#include <utils/IPermissionController.h> +#include <utils/IServiceManager.h> +#endif + +namespace android { +// For TextStream.cpp +extern Vector<int32_t> gTextBuffers; + +// For String8.cpp +extern void initialize_string8(); +extern void terminate_string8(); + +// For String16.cpp +extern void initialize_string16(); +extern void terminate_string16(); + + + +#ifndef LIBUTILS_NATIVE + +// For ProcessState.cpp +extern Mutex gProcessMutex; +extern sp<ProcessState> gProcess; + +// For ServiceManager.cpp +extern Mutex gDefaultServiceManagerLock; +extern sp<IServiceManager> gDefaultServiceManager; +extern sp<IPermissionController> gPermissionController; + +#endif + +} // namespace android diff --git a/include/private/utils/binder_module.h b/include/private/utils/binder_module.h new file mode 100644 index 0000000..fdf327e --- /dev/null +++ b/include/private/utils/binder_module.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BINDER_MODULE_H_ +#define _BINDER_MODULE_H_ + +#ifdef __cplusplus +namespace android { +#endif + +#if defined(HAVE_ANDROID_OS) + +/* obtain structures and constants from the kernel header */ + +#include <sys/ioctl.h> +#include <linux/binder.h> + +#else + +/* Some parts of the simulator need fake versions of this + * stuff in order to compile. Really this should go away + * entirely... + */ + +#define BINDER_CURRENT_PROTOCOL_VERSION 7 + +#define BINDER_TYPE_BINDER 1 +#define BINDER_TYPE_WEAK_BINDER 2 +#define BINDER_TYPE_HANDLE 3 +#define BINDER_TYPE_WEAK_HANDLE 4 +#define BINDER_TYPE_FD 5 + +struct flat_binder_object { + unsigned long type; + unsigned long flags; + union { + void *binder; + signed long handle; + }; + void *cookie; +}; + +struct binder_write_read { + signed long write_size; + signed long write_consumed; + unsigned long write_buffer; + signed long read_size; + signed long read_consumed; + unsigned long read_buffer; +}; + +struct binder_transaction_data { + union { + size_t handle; + void *ptr; + } target; + void *cookie; + unsigned int code; + + unsigned int flags; + pid_t sender_pid; + uid_t sender_euid; + size_t data_size; + size_t offsets_size; + + union { + struct { + const void *buffer; + const void *offsets; + } ptr; + uint8_t buf[8]; + } data; +}; + +enum transaction_flags { + TF_ONE_WAY = 0x01, + TF_ROOT_OBJECT = 0x04, + TF_STATUS_CODE = 0x08, + TF_ACCEPT_FDS = 0x10, +}; + + +enum { + FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, + FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, +}; + +enum BinderDriverReturnProtocol { + BR_ERROR, + BR_OK, + BR_TRANSACTION, + BR_REPLY, + BR_ACQUIRE_RESULT, + BR_DEAD_REPLY, + BR_TRANSACTION_COMPLETE, + BR_INCREFS, + BR_ACQUIRE, + BR_RELEASE, + BR_DECREFS, + BR_ATTEMPT_ACQUIRE, + BR_NOOP, + BR_SPAWN_LOOPER, + BR_FINISHED, + BR_DEAD_BINDER, + BR_CLEAR_DEATH_NOTIFICATION_DONE, + BR_FAILED_REPLY, +}; + +enum BinderDriverCommandProtocol { + BC_TRANSACTION, + BC_REPLY, + BC_ACQUIRE_RESULT, + BC_FREE_BUFFER, + BC_INCREFS, + BC_ACQUIRE, + BC_RELEASE, + BC_DECREFS, + BC_INCREFS_DONE, + BC_ACQUIRE_DONE, + BC_ATTEMPT_ACQUIRE, + BC_REGISTER_LOOPER, + BC_ENTER_LOOPER, + BC_EXIT_LOOPER, + BC_REQUEST_DEATH_NOTIFICATION, + BC_CLEAR_DEATH_NOTIFICATION, + BC_DEAD_BINDER_DONE, +}; + +#endif + +#ifdef __cplusplus +} // namespace android +#endif + +#endif // _BINDER_MODULE_H_ diff --git a/include/private/utils/futex_synchro.h b/include/private/utils/futex_synchro.h new file mode 100644 index 0000000..ac2ab19 --- /dev/null +++ b/include/private/utils/futex_synchro.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _FUTEX_SYNCHRO_H +#define _FUTEX_SYNCHRO_H + +#ifndef HAVE_FUTEX +#error "HAVE_FUTEX not defined" +#endif + +#define FUTEX_WAIT_INFINITE (0) + +typedef struct futex_mutex_t futex_mutex_t; + +struct futex_mutex_t +{ + volatile int value; +}; + +typedef struct futex_cond_t futex_cond_t; + +struct futex_cond_t +{ + volatile int value; +}; + + +#if __cplusplus +extern "C" { +#endif + +void futex_mutex_init(futex_mutex_t *m); +int futex_mutex_lock(futex_mutex_t *m, unsigned msec); +void futex_mutex_unlock(futex_mutex_t *m); +int futex_mutex_trylock(futex_mutex_t *m); + +void futex_cond_init(futex_cond_t *c); +int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec); +void futex_cond_signal(futex_cond_t *c); +void futex_cond_broadcast(futex_cond_t *c); + +#if __cplusplus +} // extern "C" +#endif + +#endif // _FUTEX_SYNCHRO_H + diff --git a/include/ui/Camera.h b/include/ui/Camera.h new file mode 100644 index 0000000..e593fea --- /dev/null +++ b/include/ui/Camera.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2008 HTC 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. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_H +#define ANDROID_HARDWARE_CAMERA_H + +#include <ui/ICameraClient.h> + +namespace android { + +/* + * A set of bit masks for specifying how the received preview frames are + * handled before the previewCallback() call. + * + * The least significant 3 bits of an "int" value are used for this purpose: + * + * ..... 0 0 0 + * ^ ^ ^ + * | | |---------> determine whether the callback is enabled or not + * | |-----------> determine whether the callback is one-shot or not + * |-------------> determine whether the frame is copied out or not + * + * WARNING: + * When a frame is sent directly without copying, it is the frame receiver's + * responsiblity to make sure that the frame data won't get corrupted by + * subsequent preview frames filled by the camera. This flag is recommended + * only when copying out data brings significant performance price and the + * handling/processing of the received frame data is always faster than + * the preview frame rate so that data corruption won't occur. + * + * For instance, + * 1. 0x00 disables the callback. In this case, copy out and one shot bits + * are ignored. + * 2. 0x01 enables a callback without copying out the received frames. A + * typical use case is the Camcorder application to avoid making costly + * frame copies. + * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical + * use case is the Camera application. + * 4. 0x07 is enabling a callback with frame copied out only once. A typical use + * case is the Barcode scanner application. + */ +#define FRAME_CALLBACK_FLAG_ENABLE_MASK 0x01 +#define FRAME_CALLBACK_FLAG_ONE_SHOT_MASK 0x02 +#define FRAME_CALLBACK_FLAG_COPY_OUT_MASK 0x04 + +// Typical use cases +#define FRAME_CALLBACK_FLAG_NOOP 0x00 +#define FRAME_CALLBACK_FLAG_CAMCORDER 0x01 +#define FRAME_CALLBACK_FLAG_CAMERA 0x05 +#define FRAME_CALLBACK_FLAG_BARCODE_SCANNER 0x07 + +class ICameraService; +class ICamera; +class Surface; +class Mutex; +class String8; + +typedef void (*shutter_callback)(void *cookie); +typedef void (*frame_callback)(const sp<IMemory>& mem, void *cookie); +typedef void (*autofocus_callback)(bool focused, void *cookie); +typedef void (*error_callback)(status_t err, void *cookie); + +class Camera : public BnCameraClient, public IBinder::DeathRecipient +{ +public: + // construct a camera client from an existing remote + Camera(const sp<ICamera>& camera); + + static sp<Camera> connect(); + ~Camera(); + void init(); + + status_t reconnect(); + void disconnect(); + status_t lock(); + status_t unlock(); + + status_t getStatus() { return mStatus; } + + // pass the buffered ISurface to the camera service + status_t setPreviewDisplay(const sp<Surface>& surface); + status_t setPreviewDisplay(const sp<ISurface>& surface); + + // start preview mode, must call setPreviewDisplay first + status_t startPreview(); + + // stop preview mode + void stopPreview(); + + // get preview state + bool previewEnabled(); + + // start recording mode, must call setPreviewDisplay first + status_t startRecording(); + + // stop recording mode + void stopRecording(); + + // get recording state + bool recordingEnabled(); + + // release a recording frame + void releaseRecordingFrame(const sp<IMemory>& mem); + + // autoFocus - status returned from callback + status_t autoFocus(); + + // take a picture - picture returned from callback + status_t takePicture(); + + // set preview/capture parameters - key/value pairs + status_t setParameters(const String8& params); + + // get preview/capture parameters - key/value pairs + String8 getParameters() const; + + void setShutterCallback(shutter_callback cb, void *cookie); + void setRawCallback(frame_callback cb, void *cookie); + void setJpegCallback(frame_callback cb, void *cookie); + void setRecordingCallback(frame_callback cb, void *cookie); + void setPreviewCallback(frame_callback cb, void *cookie, int preview_callback_flag = FRAME_CALLBACK_FLAG_NOOP); + void setErrorCallback(error_callback cb, void *cookie); + void setAutoFocusCallback(autofocus_callback cb, void *cookie); + + // ICameraClient interface + virtual void shutterCallback(); + virtual void rawCallback(const sp<IMemory>& picture); + virtual void jpegCallback(const sp<IMemory>& picture); + virtual void previewCallback(const sp<IMemory>& frame); + virtual void errorCallback(status_t error); + virtual void autoFocusCallback(bool focused); + virtual void recordingCallback(const sp<IMemory>& frame); + + sp<ICamera> remote(); + +private: + Camera(); + virtual void binderDied(const wp<IBinder>& who); + + class DeathNotifier: public IBinder::DeathRecipient + { + public: + DeathNotifier() { + } + + virtual void binderDied(const wp<IBinder>& who); + }; + + static sp<DeathNotifier> mDeathNotifier; + + // helper function to obtain camera service handle + static const sp<ICameraService>& getCameraService(); + + sp<ICamera> mCamera; + status_t mStatus; + + shutter_callback mShutterCallback; + void *mShutterCallbackCookie; + frame_callback mRawCallback; + void *mRawCallbackCookie; + frame_callback mJpegCallback; + void *mJpegCallbackCookie; + frame_callback mPreviewCallback; + void *mPreviewCallbackCookie; + frame_callback mRecordingCallback; + void *mRecordingCallbackCookie; + error_callback mErrorCallback; + void *mErrorCallbackCookie; + autofocus_callback mAutoFocusCallback; + void *mAutoFocusCallbackCookie; + + friend class DeathNotifier; + + static Mutex mLock; + static sp<ICameraService> mCameraService; + +}; + +}; // namespace android + +#endif + diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h new file mode 100644 index 0000000..73036f0 --- /dev/null +++ b/include/ui/CameraHardwareInterface.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H +#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H + +#include <utils/IMemory.h> +#include <utils/RefBase.h> +#include <ui/CameraParameters.h> +#include <ui/Overlay.h> + +namespace android { + +/** Callback for startPreview() */ +typedef void (*preview_callback)(const sp<IMemory>& mem, void* user); + +/** Callback for startRecord() */ +typedef void (*recording_callback)(const sp<IMemory>& mem, void* user); + +/** Callback for takePicture() */ +typedef void (*shutter_callback)(void* user); + +/** Callback for takePicture() */ +typedef void (*raw_callback)(const sp<IMemory>& mem, void* user); + +/** Callback for takePicture() */ +typedef void (*jpeg_callback)(const sp<IMemory>& mem, void* user); + +/** Callback for autoFocus() */ +typedef void (*autofocus_callback)(bool focused, void* user); + +/** + * CameraHardwareInterface.h defines the interface to the + * camera hardware abstraction layer, used for setting and getting + * parameters, live previewing, and taking pictures. + * + * It is a referenced counted interface with RefBase as its base class. + * CameraService calls openCameraHardware() to retrieve a strong pointer to the + * instance of this interface and may be called multiple times. The + * following steps describe a typical sequence: + * + * -# After CameraService calls openCameraHardware(), getParameters() and + * setParameters() are used to initialize the camera instance. + * CameraService calls getPreviewHeap() to establish access to the + * preview heap so it can be registered with SurfaceFlinger for + * efficient display updating while in preview mode. + * -# startPreview() is called, which is passed a preview_callback() + * function and a user parameter. The camera instance then periodically + * calls preview_callback() each time a new preview frame is available. + * The callback routine has two parameters: the first is a pointer to + * the IMemory containing the frame and the second a user parameter. If + * the preview_callback code needs to use this memory after returning, + * it must copy the data. + * + * Prior to taking a picture, CameraService calls autofocus() with + * autofocus_callback() and a user parameter. When auto focusing has + * completed, the camera instance calls autofocus_callback(), which informs + * the application whether focusing was successful. The camera instance + * only calls autofocus_callback() once and it is up to the application to + * call autoFocus() again if refocusing is desired. + * + * CameraService calls takePicture() to request the camera instance take a + * picture. This method has two callbacks: raw_callback() and jpeg_callback(). + * When the raw image is available, raw_callback() is called with a pointer + * to the IMemory containing the raw image. When the jpeg image is available, + * jpeg_callback() is called with a pointer to the IMemory containing the + * jpeg image. As with preview_callback(), the memory must be copied if it's + * needed after returning. + */ +class CameraHardwareInterface : public virtual RefBase { +public: + virtual ~CameraHardwareInterface() { } + + /** Return the IMemoryHeap for the preview image heap */ + virtual sp<IMemoryHeap> getPreviewHeap() const = 0; + + /** Return the IMemoryHeap for the raw image heap */ + virtual sp<IMemoryHeap> getRawHeap() const = 0; + + /** + * Start preview mode. When a preview image is available + * preview_callback is called with the user parameter. The + * call back parameter may be null. + */ + virtual status_t startPreview(preview_callback cb, void* user) = 0; + /** + * Only used if overlays are used for camera preview. + */ + virtual bool useOverlay() {return false;} + virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;} + + /** + * Stop a previously started preview. + */ + virtual void stopPreview() = 0; + + /** + * Returns true if preview is enabled. + */ + virtual bool previewEnabled() = 0; + + /** + * Start record mode. When a record image is available recording_callback() + * is called with the user parameter. Every record frame must be released + * by calling releaseRecordingFrame(). + */ + virtual status_t startRecording(recording_callback cb, void* user) = 0; + + /** + * Stop a previously started recording. + */ + virtual void stopRecording() = 0; + + /** + * Returns true if recording is enabled. + */ + virtual bool recordingEnabled() = 0; + + /** + * Release a record frame previously returned by the recording_callback() + * passed to startRecord(). + */ + virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0; + + /** + * Start auto focus, the callback routine is called + * once when focusing is complete. autoFocus() will + * be called again if another auto focus is needed. + */ + virtual status_t autoFocus(autofocus_callback, + void* user) = 0; + + /** + * Take a picture. The raw_callback is called when + * the uncompressed image is available. The jpeg_callback + * is called when the compressed image is available. These + * call backs may be null. The user parameter is passed + * to each of the call back routines. + */ + virtual status_t takePicture(shutter_callback, + raw_callback, + jpeg_callback, + void* user) = 0; + + /** + * Cancel a picture that was started with takePicture. You may cancel any + * of the shutter, raw, or jpeg callbacks. Calling this method when no + * picture is being taken is a no-op. + */ + virtual status_t cancelPicture(bool cancel_shutter, + bool cancel_raw, + bool cancel_jpeg) = 0; + + /** Set the camera parameters. */ + virtual status_t setParameters(const CameraParameters& params) = 0; + + /** Return the camera parameters. */ + virtual CameraParameters getParameters() const = 0; + + /** + * Release the hardware resources owned by this object. Note that this is + * *not* done in the destructor. + */ + virtual void release() = 0; + + /** + * Dump state of the camera hardware + */ + virtual status_t dump(int fd, const Vector<String16>& args) const = 0; +}; + +/** factory function to instantiate a camera hardware object */ +extern "C" sp<CameraHardwareInterface> openCameraHardware(); + +}; // namespace android + +#endif diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h new file mode 100644 index 0000000..9ca1806 --- /dev/null +++ b/include/ui/CameraParameters.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS_H +#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H + +#include <utils/KeyedVector.h> +#include <utils/String8.h> + +namespace android { + +class CameraParameters +{ +public: + CameraParameters(); + CameraParameters(const String8 ¶ms) { unflatten(params); } + ~CameraParameters(); + + enum { + CAMERA_ORIENTATION_UNKNOWN = 0, + CAMERA_ORIENTATION_PORTRAIT = 1, + CAMERA_ORIENTATION_LANDSCAPE = 2, + }; + + String8 flatten() const; + void unflatten(const String8 ¶ms); + + void set(const char *key, const char *value); + void set(const char *key, int value); + const char *get(const char *key) const; + int getInt(const char *key) const; + + /* preview-size=176x144 */ + void setPreviewSize(int width, int height); + void getPreviewSize(int *width, int *height) const; + + /* preview-fps=15 */ + void setPreviewFrameRate(int fps); + int getPreviewFrameRate() const; + + /* preview-format=rgb565|yuv422 */ + void setPreviewFormat(const char *format); + const char *getPreviewFormat() const; + + /* picture-size=1024x768 */ + void setPictureSize(int width, int height); + void getPictureSize(int *width, int *height) const; + + /* picture-format=yuv422|jpeg */ + void setPictureFormat(const char *format); + const char *getPictureFormat() const; + + int getOrientation() const; + void setOrientation(int orientation); + + void dump() const; + status_t dump(int fd, const Vector<String16>& args) const; + +private: + DefaultKeyedVector<String8,String8> mMap; +}; + + +}; // namespace android + +#endif diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h new file mode 100644 index 0000000..c419efe --- /dev/null +++ b/include/ui/DisplayInfo.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_UI_DISPLAY_INFO_H +#define ANDROID_UI_DISPLAY_INFO_H + +#include <stdint.h> +#include <sys/types.h> + +#include <ui/PixelFormat.h> + +namespace android { + +struct DisplayInfo { + uint32_t w; + uint32_t h; + PixelFormatInfo pixelFormatInfo; + uint8_t orientation; + uint8_t reserved[3]; + float fps; + float density; + float xdpi; + float ydpi; +}; + +}; // namespace android + +#endif // ANDROID_COMPOSER_DISPLAY_INFO_H + diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h new file mode 100644 index 0000000..a8b5853 --- /dev/null +++ b/include/ui/EGLDisplaySurface.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_EGL_DISPLAY_SURFACE_H +#define ANDROID_EGL_DISPLAY_SURFACE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Timers.h> + +#include <ui/EGLNativeSurface.h> + +#include <pixelflinger/pixelflinger.h> +#include <linux/fb.h> + +#include <EGL/egl.h> + +struct copybit_device_t; +struct copybit_image_t; + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Region; +class Rect; + +class EGLDisplaySurface : public EGLNativeSurface<EGLDisplaySurface> +{ +public: + EGLDisplaySurface(); + ~EGLDisplaySurface(); + + int32_t getPageFlipCount() const; + void copyFrontToBack(const Region& copyback); + void copyFrontToImage(const copybit_image_t& dst); + void copyBackToImage(const copybit_image_t& dst); + + void setSwapRectangle(int l, int t, int w, int h); + +private: + static void hook_incRef(NativeWindowType window); + static void hook_decRef(NativeWindowType window); + static uint32_t hook_swapBuffers(NativeWindowType window); + + uint32_t swapBuffers(); + + status_t mapFrameBuffer(); + + enum { + PAGE_FLIP = 0x00000001 + }; + GGLSurface mFb[2]; + int mIndex; + uint32_t mFlags; + size_t mSize; + fb_var_screeninfo mInfo; + fb_fix_screeninfo mFinfo; + int32_t mPageFlipCount; + nsecs_t mTime; + int32_t mSwapCount; + nsecs_t mSleep; + uint32_t mFeatureFlags; + copybit_device_t* mBlitEngine; +}; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // ANDROID_EGL_DISPLAY_SURFACE_H + diff --git a/include/ui/EGLNativeSurface.h b/include/ui/EGLNativeSurface.h new file mode 100644 index 0000000..7964e7c --- /dev/null +++ b/include/ui/EGLNativeSurface.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_EGL_NATIVE_SURFACE_H +#define ANDROID_EGL_NATIVE_SURFACE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <cutils/atomic.h> +#include <utils/RefBase.h> + +#include <EGL/eglnatives.h> + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +template <class TYPE> +class EGLNativeSurface : public egl_native_window_t, public LightRefBase<TYPE> +{ +public: + EGLNativeSurface() { + memset(egl_native_window_t::reserved, 0, + sizeof(egl_native_window_t::reserved)); + memset(egl_native_window_t::reserved_proc, 0, + sizeof(egl_native_window_t::reserved_proc)); + memset(egl_native_window_t::oem, 0, + sizeof(egl_native_window_t::oem)); + } +protected: + EGLNativeSurface& operator = (const EGLNativeSurface& rhs); + EGLNativeSurface(const EGLNativeSurface& rhs); + inline ~EGLNativeSurface() { }; +}; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // ANDROID_EGL_SURFACE_H + diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/EGLNativeWindowSurface.h new file mode 100644 index 0000000..3494234 --- /dev/null +++ b/include/ui/EGLNativeWindowSurface.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_EGL_NATIVE_WINDOW_SURFACE_H +#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H + +#include <stdint.h> +#include <sys/types.h> +#include <ui/EGLNativeSurface.h> +#include <EGL/egl.h> + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Surface; + +class EGLNativeWindowSurface : public EGLNativeSurface<EGLNativeWindowSurface> +{ +public: + EGLNativeWindowSurface(const sp<Surface>& surface); + ~EGLNativeWindowSurface(); + + void setSwapRectangle(int l, int t, int w, int h); + +private: + static void hook_incRef(NativeWindowType window); + static void hook_decRef(NativeWindowType window); + static uint32_t hook_swapBuffers(NativeWindowType window); + static void hook_connect(NativeWindowType window); + static void hook_disconnect(NativeWindowType window); + + uint32_t swapBuffers(); + void connect(); + void disconnect(); + + sp<Surface> mSurface; + bool mConnected; +}; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H + diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h new file mode 100644 index 0000000..3848d8c --- /dev/null +++ b/include/ui/EventHub.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef _RUNTIME_EVENT_HUB_H +#define _RUNTIME_EVENT_HUB_H + +#include <utils/String8.h> +#include <utils/threads.h> +#include <utils.h> + +#include <linux/input.h> + +struct pollfd; + +namespace android { + +class KeyLayoutMap; + +/* + * Grand Central Station for events. With a single call to waitEvent() + * you can wait for: + * - input events from the keypad of a real device + * - input events and meta-events (e.g. "quit") from the simulator + * - synthetic events from the runtime (e.g. "URL fetch completed") + * - real or forged "vsync" events + * + * Do not instantiate this class. Instead, call startUp(). + */ +class EventHub : public RefBase +{ +public: + EventHub(); + + status_t errorCheck() const; + + // bit fields for classes of devices. + enum { + CLASS_KEYBOARD = 0x00000001, + CLASS_ALPHAKEY = 0x00000002, + CLASS_TOUCHSCREEN = 0x00000004, + CLASS_TRACKBALL = 0x00000008 + }; + uint32_t getDeviceClasses(int32_t deviceId) const; + + String8 getDeviceName(int32_t deviceId) const; + + int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue, + int* outMaxValue, int* outFlat, int* outFuzz) const; + + int getSwitchState(int sw) const; + int getSwitchState(int32_t deviceId, int sw) const; + + int getScancodeState(int key) const; + int getScancodeState(int32_t deviceId, int key) const; + + int getKeycodeState(int key) const; + int getKeycodeState(int32_t deviceId, int key) const; + + // special type codes when devices are added/removed. + enum { + DEVICE_ADDED = 0x10000000, + DEVICE_REMOVED = 0x20000000 + }; + + // examine key input devices for specific framework keycode support + bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags); + + virtual bool getEvent(int32_t* outDeviceId, int32_t* outType, + int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, + int32_t* outValue, nsecs_t* outWhen); + +protected: + virtual ~EventHub(); + virtual void onFirstRef(); + +private: + bool openPlatformInput(void); + int32_t convertDeviceKey_TI_P2(int code); + + int open_device(const char *device); + int close_device(const char *device); + int scan_dir(const char *dirname); + int read_notify(int nfd); + + status_t mError; + + struct device_t { + const int32_t id; + const String8 path; + String8 name; + uint32_t classes; + uint8_t* keyBitmask; + KeyLayoutMap* layoutMap; + String8 keylayoutFilename; + device_t* next; + + device_t(int32_t _id, const char* _path); + ~device_t(); + }; + + device_t* getDevice(int32_t deviceId) const; + + // Protect all internal state. + mutable Mutex mLock; + + bool mHaveFirstKeyboard; + int32_t mFirstKeyboardId; // the API is that the build in keyboard is id 0, so map it + + struct device_ent { + device_t* device; + uint32_t seq; + }; + device_ent *mDevicesById; + int mNumDevicesById; + + device_t *mOpeningDevices; + device_t *mClosingDevices; + + device_t **mDevices; + struct pollfd *mFDs; + int mFDCount; + + // device ids that report particular switches. +#ifdef EV_SW + int32_t mSwitches[SW_MAX+1]; +#endif +}; + +}; // namespace android + +#endif // _RUNTIME_EVENT_HUB_H diff --git a/include/ui/ICamera.h b/include/ui/ICamera.h new file mode 100644 index 0000000..241fb63 --- /dev/null +++ b/include/ui/ICamera.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ICAMERA_H +#define ANDROID_HARDWARE_ICAMERA_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> +#include <ui/ISurface.h> +#include <utils/IMemory.h> +#include <utils/String8.h> +#include <ui/Camera.h> + +namespace android { + +class ICameraClient; + +class ICamera: public IInterface +{ +public: + DECLARE_META_INTERFACE(Camera); + + virtual void disconnect() = 0; + + // connect new client with existing camera remote + virtual status_t connect(const sp<ICameraClient>& client) = 0; + + // prevent other processes from using this ICamera interface + virtual status_t lock() = 0; + + // allow other processes to use this ICamera interface + virtual status_t unlock() = 0; + + // pass the buffered ISurface to the camera service + virtual status_t setPreviewDisplay(const sp<ISurface>& surface) = 0; + + // set the preview callback flag to affect how the received frames from + // preview are handled. + virtual void setPreviewCallbackFlag(int flag) = 0; + + // start preview mode, must call setPreviewDisplay first + virtual status_t startPreview() = 0; + + // stop preview mode + virtual void stopPreview() = 0; + + // get preview state + virtual bool previewEnabled() = 0; + + // start recording mode + virtual status_t startRecording() = 0; + + // stop recording mode + virtual void stopRecording() = 0; + + // get recording state + virtual bool recordingEnabled() = 0; + + // release a recording frame + virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0; + + // auto focus + virtual status_t autoFocus() = 0; + + // take a picture + virtual status_t takePicture() = 0; + + // set preview/capture parameters - key/value pairs + virtual status_t setParameters(const String8& params) = 0; + + // get preview/capture parameters - key/value pairs + virtual String8 getParameters() const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnCamera: public BnInterface<ICamera> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h new file mode 100644 index 0000000..73b951c --- /dev/null +++ b/include/ui/ICameraClient.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ICAMERA_APP_H +#define ANDROID_HARDWARE_ICAMERA_APP_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> +#include <utils/IMemory.h> + +namespace android { + +class ICameraClient: public IInterface +{ +public: + DECLARE_META_INTERFACE(CameraClient); + + virtual void shutterCallback() = 0; + virtual void rawCallback(const sp<IMemory>& picture) = 0; + virtual void jpegCallback(const sp<IMemory>& picture) = 0; + virtual void previewCallback(const sp<IMemory>& frame) = 0; + virtual void errorCallback(status_t error) = 0; + virtual void autoFocusCallback(bool focused) = 0; + virtual void recordingCallback(const sp<IMemory>& frame) = 0; + +}; + +// ---------------------------------------------------------------------------- + +class BnCameraClient: public BnInterface<ICameraClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif diff --git a/include/ui/ICameraService.h b/include/ui/ICameraService.h new file mode 100644 index 0000000..dfd8923 --- /dev/null +++ b/include/ui/ICameraService.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ICAMERASERVICE_H +#define ANDROID_HARDWARE_ICAMERASERVICE_H + +#include <utils/RefBase.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> + +#include <ui/ICameraClient.h> +#include <ui/ICamera.h> + +namespace android { + +class ICameraService : public IInterface +{ +protected: + enum { + CONNECT = IBinder::FIRST_CALL_TRANSACTION, + }; + +public: + DECLARE_META_INTERFACE(CameraService); + + virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnCameraService: public BnInterface<ICameraService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif diff --git a/include/ui/IOverlay.h b/include/ui/IOverlay.h new file mode 100644 index 0000000..699b1b0 --- /dev/null +++ b/include/ui/IOverlay.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IOVERLAY_H +#define ANDROID_IOVERLAY_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/RefBase.h> +#include <ui/PixelFormat.h> + +namespace android { + +class IOverlay : public IInterface +{ +public: + DECLARE_META_INTERFACE(Overlay); + + virtual void destroy() = 0; // one-way +}; + +// ---------------------------------------------------------------------------- + +class BnOverlay : public BnInterface<IOverlay> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IOVERLAY_H diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h new file mode 100644 index 0000000..87b320f --- /dev/null +++ b/include/ui/ISurface.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ISURFACE_H +#define ANDROID_ISURFACE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/RefBase.h> +#include <ui/PixelFormat.h> + +#include <hardware/hardware.h> + +namespace android { + +typedef int32_t SurfaceID; + +class IMemoryHeap; +class OverlayRef; + +class ISurface : public IInterface +{ +protected: + enum { + REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION, + UNREGISTER_BUFFERS, + POST_BUFFER, // one-way transaction + CREATE_OVERLAY, + }; + +public: + DECLARE_META_INTERFACE(Surface); + + + class BufferHeap { + public: + enum { + /* rotate source image 90 degrees */ + ROT_90 = HAL_TRANSFORM_ROT_90, + }; + BufferHeap(); + + BufferHeap(uint32_t w, uint32_t h, + int32_t hor_stride, int32_t ver_stride, + PixelFormat format, const sp<IMemoryHeap>& heap); + + BufferHeap(uint32_t w, uint32_t h, + int32_t hor_stride, int32_t ver_stride, + PixelFormat format, uint32_t transform, uint32_t flags, + const sp<IMemoryHeap>& heap); + + ~BufferHeap(); + + uint32_t w; + uint32_t h; + int32_t hor_stride; + int32_t ver_stride; + PixelFormat format; + uint32_t transform; + uint32_t flags; + sp<IMemoryHeap> heap; + }; + + virtual status_t registerBuffers(const BufferHeap& buffers) = 0; + + virtual void postBuffer(ssize_t offset) = 0; // one-way + + virtual void unregisterBuffers() = 0; + + virtual sp<OverlayRef> createOverlay( + uint32_t w, uint32_t h, int32_t format) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurface : public BnInterface<ISurface> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ISURFACE_H diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h new file mode 100644 index 0000000..f9eeb30 --- /dev/null +++ b/include/ui/ISurfaceComposer.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ISURFACE_COMPOSER_H +#define ANDROID_ISURFACE_COMPOSER_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> + +#include <ui/PixelFormat.h> +#include <ui/ISurfaceFlingerClient.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +class DisplayInfo; +class IGPUCallback; + +class ISurfaceComposer : public IInterface +{ +public: + DECLARE_META_INTERFACE(SurfaceComposer); + + enum { // (keep in sync with Surface.java) + eHidden = 0x00000004, + eGPU = 0x00000008, + eHardware = 0x00000010, + eDestroyBackbuffer = 0x00000020, + eSecure = 0x00000080, + eNonPremultiplied = 0x00000100, + ePushBuffers = 0x00000200, + + eFXSurfaceNormal = 0x00000000, + eFXSurfaceBlur = 0x00010000, + eFXSurfaceDim = 0x00020000, + eFXSurfaceMask = 0x000F0000, + }; + + enum { + ePositionChanged = 0x00000001, + eLayerChanged = 0x00000002, + eSizeChanged = 0x00000004, + eAlphaChanged = 0x00000008, + eMatrixChanged = 0x00000010, + eTransparentRegionChanged = 0x00000020, + eVisibilityChanged = 0x00000040, + eFreezeTintChanged = 0x00000080, + eDestroyed = 0x00000100 + }; + + enum { + eLayerHidden = 0x01, + eLayerFrozen = 0x02, + eLayerDither = 0x04, + eLayerFilter = 0x08, + eLayerBlurFreeze = 0x10 + }; + + enum { + eOrientationDefault = 0, + eOrientation90 = 1, + eOrientation180 = 2, + eOrientation270 = 3, + eOrientationSwapMask = 0x01 + }; + + /* create connection with surface flinger, requires + * ACCESS_SURFACE_FLINGER permission + */ + + virtual sp<ISurfaceFlingerClient> createConnection() = 0; + + /* retrieve the control block */ + virtual sp<IMemory> getCblk() const = 0; + + /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */ + virtual void openGlobalTransaction() = 0; + virtual void closeGlobalTransaction() = 0; + + /* [un]freeze display. recquires ACCESS_SURFACE_FLINGER permission */ + virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0; + virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0; + + /* Set display orientation. recquires ACCESS_SURFACE_FLINGER permission */ + virtual int setOrientation(DisplayID dpy, int orientation) = 0; + + /* signal that we're done booting. + * recquires ACCESS_SURFACE_FLINGER permission + */ + virtual void bootFinished() = 0; + + /* get access to the GPU. Access is relinquished when releasing regs */ + struct gpu_info_t { + struct gpu_region_t { + sp<IMemory> region; + size_t reserved; + }; + sp<IMemory> regs; + size_t count; + gpu_region_t regions[2]; + }; + virtual status_t requestGPU( + const sp<IGPUCallback>& callback, + gpu_info_t* gpu) = 0; + + /* take the gpu back from any apps using it. They'll get a + * EGL_CONTEXT_LOST error */ + virtual status_t revokeGPU() = 0; + + /* Signal surfaceflinger that there might be some work to do + * This is an ASYNCHRONOUS call. + */ + virtual void signal() const = 0; +}; + +class IGPUCallback : public IInterface +{ +public: + DECLARE_META_INTERFACE(GPUCallback); + virtual void gpuLost() = 0; //one-way +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceComposer : public BnInterface<ISurfaceComposer> +{ +public: + enum { + // Note: BOOT_FINISHED must remain this value, it is called from + // Java by ActivityManagerService. + BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, + CREATE_CONNECTION, + GET_CBLK, + OPEN_GLOBAL_TRANSACTION, + CLOSE_GLOBAL_TRANSACTION, + SET_ORIENTATION, + FREEZE_DISPLAY, + UNFREEZE_DISPLAY, + REQUEST_GPU, + REVOKE_GPU, + SIGNAL + }; + + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +class BnGPUCallback : public BnInterface<IGPUCallback> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ISURFACE_COMPOSER_H diff --git a/include/ui/ISurfaceFlingerClient.h b/include/ui/ISurfaceFlingerClient.h new file mode 100644 index 0000000..5b9361d --- /dev/null +++ b/include/ui/ISurfaceFlingerClient.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ISURFACE_FLINGER_CLIENT_H +#define ANDROID_ISURFACE_FLINGER_CLIENT_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/RefBase.h> + +#include <ui/ISurface.h> + +#include <ui/PixelFormat.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +class Rect; +class Point; +class IMemory; +class ISurface; + +typedef int32_t ClientID; +typedef int32_t DisplayID; + +// ---------------------------------------------------------------------------- + +class layer_state_t; + +class ISurfaceFlingerClient : public IInterface +{ +public: + DECLARE_META_INTERFACE(SurfaceFlingerClient); + + struct surface_data_t { + int32_t token; + int32_t identity; + sp<IMemoryHeap> heap[2]; + status_t readFromParcel(const Parcel& parcel); + status_t writeToParcel(Parcel* parcel) const; + }; + + virtual void getControlBlocks(sp<IMemory>* ctl) const = 0; + + virtual sp<ISurface> createSurface( surface_data_t* data, + int pid, + DisplayID display, + uint32_t w, + uint32_t h, + PixelFormat format, + uint32_t flags) = 0; + + virtual status_t destroySurface(SurfaceID sid) = 0; + + virtual status_t setState(int32_t count, const layer_state_t* states) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ISURFACE_FLINGER_CLIENT_H diff --git a/include/ui/KeyCharacterMap.h b/include/ui/KeyCharacterMap.h new file mode 100644 index 0000000..bad2cf8 --- /dev/null +++ b/include/ui/KeyCharacterMap.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UI_KEY_CHARACTER_MAP_H +#define _UI_KEY_CHARACTER_MAP_H + +#include <stdint.h> +#include <utils/Vector.h> + +using namespace android; + +class KeyCharacterMap +{ +public: + ~KeyCharacterMap(); + + // see the javadoc for android.text.method.KeyCharacterMap for what + // these do + unsigned short get(int keycode, int meta); + unsigned short getNumber(int keycode); + unsigned short getMatch(int keycode, const unsigned short* chars, + int charsize, uint32_t modifiers); + unsigned short getDisplayLabel(int keycode); + bool getKeyData(int keycode, unsigned short *displayLabel, + unsigned short *number, unsigned short* results); + inline unsigned int getKeyboardType() { return m_type; } + bool getEvents(uint16_t* chars, size_t len, + Vector<int32_t>* keys, Vector<uint32_t>* modifiers); + + static KeyCharacterMap* load(int id); + + enum { + NUMERIC = 1, + Q14 = 2, + QWERTY = 3 // or AZERTY or whatever + }; + +#define META_MASK 3 + +private: + struct Key + { + int32_t keycode; + uint16_t display_label; + uint16_t number; + uint16_t data[META_MASK + 1]; + }; + + KeyCharacterMap(); + static KeyCharacterMap* try_file(const char* filename); + Key* find_key(int keycode); + bool find_char(uint16_t c, uint32_t* key, uint32_t* mods); + + unsigned int m_type; + unsigned int m_keyCount; + Key* m_keys; +}; + +#endif // _UI_KEY_CHARACTER_MAP_H diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h new file mode 100644 index 0000000..efa6d2b --- /dev/null +++ b/include/ui/KeycodeLabels.h @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UI_KEYCODE_LABELS_H +#define _UI_KEYCODE_LABELS_H + +struct KeycodeLabel { + const char *literal; + int value; +}; + +static const KeycodeLabel KEYCODES[] = { + { "SOFT_LEFT", 1 }, + { "SOFT_RIGHT", 2 }, + { "HOME", 3 }, + { "BACK", 4 }, + { "CALL", 5 }, + { "ENDCALL", 6 }, + { "0", 7 }, + { "1", 8 }, + { "2", 9 }, + { "3", 10 }, + { "4", 11 }, + { "5", 12 }, + { "6", 13 }, + { "7", 14 }, + { "8", 15 }, + { "9", 16 }, + { "STAR", 17 }, + { "POUND", 18 }, + { "DPAD_UP", 19 }, + { "DPAD_DOWN", 20 }, + { "DPAD_LEFT", 21 }, + { "DPAD_RIGHT", 22 }, + { "DPAD_CENTER", 23 }, + { "VOLUME_UP", 24 }, + { "VOLUME_DOWN", 25 }, + { "POWER", 26 }, + { "CAMERA", 27 }, + { "CLEAR", 28 }, + { "A", 29 }, + { "B", 30 }, + { "C", 31 }, + { "D", 32 }, + { "E", 33 }, + { "F", 34 }, + { "G", 35 }, + { "H", 36 }, + { "I", 37 }, + { "J", 38 }, + { "K", 39 }, + { "L", 40 }, + { "M", 41 }, + { "N", 42 }, + { "O", 43 }, + { "P", 44 }, + { "Q", 45 }, + { "R", 46 }, + { "S", 47 }, + { "T", 48 }, + { "U", 49 }, + { "V", 50 }, + { "W", 51 }, + { "X", 52 }, + { "Y", 53 }, + { "Z", 54 }, + { "COMMA", 55 }, + { "PERIOD", 56 }, + { "ALT_LEFT", 57 }, + { "ALT_RIGHT", 58 }, + { "SHIFT_LEFT", 59 }, + { "SHIFT_RIGHT", 60 }, + { "TAB", 61 }, + { "SPACE", 62 }, + { "SYM", 63 }, + { "EXPLORER", 64 }, + { "ENVELOPE", 65 }, + { "ENTER", 66 }, + { "DEL", 67 }, + { "GRAVE", 68 }, + { "MINUS", 69 }, + { "EQUALS", 70 }, + { "LEFT_BRACKET", 71 }, + { "RIGHT_BRACKET", 72 }, + { "BACKSLASH", 73 }, + { "SEMICOLON", 74 }, + { "APOSTROPHE", 75 }, + { "SLASH", 76 }, + { "AT", 77 }, + { "NUM", 78 }, + { "HEADSETHOOK", 79 }, + { "FOCUS", 80 }, + { "PLUS", 81 }, + { "MENU", 82 }, + { "NOTIFICATION", 83 }, + { "SEARCH", 84 }, + { "PLAYPAUSE", 85 }, + { "STOP", 86 }, + { "NEXTSONG", 87 }, + { "PREVIOUSSONG", 88 }, + { "REWIND", 89 }, + { "FORWARD", 90 }, + { "MUTE", 91 }, + + // NOTE: If you add a new keycode here you must also add it to: + // (enum KeyCode, in this file) + // frameworks/base/core/java/android/view/KeyEvent.java + // tools/puppet_master/PuppetMaster.nav_keys.py + // frameworks/base/core/res/res/values/attrs.xml + + { NULL, 0 } +}; + +// These constants need to match the above mappings. +typedef enum KeyCode { + kKeyCodeUnknown = 0, + + kKeyCodeSoftLeft = 1, + kKeyCodeSoftRight = 2, + kKeyCodeHome = 3, + kKeyCodeBack = 4, + kKeyCodeCall = 5, + kKeyCodeEndCall = 6, + kKeyCode0 = 7, + kKeyCode1 = 8, + kKeyCode2 = 9, + kKeyCode3 = 10, + kKeyCode4 = 11, + kKeyCode5 = 12, + kKeyCode6 = 13, + kKeyCode7 = 14, + kKeyCode8 = 15, + kKeyCode9 = 16, + kKeyCodeStar = 17, + kKeyCodePound = 18, + kKeyCodeDpadUp = 19, + kKeyCodeDpadDown = 20, + kKeyCodeDpadLeft = 21, + kKeyCodeDpadRight = 22, + kKeyCodeDpadCenter = 23, + kKeyCodeVolumeUp = 24, + kKeyCodeVolumeDown = 25, + kKeyCodePower = 26, + kKeyCodeCamera = 27, + kKeyCodeClear = 28, + kKeyCodeA = 29, + kKeyCodeB = 30, + kKeyCodeC = 31, + kKeyCodeD = 32, + kKeyCodeE = 33, + kKeyCodeF = 34, + kKeyCodeG = 35, + kKeyCodeH = 36, + kKeyCodeI = 37, + kKeyCodeJ = 38, + kKeyCodeK = 39, + kKeyCodeL = 40, + kKeyCodeM = 41, + kKeyCodeN = 42, + kKeyCodeO = 43, + kKeyCodeP = 44, + kKeyCodeQ = 45, + kKeyCodeR = 46, + kKeyCodeS = 47, + kKeyCodeT = 48, + kKeyCodeU = 49, + kKeyCodeV = 50, + kKeyCodeW = 51, + kKeyCodeX = 52, + kKeyCodeY = 53, + kKeyCodeZ = 54, + kKeyCodeComma = 55, + kKeyCodePeriod = 56, + kKeyCodeAltLeft = 57, + kKeyCodeAltRight = 58, + kKeyCodeShiftLeft = 59, + kKeyCodeShiftRight = 60, + kKeyCodeTab = 61, + kKeyCodeSpace = 62, + kKeyCodeSym = 63, + kKeyCodeExplorer = 64, + kKeyCodeEnvelope = 65, + kKeyCodeNewline = 66, + kKeyCodeDel = 67, + kKeyCodeGrave = 68, + kKeyCodeMinus = 69, + kKeyCodeEquals = 70, + kKeyCodeLeftBracket = 71, + kKeyCodeRightBracket = 72, + kKeyCodeBackslash = 73, + kKeyCodeSemicolon = 74, + kKeyCodeApostrophe = 75, + kKeyCodeSlash = 76, + kKeyCodeAt = 77, + kKeyCodeNum = 78, + kKeyCodeHeadSetHook = 79, + kKeyCodeFocus = 80, + kKeyCodePlus = 81, + kKeyCodeMenu = 82, + kKeyCodeNotification = 83, + kKeyCodeSearch = 84, + kKeyCodePlayPause = 85, + kKeyCodeStop = 86, + kKeyCodeNextSong = 87, + kKeyCodePreviousSong = 88, + kKeyCodeRewind = 89, + kKeyCodeForward = 90, + kKeyCodeMute = 91 +} KeyCode; + +static const KeycodeLabel FLAGS[] = { + { "WAKE", 0x00000001 }, + { "WAKE_DROPPED", 0x00000002 }, + { "SHIFT", 0x00000004 }, + { "CAPS_LOCK", 0x00000008 }, + { "ALT", 0x00000010 }, + { "ALT_GR", 0x00000020 }, + { "MENU", 0x00000040 }, + { "LAUNCHER", 0x00000080 }, + { NULL, 0 } +}; + +#endif // _UI_KEYCODE_LABELS_H diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h new file mode 100644 index 0000000..66514b4 --- /dev/null +++ b/include/ui/Overlay.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_OVERLAY_H +#define ANDROID_OVERLAY_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/IInterface.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/PixelFormat.h> +#include <ui/IOverlay.h> + +#include <hardware/overlay.h> + +namespace android { + +class IMemory; +class IMemoryHeap; + +// ---------------------------------------------------------------------------- + +class OverlayRef : public LightRefBase<OverlayRef> +{ +public: + OverlayRef(overlay_handle_t, const sp<IOverlay>&, + uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs); + + static sp<OverlayRef> readFromParcel(const Parcel& data); + static status_t writeToParcel(Parcel* reply, const sp<OverlayRef>& o); + +private: + friend class LightRefBase<OverlayRef>; + friend class Overlay; + + OverlayRef(); + virtual ~OverlayRef(); + + overlay_handle_t mOverlayHandle; + sp<IOverlay> mOverlayChannel; + uint32_t mWidth; + uint32_t mHeight; + int32_t mFormat; + int32_t mWidthStride; + int32_t mHeightStride; + bool mOwnHandle; +}; + +// ---------------------------------------------------------------------------- + +class Overlay : public virtual RefBase +{ +public: + Overlay(const sp<OverlayRef>& overlayRef); + + /* destroys this overlay */ + void destroy(); + + /* get the HAL handle for this overlay */ + overlay_handle_t getHandleRef() const; + + /* blocks until an overlay buffer is available and return that buffer. */ + status_t dequeueBuffer(overlay_buffer_t* buffer); + + /* release the overlay buffer and post it */ + status_t queueBuffer(overlay_buffer_t buffer); + + /* returns the address of a given buffer if supported, NULL otherwise. */ + void* getBufferAddress(overlay_buffer_t buffer); + + /* get physical informations about the overlay */ + uint32_t getWidth() const; + uint32_t getHeight() const; + int32_t getFormat() const; + int32_t getWidthStride() const; + int32_t getHeightStride() const; + int32_t getBufferCount() const; + status_t getStatus() const; + +private: + virtual ~Overlay(); + + sp<OverlayRef> mOverlayRef; + overlay_data_device_t *mOverlayData; + status_t mStatus; +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_OVERLAY_H diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h new file mode 100644 index 0000000..14af823 --- /dev/null +++ b/include/ui/PixelFormat.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +// Pixel formats used across the system. +// These formats might not all be supported by all renderers, for instance +// skia or SurfaceFlinger are not required to support all of these formats +// (either as source or destination) + +// XXX: we should consolidate these formats and skia's + +#ifndef UI_PIXELFORMAT_H +#define UI_PIXELFORMAT_H + +#include <stdint.h> +#include <sys/types.h> +#include <utils/Errors.h> +#include <pixelflinger/format.h> + +namespace android { + +enum { + // + // these constants need to match those + // in graphics/PixelFormat.java & pixelflinger/format.h + // + PIXEL_FORMAT_UNKNOWN = 0, + PIXEL_FORMAT_NONE = 0, + + // logical pixel formats used by the SurfaceFlinger ----------------------- + PIXEL_FORMAT_CUSTOM = -4, + // Custom pixel-format described by a PixelFormatInfo structure + + PIXEL_FORMAT_TRANSLUCENT = -3, + // System chooses a format that supports translucency (many alpha bits) + + PIXEL_FORMAT_TRANSPARENT = -2, + // System chooses a format that supports transparency + // (at least 1 alpha bit) + + PIXEL_FORMAT_OPAQUE = -1, + // System chooses an opaque format (no alpha bits required) + + // real pixel formats supported for rendering ----------------------------- + + PIXEL_FORMAT_RGBA_8888 = GGL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA + PIXEL_FORMAT_RGBX_8888 = GGL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0 + PIXEL_FORMAT_RGB_888 = GGL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB + PIXEL_FORMAT_RGB_565 = GGL_PIXEL_FORMAT_RGB_565, // 16-bit RGB + PIXEL_FORMAT_BGRA_8888 = GGL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA + PIXEL_FORMAT_RGBA_5551 = GGL_PIXEL_FORMAT_RGBA_5551, // 16-bit ARGB + PIXEL_FORMAT_RGBA_4444 = GGL_PIXEL_FORMAT_RGBA_4444, // 16-bit ARGB + PIXEL_FORMAT_A_8 = GGL_PIXEL_FORMAT_A_8, // 8-bit A + PIXEL_FORMAT_L_8 = GGL_PIXEL_FORMAT_L_8, // 8-bit L (R=G=B=L) + PIXEL_FORMAT_LA_88 = GGL_PIXEL_FORMAT_LA_88, // 16-bit LA + PIXEL_FORMAT_RGB_332 = GGL_PIXEL_FORMAT_RGB_332, // 8-bit RGB + + PIXEL_FORMAT_YCbCr_422_SP= GGL_PIXEL_FORMAT_YCbCr_422_SP, + PIXEL_FORMAT_YCbCr_420_SP= GGL_PIXEL_FORMAT_YCbCr_420_SP, + PIXEL_FORMAT_YCbCr_422_P = GGL_PIXEL_FORMAT_YCbCr_422_P, + PIXEL_FORMAT_YCbCr_420_P = GGL_PIXEL_FORMAT_YCbCr_420_P, + PIXEL_FORMAT_YCbCr_422_I = GGL_PIXEL_FORMAT_YCbCr_422_I, + PIXEL_FORMAT_YCbCr_420_I = GGL_PIXEL_FORMAT_YCbCr_420_I, + + // New formats can be added if they're also defined in + // pixelflinger/format.h +}; + +typedef int32_t PixelFormat; + +struct PixelFormatInfo +{ + enum { // components + ALPHA = 1, + RGB = 2, + RGBA = 3, + LUMINANCE = 4, + LUMINANCE_ALPHA = 5, + Y_CB_CR_SP = 6, + Y_CB_CR_P = 7, + Y_CB_CR_I = 8, + }; + + inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { } + size_t getScanlineSize(unsigned int width) const; + size_t version; + PixelFormat format; + size_t bytesPerPixel; + size_t bitsPerPixel; + uint8_t h_alpha; + uint8_t l_alpha; + uint8_t h_red; + uint8_t l_red; + uint8_t h_green; + uint8_t l_green; + uint8_t h_blue; + uint8_t l_blue; + uint8_t components; + uint8_t reserved0[3]; + uint32_t reserved1; +}; + +// Consider caching the results of these functions are they're not +// guaranteed to be fast. +ssize_t bytesPerPixel(PixelFormat format); +ssize_t bitsPerPixel(PixelFormat format); +status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info); + +}; // namespace android + +#endif // UI_PIXELFORMAT_H diff --git a/include/ui/Point.h b/include/ui/Point.h new file mode 100644 index 0000000..dbbad1e --- /dev/null +++ b/include/ui/Point.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_POINT +#define ANDROID_UI_POINT + +#include <utils/TypeHelpers.h> + +namespace android { + +class Point +{ +public: + int x; + int y; + + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + // Default constructor doesn't initialize the Point + inline Point() + { + } + + inline Point(int _x, int _y) : x(_x), y(_y) + { + } + + inline bool operator == (const Point& rhs) const { + return (x == rhs.x) && (y == rhs.y); + } + inline bool operator != (const Point& rhs) const { + return !operator == (rhs); + } + + inline bool isOrigin() const { + return !(x|y); + } + + // operator < defines an order which allows to use points in sorted + // vectors. + bool operator < (const Point& rhs) const { + return y<rhs.y || (y==rhs.y && x<rhs.x); + } + + inline Point& operator - () { + x=-x; + y=-y; + return *this; + } + + inline Point& operator += (const Point& rhs) { + x += rhs.x; + y += rhs.y; + return *this; + } + inline Point& operator -= (const Point& rhs) { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + Point operator + (const Point& rhs) const { + return Point(x+rhs.x, y+rhs.y); + } + Point operator - (const Point& rhs) const { + return Point(x-rhs.x, y-rhs.y); + } +}; + +ANDROID_BASIC_TYPES_TRAITS(Point) + +}; // namespace android + +#endif // ANDROID_UI_POINT diff --git a/include/ui/Rect.h b/include/ui/Rect.h new file mode 100644 index 0000000..d232847 --- /dev/null +++ b/include/ui/Rect.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_RECT +#define ANDROID_UI_RECT + +#include <utils/TypeHelpers.h> +#include <ui/Point.h> + +namespace android { + +class Rect +{ +public: + int left; + int top; + int right; + int bottom; + + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + inline Rect() + { + } + + inline Rect(int w, int 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) + { + } + + inline Rect(const Point& lt, const Point& rb) + : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) + { + } + + void makeInvalid(); + + // a valid rectangle has a non negative width and height + inline bool isValid() const { + return (width()>=0) && (height()>=0); + } + + // an empty rect has a zero width or height, or is invalid + inline bool isEmpty() const { + return (width()<=0) || (height()<=0); + } + + inline void set(const Rect& rhs) { + operator = (rhs); + } + + // rectangle's width + inline int width() const { + return right-left; + } + + // rectangle's height + inline int height() const { + return bottom-top; + } + + // returns left-top Point non-const reference, can be assigned + inline Point& leftTop() { + return reinterpret_cast<Point&>(left); + } + // returns right bottom non-const reference, can be assigned + inline Point& rightBottom() { + return reinterpret_cast<Point&>(right); + } + + // the following 4 functions return the 4 corners of the rect as Point + inline const Point& leftTop() const { + return reinterpret_cast<const Point&>(left); + } + inline const Point& rightBottom() const { + return reinterpret_cast<const Point&>(right); + } + Point rightTop() const { + return Point(right, top); + } + Point leftBottom() const { + return Point(left, bottom); + } + + // comparisons + inline bool operator == (const Rect& rhs) const { + return (left == rhs.left) && (top == rhs.top) && + (right == rhs.right) && (bottom == rhs.bottom); + } + + inline bool operator != (const Rect& rhs) const { + return !operator == (rhs); + } + + // operator < defines an order which allows to use rectangles in sorted + // vectors. + bool operator < (const Rect& rhs) const; + + Rect& offsetToOrigin() { + right -= left; + bottom -= top; + left = top = 0; + return *this; + } + Rect& offsetTo(const Point& p) { + return offsetTo(p.x, p.y); + } + Rect& offsetBy(const Point& dp) { + return offsetBy(dp.x, dp.y); + } + Rect& operator += (const Point& rhs) { + return offsetBy(rhs.x, rhs.y); + } + Rect& operator -= (const Point& rhs) { + return offsetBy(-rhs.x, -rhs.y); + } + Rect operator + (const Point& rhs) const; + Rect operator - (const Point& rhs) const; + + void translate(int dx, int dy) { // legacy, don't use. + offsetBy(dx, dy); + } + + Rect& offsetTo(int x, int y); + Rect& offsetBy(int x, int y); + bool intersect(const Rect& with, Rect* result) const; +}; + +ANDROID_BASIC_TYPES_TRAITS(Rect) + +}; // namespace android + +#endif // ANDROID_UI_RECT diff --git a/include/ui/Region.h b/include/ui/Region.h new file mode 100644 index 0000000..7689673 --- /dev/null +++ b/include/ui/Region.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_REGION_H +#define ANDROID_UI_REGION_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Vector.h> +#include <utils/Parcel.h> + +#include <ui/Rect.h> + +#include <hardware/copybit.h> + +#include <core/SkRegion.h> + +namespace android { +// --------------------------------------------------------------------------- + +class String8; + +// --------------------------------------------------------------------------- +class Region +{ +public: + Region(); + Region(const Region& rhs); + explicit Region(const SkRegion& rhs); + explicit Region(const Rect& rhs); + explicit Region(const Parcel& parcel); + explicit Region(const void* buffer); + ~Region(); + + Region& operator = (const Region& rhs); + + inline bool isEmpty() const { return mRegion.isEmpty(); } + inline bool isRect() const { return mRegion.isRect(); } + + Rect bounds() const; + + const SkRegion& toSkRegion() const; + + void clear(); + void set(const Rect& r); + + Region& orSelf(const Rect& rhs); + Region& andSelf(const Rect& rhs); + + // boolean operators, applied on this + Region& orSelf(const Region& rhs); + Region& andSelf(const Region& rhs); + Region& subtractSelf(const Region& rhs); + + // these translate rhs first + Region& translateSelf(int dx, int dy); + Region& orSelf(const Region& rhs, int dx, int dy); + Region& andSelf(const Region& rhs, int dx, int dy); + Region& subtractSelf(const Region& rhs, int dx, int dy); + + // boolean operators + Region merge(const Region& rhs) const; + Region intersect(const Region& rhs) const; + Region subtract(const Region& rhs) const; + + // these translate rhs first + Region translate(int dx, int dy) const; + Region merge(const Region& rhs, int dx, int dy) const; + Region intersect(const Region& rhs, int dx, int dy) const; + Region subtract(const Region& rhs, int dx, int dy) const; + + // convenience operators overloads + inline Region operator | (const Region& rhs) const; + inline Region operator & (const Region& rhs) const; + inline Region operator - (const Region& rhs) const; + inline Region operator + (const Point& pt) const; + + inline Region& operator |= (const Region& rhs); + inline Region& operator &= (const Region& rhs); + inline Region& operator -= (const Region& rhs); + inline Region& operator += (const Point& pt); + + class iterator { + SkRegion::Iterator mIt; + public: + iterator(const Region& r); + inline operator bool () const { return !done(); } + int iterate(Rect* rect); + private: + inline bool done() const { + return const_cast<SkRegion::Iterator&>(mIt).done(); + } + }; + + size_t rects(Vector<Rect>& rectList) const; + + // flatten/unflatten a region to/from a Parcel + status_t write(Parcel& parcel) const; + status_t read(const Parcel& parcel); + + // flatten/unflatten a region to/from a raw buffer + ssize_t write(void* buffer, size_t size) const; + static ssize_t writeEmpty(void* buffer, size_t size); + + ssize_t read(const void* buffer); + static bool isEmpty(void* buffer); + + void dump(String8& out, const char* what, uint32_t flags=0) const; + void dump(const char* what, uint32_t flags=0) const; + +private: + SkRegion mRegion; +}; + + +Region Region::operator | (const Region& rhs) const { + return merge(rhs); +} +Region Region::operator & (const Region& rhs) const { + return intersect(rhs); +} +Region Region::operator - (const Region& rhs) const { + return subtract(rhs); +} +Region Region::operator + (const Point& pt) const { + return translate(pt.x, pt.y); +} + + +Region& Region::operator |= (const Region& rhs) { + return orSelf(rhs); +} +Region& Region::operator &= (const Region& rhs) { + return andSelf(rhs); +} +Region& Region::operator -= (const Region& rhs) { + return subtractSelf(rhs); +} +Region& Region::operator += (const Point& pt) { + return translateSelf(pt.x, pt.y); +} + +// --------------------------------------------------------------------------- + +struct region_iterator : public copybit_region_t { + region_iterator(const Region& region) : i(region) { + this->next = iterate; + } +private: + static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { + return static_cast<const region_iterator*>(self) + ->i.iterate(reinterpret_cast<Rect*>(rect)); + } + mutable Region::iterator i; +}; +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UI_REGION_H + diff --git a/include/ui/Surface.h b/include/ui/Surface.h new file mode 100644 index 0000000..33953a9 --- /dev/null +++ b/include/ui/Surface.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_SURFACE_H +#define ANDROID_UI_SURFACE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/ISurface.h> +#include <ui/PixelFormat.h> +#include <ui/Region.h> +#include <ui/ISurfaceFlingerClient.h> + +namespace android { + +// --------------------------------------------------------------------------- + +class Rect; +class SurfaceComposerClient; + +class Surface : public RefBase +{ + +public: + struct SurfaceInfo { + uint32_t w; + uint32_t h; + uint32_t bpr; + PixelFormat format; + void* bits; + void* base; + uint32_t reserved[2]; + }; + + bool isValid() const { return this && mToken>=0 && mClient!=0; } + SurfaceID ID() const { return mToken; } + + status_t lock(SurfaceInfo* info, bool blocking = true); + status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); + status_t unlockAndPost(); + status_t unlock(); + + void* heapBase(int i) const; + uint32_t getFlags() const { return mFlags; } + + // setSwapRectangle() is mainly used by EGL + void setSwapRectangle(const Rect& r); + const Rect& swapRectangle() const; + status_t nextBuffer(SurfaceInfo* info); + + sp<Surface> dup() const; + static sp<Surface> readFromParcel(Parcel* parcel); + static status_t writeToParcel(const sp<Surface>& surface, Parcel* parcel); + static bool isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs); + + status_t setLayer(int32_t layer); + status_t setPosition(int32_t x, int32_t y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(int32_t layer = -1); + status_t freeze(); + status_t unfreeze(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + status_t setFreezeTint(uint32_t tint); + + uint32_t getIdentity() const { return mIdentity; } +private: + friend class SurfaceComposerClient; + + // camera and camcorder need access to the ISurface binder interface for preview + friend class Camera; + friend class MediaRecorder; + // mediaplayer needs access to ISurface for display + friend class MediaPlayer; + friend class Test; + const sp<ISurface>& getISurface() const { return mSurface; } + + // can't be copied + Surface& operator = (Surface& rhs); + Surface(const Surface& rhs); + + Surface(const sp<SurfaceComposerClient>& client, + const sp<ISurface>& surface, + const ISurfaceFlingerClient::surface_data_t& data, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, + bool owner = true); + + Surface(Surface const* rhs); + + ~Surface(); + + Region dirtyRegion() const; + void setDirtyRegion(const Region& region) const; + + // this locks protects calls to lockSurface() / unlockSurface() + // and is called by SurfaceComposerClient. + Mutex& getLock() const { return mSurfaceLock; } + + sp<SurfaceComposerClient> mClient; + sp<ISurface> mSurface; + sp<IMemoryHeap> mHeap[2]; + SurfaceID mToken; + uint32_t mIdentity; + PixelFormat mFormat; + uint32_t mFlags; + const bool mOwner; + mutable void* mSurfaceHeapBase[2]; + mutable Region mDirtyRegion; + mutable Rect mSwapRectangle; + mutable uint8_t mBackbufferIndex; + mutable Mutex mSurfaceLock; +}; + +}; // namespace android + +#endif // ANDROID_UI_SURFACE_H + diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h new file mode 100644 index 0000000..5d9222d --- /dev/null +++ b/include/ui/SurfaceComposerClient.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SURFACE_COMPOSER_CLIENT_H +#define ANDROID_SURFACE_COMPOSER_CLIENT_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/SortedVector.h> +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/PixelFormat.h> +#include <ui/ISurfaceComposer.h> +#include <ui/Region.h> +#include <ui/Surface.h> + +namespace android { + +// --------------------------------------------------------------------------- + +class Region; +class SurfaceFlingerSynchro; +struct per_client_cblk_t; +struct layer_cblk_t; + +class SurfaceComposerClient : virtual public RefBase +{ +public: + SurfaceComposerClient(); + virtual ~SurfaceComposerClient(); + + // Always make sure we could initialize + status_t initCheck() const; + + // Return the connection of this client + sp<IBinder> connection() const; + + // Retrieve a client for an existing connection. + static sp<SurfaceComposerClient> + clientForConnection(const sp<IBinder>& conn); + + // Forcibly remove connection before all references have gone away. + void dispose(); + + // ------------------------------------------------------------------------ + // surface creation / destruction + + //! Create a surface + sp<Surface> createSurface( + int pid, //!< pid of the process the surfacec is for + DisplayID display, //!< Display to create this surface on + uint32_t w, //!< width in pixel + uint32_t h, //!< height in pixel + PixelFormat format, //!< pixel-format desired + uint32_t flags = 0 //!< usage flags + ); + + // ------------------------------------------------------------------------ + // Composer parameters + // All composer parameters must be changed within a transaction + // several surfaces can be updated in one transaction, all changes are + // committed at once when the transaction is closed. + // CloseTransaction() usually requires an IPC with the server. + + //! Open a composer transaction + status_t openTransaction(); + + //! commit the transaction + status_t closeTransaction(); + + //! Open a composer transaction on all active SurfaceComposerClients. + static void openGlobalTransaction(); + + //! Close a composer transaction on all active SurfaceComposerClients. + static void closeGlobalTransaction(); + + //! Freeze the specified display but not transactions. + static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0); + + //! Resume updates on the specified display. + static status_t unfreezeDisplay(DisplayID dpy, uint32_t flags = 0); + + //! Set the orientation of the given display + static int setOrientation(DisplayID dpy, int orientation); + + // Query the number of displays + static ssize_t getNumberOfDisplays(); + + // Get information about a display + static status_t getDisplayInfo(DisplayID dpy, DisplayInfo* info); + static ssize_t getDisplayWidth(DisplayID dpy); + static ssize_t getDisplayHeight(DisplayID dpy); + static ssize_t getDisplayOrientation(DisplayID dpy); + + +private: + friend class Surface; + + SurfaceComposerClient(const sp<ISurfaceComposer>& sm, + const sp<IBinder>& conn); + + status_t hide(Surface* surface); + status_t show(Surface* surface, int32_t layer = -1); + status_t freeze(Surface* surface); + status_t unfreeze(Surface* surface); + status_t setFlags(Surface* surface, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(Surface* surface, const Region& transparent); + status_t setLayer(Surface* surface, int32_t layer); + status_t setAlpha(Surface* surface, float alpha=1.0f); + status_t setFreezeTint(Surface* surface, uint32_t tint); + status_t setMatrix(Surface* surface, float dsdx, float dtdx, float dsdy, float dtdy); + status_t setPosition(Surface* surface, int32_t x, int32_t y); + status_t setSize(Surface* surface, uint32_t w, uint32_t h); + + //! Unlock the surface, and specify the dirty region if any + status_t unlockAndPostSurface(Surface* surface); + status_t unlockSurface(Surface* surface); + + status_t lockSurface(Surface* surface, + Surface::SurfaceInfo* info, + Region* dirty, + bool blocking = true); + + status_t nextBuffer(Surface* surface, + Surface::SurfaceInfo* info); + + status_t destroySurface(SurfaceID sid); + + void _init(const sp<ISurfaceComposer>& sm, + const sp<ISurfaceFlingerClient>& conn); + void _signal_server(); + static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); + + inline layer_state_t* _get_state_l(const sp<Surface>& surface); + layer_state_t* _lockLayerState(const sp<Surface>& surface); + inline void _unlockLayerState(); + + status_t validateSurface( + per_client_cblk_t const* cblk, Surface const * surface); + + void pinHeap(const sp<IMemoryHeap>& heap); + + mutable Mutex mLock; + layer_state_t* mPrebuiltLayerState; + SortedVector<layer_state_t> mStates; + int32_t mTransactionOpen; + + // these don't need to be protected because they never change + // after assignment + status_t mStatus; + per_client_cblk_t* mControl; + sp<IMemory> mControlMemory; + sp<ISurfaceFlingerClient> mClient; + sp<IMemoryHeap> mSurfaceHeap; + uint8_t* mSurfaceHeapBase; + void* mGL; + SurfaceFlingerSynchro* mSignalServer; +}; + +}; // namespace android + +#endif // ANDROID_SURFACE_COMPOSER_CLIENT_H + diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 0000000..30648b1 --- /dev/null +++ b/include/utils.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Handy utility functions and portability code. This file includes all +// of the generally-useful headers in the "utils" directory. +// +#ifndef _LIBS_UTILS_H +#define _LIBS_UTILS_H + +#include <utils/ported.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/Timers.h> +#include <utils/List.h> +#include <utils/string_array.h> +#include <utils/misc.h> +#include <utils/Errors.h> + +#endif // _LIBS_UTILS_H diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h new file mode 100644 index 0000000..563fcd0 --- /dev/null +++ b/include/utils/AndroidUnicode.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +#ifndef ANDROID_UNICODE_H +#define ANDROID_UNICODE_H + +#include <stdint.h> +#include <sys/types.h> + +#define REPLACEMENT_CHAR (0xFFFD) + +// this part of code is copied from umachine.h under ICU +/** + * Define UChar32 as a type for single Unicode code points. + * UChar32 is a signed 32-bit integer (same as int32_t). + * + * The Unicode code point range is 0..0x10ffff. + * All other values (negative or >=0x110000) are illegal as Unicode code points. + * They may be used as sentinel values to indicate "done", "error" + * or similar non-code point conditions. + * + * @stable ICU 2.4 + */ +typedef int32_t UChar32; + +namespace android { + + class Encoding; + /** + * \class Unicode + * + * Helper class for getting properties of Unicode characters. Characters + * can have one of the types listed in CharType and each character can have the + * directionality of Direction. + */ + class Unicode + { + public: + /** + * Directions specified in the Unicode standard. These directions map directly + * to java.lang.Character. + */ + enum Direction { + DIRECTIONALITY_UNDEFINED = -1, + DIRECTIONALITY_LEFT_TO_RIGHT, + DIRECTIONALITY_RIGHT_TO_LEFT, + DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC, + DIRECTIONALITY_EUROPEAN_NUMBER, + DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR, + DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR, + DIRECTIONALITY_ARABIC_NUMBER, + DIRECTIONALITY_COMMON_NUMBER_SEPARATOR, + DIRECTIONALITY_NONSPACING_MARK, + DIRECTIONALITY_BOUNDARY_NEUTRAL, + DIRECTIONALITY_PARAGRAPH_SEPARATOR, + DIRECTIONALITY_SEGMENT_SEPARATOR, + DIRECTIONALITY_WHITESPACE, + DIRECTIONALITY_OTHER_NEUTRALS, + DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING, + DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE, + DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING, + DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE, + DIRECTIONALITY_POP_DIRECTIONAL_FORMAT + }; + + /** + * Character types as specified in the Unicode standard. These map directly to + * java.lang.Character. + */ + enum CharType { + CHARTYPE_UNASSIGNED = 0, + CHARTYPE_UPPERCASE_LETTER, + CHARTYPE_LOWERCASE_LETTER, + CHARTYPE_TITLECASE_LETTER, + CHARTYPE_MODIFIER_LETTER, + CHARTYPE_OTHER_LETTER, + CHARTYPE_NON_SPACING_MARK, + CHARTYPE_ENCLOSING_MARK, + CHARTYPE_COMBINING_SPACING_MARK, + CHARTYPE_DECIMAL_DIGIT_NUMBER, + CHARTYPE_LETTER_NUMBER, + CHARTYPE_OTHER_NUMBER, + CHARTYPE_SPACE_SEPARATOR, + CHARTYPE_LINE_SEPARATOR, + CHARTYPE_PARAGRAPH_SEPARATOR, + CHARTYPE_CONTROL, + CHARTYPE_FORMAT, + CHARTYPE_MISSING_VALUE_FOR_JAVA, /* This is the mysterious missing 17 value from the java constants */ + CHARTYPE_PRIVATE_USE, + CHARTYPE_SURROGATE, + CHARTYPE_DASH_PUNCTUATION, + CHARTYPE_START_PUNCTUATION, + CHARTYPE_END_PUNCTUATION, + CHARTYPE_CONNECTOR_PUNCTUATION, + CHARTYPE_OTHER_PUNCTUATION, + CHARTYPE_MATH_SYMBOL, + CHARTYPE_CURRENCY_SYMBOL, + CHARTYPE_MODIFIER_SYMBOL, + CHARTYPE_OTHER_SYMBOL, + CHARTYPE_INITIAL_QUOTE_PUNCTUATION, + CHARTYPE_FINAL_QUOTE_PUNCTUATION + }; + + /** + * Decomposition types as described by the unicode standard. These values map to + * the same values in uchar.h in ICU. + */ + enum DecompositionType { + DECOMPOSITION_NONE = 0, + DECOMPOSITION_CANONICAL, + DECOMPOSITION_COMPAT, + DECOMPOSITION_CIRCLE, + DECOMPOSITION_FINAL, + DECOMPOSITION_FONT, + DECOMPOSITION_FRACTION, + DECOMPOSITION_INITIAL, + DECOMPOSITION_ISOLATED, + DECOMPOSITION_MEDIAL, + DECOMPOSITION_NARROW, + DECOMPOSITION_NOBREAK, + DECOMPOSITION_SMALL, + DECOMPOSITION_SQUARE, + DECOMPOSITION_SUB, + DECOMPOSITION_SUPER, + DECOMPOSITION_VERTICAL, + DECOMPOSITION_WIDE + }; + + /** + * Returns the packed data for java calls + * @param c The unicode character. + * @return The packed data for the character. + * + * Copied from java.lang.Character implementation: + * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + * F E D C B A 9 8 7 6 5 4 3 2 1 0 F E D C B A 9 8 7 6 5 4 3 2 1 0 + * + * 31 types --------- + * 18 directionalities --------- + * 2 mirroreds - + * ----------- 56 toupper diffs + * ----------- 48 tolower diffs + * --- 4 totitlecase diffs + * ------------- 84 numeric values + * --------- 24 mirror char diffs + */ + static uint32_t getPackedData(UChar32 c); + + /** + * Get the Character type. + * @param c The unicode character. + * @return The character's type or CHARTYPE_UNASSIGNED if the character is invalid + * or has an unassigned class. + */ + static CharType getType(UChar32 c); + + /** + * Get the Character's decomposition type. + * @param c The unicode character. + * @return The character's decomposition type or DECOMPOSITION_NONE is there + * is no decomposition. + */ + static DecompositionType getDecompositionType(UChar32 c); + + /** + * Returns the digit value of a character or -1 if the character + * is not within the specified radix. + * + * The digit value is computed for integer characters and letters + * within the given radix. This function does not handle Roman Numerals, + * fractions, or any other characters that may represent numbers. + * + * @param c The unicode character + * @param radix The intended radix. + * @return The digit value or -1 if there is no digit value or if the value is outside the radix. + */ + static int getDigitValue(UChar32 c, int radix = 10); + + /** + * Return the numeric value of a character + * + * @param c The unicode character. + * @return The numeric value of the character. -1 if the character has no numeric value, + * -2 if the character has a numeric value that is not representable by an integer. + */ + static int getNumericValue(UChar32 c); + + /** + * Convert the character to lowercase + * @param c The unicode character. + * @return The lowercase character equivalent of c. If c does not have a lowercase equivalent, + * the original character is returned. + */ + static UChar32 toLower(UChar32 c); + + /** + * Convert the character to uppercase + * @param c The unicode character. + * @return The uppercase character equivalent of c. If c does not have an uppercase equivalent, + * the original character is returned. + */ + static UChar32 toUpper(UChar32 c); + + /** + * Get the directionality of the character. + * @param c The unicode character. + * @return The direction of the character or DIRECTIONALITY_UNDEFINED. + */ + static Direction getDirectionality(UChar32 c); + + /** + * Check if the character is a mirrored character. This means that the character + * has an equivalent character that is the mirror image of itself. + * @param c The unicode character. + * @return True iff c has a mirror equivalent. + */ + static bool isMirrored(UChar32 c); + + /** + * Return the mirror of the given character. + * @param c The unicode character. + * @return The mirror equivalent of c. If c does not have a mirror equivalent, + * the original character is returned. + * @see isMirrored + */ + static UChar32 toMirror(UChar32 c); + + /** + * Convert the character to title case. + * @param c The unicode character. + * @return The titlecase equivalent of c. If c does not have a titlecase equivalent, + * the original character is returned. + */ + static UChar32 toTitle(UChar32 c); + + }; + +} + +#endif diff --git a/include/utils/Asset.h b/include/utils/Asset.h new file mode 100644 index 0000000..453a204 --- /dev/null +++ b/include/utils/Asset.h @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Class providing access to a read-only asset. Asset objects are NOT +// thread-safe, and should not be shared across threads. +// +#ifndef __LIBS_ASSET_H +#define __LIBS_ASSET_H + +#include <stdio.h> +#include <sys/types.h> +#include "FileMap.h" +#include "String8.h" +#include "Errors.h" + +namespace android { + +/* + * Instances of this class provide read-only operations on a byte stream. + * + * Access may be optimized for streaming, random, or whole buffer modes. All + * operations are supported regardless of how the file was opened, but some + * things will be less efficient. [pass that in??] + * + * "Asset" is the base class for all types of assets. The classes below + * provide most of the implementation. The AssetManager uses one of the + * static "create" functions defined here to create a new instance. + */ +class Asset { +public: + virtual ~Asset(void); + + static int32_t getGlobalCount(); + + /* used when opening an asset */ + typedef enum AccessMode { + ACCESS_UNKNOWN = 0, + + /* read chunks, and seek forward and backward */ + ACCESS_RANDOM, + + /* read sequentially, with an occasional forward seek */ + ACCESS_STREAMING, + + /* caller plans to ask for a read-only buffer with all data */ + ACCESS_BUFFER, + } AccessMode; + + enum { + /* data larger than this does not get uncompressed into a buffer */ +#ifdef HAVE_ANDROID_OS + UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024 +#else + UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024 +#endif + }; + + /* + * Read data from the current offset. Returns the actual number of + * bytes read, 0 on EOF, or -1 on error. + */ + virtual ssize_t read(void* buf, size_t count) = 0; + + /* + * Seek to the specified offset. "whence" uses the same values as + * lseek/fseek. Returns the new position on success, or (off_t) -1 + * on failure. + */ + virtual off_t seek(off_t offset, int whence) = 0; + + /* + * Close the asset, freeing all associated resources. + */ + virtual void close(void) = 0; + + /* + * Get a pointer to a buffer with the entire contents of the file. + */ + virtual const void* getBuffer(bool wordAligned) = 0; + + /* + * Get the total amount of data that can be read. + */ + virtual off_t getLength(void) const = 0; + + /* + * Get the total amount of data that can be read from the current position. + */ + virtual off_t getRemainingLength(void) const = 0; + + /* + * Open a new file descriptor that can be used to read this asset. + * Returns -1 if you can not use the file descriptor (for example if the + * asset is compressed). + */ + virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0; + + /* + * Get a string identifying the asset's source. This might be a full + * path, it might be a colon-separated list of identifiers. + * + * This is NOT intended to be used for anything except debug output. + * DO NOT try to parse this or use it to open a file. + */ + const char* getAssetSource(void) const { return mAssetSource.string(); } + +protected: + Asset(void); // constructor; only invoked indirectly + + /* handle common seek() housekeeping */ + off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn); + + /* set the asset source string */ + void setAssetSource(const String8& path) { mAssetSource = path; } + + AccessMode getAccessMode(void) const { return mAccessMode; } + +private: + /* these operations are not implemented */ + Asset(const Asset& src); + Asset& operator=(const Asset& src); + + /* AssetManager needs access to our "create" functions */ + friend class AssetManager; + + /* + * Create the asset from a named file on disk. + */ + static Asset* createFromFile(const char* fileName, AccessMode mode); + + /* + * Create the asset from a named, compressed file on disk (e.g. ".gz"). + */ + static Asset* createFromCompressedFile(const char* fileName, + AccessMode mode); + +#if 0 + /* + * Create the asset from a segment of an open file. This will fail + * if "offset" and "length" don't fit within the bounds of the file. + * + * The asset takes ownership of the file descriptor. + */ + static Asset* createFromFileSegment(int fd, off_t offset, size_t length, + AccessMode mode); + + /* + * Create from compressed data. "fd" should be seeked to the start of + * the compressed data. This could be inside a gzip file or part of a + * Zip archive. + * + * The asset takes ownership of the file descriptor. + * + * This may not verify the validity of the compressed data until first + * use. + */ + static Asset* createFromCompressedData(int fd, off_t offset, + int compressionMethod, size_t compressedLength, + size_t uncompressedLength, AccessMode mode); +#endif + + /* + * Create the asset from a memory-mapped file segment. + * + * The asset takes ownership of the FileMap. + */ + static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode); + + /* + * Create the asset from a memory-mapped file segment with compressed + * data. "method" is a Zip archive compression method constant. + * + * The asset takes ownership of the FileMap. + */ + static Asset* createFromCompressedMap(FileMap* dataMap, int method, + size_t uncompressedLen, AccessMode mode); + + + /* + * Create from a reference-counted chunk of shared memory. + */ + // TODO + + AccessMode mAccessMode; // how the asset was opened + String8 mAssetSource; // debug string +}; + + +/* + * =========================================================================== + * + * Innards follow. Do not use these classes directly. + */ + +/* + * An asset based on an uncompressed file on disk. It may encompass the + * entire file or just a piece of it. Access is through fread/fseek. + */ +class _FileAsset : public Asset { +public: + _FileAsset(void); + virtual ~_FileAsset(void); + + /* + * Use a piece of an already-open file. + * + * On success, the object takes ownership of "fd". + */ + status_t openChunk(const char* fileName, int fd, off_t offset, size_t length); + + /* + * Use a memory-mapped region. + * + * On success, the object takes ownership of "dataMap". + */ + status_t openChunk(FileMap* dataMap); + + /* + * Standard Asset interfaces. + */ + virtual ssize_t read(void* buf, size_t count); + virtual off_t seek(off_t offset, int whence); + virtual void close(void); + virtual const void* getBuffer(bool wordAligned); + virtual off_t getLength(void) const { return mLength; } + virtual off_t getRemainingLength(void) const { return mLength-mOffset; } + virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const; + +private: + off_t mStart; // absolute file offset of start of chunk + off_t mLength; // length of the chunk + off_t mOffset; // current local offset, 0 == mStart + FILE* mFp; // for read/seek + char* mFileName; // for opening + + /* + * To support getBuffer() we either need to read the entire thing into + * a buffer or memory-map it. For small files it's probably best to + * just read them in. + */ + enum { kReadVsMapThreshold = 4096 }; + + FileMap* mMap; // for memory map + unsigned char* mBuf; // for read + + const void* ensureAlignment(FileMap* map); +}; + + +/* + * An asset based on compressed data in a file. + */ +class _CompressedAsset : public Asset { +public: + _CompressedAsset(void); + virtual ~_CompressedAsset(void); + + /* + * Use a piece of an already-open file. + * + * On success, the object takes ownership of "fd". + */ + status_t openChunk(int fd, off_t offset, int compressionMethod, + size_t uncompressedLen, size_t compressedLen); + + /* + * Use a memory-mapped region. + * + * On success, the object takes ownership of "fd". + */ + status_t openChunk(FileMap* dataMap, int compressionMethod, + size_t uncompressedLen); + + /* + * Standard Asset interfaces. + */ + virtual ssize_t read(void* buf, size_t count); + virtual off_t seek(off_t offset, int whence); + virtual void close(void); + virtual const void* getBuffer(bool wordAligned); + virtual off_t getLength(void) const { return mUncompressedLen; } + virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; } + virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; } + +private: + off_t mStart; // offset to start of compressed data + off_t mCompressedLen; // length of the compressed data + off_t mUncompressedLen; // length of the uncompressed data + off_t mOffset; // current offset, 0 == start of uncomp data + + FileMap* mMap; // for memory-mapped input + int mFd; // for file input + + unsigned char* mBuf; // for getBuffer() +}; + +// need: shared mmap version? + +}; // namespace android + +#endif // __LIBS_ASSET_H diff --git a/include/utils/AssetDir.h b/include/utils/AssetDir.h new file mode 100644 index 0000000..abf8a35 --- /dev/null +++ b/include/utils/AssetDir.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Access a chunk of the asset hierarchy as if it were a single directory. +// +#ifndef __LIBS_ASSETDIR_H +#define __LIBS_ASSETDIR_H + +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/SortedVector.h> +#include <utils/misc.h> +#include <sys/types.h> + +namespace android { + +/* + * This provides vector-style access to a directory. We do this rather + * than modeling opendir/readdir access because it's simpler and the + * nature of the operation requires us to have all data on hand anyway. + * + * The list of files will be sorted in ascending order by ASCII value. + * + * The contents are populated by our friend, the AssetManager. + */ +class AssetDir { +public: + AssetDir(void) + : mFileInfo(NULL) + {} + virtual ~AssetDir(void) { + delete mFileInfo; + } + + /* + * Vector-style access. + */ + size_t getFileCount(void) { return mFileInfo->size(); } + const String8& getFileName(int idx) { + return mFileInfo->itemAt(idx).getFileName(); + } + const String8& getSourceName(int idx) { + return mFileInfo->itemAt(idx).getSourceName(); + } + + /* + * Get the type of a file (usually regular or directory). + */ + FileType getFileType(int idx) { + return mFileInfo->itemAt(idx).getFileType(); + } + +private: + /* these operations are not implemented */ + AssetDir(const AssetDir& src); + const AssetDir& operator=(const AssetDir& src); + + friend class AssetManager; + + /* + * This holds information about files in the asset hierarchy. + */ + class FileInfo { + public: + FileInfo(void) {} + FileInfo(const String8& path) // useful for e.g. svect.indexOf + : mFileName(path), mFileType(kFileTypeUnknown) + {} + ~FileInfo(void) {} + FileInfo(const FileInfo& src) { + copyMembers(src); + } + const FileInfo& operator= (const FileInfo& src) { + if (this != &src) + copyMembers(src); + return *this; + } + + void copyMembers(const FileInfo& src) { + mFileName = src.mFileName; + mFileType = src.mFileType; + mSourceName = src.mSourceName; + } + + /* need this for SortedVector; must compare only on file name */ + bool operator< (const FileInfo& rhs) const { + return mFileName < rhs.mFileName; + } + + /* used by AssetManager */ + bool operator== (const FileInfo& rhs) const { + return mFileName == rhs.mFileName; + } + + void set(const String8& path, FileType type) { + mFileName = path; + mFileType = type; + } + + const String8& getFileName(void) const { return mFileName; } + void setFileName(const String8& path) { mFileName = path; } + + FileType getFileType(void) const { return mFileType; } + void setFileType(FileType type) { mFileType = type; } + + const String8& getSourceName(void) const { return mSourceName; } + void setSourceName(const String8& path) { mSourceName = path; } + + /* + * Handy utility for finding an entry in a sorted vector of FileInfo. + * Returns the index of the matching entry, or -1 if none found. + */ + static int findEntry(const SortedVector<FileInfo>* pVector, + const String8& fileName); + + private: + String8 mFileName; // filename only + FileType mFileType; // regular, directory, etc + + String8 mSourceName; // currently debug-only + }; + + /* AssetManager uses this to initialize us */ + void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; } + + SortedVector<FileInfo>* mFileInfo; +}; + +}; // namespace android + +#endif // __LIBS_ASSETDIR_H diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h new file mode 100644 index 0000000..e94c0e8 --- /dev/null +++ b/include/utils/AssetManager.h @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Asset management class. AssetManager objects are thread-safe. +// +#ifndef __LIBS_ASSETMANAGER_H +#define __LIBS_ASSETMANAGER_H + +#include <utils/Asset.h> +#include <utils/AssetDir.h> +#include <utils/KeyedVector.h> +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/String16.h> +#include <utils/ZipFileRO.h> +#include <utils/threads.h> + +namespace android { + +class Asset; // fwd decl for things that include Asset.h first +class ResTable; +struct ResTable_config; + +/* + * Every application that uses assets needs one instance of this. A + * single instance may be shared across multiple threads, and a single + * thread may have more than one instance (the latter is discouraged). + * + * The purpose of the AssetManager is to create Asset objects. To do + * this efficiently it may cache information about the locations of + * files it has seen. This can be controlled with the "cacheMode" + * argument. + * + * The asset hierarchy may be examined like a filesystem, using + * AssetDir objects to peruse a single directory. + */ +class AssetManager { +public: + typedef enum CacheMode { + CACHE_UNKNOWN = 0, + CACHE_OFF, // don't try to cache file locations + CACHE_DEFER, // construct cache as pieces are needed + //CACHE_SCAN, // scan full(!) asset hierarchy at init() time + } CacheMode; + + AssetManager(CacheMode cacheMode = CACHE_OFF); + virtual ~AssetManager(void); + + static int32_t getGlobalCount(); + + /* + * Add a new source for assets. This can be called multiple times to + * look in multiple places for assets. It can be either a directory (for + * finding assets as raw files on the disk) or a ZIP file. This newly + * added asset path will be examined first when searching for assets, + * before any that were previously added. + * + * Returns "true" on success, "false" on failure. If 'cookie' is non-NULL, + * then on success, *cookie is set to the value corresponding to the + * newly-added asset source. + */ + bool addAssetPath(const String8& path, void** cookie); + + /* + * Convenience for adding the standard system assets. Uses the + * ANDROID_ROOT environment variable to find them. + */ + bool addDefaultAssets(); + + /* + * Iterate over the asset paths in this manager. (Previously + * added via addAssetPath() and addDefaultAssets().) On first call, + * 'cookie' must be NULL, resulting in the first cookie being returned. + * Each next cookie will be returned there-after, until NULL indicating + * the end has been reached. + */ + void* nextAssetPath(void* cookie) const; + + /* + * Return an asset path in the manager. 'which' must be between 0 and + * countAssetPaths(). + */ + String8 getAssetPath(void* cookie) const; + + /* + * Set the current locale and vendor. The locale can change during + * the lifetime of an AssetManager if the user updates the device's + * language setting. The vendor is less likely to change. + * + * Pass in NULL to indicate no preference. + */ + void setLocale(const char* locale); + void setVendor(const char* vendor); + + /* + * Choose screen orientation for resources values returned. + */ + void setConfiguration(const ResTable_config& config, const char* locale = NULL); + + typedef Asset::AccessMode AccessMode; // typing shortcut + + /* + * Open an asset. + * + * This will search through locale-specific and vendor-specific + * directories and packages to find the file. + * + * The object returned does not depend on the AssetManager. It should + * be freed by calling Asset::close(). + */ + Asset* open(const char* fileName, AccessMode mode); + + /* + * Open a non-asset file as an asset. + * + * This is for opening files that are included in an asset package + * but aren't assets. These sit outside the usual "locale/vendor" + * path hierarchy, and will not be seen by "AssetDir" or included + * in our filename cache. + */ + Asset* openNonAsset(const char* fileName, AccessMode mode); + + /* + * Explicit non-asset file. The file explicitly named by the cookie (the + * resource set to look in) and fileName will be opened and returned. + */ + Asset* openNonAsset(void* cookie, const char* fileName, AccessMode mode); + + /* + * Open a directory within the asset hierarchy. + * + * The contents of the directory are an amalgam of vendor-specific, + * locale-specific, and generic assets stored loosely or in asset + * packages. Depending on the cache setting and previous accesses, + * this call may incur significant disk overhead. + * + * To open the top-level directory, pass in "". + */ + AssetDir* openDir(const char* dirName); + + /* + * Get the type of a file in the asset hierarchy. They will either + * be "regular" or "directory". [Currently only works for "regular".] + * + * Can also be used as a quick test for existence of a file. + */ + FileType getFileType(const char* fileName); + + /* + * Return the complete resource table to find things in the package. + */ + const ResTable& getResources(bool required = true) const; + + /* + * Discard cached filename information. This only needs to be called + * if somebody has updated the set of "loose" files, and we want to + * discard our cached notion of what's where. + */ + void purge(void) { purgeFileNameCacheLocked(); } + + /* + * Return true if the files this AssetManager references are all + * up-to-date (have not been changed since it was created). If false + * is returned, you will need to create a new AssetManager to get + * the current data. + */ + bool isUpToDate(); + + /** + * Get the known locales for this asset manager object. + */ + void getLocales(Vector<String8>* locales) const; + +private: + struct asset_path + { + String8 path; + FileType type; + }; + + Asset* openInPathLocked(const char* fileName, AccessMode mode, + const asset_path& path); + Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode, + const asset_path& path); + Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode, + const asset_path& path, const char* locale, const char* vendor); + String8 createPathNameLocked(const asset_path& path, const char* locale, + const char* vendor); + String8 createPathNameLocked(const asset_path& path, const char* rootDir); + String8 createZipSourceNameLocked(const String8& zipFileName, + const String8& dirName, const String8& fileName); + + ZipFileRO* getZipFileLocked(const asset_path& path); + Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode); + Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile, + const ZipEntryRO entry, AccessMode mode, const String8& entryName); + + bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, + const asset_path& path, const char* rootDir, const char* dirName); + SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path); + bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, + const asset_path& path, const char* rootDir, const char* dirName); + void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, + const SortedVector<AssetDir::FileInfo>* pContents); + + void loadFileNameCacheLocked(void); + void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, + const char* dirName); + bool fncScanAndMergeDirLocked( + SortedVector<AssetDir::FileInfo>* pMergedInfo, + const asset_path& path, const char* locale, const char* vendor, + const char* dirName); + void purgeFileNameCacheLocked(void); + + const ResTable* getResTable(bool required = true) const; + void setLocaleLocked(const char* locale); + void updateResourceParamsLocked() const; + + class SharedZip : public RefBase { + public: + static sp<SharedZip> get(const String8& path); + + ZipFileRO* getZip(); + + Asset* getResourceTableAsset(); + Asset* setResourceTableAsset(Asset* asset); + + bool isUpToDate(); + + protected: + ~SharedZip(); + + private: + SharedZip(const String8& path, time_t modWhen); + SharedZip(); // <-- not implemented + + String8 mPath; + ZipFileRO* mZipFile; + time_t mModWhen; + + Asset* mResourceTableAsset; + + static Mutex gLock; + static DefaultKeyedVector<String8, wp<SharedZip> > gOpen; + }; + + /* + * Manage a set of Zip files. For each file we need a pointer to the + * ZipFile and a time_t with the file's modification date. + * + * We currently only have two zip files (current app, "common" app). + * (This was originally written for 8, based on app/locale/vendor.) + */ + class ZipSet { + public: + ZipSet(void); + ~ZipSet(void); + + /* + * Return a ZipFileRO structure for a ZipFileRO with the specified + * parameters. + */ + ZipFileRO* getZip(const String8& path); + + Asset* getZipResourceTable(const String8& path); + Asset* setZipResourceTable(const String8& path, Asset* asset); + + // generate path, e.g. "common/en-US-noogle.zip" + static String8 getPathName(const char* path); + + bool isUpToDate(); + + private: + void closeZip(int idx); + + int getIndex(const String8& zip) const; + mutable Vector<String8> mZipPath; + mutable Vector<sp<SharedZip> > mZipFile; + }; + + // Protect all internal state. + mutable Mutex mLock; + + ZipSet mZipSet; + + Vector<asset_path> mAssetPaths; + char* mLocale; + char* mVendor; + + mutable ResTable* mResources; + ResTable_config* mConfig; + + /* + * Cached data for "loose" files. This lets us avoid poking at the + * filesystem when searching for loose assets. Each entry is the + * "extended partial" path, e.g. "default/default/foo/bar.txt". The + * full set of files is present, including ".EXCLUDE" entries. + * + * We do not cache directory names. We don't retain the ".gz", + * because to our clients "foo" and "foo.gz" both look like "foo". + */ + CacheMode mCacheMode; // is the cache enabled? + bool mCacheValid; // clear when locale or vendor changes + SortedVector<AssetDir::FileInfo> mCache; +}; + +}; // namespace android + +#endif // __LIBS_ASSETMANAGER_H diff --git a/include/utils/Atomic.h b/include/utils/Atomic.h new file mode 100644 index 0000000..7eb476c --- /dev/null +++ b/include/utils/Atomic.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_ATOMIC_H +#define ANDROID_UTILS_ATOMIC_H + +#include <cutils/atomic.h> + +#endif // ANDROID_UTILS_ATOMIC_H diff --git a/include/utils/Binder.h b/include/utils/Binder.h new file mode 100644 index 0000000..b5b8d98 --- /dev/null +++ b/include/utils/Binder.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BINDER_H +#define ANDROID_BINDER_H + +#include <utils/IBinder.h> + +// --------------------------------------------------------------------------- +namespace android { + +class BBinder : public IBinder +{ +public: + BBinder(); + + virtual String16 getInterfaceDescriptor() const; + virtual bool isBinderAlive() const; + virtual status_t pingBinder(); + virtual status_t dump(int fd, const Vector<String16>& args); + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0); + + virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp<DeathRecipient>* outRecipient = NULL); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func); + virtual void* findObject(const void* objectID) const; + virtual void detachObject(const void* objectID); + + virtual BBinder* localBinder(); + +protected: + virtual ~BBinder(); + + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + +private: + BBinder(const BBinder& o); + BBinder& operator=(const BBinder& o); + + class Extras; + + Extras* mExtras; + void* mReserved0; +}; + +// --------------------------------------------------------------------------- + +class BpRefBase : public virtual RefBase +{ +protected: + BpRefBase(const sp<IBinder>& o); + virtual ~BpRefBase(); + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + + inline IBinder* remote() { return mRemote; } + inline IBinder* remote() const { return mRemote; } + +private: + BpRefBase(const BpRefBase& o); + BpRefBase& operator=(const BpRefBase& o); + + IBinder* const mRemote; + RefBase::weakref_type* mRefs; + volatile int32_t mState; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_BINDER_H diff --git a/include/utils/BpBinder.h b/include/utils/BpBinder.h new file mode 100644 index 0000000..7b96e29 --- /dev/null +++ b/include/utils/BpBinder.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BPBINDER_H +#define ANDROID_BPBINDER_H + +#include <utils/IBinder.h> +#include <utils/KeyedVector.h> +#include <utils/threads.h> + +// --------------------------------------------------------------------------- +namespace android { + +class BpBinder : public IBinder +{ +public: + BpBinder(int32_t handle); + + inline int32_t handle() const { return mHandle; } + + virtual String16 getInterfaceDescriptor() const; + virtual bool isBinderAlive() const; + virtual status_t pingBinder(); + virtual status_t dump(int fd, const Vector<String16>& args); + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0); + virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp<DeathRecipient>* outRecipient = NULL); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func); + virtual void* findObject(const void* objectID) const; + virtual void detachObject(const void* objectID); + + virtual BpBinder* remoteBinder(); + + status_t setConstantData(const void* data, size_t size); + void sendObituary(); + + class ObjectManager + { + public: + ObjectManager(); + ~ObjectManager(); + + void attach( const void* objectID, + void* object, + void* cleanupCookie, + IBinder::object_cleanup_func func); + void* find(const void* objectID) const; + void detach(const void* objectID); + + void kill(); + + private: + ObjectManager(const ObjectManager&); + ObjectManager& operator=(const ObjectManager&); + + struct entry_t + { + void* object; + void* cleanupCookie; + IBinder::object_cleanup_func func; + }; + + KeyedVector<const void*, entry_t> mObjects; + }; + +protected: + virtual ~BpBinder(); + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + +private: + const int32_t mHandle; + + struct Obituary { + wp<DeathRecipient> recipient; + void* cookie; + uint32_t flags; + }; + + void reportOneDeath(const Obituary& obit); + + mutable Mutex mLock; + volatile int32_t mAlive; + volatile int32_t mObitsSent; + Vector<Obituary>* mObituaries; + ObjectManager mObjects; + Parcel* mConstantData; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_BPBINDER_H diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h new file mode 100644 index 0000000..8e22b0f --- /dev/null +++ b/include/utils/Buffer.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_BUFFER_H__ +#define __UTILS_BUFFER_H__ 1 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +namespace android { + +class Buffer +{ +private: + char *buf; + int bufsiz; + int used; + void ensureCapacity(int len); + + void + makeRoomFor(int len) + { + if (len + used >= bufsiz) { + bufsiz = (len + used) * 3/2 + 2; + char *blah = new char[bufsiz]; + + memcpy(blah, buf, used); + delete[] buf; + buf = blah; + } + } + +public: + Buffer() + { + bufsiz = 16; + buf = new char[bufsiz]; + clear(); + } + + ~Buffer() + { + delete[] buf; + } + + void + clear() + { + buf[0] = '\0'; + used = 0; + } + + int + length() + { + return used; + } + + void + append(const char c) + { + makeRoomFor(1); + buf[used] = c; + used++; + buf[used] = '\0'; + } + + void + append(const char *s, int len) + { + makeRoomFor(len); + + memcpy(buf + used, s, len); + used += len; + buf[used] = '\0'; + } + + void + append(const char *s) + { + append(s, strlen(s)); + } + + char * + getBytes() + { + return buf; + } +}; + +}; // namespace android + +#endif diff --git a/include/utils/BufferedTextOutput.h b/include/utils/BufferedTextOutput.h new file mode 100644 index 0000000..69c6240 --- /dev/null +++ b/include/utils/BufferedTextOutput.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BUFFEREDTEXTOUTPUT_H +#define ANDROID_BUFFEREDTEXTOUTPUT_H + +#include <utils/TextOutput.h> +#include <utils/threads.h> +#include <cutils/uio.h> + +// --------------------------------------------------------------------------- +namespace android { + +class BufferedTextOutput : public TextOutput +{ +public: + //** Flags for constructor */ + enum { + MULTITHREADED = 0x0001 + }; + + BufferedTextOutput(uint32_t flags = 0); + virtual ~BufferedTextOutput(); + + virtual status_t print(const char* txt, size_t len); + virtual void moveIndent(int delta); + + virtual void pushBundle(); + virtual void popBundle(); + +protected: + virtual status_t writeLines(const struct iovec& vec, size_t N) = 0; + +private: + struct BufferState; + struct ThreadState; + + static ThreadState*getThreadState(); + static void threadDestructor(void *st); + + BufferState*getBuffer() const; + + uint32_t mFlags; + const int32_t mSeq; + const int32_t mIndex; + + Mutex mLock; + BufferState* mGlobalState; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BUFFEREDTEXTOUTPUT_H diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h new file mode 100644 index 0000000..4c06067 --- /dev/null +++ b/include/utils/ByteOrder.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +#ifndef _LIBS_UTILS_BYTE_ORDER_H +#define _LIBS_UTILS_BYTE_ORDER_H + +#include <stdint.h> +#include <sys/types.h> +#ifdef HAVE_WINSOCK +#include <winsock2.h> +#else +#include <netinet/in.h> +#endif + +/* + * These macros are like the hton/ntoh byte swapping macros, + * except they allow you to swap to and from the "device" byte + * order. The device byte order is the endianness of the target + * device -- for the ARM CPUs we use today, this is little endian. + * + * Note that the byte swapping functions have not been optimized + * much; performance is currently not an issue for them since the + * intent is to allow us to avoid byte swapping on the device. + */ + +#define DEVICE_BYTE_ORDER LITTLE_ENDIAN + +#if BYTE_ORDER == DEVICE_BYTE_ORDER + +#define dtohl(x) (x) +#define dtohs(x) (x) +#define htodl(x) (x) +#define htods(x) (x) + +#else + +static inline uint32_t android_swap_long(uint32_t v) +{ + return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24); +} + +static inline uint16_t android_swap_short(uint16_t v) +{ + return (v<<8) | (v>>8); +} + +#define dtohl(x) (android_swap_long(x)) +#define dtohs(x) (android_swap_short(x)) +#define htodl(x) (android_swap_long(x)) +#define htods(x) (android_swap_short(x)) + +#endif + +#endif // _LIBS_UTILS_BYTE_ORDER_H diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h new file mode 100644 index 0000000..c2c8ce5 --- /dev/null +++ b/include/utils/CallStack.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CALLSTACK_H +#define ANDROID_CALLSTACK_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/String8.h> + +// --------------------------------------------------------------------------- + +namespace android { + +class CallStack +{ +public: + enum { + MAX_DEPTH = 31 + }; + + CallStack(); + CallStack(const CallStack& rhs); + ~CallStack(); + + CallStack& operator = (const CallStack& rhs); + + bool operator == (const CallStack& rhs) const; + bool operator != (const CallStack& rhs) const; + bool operator < (const CallStack& rhs) const; + bool operator >= (const CallStack& rhs) const; + bool operator > (const CallStack& rhs) const; + bool operator <= (const CallStack& rhs) const; + + const void* operator [] (int index) const; + + void clear(); + + void update(int32_t ignoreDepth=0, int32_t maxDepth=MAX_DEPTH); + + // Dump a stack trace to the log + void dump(const char* prefix = 0) const; + + // Return a string (possibly very long) containing the complete stack trace + String8 toString(const char* prefix = 0) const; + + size_t size() const { return mCount; } + +private: + // Internal helper function + String8 toStringSingleLevel(const char* prefix, int32_t level) const; + + size_t mCount; + const void* mStack[MAX_DEPTH]; +}; + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_CALLSTACK_H diff --git a/include/utils/Debug.h b/include/utils/Debug.h new file mode 100644 index 0000000..a662b9c --- /dev/null +++ b/include/utils/Debug.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Debugging tools. These should be able to be stripped +// in release builds. +// +#ifndef ANDROID_DEBUG_H +#define ANDROID_DEBUG_H + +#include <stdint.h> +#include <sys/types.h> + +namespace android { + +template<bool> struct CompileTimeAssert; +template<> struct CompileTimeAssert<true> {}; + +const char* stringForIndent(int32_t indentLevel); + +typedef void (*debugPrintFunc)(void* cookie, const char* txt); + +void printTypeCode(uint32_t typeCode, + debugPrintFunc func = 0, void* cookie = 0); +void printHexData(int32_t indent, const void *buf, size_t length, + size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16, + size_t alignment=0, bool cArrayStyle=false, + debugPrintFunc func = 0, void* cookie = 0); + +}; // namespace android + +#endif // ANDROID_DEBUG_H diff --git a/include/utils/Endian.h b/include/utils/Endian.h new file mode 100644 index 0000000..19f2504 --- /dev/null +++ b/include/utils/Endian.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Android endian-ness defines. +// +#ifndef _LIBS_UTILS_ENDIAN_H +#define _LIBS_UTILS_ENDIAN_H + +#if defined(HAVE_ENDIAN_H) + +#include <endian.h> + +#else /*not HAVE_ENDIAN_H*/ + +#define __BIG_ENDIAN 0x1000 +#define __LITTLE_ENDIAN 0x0001 + +#if defined(HAVE_LITTLE_ENDIAN) +# define __BYTE_ORDER __LITTLE_ENDIAN +#else +# define __BYTE_ORDER __BIG_ENDIAN +#endif + +#endif /*not HAVE_ENDIAN_H*/ + +#endif /*_LIBS_UTILS_ENDIAN_H*/ diff --git a/include/utils/Errors.h b/include/utils/Errors.h new file mode 100644 index 0000000..1bf9e6f --- /dev/null +++ b/include/utils/Errors.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ERRORS_H +#define ANDROID_ERRORS_H + +#include <sys/types.h> +#include <errno.h> + +namespace android { + +// use this type to return error codes +#ifdef HAVE_MS_C_RUNTIME +typedef int status_t; +#else +typedef int32_t status_t; +#endif + +/* the MS C runtime lacks a few error codes */ + +/* + * Error codes. + * All error codes are negative values. + */ + +// Win32 #defines NO_ERROR as well. It has the same value, so there's no +// real conflict, though it's a bit awkward. +#ifdef _WIN32 +# undef NO_ERROR +#endif + +enum { + OK = 0, // Everything's swell. + NO_ERROR = 0, // No errors. + + UNKNOWN_ERROR = 0x80000000, + + NO_MEMORY = -ENOMEM, + INVALID_OPERATION = -ENOSYS, + BAD_VALUE = -EINVAL, + BAD_TYPE = 0x80000001, + NAME_NOT_FOUND = -ENOENT, + PERMISSION_DENIED = -EPERM, + NO_INIT = -ENODEV, + ALREADY_EXISTS = -EEXIST, + DEAD_OBJECT = -EPIPE, + FAILED_TRANSACTION = 0x80000002, + JPARKS_BROKE_IT = -EPIPE, +#if !defined(HAVE_MS_C_RUNTIME) + BAD_INDEX = -EOVERFLOW, + NOT_ENOUGH_DATA = -ENODATA, + WOULD_BLOCK = -EWOULDBLOCK, + TIMED_OUT = -ETIME, + UNKNOWN_TRANSACTION = -EBADMSG, +#else + BAD_INDEX = -E2BIG, + NOT_ENOUGH_DATA = 0x80000003, + WOULD_BLOCK = 0x80000004, + TIMED_OUT = 0x80000005, + UNKNOWN_TRANSACTION = 0x80000006, +#endif +}; + +// Restore define; enumeration is in "android" namespace, so the value defined +// there won't work for Win32 code in a different namespace. +#ifdef _WIN32 +# define NO_ERROR 0L +#endif + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_ERRORS_H diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h new file mode 100644 index 0000000..8dfd3be --- /dev/null +++ b/include/utils/FileMap.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Encapsulate a shared file mapping. +// +#ifndef __LIBS_FILE_MAP_H +#define __LIBS_FILE_MAP_H + +#include <sys/types.h> + +#ifdef HAVE_WIN32_FILEMAP +#include <windows.h> +#endif + +namespace android { + +/* + * This represents a memory-mapped file. It might be the entire file or + * only part of it. This requires a little bookkeeping because the mapping + * needs to be aligned on page boundaries, and in some cases we'd like to + * have multiple references to the mapped area without creating additional + * maps. + * + * This always uses MAP_SHARED. + * + * TODO: we should be able to create a new FileMap that is a subset of + * an existing FileMap and shares the underlying mapped pages. Requires + * completing the refcounting stuff and possibly introducing the notion + * of a FileMap hierarchy. + */ +class FileMap { +public: + FileMap(void); + + /* + * Create a new mapping on an open file. + * + * Closing the file descriptor does not unmap the pages, so we don't + * claim ownership of the fd. + * + * Returns "false" on failure. + */ + bool create(const char* origFileName, int fd, + off_t offset, size_t length, bool readOnly); + + /* + * Return the name of the file this map came from, if known. + */ + const char* getFileName(void) const { return mFileName; } + + /* + * Get a pointer to the piece of the file we requested. + */ + void* getDataPtr(void) const { return mDataPtr; } + + /* + * Get the length we requested. + */ + size_t getDataLength(void) const { return mDataLength; } + + /* + * Get the data offset used to create this map. + */ + off_t getDataOffset(void) const { return mDataOffset; } + + /* + * Get a "copy" of the object. + */ + FileMap* acquire(void) { mRefCount++; return this; } + + /* + * Call this when mapping is no longer needed. + */ + void release(void) { + if (--mRefCount <= 0) + delete this; + } + + /* + * This maps directly to madvise() values, but allows us to avoid + * including <sys/mman.h> everywhere. + */ + enum MapAdvice { + NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED + }; + + /* + * Apply an madvise() call to the entire file. + * + * Returns 0 on success, -1 on failure. + */ + int advise(MapAdvice advice); + +protected: + // don't delete objects; call release() + ~FileMap(void); + +private: + // these are not implemented + FileMap(const FileMap& src); + const FileMap& operator=(const FileMap& src); + + int mRefCount; // reference count + char* mFileName; // original file name, if known + void* mBasePtr; // base of mmap area; page aligned + size_t mBaseLength; // length, measured from "mBasePtr" + off_t mDataOffset; // offset used when map was created + void* mDataPtr; // start of requested data, offset from base + size_t mDataLength; // length, measured from "mDataPtr" +#ifdef HAVE_WIN32_FILEMAP + HANDLE mFileHandle; // Win32 file handle + HANDLE mFileMapping; // Win32 file mapping handle +#endif + + static long mPageSize; +}; + +}; // namespace android + +#endif // __LIBS_FILE_MAP_H diff --git a/include/utils/IBinder.h b/include/utils/IBinder.h new file mode 100644 index 0000000..7370330 --- /dev/null +++ b/include/utils/IBinder.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IBINDER_H +#define ANDROID_IBINDER_H + +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/String16.h> +#include <utils/Vector.h> + + +#define B_PACK_CHARS(c1, c2, c3, c4) \ + ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) + +// --------------------------------------------------------------------------- +namespace android { + +class BBinder; +class BpBinder; +class IInterface; +class Parcel; + +/** + * Base class and low-level protocol for a remotable object. + * You can derive from this class to create an object for which other + * processes can hold references to it. Communication between processes + * (method calls, property get and set) is down through a low-level + * protocol implemented on top of the transact() API. + */ +class IBinder : public virtual RefBase +{ +public: + enum { + FIRST_CALL_TRANSACTION = 0x00000001, + LAST_CALL_TRANSACTION = 0x00ffffff, + + PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'), + DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'), + INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'), + + // Corresponds to tfOneWay -- an asynchronous call. + FLAG_ONEWAY = 0x00000001 + }; + + inline IBinder() { } + + /** + * Check if this IBinder implements the interface named by + * @a descriptor. If it does, the base pointer to it is returned, + * which you can safely static_cast<> to the concrete C++ interface. + */ + virtual sp<IInterface> queryLocalInterface(const String16& descriptor); + + /** + * Return the canonical name of the interface provided by this IBinder + * object. + */ + virtual String16 getInterfaceDescriptor() const = 0; + + virtual bool isBinderAlive() const = 0; + virtual status_t pingBinder() = 0; + virtual status_t dump(int fd, const Vector<String16>& args) = 0; + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0) = 0; + + /** + * This method allows you to add data that is transported through + * IPC along with your IBinder pointer. When implementing a Binder + * object, override it to write your desired data in to @a outData. + * You can then call getConstantData() on your IBinder to retrieve + * that data, from any process. You MUST return the number of bytes + * written in to the parcel (including padding). + */ + class DeathRecipient : public virtual RefBase + { + public: + virtual void binderDied(const wp<IBinder>& who) = 0; + }; + + /** + * Register the @a recipient for a notification if this binder + * goes away. If this binder object unexpectedly goes away + * (typically because its hosting process has been killed), + * then DeathRecipient::binderDied() will be called with a referene + * to this. + * + * The @a cookie is optional -- if non-NULL, it should be a + * memory address that you own (that is, you know it is unique). + * + * @note You will only receive death notifications for remote binders, + * as local binders by definition can't die without you dying as well. + * Trying to use this function on a local binder will result in an + * INVALID_OPERATION code being returned and nothing happening. + * + * @note This link always holds a weak reference to its recipient. + * + * @note You will only receive a weak reference to the dead + * binder. You should not try to promote this to a strong reference. + * (Nor should you need to, as there is nothing useful you can + * directly do with it now that it has passed on.) + */ + virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0) = 0; + + /** + * Remove a previously registered death notification. + * The @a recipient will no longer be called if this object + * dies. The @a cookie is optional. If non-NULL, you can + * supply a NULL @a recipient, and the recipient previously + * added with that cookie will be unlinked. + */ + virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp<DeathRecipient>* outRecipient = NULL) = 0; + + virtual bool checkSubclass(const void* subclassID) const; + + typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func) = 0; + virtual void* findObject(const void* objectID) const = 0; + virtual void detachObject(const void* objectID) = 0; + + virtual BBinder* localBinder(); + virtual BpBinder* remoteBinder(); + +protected: + inline virtual ~IBinder() { } + +private: +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_IBINDER_H diff --git a/include/utils/IInterface.h b/include/utils/IInterface.h new file mode 100644 index 0000000..959722a --- /dev/null +++ b/include/utils/IInterface.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IINTERFACE_H +#define ANDROID_IINTERFACE_H + +#include <utils/Binder.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IInterface : public virtual RefBase +{ +public: + sp<IBinder> asBinder(); + sp<const IBinder> asBinder() const; + +protected: + virtual IBinder* onAsBinder() = 0; +}; + +// ---------------------------------------------------------------------- + +template<typename INTERFACE> +inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) +{ + return INTERFACE::asInterface(obj); +} + +// ---------------------------------------------------------------------- + +template<typename INTERFACE> +class BnInterface : public INTERFACE, public BBinder +{ +public: + virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); + virtual String16 getInterfaceDescriptor() const; + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +template<typename INTERFACE> +class BpInterface : public INTERFACE, public BpRefBase +{ +public: + BpInterface(const sp<IBinder>& remote); + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +#define DECLARE_META_INTERFACE(INTERFACE) \ + static const String16 descriptor; \ + static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \ + virtual String16 getInterfaceDescriptor() const; \ + +#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + const String16 I##INTERFACE::descriptor(NAME); \ + String16 I##INTERFACE::getInterfaceDescriptor() const { \ + return I##INTERFACE::descriptor; \ + } \ + sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ + { \ + sp<I##INTERFACE> intr; \ + if (obj != NULL) { \ + intr = static_cast<I##INTERFACE*>( \ + obj->queryLocalInterface( \ + I##INTERFACE::descriptor).get()); \ + if (intr == NULL) { \ + intr = new Bp##INTERFACE(obj); \ + } \ + } \ + return intr; \ + } \ + +// ---------------------------------------------------------------------- +// No user-servicable parts after this... + +template<typename INTERFACE> +inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( + const String16& _descriptor) +{ + if (_descriptor == INTERFACE::descriptor) return this; + return NULL; +} + +template<typename INTERFACE> +inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const +{ + return INTERFACE::getInterfaceDescriptor(); +} + +template<typename INTERFACE> +IBinder* BnInterface<INTERFACE>::onAsBinder() +{ + return this; +} + +template<typename INTERFACE> +inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) + : BpRefBase(remote) +{ +} + +template<typename INTERFACE> +inline IBinder* BpInterface<INTERFACE>::onAsBinder() +{ + return remote(); +} + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IINTERFACE_H diff --git a/include/utils/IMemory.h b/include/utils/IMemory.h new file mode 100644 index 0000000..35a3fd7 --- /dev/null +++ b/include/utils/IMemory.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEMORY_H +#define ANDROID_IMEMORY_H + +#include <stdint.h> +#include <sys/types.h> +#include <sys/mman.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +class IMemoryHeap : public IInterface +{ +public: + DECLARE_META_INTERFACE(MemoryHeap); + + // flags returned by getFlags() + enum { + READ_ONLY = 0x00000001, + MAP_ONCE = 0x00000002 + }; + + virtual int getHeapID() const = 0; + virtual void* getBase() const = 0; + virtual size_t getSize() const = 0; + virtual uint32_t getFlags() const = 0; + + // these are there just for backward source compatibility + int32_t heapID() const { return getHeapID(); } + void* base() const { return getBase(); } + size_t virtualSize() const { return getSize(); } +}; + +class BnMemoryHeap : public BnInterface<IMemoryHeap> +{ +public: + virtual status_t onTransact( + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +class IMemory : public IInterface +{ +public: + DECLARE_META_INTERFACE(Memory); + + virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const = 0; + + // helpers + void* fastPointer(const sp<IBinder>& heap, ssize_t offset) const; + void* pointer() const; + size_t size() const; + ssize_t offset() const; +}; + +class BnMemory : public BnInterface<IMemory> +{ +public: + virtual status_t onTransact( + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IMEMORY_H diff --git a/include/utils/IPCThreadState.h b/include/utils/IPCThreadState.h new file mode 100644 index 0000000..0490fd3 --- /dev/null +++ b/include/utils/IPCThreadState.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IPC_THREAD_STATE_H +#define ANDROID_IPC_THREAD_STATE_H + +#include <utils/Errors.h> +#include <utils/Parcel.h> +#include <utils/ProcessState.h> +#include <utils/Vector.h> + +#ifdef HAVE_WIN32_PROC +typedef int uid_t; +#endif + +// --------------------------------------------------------------------------- +namespace android { + +class IPCThreadState +{ +public: + static IPCThreadState* self(); + + sp<ProcessState> process(); + + status_t clearLastError(); + + int getCallingPid(); + int getCallingUid(); + + int64_t clearCallingIdentity(); + void restoreCallingIdentity(int64_t token); + + void flushCommands(); + + void joinThreadPool(bool isMain = true); + + // Stop the local process. + void stopProcess(bool immediate = true); + + status_t transact(int32_t handle, + uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags); + + void incStrongHandle(int32_t handle); + void decStrongHandle(int32_t handle); + void incWeakHandle(int32_t handle); + void decWeakHandle(int32_t handle); + status_t attemptIncStrongHandle(int32_t handle); + static void expungeHandle(int32_t handle, IBinder* binder); + status_t requestDeathNotification( int32_t handle, + BpBinder* proxy); + status_t clearDeathNotification( int32_t handle, + BpBinder* proxy); + + static void shutdown(); + +private: + IPCThreadState(); + ~IPCThreadState(); + + status_t sendReply(const Parcel& reply, uint32_t flags); + status_t waitForResponse(Parcel *reply, + status_t *acquireResult=NULL); + status_t talkWithDriver(bool doReceive=true); + status_t writeTransactionData(int32_t cmd, + uint32_t binderFlags, + int32_t handle, + uint32_t code, + const Parcel& data, + status_t* statusBuffer); + status_t executeCommand(int32_t command); + + void clearCaller(); + + static void threadDestructor(void *st); + static void freeBuffer(Parcel* parcel, + const uint8_t* data, size_t dataSize, + const size_t* objects, size_t objectsSize, + void* cookie); + + const sp<ProcessState> mProcess; + Vector<BBinder*> mPendingStrongDerefs; + Vector<RefBase::weakref_type*> mPendingWeakDerefs; + + Parcel mIn; + Parcel mOut; + status_t mLastError; + pid_t mCallingPid; + uid_t mCallingUid; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_IPC_THREAD_STATE_H diff --git a/include/utils/IPermissionController.h b/include/utils/IPermissionController.h new file mode 100644 index 0000000..cb1dd34 --- /dev/null +++ b/include/utils/IPermissionController.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IPERMISSION_CONTROLLER_H +#define ANDROID_IPERMISSION_CONTROLLER_H + +#include <utils/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IPermissionController : public IInterface +{ +public: + DECLARE_META_INTERFACE(PermissionController); + + virtual bool checkPermission(const String16& permission, + int32_t pid, int32_t uid) = 0; + + enum { + CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + }; +}; + +// ---------------------------------------------------------------------- + +class BnPermissionController : public BnInterface<IPermissionController> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IPERMISSION_CONTROLLER_H + diff --git a/include/utils/IServiceManager.h b/include/utils/IServiceManager.h new file mode 100644 index 0000000..e3d99fe --- /dev/null +++ b/include/utils/IServiceManager.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_ISERVICE_MANAGER_H +#define ANDROID_ISERVICE_MANAGER_H + +#include <utils/IInterface.h> +#include <utils/IPermissionController.h> +#include <utils/Vector.h> +#include <utils/String16.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IServiceManager : public IInterface +{ +public: + DECLARE_META_INTERFACE(ServiceManager); + + /** + * Retrieve an existing service, blocking for a few seconds + * if it doesn't yet exist. + */ + virtual sp<IBinder> getService( const String16& name) const = 0; + + /** + * Retrieve an existing service, non-blocking. + */ + virtual sp<IBinder> checkService( const String16& name) const = 0; + + /** + * Register a service. + */ + virtual status_t addService( const String16& name, + const sp<IBinder>& service) = 0; + + /** + * Return list of all existing services. + */ + virtual Vector<String16> listServices() = 0; + + enum { + GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + CHECK_SERVICE_TRANSACTION, + ADD_SERVICE_TRANSACTION, + LIST_SERVICES_TRANSACTION, + }; +}; + +sp<IServiceManager> defaultServiceManager(); + +template<typename INTERFACE> +status_t getService(const String16& name, sp<INTERFACE>* outService) +{ + const sp<IServiceManager> sm = defaultServiceManager(); + if (sm != NULL) { + *outService = interface_cast<INTERFACE>(sm->getService(name)); + if ((*outService) != NULL) return NO_ERROR; + } + return NAME_NOT_FOUND; +} + +bool checkCallingPermission(const String16& permission); +bool checkCallingPermission(const String16& permission, + int32_t* outPid, int32_t* outUid); + +// ---------------------------------------------------------------------- + +class BnServiceManager : public BnInterface<IServiceManager> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ISERVICE_MANAGER_H + diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h new file mode 100644 index 0000000..f4513ee --- /dev/null +++ b/include/utils/KeyedVector.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_KEYED_VECTOR_H +#define ANDROID_KEYED_VECTOR_H + +#include <assert.h> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/SortedVector.h> +#include <utils/TypeHelpers.h> +#include <utils/Errors.h> + +// --------------------------------------------------------------------------- + +namespace android { + +template <typename KEY, typename VALUE> +class KeyedVector +{ +public: + typedef KEY key_type; + typedef VALUE value_type; + + inline KeyedVector(); + + /* + * empty the vector + */ + + inline void clear() { mVector.clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return mVector.size(); } + //! returns wether or not the vector is empty + inline bool isEmpty() const { return mVector.isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return mVector.capacity(); } + //! setst the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); } + + /*! + * accessors + */ + const VALUE& valueFor(const KEY& key) const; + const VALUE& valueAt(size_t index) const; + const KEY& keyAt(size_t index) const; + ssize_t indexOfKey(const KEY& key) const; + + /*! + * modifing the array + */ + + VALUE& editValueFor(const KEY& key); + VALUE& editValueAt(size_t index); + + /*! + * add/insert/replace items + */ + + ssize_t add(const KEY& key, const VALUE& item); + ssize_t replaceValueFor(const KEY& key, const VALUE& item); + ssize_t replaceValueAt(size_t index, const VALUE& item); + + /*! + * remove items + */ + + ssize_t removeItem(const KEY& key); + ssize_t removeItemsAt(size_t index, size_t count = 1); + +private: + SortedVector< key_value_pair_t<KEY, VALUE> > mVector; +}; + +// --------------------------------------------------------------------------- + +/** + * Variation of KeyedVector that holds a default value to return when + * valueFor() is called with a key that doesn't exist. + */ +template <typename KEY, typename VALUE> +class DefaultKeyedVector : public KeyedVector<KEY, VALUE> +{ +public: + inline DefaultKeyedVector(const VALUE& defValue = VALUE()); + const VALUE& valueFor(const KEY& key) const; + +private: + VALUE mDefault; +}; + +// --------------------------------------------------------------------------- + +template<typename KEY, typename VALUE> inline +KeyedVector<KEY,VALUE>::KeyedVector() +{ +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const { + return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) ); +} + +template<typename KEY, typename VALUE> inline +const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { + ssize_t i = indexOfKey(key); + assert(i>=0); + return mVector.itemAt(i).value; +} + +template<typename KEY, typename VALUE> inline +const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const { + return mVector.itemAt(index).value; +} + +template<typename KEY, typename VALUE> inline +const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const { + return mVector.itemAt(index).key; +} + +template<typename KEY, typename VALUE> inline +VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) { + ssize_t i = indexOfKey(key); + assert(i>=0); + return mVector.editItemAt(i).value; +} + +template<typename KEY, typename VALUE> inline +VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) { + return mVector.editItemAt(index).value; +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) { + return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) ); +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) { + key_value_pair_t<KEY,VALUE> pair(key, value); + mVector.remove(pair); + return mVector.add(pair); +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) { + if (index<size()) { + mVector.editValueAt(index).value = item; + return index; + } + return BAD_INDEX; +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) { + return mVector.remove(key_value_pair_t<KEY,VALUE>(key)); +} + +template<typename KEY, typename VALUE> inline +ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) { + return mVector.removeItemsAt(index, count); +} + +// --------------------------------------------------------------------------- + +template<typename KEY, typename VALUE> inline +DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue) + : mDefault(defValue) +{ +} + +template<typename KEY, typename VALUE> inline +const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { + ssize_t i = indexOfKey(key); + return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_KEYED_VECTOR_H diff --git a/include/utils/List.h b/include/utils/List.h new file mode 100644 index 0000000..1a6be9a --- /dev/null +++ b/include/utils/List.h @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Templated list class. Normally we'd use STL, but we don't have that. +// This class mimics STL's interfaces. +// +// Objects are copied into the list with the '=' operator or with copy- +// construction, so if the compiler's auto-generated versions won't work for +// you, define your own. +// +// The only class you want to use from here is "List". Do not use classes +// starting with "_" directly. +// +#ifndef _LIBS_UTILS_LIST_H +#define _LIBS_UTILS_LIST_H + +namespace android { + +/* + * One element in the list. + */ +template<class T> class _ListNode { +public: + typedef _ListNode<T> _Node; + + _ListNode(const T& val) : mVal(val) {} + ~_ListNode(void) {} + + T& getRef(void) { return mVal; } + void setVal(const T& val) { mVal = val; } + + _Node* getPrev(void) const { return mpPrev; } + void setPrev(_Node* ptr) { mpPrev = ptr; } + _Node* getNext(void) const { return mpNext; } + void setNext(_Node* ptr) { mpNext = ptr; } + +private: + T mVal; + _Node* mpPrev; + _Node* mpNext; +}; + +/* + * Iterator for walking through the list. + */ +template<class T, class Tref> class _ListIterator { +public: + typedef _ListIterator<T,Tref> _Iter; + typedef _ListNode<T> _Node; + + _ListIterator(void) {} + _ListIterator(_Node* ptr) : mpNode(ptr) {} + ~_ListIterator(void) {} + + /* + * Dereference operator. Used to get at the juicy insides. + */ + Tref operator*() const { return mpNode->getRef(); } + + /* + * Iterator comparison. + */ + bool operator==(const _Iter& right) const { return mpNode == right.mpNode; } + bool operator!=(const _Iter& right) const { return mpNode != right.mpNode; } + + /* + * Incr/decr, used to move through the list. + */ + _Iter& operator++(void) { // pre-increment + mpNode = mpNode->getNext(); + return *this; + } + _Iter operator++(int) { // post-increment + _Iter tmp = *this; + ++*this; + return tmp; + } + _Iter& operator--(void) { // pre-increment + mpNode = mpNode->getPrev(); + return *this; + } + _Iter operator--(int) { // post-increment + _Iter tmp = *this; + --*this; + return tmp; + } + + _Node* getNode(void) const { return mpNode; } + +private: + _Node* mpNode; +}; + + +/* + * Doubly-linked list. Instantiate with "List<MyClass> myList". + * + * Objects added to the list are copied using the assignment operator, + * so this must be defined. + */ +template<class T> class List { +public: + typedef _ListNode<T> _Node; + + List(void) { + prep(); + } + List(const List<T>& src) { // copy-constructor + prep(); + insert(begin(), src.begin(), src.end()); + } + virtual ~List(void) { + clear(); + delete[] (unsigned char*) mpMiddle; + } + + typedef _ListIterator<T,T&> iterator; + typedef _ListIterator<T, const T&> const_iterator; + + List<T>& operator=(const List<T>& right); + + /* returns true if the list is empty */ + bool empty(void) const { return mpMiddle->getNext() == mpMiddle; } + + /* return #of elements in list */ + unsigned int size(void) const { + return distance(begin(), end()); + } + + /* + * Return the first element or one past the last element. The + * _ListNode* we're returning is converted to an "iterator" by a + * constructor in _ListIterator. + */ + iterator begin() { return mpMiddle->getNext(); } + const_iterator begin() const { return mpMiddle->getNext(); } + iterator end() { return mpMiddle; } + const_iterator end() const { return mpMiddle; } + + /* add the object to the head or tail of the list */ + void push_front(const T& val) { insert(begin(), val); } + void push_back(const T& val) { insert(end(), val); } + + /* insert before the current node; returns iterator at new node */ + iterator insert(iterator posn, const T& val) { + _Node* newNode = new _Node(val); // alloc & copy-construct + newNode->setNext(posn.getNode()); + newNode->setPrev(posn.getNode()->getPrev()); + posn.getNode()->getPrev()->setNext(newNode); + posn.getNode()->setPrev(newNode); + return newNode; + } + + /* insert a range of elements before the current node */ + void insert(iterator posn, const_iterator first, const_iterator last) { + for ( ; first != last; ++first) + insert(posn, *first); + } + + /* remove one entry; returns iterator at next node */ + iterator erase(iterator posn) { + _Node* pNext = posn.getNode()->getNext(); + _Node* pPrev = posn.getNode()->getPrev(); + pPrev->setNext(pNext); + pNext->setPrev(pPrev); + delete posn.getNode(); + return pNext; + } + + /* remove a range of elements */ + iterator erase(iterator first, iterator last) { + while (first != last) + erase(first++); // don't erase than incr later! + return last; + } + + /* remove all contents of the list */ + void clear(void) { + _Node* pCurrent = mpMiddle->getNext(); + _Node* pNext; + + while (pCurrent != mpMiddle) { + pNext = pCurrent->getNext(); + delete pCurrent; + pCurrent = pNext; + } + mpMiddle->setPrev(mpMiddle); + mpMiddle->setNext(mpMiddle); + } + + /* + * Measure the distance between two iterators. On exist, "first" + * will be equal to "last". The iterators must refer to the same + * list. + * + * (This is actually a generic iterator function. It should be part + * of some other class, possibly an iterator base class. It needs to + * know the difference between a list, which has to march through, + * and a vector, which can just do pointer math.) + */ + unsigned int distance(iterator first, iterator last) { + unsigned int count = 0; + while (first != last) { + ++first; + ++count; + } + return count; + } + unsigned int distance(const_iterator first, const_iterator last) const { + unsigned int count = 0; + while (first != last) { + ++first; + ++count; + } + return count; + } + +private: + /* + * I want a _ListNode but don't need it to hold valid data. More + * to the point, I don't want T's constructor to fire, since it + * might have side-effects or require arguments. So, we do this + * slightly uncouth storage alloc. + */ + void prep(void) { + mpMiddle = (_Node*) new unsigned char[sizeof(_Node)]; + mpMiddle->setPrev(mpMiddle); + mpMiddle->setNext(mpMiddle); + } + + /* + * This node plays the role of "pointer to head" and "pointer to tail". + * It sits in the middle of a circular list of nodes. The iterator + * runs around the circle until it encounters this one. + */ + _Node* mpMiddle; +}; + +/* + * Assignment operator. + * + * The simplest way to do this would be to clear out the target list and + * fill it with the source. However, we can speed things along by + * re-using existing elements. + */ +template<class T> +List<T>& List<T>::operator=(const List<T>& right) +{ + if (this == &right) + return *this; // self-assignment + iterator firstDst = begin(); + iterator lastDst = end(); + const_iterator firstSrc = right.begin(); + const_iterator lastSrc = right.end(); + while (firstSrc != lastSrc && firstDst != lastDst) + *firstDst++ = *firstSrc++; + if (firstSrc == lastSrc) // ran out of elements in source? + erase(firstDst, lastDst); // yes, erase any extras + else + insert(lastDst, firstSrc, lastSrc); // copy remaining over + return *this; +} + +}; // namespace android + +#endif // _LIBS_UTILS_LIST_H diff --git a/include/utils/Log.h b/include/utils/Log.h new file mode 100644 index 0000000..3c6cc8b --- /dev/null +++ b/include/utils/Log.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// C/C++ logging functions. See the logging documentation for API details. +// +// We'd like these to be available from C code (in case we import some from +// somewhere), so this has a C interface. +// +// The output will be correct when the log file is shared between multiple +// threads and/or multiple processes so long as the operating system +// supports O_APPEND. These calls have mutex-protected data structures +// and so are NOT reentrant. Do not use LOG in a signal handler. +// +#ifndef _LIBS_UTILS_LOG_H +#define _LIBS_UTILS_LOG_H + +#include <cutils/log.h> + +#endif // _LIBS_UTILS_LOG_H diff --git a/include/utils/LogSocket.h b/include/utils/LogSocket.h new file mode 100644 index 0000000..01fbfb5 --- /dev/null +++ b/include/utils/LogSocket.h @@ -0,0 +1,20 @@ +/* utils/LogSocket.h +** +** Copyright 2008, The Android Open Source Project +** +** This file is dual licensed. It may be redistributed and/or modified +** under the terms of the Apache 2.0 License OR version 2 of the GNU +** General Public License. +*/ + +#ifndef _UTILS_LOGSOCKET_H +#define _UTILS_LOGSOCKET_H + +#define SOCKET_CLOSE_LOCAL 0 + +void add_send_stats(int fd, int send); +void add_recv_stats(int fd, int recv); +void log_socket_close(int fd, short reason); +void log_socket_connect(int fd, unsigned int ip, unsigned short port); + +#endif /* _UTILS_LOGSOCKET_H */ diff --git a/include/utils/MemoryBase.h b/include/utils/MemoryBase.h new file mode 100644 index 0000000..eb5a9d2 --- /dev/null +++ b/include/utils/MemoryBase.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_BASE_H +#define ANDROID_MEMORY_BASE_H + +#include <stdlib.h> +#include <stdint.h> + +#include <utils/IMemory.h> + + +namespace android { + +// --------------------------------------------------------------------------- + +class MemoryBase : public BnMemory +{ +public: + MemoryBase(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size); + virtual ~MemoryBase(); + virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const; + +protected: + size_t getSize() const { return mSize; } + ssize_t getOffset() const { return mOffset; } + const sp<IMemoryHeap>& getHeap() const { return mHeap; } + +private: + size_t mSize; + ssize_t mOffset; + sp<IMemoryHeap> mHeap; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_BASE_H diff --git a/include/utils/MemoryDealer.h b/include/utils/MemoryDealer.h new file mode 100644 index 0000000..454b627 --- /dev/null +++ b/include/utils/MemoryDealer.h @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_DEALER_H +#define ANDROID_MEMORY_DEALER_H + + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/IMemory.h> +#include <utils/threads.h> +#include <utils/MemoryHeapBase.h> + +namespace android { +// ---------------------------------------------------------------------------- +class String8; + +/* + * interface for implementing a "heap". A heap basically provides + * the IMemoryHeap interface for cross-process sharing and the + * ability to map/unmap pages within the heap. + */ +class HeapInterface : public virtual BnMemoryHeap +{ +public: + // all values must be page-aligned + virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0; +}; + +// ---------------------------------------------------------------------------- + +/* + * interface for implementing an allocator. An allocator provides + * methods for allocating and freeing memory blocks and dumping + * its state. + */ +class AllocatorInterface : public RefBase +{ +public: + enum { + PAGE_ALIGNED = 0x00000001 + }; + + virtual size_t allocate(size_t size, uint32_t flags = 0) = 0; + virtual status_t deallocate(size_t offset) = 0; + virtual size_t size() const = 0; + 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; +}; + +// ---------------------------------------------------------------------------- + +/* + * concrete implementation of HeapInterface on top of mmap() + */ +class SharedHeap : public HeapInterface, public MemoryHeapBase +{ +public: + SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL); + virtual ~SharedHeap(); + virtual sp<IMemory> mapMemory(size_t offset, size_t size); +}; + +// ---------------------------------------------------------------------------- + +/* + * A simple templatized doubly linked-list implementation + */ + +template <typename NODE> +class LinkedList +{ + NODE* mFirst; + NODE* mLast; + +public: + LinkedList() : mFirst(0), mLast(0) { } + bool isEmpty() const { return mFirst == 0; } + NODE const* head() const { return mFirst; } + NODE* head() { return mFirst; } + NODE const* tail() const { return mLast; } + NODE* tail() { return mLast; } + + void insertAfter(NODE* node, NODE* newNode) { + newNode->prev = node; + newNode->next = node->next; + if (node->next == 0) mLast = newNode; + else node->next->prev = newNode; + node->next = newNode; + } + + void insertBefore(NODE* node, NODE* newNode) { + newNode->prev = node->prev; + newNode->next = node; + if (node->prev == 0) mFirst = newNode; + else node->prev->next = newNode; + node->prev = newNode; + } + + void insertHead(NODE* newNode) { + if (mFirst == 0) { + mFirst = mLast = newNode; + newNode->prev = newNode->next = 0; + } else { + insertBefore(mFirst, newNode); + } + } + + void insertTail(NODE* newNode) { + if (mLast == 0) insertBeginning(newNode); + else insertAfter(mLast, newNode); + } + + NODE* remove(NODE* node) { + if (node->prev == 0) mFirst = node->next; + else node->prev->next = node->next; + if (node->next == 0) mLast = node->prev; + else node->next->prev = node->prev; + return node; + } +}; + + +/* + * concrete implementation of AllocatorInterface using a simple + * best-fit allocation scheme + */ +class SimpleBestFitAllocator : public AllocatorInterface +{ +public: + + SimpleBestFitAllocator(size_t size); + virtual ~SimpleBestFitAllocator(); + + virtual size_t allocate(size_t size, uint32_t flags = 0); + virtual status_t deallocate(size_t offset); + virtual size_t size() const; + virtual void dump(const char* what, uint32_t flags = 0) const; + virtual void dump(String8& res, + const char* what, uint32_t flags = 0) const; + +private: + + struct chunk_t { + chunk_t(size_t start, size_t size) + : start(start), size(size), free(1), prev(0), next(0) { + } + size_t start; + size_t size : 28; + int free : 4; + mutable chunk_t* prev; + mutable chunk_t* next; + }; + + ssize_t alloc(size_t size, uint32_t flags); + chunk_t* dealloc(size_t start); + void dump_l(const char* what, uint32_t flags = 0) const; + void dump_l(String8& res, const char* what, uint32_t flags = 0) const; + + static const int kMemoryAlign; + mutable Mutex mLock; + LinkedList<chunk_t> mList; + size_t mHeapSize; +}; + +// ---------------------------------------------------------------------------- + +class MemoryDealer : public RefBase +{ +public: + + enum { + READ_ONLY = MemoryHeapBase::READ_ONLY, + PAGE_ALIGNED = AllocatorInterface::PAGE_ALIGNED + }; + + // creates a memory dealer with the SharedHeap and SimpleBestFitAllocator + MemoryDealer(size_t size, uint32_t flags = 0, const char* name = 0); + + // provide a custom heap but use the SimpleBestFitAllocator + MemoryDealer(const sp<HeapInterface>& heap); + + // provide both custom heap and allocotar + MemoryDealer( + const sp<HeapInterface>& heap, + const sp<AllocatorInterface>& allocator); + + virtual ~MemoryDealer(); + + virtual sp<IMemory> allocate(size_t size, uint32_t flags = 0); + virtual void deallocate(size_t offset); + virtual void dump(const char* what, uint32_t flags = 0) const; + + + sp<IMemoryHeap> getMemoryHeap() const { return heap(); } + sp<AllocatorInterface> getAllocator() const { return allocator(); } + +private: + const sp<HeapInterface>& heap() const; + const sp<AllocatorInterface>& allocator() const; + + class Allocation : public BnMemory { + public: + Allocation(const sp<MemoryDealer>& dealer, + ssize_t offset, size_t size, const sp<IMemory>& memory); + virtual ~Allocation(); + virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const; + private: + sp<MemoryDealer> mDealer; + ssize_t mOffset; + size_t mSize; + sp<IMemory> mMemory; + }; + + sp<HeapInterface> mHeap; + sp<AllocatorInterface> mAllocator; +}; + + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_DEALER_H diff --git a/include/utils/MemoryHeapBase.h b/include/utils/MemoryHeapBase.h new file mode 100644 index 0000000..574acf4 --- /dev/null +++ b/include/utils/MemoryHeapBase.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_HEAP_BASE_H +#define ANDROID_MEMORY_HEAP_BASE_H + +#include <stdlib.h> +#include <stdint.h> + +#include <utils/IMemory.h> + + +namespace android { + +// --------------------------------------------------------------------------- + +class MemoryHeapBase : public virtual BnMemoryHeap +{ +public: + enum { + READ_ONLY = IMemoryHeap::READ_ONLY, + MAP_ONCE = IMemoryHeap::MAP_ONCE, + // memory won't be mapped locally, but will be mapped in the remote + // process. + DONT_MAP_LOCALLY = 0x00000100 + }; + + /* + * maps the memory referenced by fd. but DOESN'T take ownership + * of the filedescriptor (it makes a copy with dup() + */ + MemoryHeapBase(int fd, size_t size, uint32_t flags = 0); + + /* + * maps memory from the given device + */ + MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0); + + /* + * maps memory from ashmem, with the given name for debugging + */ + MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL); + + virtual ~MemoryHeapBase(); + + /* implement IMemoryHeap interface */ + virtual int getHeapID() const; + virtual void* getBase() const; + virtual size_t getSize() const; + virtual uint32_t getFlags() const; + + const char* getDevice() const; + + /* this closes this heap -- use carefully */ + void dispose(); + + /* this is only needed as a workaround, use only if you know + * what you are doing */ + status_t setDevice(const char* device) { + if (mDevice == 0) + mDevice = device; + return mDevice ? NO_ERROR : ALREADY_EXISTS; + } + +protected: + MemoryHeapBase(); + // init() takes ownership of fd + status_t init(int fd, void *base, int size, + int flags = 0, const char* device = NULL); + +private: + status_t mapfd(int fd, size_t size); + + int mFD; + size_t mSize; + void* mBase; + uint32_t mFlags; + const char* mDevice; + bool mNeedUnmap; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_HEAP_BASE_H diff --git a/include/utils/MemoryHeapPmem.h b/include/utils/MemoryHeapPmem.h new file mode 100644 index 0000000..60335ad --- /dev/null +++ b/include/utils/MemoryHeapPmem.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_HEAP_PMEM_H +#define ANDROID_MEMORY_HEAP_PMEM_H + +#include <stdlib.h> +#include <stdint.h> + +#include <utils/MemoryDealer.h> +#include <utils/MemoryHeapBase.h> +#include <utils/IMemory.h> +#include <utils/SortedVector.h> + +namespace android { + +class MemoryHeapBase; + +// --------------------------------------------------------------------------- + +class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase +{ +public: + class MemoryPmem : public BnMemory { + public: + MemoryPmem(const sp<MemoryHeapPmem>& heap); + ~MemoryPmem(); + protected: + const sp<MemoryHeapPmem>& getHeap() const { return mClientHeap; } + private: + friend class MemoryHeapPmem; + virtual void revoke() = 0; + sp<MemoryHeapPmem> mClientHeap; + }; + + MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, + uint32_t flags = IMemoryHeap::MAP_ONCE); + ~MemoryHeapPmem(); + + /* HeapInterface additions */ + virtual sp<IMemory> mapMemory(size_t offset, size_t size); + + /* make the whole heap visible (you know who you are) */ + virtual status_t slap(); + + /* hide (revoke) the whole heap (the client will see the garbage page) */ + virtual status_t unslap(); + + /* revoke all allocations made by this heap */ + virtual void revoke(); + +private: + /* use this to create your own IMemory for mapMemory */ + virtual sp<MemoryPmem> createMemory(size_t offset, size_t size); + void remove(const wp<MemoryPmem>& memory); + +private: + sp<MemoryHeapBase> mParentHeap; + mutable Mutex mLock; + SortedVector< wp<MemoryPmem> > mAllocations; +}; + + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_HEAP_PMEM_H diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h new file mode 100644 index 0000000..9087c44 --- /dev/null +++ b/include/utils/Parcel.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PARCEL_H +#define ANDROID_PARCEL_H + +#include <cutils/native_handle.h> +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/String16.h> +#include <utils/Vector.h> + +// --------------------------------------------------------------------------- +namespace android { + +class IBinder; +class ProcessState; +class String8; +class TextOutput; + +struct flat_binder_object; // defined in support_p/binder_module.h + +class Parcel +{ +public: + Parcel(); + ~Parcel(); + + const uint8_t* data() const; + size_t dataSize() const; + size_t dataAvail() const; + size_t dataPosition() const; + size_t dataCapacity() const; + + status_t setDataSize(size_t size); + void setDataPosition(size_t pos) const; + status_t setDataCapacity(size_t size); + + status_t setData(const uint8_t* buffer, size_t len); + + status_t appendFrom(Parcel *parcel, size_t start, size_t len); + + bool hasFileDescriptors() const; + + status_t writeInterfaceToken(const String16& interface); + bool enforceInterface(const String16& interface) const; + + void freeData(); + + const size_t* objects() const; + size_t objectsCount() const; + + status_t errorCheck() const; + void setError(status_t err); + + status_t write(const void* data, size_t len); + void* writeInplace(size_t len); + status_t writeUnpadded(const void* data, size_t len); + status_t writeInt32(int32_t val); + status_t writeInt64(int64_t val); + status_t writeFloat(float val); + status_t writeDouble(double val); + status_t writeCString(const char* str); + status_t writeString8(const String8& str); + status_t writeString16(const String16& str); + status_t writeString16(const char16_t* str, size_t len); + status_t writeStrongBinder(const sp<IBinder>& val); + status_t writeWeakBinder(const wp<IBinder>& val); + + // doesn't take ownership of the native_handle + status_t writeNativeHandle(const native_handle& handle); + + // Place a file descriptor into the parcel. The given fd must remain + // valid for the lifetime of the parcel. + status_t writeFileDescriptor(int fd); + + // Place a file descriptor into the parcel. A dup of the fd is made, which + // will be closed once the parcel is destroyed. + status_t writeDupFileDescriptor(int fd); + + status_t writeObject(const flat_binder_object& val, bool nullMetaData); + + void remove(size_t start, size_t amt); + + status_t read(void* outData, size_t len) const; + const void* readInplace(size_t len) const; + int32_t readInt32() const; + status_t readInt32(int32_t *pArg) const; + int64_t readInt64() const; + status_t readInt64(int64_t *pArg) const; + float readFloat() const; + status_t readFloat(float *pArg) const; + double readDouble() const; + status_t readDouble(double *pArg) const; + + const char* readCString() const; + String8 readString8() const; + String16 readString16() const; + const char16_t* readString16Inplace(size_t* outLen) const; + sp<IBinder> readStrongBinder() const; + wp<IBinder> readWeakBinder() const; + + + // if alloc is NULL, native_handle is allocated with malloc(), otherwise + // alloc is used. If the function fails, the effects of alloc() must be + // reverted by the caller. + native_handle* readNativeHandle( + native_handle* (*alloc)(void* cookie, int numFds, int ints), + void* cookie) const; + + + // Retrieve a file descriptor from the parcel. This returns the raw fd + // in the parcel, which you do not own -- use dup() to get your own copy. + int readFileDescriptor() const; + + const flat_binder_object* readObject(bool nullMetaData) const; + + // Explicitly close all file descriptors in the parcel. + void closeFileDescriptors(); + + typedef void (*release_func)(Parcel* parcel, + const uint8_t* data, size_t dataSize, + const size_t* objects, size_t objectsSize, + void* cookie); + + const uint8_t* ipcData() const; + size_t ipcDataSize() const; + const size_t* ipcObjects() const; + size_t ipcObjectsCount() const; + void ipcSetDataReference(const uint8_t* data, size_t dataSize, + const size_t* objects, size_t objectsCount, + release_func relFunc, void* relCookie); + + void print(TextOutput& to, uint32_t flags = 0) const; + +private: + Parcel(const Parcel& o); + Parcel& operator=(const Parcel& o); + + status_t finishWrite(size_t len); + void releaseObjects(); + void acquireObjects(); + status_t growData(size_t len); + status_t restartWrite(size_t desired); + status_t continueWrite(size_t desired); + void freeDataNoInit(); + void initState(); + void scanForFds() const; + + status_t mError; + uint8_t* mData; + size_t mDataSize; + size_t mDataCapacity; + mutable size_t mDataPos; + size_t* mObjects; + size_t mObjectsSize; + size_t mObjectsCapacity; + mutable size_t mNextObjectHint; + + mutable bool mFdsKnown; + mutable bool mHasFds; + + release_func mOwner; + void* mOwnerCookie; +}; + +// --------------------------------------------------------------------------- + +inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) +{ + parcel.print(to); + return to; +} + +// --------------------------------------------------------------------------- + +// Generic acquire and release of objects. +void acquire_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who); +void release_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who); + +void flatten_binder(const sp<ProcessState>& proc, + const sp<IBinder>& binder, flat_binder_object* out); +void flatten_binder(const sp<ProcessState>& proc, + const wp<IBinder>& binder, flat_binder_object* out); +status_t unflatten_binder(const sp<ProcessState>& proc, + const flat_binder_object& flat, sp<IBinder>* out); +status_t unflatten_binder(const sp<ProcessState>& proc, + const flat_binder_object& flat, wp<IBinder>* out); + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_PARCEL_H diff --git a/include/utils/Pipe.h b/include/utils/Pipe.h new file mode 100644 index 0000000..6404168 --- /dev/null +++ b/include/utils/Pipe.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// FIFO I/O. +// +#ifndef _LIBS_UTILS_PIPE_H +#define _LIBS_UTILS_PIPE_H + +#ifdef HAVE_ANDROID_OS +#error DO NOT USE THIS FILE IN THE DEVICE BUILD +#endif + +namespace android { + +/* + * Simple anonymous unidirectional pipe. + * + * The primary goal is to create an implementation with minimal overhead + * under Linux. Making Windows, Mac OS X, and Linux all work the same way + * is a secondary goal. Part of this goal is to have something that can + * be fed to a select() call, so that the application can sleep in the + * kernel until something interesting happens. + */ +class Pipe { +public: + Pipe(void); + virtual ~Pipe(void); + + /* Create the pipe */ + bool create(void); + + /* Create a read-only pipe, using the supplied handle as read handle */ + bool createReader(unsigned long handle); + /* Create a write-only pipe, using the supplied handle as write handle */ + bool createWriter(unsigned long handle); + + /* Is this object ready to go? */ + bool isCreated(void); + + /* + * Read "count" bytes from the pipe. Returns the amount of data read, + * or 0 if no data available and we're non-blocking. + * Returns -1 on error. + */ + int read(void* buf, int count); + + /* + * Write "count" bytes into the pipe. Returns number of bytes written, + * or 0 if there's no room for more data and we're non-blocking. + * Returns -1 on error. + */ + int write(const void* buf, int count); + + /* Returns "true" if data is available to read */ + bool readReady(void); + + /* Enable or disable non-blocking I/O for reads */ + bool setReadNonBlocking(bool val); + /* Enable or disable non-blocking I/O for writes. Only works on Linux. */ + bool setWriteNonBlocking(bool val); + + /* + * Get the handle. Only useful in some platform-specific situations. + */ + unsigned long getReadHandle(void); + unsigned long getWriteHandle(void); + + /* + * Modify inheritance, i.e. whether or not a child process will get + * copies of the descriptors. Systems with fork+exec allow us to close + * the descriptors before launching the child process, but Win32 + * doesn't allow it. + */ + bool disallowReadInherit(void); + bool disallowWriteInherit(void); + + /* + * Close one side or the other. Useful in the parent after launching + * a child process. + */ + bool closeRead(void); + bool closeWrite(void); + +private: + bool mReadNonBlocking; + bool mWriteNonBlocking; + + unsigned long mReadHandle; + unsigned long mWriteHandle; +}; + +}; // android + +#endif // _LIBS_UTILS_PIPE_H diff --git a/include/utils/ProcessState.h b/include/utils/ProcessState.h new file mode 100644 index 0000000..39584f4 --- /dev/null +++ b/include/utils/ProcessState.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROCESS_STATE_H +#define ANDROID_PROCESS_STATE_H + +#include <utils/IBinder.h> +#include <utils/KeyedVector.h> +#include <utils/String8.h> +#include <utils/String16.h> + +#include <utils/threads.h> + +// --------------------------------------------------------------------------- +namespace android { + +// Global variables +extern int mArgC; +extern const char* const* mArgV; +extern int mArgLen; + +class IPCThreadState; + +class ProcessState : public virtual RefBase +{ +public: + static sp<ProcessState> self(); + + static void setSingleProcess(bool singleProcess); + + void setContextObject(const sp<IBinder>& object); + sp<IBinder> getContextObject(const sp<IBinder>& caller); + + void setContextObject(const sp<IBinder>& object, + const String16& name); + sp<IBinder> getContextObject(const String16& name, + const sp<IBinder>& caller); + + bool supportsProcesses() const; + + void startThreadPool(); + + typedef bool (*context_check_func)(const String16& name, + const sp<IBinder>& caller, + void* userData); + + bool isContextManager(void) const; + bool becomeContextManager( + context_check_func checkFunc, + void* userData); + + sp<IBinder> getStrongProxyForHandle(int32_t handle); + wp<IBinder> getWeakProxyForHandle(int32_t handle); + void expungeHandle(int32_t handle, IBinder* binder); + + void setArgs(int argc, const char* const argv[]); + int getArgC() const; + const char* const* getArgV() const; + + void setArgV0(const char* txt); + + void spawnPooledThread(bool isMain); + +private: + friend class IPCThreadState; + + ProcessState(); + ~ProcessState(); + + ProcessState(const ProcessState& o); + ProcessState& operator=(const ProcessState& o); + + struct handle_entry { + IBinder* binder; + RefBase::weakref_type* refs; + }; + + handle_entry* lookupHandleLocked(int32_t handle); + + int mDriverFD; + void* mVMStart; + + mutable Mutex mLock; // protects everything below. + + Vector<handle_entry>mHandleToObject; + + bool mManagesContexts; + context_check_func mBinderContextCheckFunc; + void* mBinderContextUserData; + + KeyedVector<String16, sp<IBinder> > + mContexts; + + + String8 mRootDir; + bool mThreadPoolStarted; + volatile int32_t mThreadPoolSeq; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_PROCESS_STATE_H diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h new file mode 100644 index 0000000..cbda0fd --- /dev/null +++ b/include/utils/RefBase.h @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_REF_BASE_H +#define ANDROID_REF_BASE_H + +#include <cutils/atomic.h> +#include <utils/TextOutput.h> + +#include <stdint.h> +#include <sys/types.h> +#include <stdlib.h> + +// --------------------------------------------------------------------------- +namespace android { + +template<typename T> class wp; + +// --------------------------------------------------------------------------- + +#define COMPARE(_op_) \ +inline bool operator _op_ (const sp<T>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +inline bool operator _op_ (const wp<T>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +inline bool operator _op_ (const T* o) const { \ + return m_ptr _op_ o; \ +} \ +template<typename U> \ +inline bool operator _op_ (const sp<U>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template<typename U> \ +inline bool operator _op_ (const wp<U>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template<typename U> \ +inline bool operator _op_ (const U* o) const { \ + return m_ptr _op_ o; \ +} + +// --------------------------------------------------------------------------- + +class RefBase +{ +public: + void incStrong(const void* id) const; + void decStrong(const void* id) const; + + void forceIncStrong(const void* id) const; + + //! DEBUGGING ONLY: Get current strong ref count. + int32_t getStrongCount() const; + + class weakref_type + { + public: + RefBase* refBase() const; + + void incWeak(const void* id); + void decWeak(const void* id); + + bool attemptIncStrong(const void* id); + + //! This is only safe if you have set OBJECT_LIFETIME_FOREVER. + bool attemptIncWeak(const void* id); + + //! DEBUGGING ONLY: Get current weak ref count. + int32_t getWeakCount() const; + + //! DEBUGGING ONLY: Print references held on object. + void printRefs() const; + + //! DEBUGGING ONLY: Enable tracking for this object. + // enable -- enable/disable tracking + // retain -- when tracking is enable, if true, then we save a stack trace + // for each reference and dereference; when retain == false, we + // match up references and dereferences and keep only the + // outstanding ones. + + void trackMe(bool enable, bool retain); + }; + + weakref_type* createWeak(const void* id) const; + + weakref_type* getWeakRefs() const; + + //! DEBUGGING ONLY: Print references held on object. + inline void printRefs() const { getWeakRefs()->printRefs(); } + + //! DEBUGGING ONLY: Enable tracking of object. + inline void trackMe(bool enable, bool retain) + { + getWeakRefs()->trackMe(enable, retain); + } + +protected: + RefBase(); + virtual ~RefBase(); + + //! Flags for extendObjectLifetime() + enum { + OBJECT_LIFETIME_WEAK = 0x0001, + OBJECT_LIFETIME_FOREVER = 0x0003 + }; + + void extendObjectLifetime(int32_t mode); + + //! Flags for onIncStrongAttempted() + enum { + FIRST_INC_STRONG = 0x0001 + }; + + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + virtual void onLastWeakRef(const void* id); + +private: + friend class weakref_type; + class weakref_impl; + + RefBase(const RefBase& o); + RefBase& operator=(const RefBase& o); + + weakref_impl* const mRefs; +}; + +// --------------------------------------------------------------------------- + +template <class T> +class LightRefBase +{ +public: + inline LightRefBase() : mCount(0) { } + inline void incStrong(const void* id) const { + android_atomic_inc(&mCount); + } + inline void decStrong(const void* id) const { + if (android_atomic_dec(&mCount) == 1) { + delete static_cast<const T*>(this); + } + } + +protected: + inline ~LightRefBase() { } + +private: + mutable volatile int32_t mCount; +}; + +// --------------------------------------------------------------------------- + +template <typename T> +class sp +{ +public: + typedef typename RefBase::weakref_type weakref_type; + + inline sp() : m_ptr(0) { } + + sp(T* other); + sp(const sp<T>& other); + template<typename U> sp(U* other); + template<typename U> sp(const sp<U>& other); + + ~sp(); + + // Assignment + + sp& operator = (T* other); + sp& operator = (const sp<T>& other); + + template<typename U> sp& operator = (const sp<U>& other); + template<typename U> sp& operator = (U* other); + + //! Special optimization for use by ProcessState (and nobody else). + void force_set(T* other); + + // Reset + + void clear(); + + // Accessors + + inline T& operator* () const { return *m_ptr; } + inline T* operator-> () const { return m_ptr; } + inline T* get() const { return m_ptr; } + + // Operators + + COMPARE(==) + COMPARE(!=) + COMPARE(>) + COMPARE(<) + COMPARE(<=) + COMPARE(>=) + +private: + template<typename Y> friend class sp; + template<typename Y> friend class wp; + + // Optimization for wp::promote(). + sp(T* p, weakref_type* refs); + + T* m_ptr; +}; + +template <typename T> +TextOutput& operator<<(TextOutput& to, const sp<T>& val); + +// --------------------------------------------------------------------------- + +template <typename T> +class wp +{ +public: + typedef typename RefBase::weakref_type weakref_type; + + inline wp() : m_ptr(0) { } + + wp(T* other); + wp(const wp<T>& other); + wp(const sp<T>& other); + template<typename U> wp(U* other); + template<typename U> wp(const sp<U>& other); + template<typename U> wp(const wp<U>& other); + + ~wp(); + + // Assignment + + wp& operator = (T* other); + wp& operator = (const wp<T>& other); + wp& operator = (const sp<T>& other); + + template<typename U> wp& operator = (U* other); + template<typename U> wp& operator = (const wp<U>& other); + template<typename U> wp& operator = (const sp<U>& other); + + void set_object_and_refs(T* other, weakref_type* refs); + + // promotion to sp + + sp<T> promote() const; + + // Reset + + void clear(); + + // Accessors + + inline weakref_type* get_refs() const { return m_refs; } + + inline T* unsafe_get() const { return m_ptr; } + + // Operators + + COMPARE(==) + COMPARE(!=) + COMPARE(>) + COMPARE(<) + COMPARE(<=) + COMPARE(>=) + +private: + template<typename Y> friend class sp; + template<typename Y> friend class wp; + + T* m_ptr; + weakref_type* m_refs; +}; + +template <typename T> +TextOutput& operator<<(TextOutput& to, const wp<T>& val); + +#undef COMPARE + +// --------------------------------------------------------------------------- +// No user serviceable parts below here. + +template<typename T> +sp<T>::sp(T* other) + : m_ptr(other) +{ + if (other) other->incStrong(this); +} + +template<typename T> +sp<T>::sp(const sp<T>& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) m_ptr->incStrong(this); +} + +template<typename T> template<typename U> +sp<T>::sp(U* other) : m_ptr(other) +{ + if (other) other->incStrong(this); +} + +template<typename T> template<typename U> +sp<T>::sp(const sp<U>& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) m_ptr->incStrong(this); +} + +template<typename T> +sp<T>::~sp() +{ + if (m_ptr) m_ptr->decStrong(this); +} + +template<typename T> +sp<T>& sp<T>::operator = (const sp<T>& other) { + if (other.m_ptr) other.m_ptr->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other.m_ptr; + return *this; +} + +template<typename T> +sp<T>& sp<T>::operator = (T* other) +{ + if (other) other->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template<typename T> template<typename U> +sp<T>& sp<T>::operator = (const sp<U>& other) +{ + if (other.m_ptr) other.m_ptr->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other.m_ptr; + return *this; +} + +template<typename T> template<typename U> +sp<T>& sp<T>::operator = (U* other) +{ + if (other) other->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template<typename T> +void sp<T>::force_set(T* other) +{ + other->forceIncStrong(this); + m_ptr = other; +} + +template<typename T> +void sp<T>::clear() +{ + if (m_ptr) { + m_ptr->decStrong(this); + m_ptr = 0; + } +} + +template<typename T> +sp<T>::sp(T* p, weakref_type* refs) + : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0) +{ +} + +template <typename T> +inline TextOutput& operator<<(TextOutput& to, const sp<T>& val) +{ + to << "sp<>(" << val.get() << ")"; + return to; +} + +// --------------------------------------------------------------------------- + +template<typename T> +wp<T>::wp(T* other) + : m_ptr(other) +{ + if (other) m_refs = other->createWeak(this); +} + +template<typename T> +wp<T>::wp(const wp<T>& other) + : m_ptr(other.m_ptr), m_refs(other.m_refs) +{ + if (m_ptr) m_refs->incWeak(this); +} + +template<typename T> +wp<T>::wp(const sp<T>& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = m_ptr->createWeak(this); + } +} + +template<typename T> template<typename U> +wp<T>::wp(U* other) + : m_ptr(other) +{ + if (other) m_refs = other->createWeak(this); +} + +template<typename T> template<typename U> +wp<T>::wp(const wp<U>& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = other.m_refs; + m_refs->incWeak(this); + } +} + +template<typename T> template<typename U> +wp<T>::wp(const sp<U>& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = m_ptr->createWeak(this); + } +} + +template<typename T> +wp<T>::~wp() +{ + if (m_ptr) m_refs->decWeak(this); +} + +template<typename T> +wp<T>& wp<T>::operator = (T* other) +{ + weakref_type* newRefs = + other ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = newRefs; + return *this; +} + +template<typename T> +wp<T>& wp<T>::operator = (const wp<T>& other) +{ + if (other.m_ptr) other.m_refs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = other.m_ptr; + m_refs = other.m_refs; + return *this; +} + +template<typename T> +wp<T>& wp<T>::operator = (const sp<T>& other) +{ + weakref_type* newRefs = + other != NULL ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other.get(); + m_refs = newRefs; + return *this; +} + +template<typename T> template<typename U> +wp<T>& wp<T>::operator = (U* other) +{ + weakref_type* newRefs = + other ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = newRefs; + return *this; +} + +template<typename T> template<typename U> +wp<T>& wp<T>::operator = (const wp<U>& other) +{ + if (other.m_ptr) other.m_refs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = other.m_ptr; + m_refs = other.m_refs; + return *this; +} + +template<typename T> template<typename U> +wp<T>& wp<T>::operator = (const sp<U>& other) +{ + weakref_type* newRefs = + other != NULL ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other.get(); + m_refs = newRefs; + return *this; +} + +template<typename T> +void wp<T>::set_object_and_refs(T* other, weakref_type* refs) +{ + if (other) refs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = refs; +} + +template<typename T> +sp<T> wp<T>::promote() const +{ + return sp<T>(m_ptr, m_refs); +} + +template<typename T> +void wp<T>::clear() +{ + if (m_ptr) { + m_refs->decWeak(this); + m_ptr = 0; + } +} + +template <typename T> +inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) +{ + to << "wp<>(" << val.unsafe_get() << ")"; + return to; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_REF_BASE_H diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h new file mode 100644 index 0000000..7d3fcf2 --- /dev/null +++ b/include/utils/ResourceTypes.h @@ -0,0 +1,1720 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Definitions of resource data structures. +// +#ifndef _LIBS_UTILS_RESOURCE_TYPES_H +#define _LIBS_UTILS_RESOURCE_TYPES_H + +#include <utils/Asset.h> +#include <utils/ByteOrder.h> +#include <utils/Errors.h> +#include <utils/String16.h> +#include <utils/Vector.h> + +#include <utils/threads.h> + +#include <stdint.h> +#include <sys/types.h> + +namespace android { + +/** ******************************************************************** + * PNG Extensions + * + * New private chunks that may be placed in PNG images. + * + *********************************************************************** */ + +/** + * This chunk specifies how to split an image into segments for + * scaling. + * + * There are J horizontal and K vertical segments. These segments divide + * the image into J*K regions as follows (where J=4 and K=3): + * + * F0 S0 F1 S1 + * +-----+----+------+-------+ + * S2| 0 | 1 | 2 | 3 | + * +-----+----+------+-------+ + * | | | | | + * | | | | | + * F2| 4 | 5 | 6 | 7 | + * | | | | | + * | | | | | + * +-----+----+------+-------+ + * S3| 8 | 9 | 10 | 11 | + * +-----+----+------+-------+ + * + * Each horizontal and vertical segment is considered to by either + * stretchable (marked by the Sx labels) or fixed (marked by the Fy + * labels), in the horizontal or vertical axis, respectively. In the + * above example, the first is horizontal segment (F0) is fixed, the + * next is stretchable and then they continue to alternate. Note that + * the segment list for each axis can begin or end with a stretchable + * or fixed segment. + * + * The relative sizes of the stretchy segments indicates the relative + * amount of stretchiness of the regions bordered by the segments. For + * example, regions 3, 7 and 11 above will take up more horizontal space + * than regions 1, 5 and 9 since the horizonal segment associated with + * the first set of regions is larger than the other set of regions. The + * ratios of the amount of horizontal (or vertical) space taken by any + * two stretchable slices is exactly the ratio of their corresponding + * segment lengths. + * + * xDivs and yDivs point to arrays of horizontal and vertical pixel + * indices. The first pair of Divs (in either array) indicate the + * starting and ending points of the first stretchable segment in that + * axis. The next pair specifies the next stretchable segment, etc. So + * in the above example xDiv[0] and xDiv[1] specify the horizontal + * coordinates for the regions labeled 1, 5 and 9. xDiv[2] and + * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that + * the leftmost slices always start at x=0 and the rightmost slices + * always end at the end of the image. So, for example, the regions 0, + * 4 and 8 (which are fixed along the X axis) start at x value 0 and + * go to xDiv[0] amd slices 2, 6 and 10 start at xDiv[1] and end at + * xDiv[2]. + * + * The array pointed to by the colors field lists contains hints for + * each of the regions. They are ordered according left-to-right and + * top-to-bottom as indicated above. For each segment that is a solid + * color the array entry will contain that color value; otherwise it + * will contain NO_COLOR. Segments that are completely transparent + * will always have the value TRANSPARENT_COLOR. + * + * The PNG chunk type is "npTc". + */ +struct Res_png_9patch +{ + Res_png_9patch() : wasDeserialized(false), xDivs(NULL), + yDivs(NULL), colors(NULL) { } + + int8_t wasDeserialized; + int8_t numXDivs; + int8_t numYDivs; + int8_t numColors; + + // These tell where the next section of a patch starts. + // For example, the first patch includes the pixels from + // 0 to xDivs[0]-1 and the second patch includes the pixels + // from xDivs[0] to xDivs[1]-1. + // Note: allocation/free of these pointers is left to the caller. + int32_t* xDivs; + int32_t* yDivs; + + int32_t paddingLeft, paddingRight; + int32_t paddingTop, paddingBottom; + + enum { + // The 9 patch segment is not a solid color. + NO_COLOR = 0x00000001, + + // The 9 patch segment is completely transparent. + TRANSPARENT_COLOR = 0x00000000 + }; + // Note: allocation/free of this pointer is left to the caller. + uint32_t* colors; + + // Convert data from device representation to PNG file representation. + void deviceToFile(); + // Convert data from PNG file representation to device representation. + void fileToDevice(); + // Serialize/Marshall the patch data into a newly malloc-ed block + void* serialize(); + // Serialize/Marshall the patch data + void serialize(void* outData); + // Deserialize/Unmarshall the patch data + static Res_png_9patch* deserialize(const void* data); + // Compute the size of the serialized data structure + size_t serializedSize(); +}; + +/** ******************************************************************** + * Base Types + * + * These are standard types that are shared between multiple specific + * resource types. + * + *********************************************************************** */ + +/** + * Header that appears at the front of every data chunk in a resource. + */ +struct ResChunk_header +{ + // Type identifier for this chunk. The meaning of this value depends + // on the containing chunk. + uint16_t type; + + // Size of the chunk header (in bytes). Adding this value to + // the address of the chunk allows you to find its associated data + // (if any). + uint16_t headerSize; + + // Total size of this chunk (in bytes). This is the chunkSize plus + // the size of any data associated with the chunk. Adding this value + // to the chunk allows you to completely skip its contents (including + // any child chunks). If this value is the same as chunkSize, there is + // no data associated with the chunk. + uint32_t size; +}; + +enum { + RES_NULL_TYPE = 0x0000, + RES_STRING_POOL_TYPE = 0x0001, + RES_TABLE_TYPE = 0x0002, + RES_XML_TYPE = 0x0003, + + // Chunk types in RES_XML_TYPE + RES_XML_FIRST_CHUNK_TYPE = 0x0100, + RES_XML_START_NAMESPACE_TYPE= 0x0100, + RES_XML_END_NAMESPACE_TYPE = 0x0101, + RES_XML_START_ELEMENT_TYPE = 0x0102, + RES_XML_END_ELEMENT_TYPE = 0x0103, + RES_XML_CDATA_TYPE = 0x0104, + RES_XML_LAST_CHUNK_TYPE = 0x017f, + // This contains a uint32_t array mapping strings in the string + // pool back to resource identifiers. It is optional. + RES_XML_RESOURCE_MAP_TYPE = 0x0180, + + // Chunk types in RES_TABLE_TYPE + RES_TABLE_PACKAGE_TYPE = 0x0200, + RES_TABLE_TYPE_TYPE = 0x0201, + RES_TABLE_TYPE_SPEC_TYPE = 0x0202 +}; + +/** + * Macros for building/splitting resource identifiers. + */ +#define Res_VALIDID(resid) (resid != 0) +#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0) +#define Res_MAKEID(package, type, entry) \ + (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF)) +#define Res_GETPACKAGE(id) ((id>>24)-1) +#define Res_GETTYPE(id) (((id>>16)&0xFF)-1) +#define Res_GETENTRY(id) (id&0xFFFF) + +#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0) +#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF)) +#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF)) + +#define Res_MAXPACKAGE 255 + +/** + * Representation of a value in a resource, supplying type + * information. + */ +struct Res_value +{ + // Number of bytes in this structure. + uint16_t size; + + // Always set to 0. + uint8_t res0; + + // Type of the data value. + enum { + // Contains no data. + TYPE_NULL = 0x00, + // The 'data' holds a ResTable_ref, a reference to another resource + // table entry. + TYPE_REFERENCE = 0x01, + // The 'data' holds an attribute resource identifier. + TYPE_ATTRIBUTE = 0x02, + // The 'data' holds an index into the containing resource table's + // global value string pool. + TYPE_STRING = 0x03, + // The 'data' holds a single-precision floating point number. + TYPE_FLOAT = 0x04, + // The 'data' holds a complex number encoding a dimension value, + // such as "100in". + TYPE_DIMENSION = 0x05, + // The 'data' holds a complex number encoding a fraction of a + // container. + TYPE_FRACTION = 0x06, + + // Beginning of integer flavors... + TYPE_FIRST_INT = 0x10, + + // The 'data' is a raw integer value of the form n..n. + TYPE_INT_DEC = 0x10, + // The 'data' is a raw integer value of the form 0xn..n. + TYPE_INT_HEX = 0x11, + // The 'data' is either 0 or 1, for input "false" or "true" respectively. + TYPE_INT_BOOLEAN = 0x12, + + // Beginning of color integer flavors... + TYPE_FIRST_COLOR_INT = 0x1c, + + // The 'data' is a raw integer value of the form #aarrggbb. + TYPE_INT_COLOR_ARGB8 = 0x1c, + // The 'data' is a raw integer value of the form #rrggbb. + TYPE_INT_COLOR_RGB8 = 0x1d, + // The 'data' is a raw integer value of the form #argb. + TYPE_INT_COLOR_ARGB4 = 0x1e, + // The 'data' is a raw integer value of the form #rgb. + TYPE_INT_COLOR_RGB4 = 0x1f, + + // ...end of integer flavors. + TYPE_LAST_COLOR_INT = 0x1f, + + // ...end of integer flavors. + TYPE_LAST_INT = 0x1f + }; + uint8_t dataType; + + // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION) + enum { + // Where the unit type information is. This gives us 16 possible + // types, as defined below. + COMPLEX_UNIT_SHIFT = 0, + COMPLEX_UNIT_MASK = 0xf, + + // TYPE_DIMENSION: Value is raw pixels. + COMPLEX_UNIT_PX = 0, + // TYPE_DIMENSION: Value is Device Independent Pixels. + COMPLEX_UNIT_DIP = 1, + // TYPE_DIMENSION: Value is a Scaled device independent Pixels. + COMPLEX_UNIT_SP = 2, + // TYPE_DIMENSION: Value is in points. + COMPLEX_UNIT_PT = 3, + // TYPE_DIMENSION: Value is in inches. + COMPLEX_UNIT_IN = 4, + // TYPE_DIMENSION: Value is in millimeters. + COMPLEX_UNIT_MM = 5, + + // TYPE_FRACTION: A basic fraction of the overall size. + COMPLEX_UNIT_FRACTION = 0, + // TYPE_FRACTION: A fraction of the parent size. + COMPLEX_UNIT_FRACTION_PARENT = 1, + + // Where the radix information is, telling where the decimal place + // appears in the mantissa. This give us 4 possible fixed point + // representations as defined below. + COMPLEX_RADIX_SHIFT = 4, + COMPLEX_RADIX_MASK = 0x3, + + // The mantissa is an integral number -- i.e., 0xnnnnnn.0 + COMPLEX_RADIX_23p0 = 0, + // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn + COMPLEX_RADIX_16p7 = 1, + // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn + COMPLEX_RADIX_8p15 = 2, + // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn + COMPLEX_RADIX_0p23 = 3, + + // Where the actual value is. This gives us 23 bits of + // precision. The top bit is the sign. + COMPLEX_MANTISSA_SHIFT = 8, + COMPLEX_MANTISSA_MASK = 0xffffff + }; + + // The data for this item, as interpreted according to dataType. + uint32_t data; + + void copyFrom_dtoh(const Res_value& src); +}; + +/** + * This is a reference to a unique entry (a ResTable_entry structure) + * in a resource table. The value is structured as: 0xpptteeee, + * where pp is the package index, tt is the type index in that + * package, and eeee is the entry index in that type. The package + * and type values start at 1 for the first item, to help catch cases + * where they have not been supplied. + */ +struct ResTable_ref +{ + uint32_t ident; +}; + +/** + * Reference to a string in a string pool. + */ +struct ResStringPool_ref +{ + // Index into the string pool table (uint32_t-offset from the indices + // immediately after ResStringPool_header) at which to find the location + // of the string data in the pool. + uint32_t index; +}; + +/** ******************************************************************** + * String Pool + * + * A set of strings that can be references by others through a + * ResStringPool_ref. + * + *********************************************************************** */ + +/** + * Definition for a pool of strings. The data of this chunk is an + * array of uint32_t providing indices into the pool, relative to + * stringsStart. At stringsStart are all of the UTF-16 strings + * concatenated together; each starts with a uint16_t of the string's + * length and each ends with a 0x0000 terminator. If a string is > + * 32767 characters, the high bit of the length is set meaning to take + * those 15 bits as a high word and it will be followed by another + * uint16_t containing the low word. + * + * If styleCount is not zero, then immediately following the array of + * uint32_t indices into the string table is another array of indices + * into a style table starting at stylesStart. Each entry in the + * style table is an array of ResStringPool_span structures. + */ +struct ResStringPool_header +{ + struct ResChunk_header header; + + // Number of strings in this pool (number of uint32_t indices that follow + // in the data). + uint32_t stringCount; + + // Number of style span arrays in the pool (number of uint32_t indices + // follow the string indices). + uint32_t styleCount; + + // Flags. + enum { + // If set, the string index is sorted by the string values (based + // on strcmp16()). + SORTED_FLAG = 1<<0 + }; + uint32_t flags; + + // Index from header of the string data. + uint32_t stringsStart; + + // Index from header of the style data. + uint32_t stylesStart; +}; + +/** + * This structure defines a span of style information associated with + * a string in the pool. + */ +struct ResStringPool_span +{ + enum { + END = 0xFFFFFFFF + }; + + // This is the name of the span -- that is, the name of the XML + // tag that defined it. The special value END (0xFFFFFFFF) indicates + // the end of an array of spans. + ResStringPool_ref name; + + // The range of characters in the string that this span applies to. + uint32_t firstChar, lastChar; +}; + +/** + * Convenience class for accessing data in a ResStringPool resource. + */ +class ResStringPool +{ +public: + ResStringPool(); + ResStringPool(const void* data, size_t size, bool copyData=false); + ~ResStringPool(); + + status_t setTo(const void* data, size_t size, bool copyData=false); + + status_t getError() const; + + void uninit(); + + inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const { + return stringAt(ref.index, outLen); + } + const char16_t* stringAt(size_t idx, size_t* outLen) const; + + const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const; + const ResStringPool_span* styleAt(size_t idx) const; + + ssize_t indexOfString(const char16_t* str, size_t strLen) const; + + size_t size() const; + +private: + status_t mError; + void* mOwnedData; + const ResStringPool_header* mHeader; + size_t mSize; + const uint32_t* mEntries; + const uint32_t* mEntryStyles; + const char16_t* mStrings; + uint32_t mStringPoolSize; // number of uint16_t + const uint32_t* mStyles; + uint32_t mStylePoolSize; // number of uint32_t +}; + +/** ******************************************************************** + * XML Tree + * + * Binary representation of an XML document. This is designed to + * express everything in an XML document, in a form that is much + * easier to parse on the device. + * + *********************************************************************** */ + +/** + * XML tree header. This appears at the front of an XML tree, + * describing its content. It is followed by a flat array of + * ResXMLTree_node structures; the hierarchy of the XML document + * is described by the occurrance of RES_XML_START_ELEMENT_TYPE + * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array. + */ +struct ResXMLTree_header +{ + struct ResChunk_header header; +}; + +/** + * Basic XML tree node. A single item in the XML document. Extended info + * about the node can be found after header.headerSize. + */ +struct ResXMLTree_node +{ + struct ResChunk_header header; + + // Line number in original source file at which this element appeared. + uint32_t lineNumber; + + // Optional XML comment that was associated with this element; -1 if none. + struct ResStringPool_ref comment; +}; + +/** + * Extended XML tree node for CDATA tags -- includes the CDATA string. + * Appears header.headerSize bytes after a ResXMLTree_node. + */ +struct ResXMLTree_cdataExt +{ + // The raw CDATA character data. + struct ResStringPool_ref data; + + // The typed value of the character data if this is a CDATA node. + struct Res_value typedData; +}; + +/** + * Extended XML tree node for namespace start/end nodes. + * Appears header.headerSize bytes after a ResXMLTree_node. + */ +struct ResXMLTree_namespaceExt +{ + // The prefix of the namespace. + struct ResStringPool_ref prefix; + + // The URI of the namespace. + struct ResStringPool_ref uri; +}; + +/** + * Extended XML tree node for element start/end nodes. + * Appears header.headerSize bytes after a ResXMLTree_node. + */ +struct ResXMLTree_endElementExt +{ + // String of the full namespace of this element. + struct ResStringPool_ref ns; + + // String name of this node if it is an ELEMENT; the raw + // character data if this is a CDATA node. + struct ResStringPool_ref name; +}; + +/** + * Extended XML tree node for start tags -- includes attribute + * information. + * Appears header.headerSize bytes after a ResXMLTree_node. + */ +struct ResXMLTree_attrExt +{ + // String of the full namespace of this element. + struct ResStringPool_ref ns; + + // String name of this node if it is an ELEMENT; the raw + // character data if this is a CDATA node. + struct ResStringPool_ref name; + + // Byte offset from the start of this structure where the attributes start. + uint16_t attributeStart; + + // Size of the ResXMLTree_attribute structures that follow. + uint16_t attributeSize; + + // Number of attributes associated with an ELEMENT. These are + // available as an array of ResXMLTree_attribute structures + // immediately following this node. + uint16_t attributeCount; + + // Index (1-based) of the "id" attribute. 0 if none. + uint16_t idIndex; + + // Index (1-based) of the "class" attribute. 0 if none. + uint16_t classIndex; + + // Index (1-based) of the "style" attribute. 0 if none. + uint16_t styleIndex; +}; + +struct ResXMLTree_attribute +{ + // Namespace of this attribute. + struct ResStringPool_ref ns; + + // Name of this attribute. + struct ResStringPool_ref name; + + // The original raw string value of this attribute. + struct ResStringPool_ref rawValue; + + // Processesd typed value of this attribute. + struct Res_value typedValue; +}; + +class ResXMLTree; + +class ResXMLParser +{ +public: + ResXMLParser(const ResXMLTree& tree); + + enum event_code_t { + BAD_DOCUMENT = -1, + START_DOCUMENT = 0, + END_DOCUMENT = 1, + + FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, + + START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE, + END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE, + START_TAG = RES_XML_START_ELEMENT_TYPE, + END_TAG = RES_XML_END_ELEMENT_TYPE, + TEXT = RES_XML_CDATA_TYPE + }; + + struct ResXMLPosition + { + event_code_t eventCode; + const ResXMLTree_node* curNode; + const void* curExt; + }; + + void restart(); + + event_code_t getEventType() const; + // Note, unlike XmlPullParser, the first call to next() will return + // START_TAG of the first element. + event_code_t next(); + + // These are available for all nodes: + const int32_t getCommentID() const; + const uint16_t* getComment(size_t* outLen) const; + const uint32_t getLineNumber() const; + + // This is available for TEXT: + const int32_t getTextID() const; + const uint16_t* getText(size_t* outLen) const; + ssize_t getTextValue(Res_value* outValue) const; + + // These are available for START_NAMESPACE and END_NAMESPACE: + const int32_t getNamespacePrefixID() const; + const uint16_t* getNamespacePrefix(size_t* outLen) const; + const int32_t getNamespaceUriID() const; + const uint16_t* getNamespaceUri(size_t* outLen) const; + + // These are available for START_TAG and END_TAG: + const int32_t getElementNamespaceID() const; + const uint16_t* getElementNamespace(size_t* outLen) const; + const int32_t getElementNameID() const; + const uint16_t* getElementName(size_t* outLen) const; + + // Remaining methods are for retrieving information about attributes + // associated with a START_TAG: + + size_t getAttributeCount() const; + + // Returns -1 if no namespace, -2 if idx out of range. + const int32_t getAttributeNamespaceID(size_t idx) const; + const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const; + + const int32_t getAttributeNameID(size_t idx) const; + const uint16_t* getAttributeName(size_t idx, size_t* outLen) const; + const uint32_t getAttributeNameResID(size_t idx) const; + + const int32_t getAttributeValueStringID(size_t idx) const; + const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const; + + int32_t getAttributeDataType(size_t idx) const; + int32_t getAttributeData(size_t idx) const; + ssize_t getAttributeValue(size_t idx, Res_value* outValue) const; + + ssize_t indexOfAttribute(const char* ns, const char* attr) const; + ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen, + const char16_t* attr, size_t attrLen) const; + + ssize_t indexOfID() const; + ssize_t indexOfClass() const; + ssize_t indexOfStyle() const; + + void getPosition(ResXMLPosition* pos) const; + void setPosition(const ResXMLPosition& pos); + +private: + friend class ResXMLTree; + + event_code_t nextNode(); + + const ResXMLTree& mTree; + event_code_t mEventCode; + const ResXMLTree_node* mCurNode; + const void* mCurExt; +}; + +/** + * Convenience class for accessing data in a ResXMLTree resource. + */ +class ResXMLTree : public ResXMLParser +{ +public: + ResXMLTree(); + ResXMLTree(const void* data, size_t size, bool copyData=false); + ~ResXMLTree(); + + status_t setTo(const void* data, size_t size, bool copyData=false); + + status_t getError() const; + + void uninit(); + + const ResStringPool& getStrings() const; + +private: + friend class ResXMLParser; + + status_t validateNode(const ResXMLTree_node* node) const; + + status_t mError; + void* mOwnedData; + const ResXMLTree_header* mHeader; + size_t mSize; + const uint8_t* mDataEnd; + ResStringPool mStrings; + const uint32_t* mResIds; + size_t mNumResIds; + const ResXMLTree_node* mRootNode; + const void* mRootExt; + event_code_t mRootCode; +}; + +/** ******************************************************************** + * RESOURCE TABLE + * + *********************************************************************** */ + +/** + * Header for a resource table. Its data contains a series of + * additional chunks: + * * A ResStringPool_header containing all table values. + * * One or more ResTable_package chunks. + * + * Specific entries within a resource table can be uniquely identified + * with a single integer as defined by the ResTable_ref structure. + */ +struct ResTable_header +{ + struct ResChunk_header header; + + // The number of ResTable_package structures. + uint32_t packageCount; +}; + +/** + * A collection of resource data types within a package. Followed by + * one or more ResTable_type and ResTable_typeSpec structures containing the + * entry values for each resource type. + */ +struct ResTable_package +{ + struct ResChunk_header header; + + // If this is a base package, its ID. Package IDs start + // at 1 (corresponding to the value of the package bits in a + // resource identifier). 0 means this is not a base package. + uint32_t id; + + // Actual name of this package, \0-terminated. + char16_t name[128]; + + // Offset to a ResStringPool_header defining the resource + // type symbol table. If zero, this package is inheriting from + // another base package (overriding specific values in it). + uint32_t typeStrings; + + // Last index into typeStrings that is for public use by others. + uint32_t lastPublicType; + + // Offset to a ResStringPool_header defining the resource + // key symbol table. If zero, this package is inheriting from + // another base package (overriding specific values in it). + uint32_t keyStrings; + + // Last index into keyStrings that is for public use by others. + uint32_t lastPublicKey; +}; + +/** + * Describes a particular resource configuration. + */ +struct ResTable_config +{ + // Number of bytes in this structure. + uint32_t size; + + union { + struct { + // Mobile country code (from SIM). 0 means "any". + uint16_t mcc; + // Mobile network code (from SIM). 0 means "any". + uint16_t mnc; + }; + uint32_t imsi; + }; + + union { + struct { + // \0\0 means "any". Otherwise, en, fr, etc. + char language[2]; + + // \0\0 means "any". Otherwise, US, CA, etc. + char country[2]; + }; + uint32_t locale; + }; + + enum { + ORIENTATION_ANY = 0x0000, + ORIENTATION_PORT = 0x0001, + ORIENTATION_LAND = 0x0002, + ORIENTATION_SQUARE = 0x0002, + }; + + enum { + TOUCHSCREEN_ANY = 0x0000, + TOUCHSCREEN_NOTOUCH = 0x0001, + TOUCHSCREEN_STYLUS = 0x0002, + TOUCHSCREEN_FINGER = 0x0003, + }; + + enum { + DENSITY_ANY = 0 + }; + + union { + struct { + uint8_t orientation; + uint8_t touchscreen; + uint16_t density; + }; + uint32_t screenType; + }; + + enum { + KEYBOARD_ANY = 0x0000, + KEYBOARD_NOKEYS = 0x0001, + KEYBOARD_QWERTY = 0x0002, + KEYBOARD_12KEY = 0x0003, + }; + + enum { + NAVIGATION_ANY = 0x0000, + NAVIGATION_NONAV = 0x0001, + NAVIGATION_DPAD = 0x0002, + NAVIGATION_TRACKBALL = 0x0003, + NAVIGATION_WHEEL = 0x0004, + }; + + enum { + MASK_KEYSHIDDEN = 0x0003, + SHIFT_KEYSHIDDEN = 0, + KEYSHIDDEN_ANY = 0x0000, + KEYSHIDDEN_NO = 0x0001, + KEYSHIDDEN_YES = 0x0002, + KEYSHIDDEN_SOFT = 0x0003, + }; + + union { + struct { + uint8_t keyboard; + uint8_t navigation; + uint8_t inputFlags; + uint8_t pad0; + }; + uint32_t input; + }; + + enum { + SCREENWIDTH_ANY = 0 + }; + + enum { + SCREENHEIGHT_ANY = 0 + }; + + union { + struct { + uint16_t screenWidth; + uint16_t screenHeight; + }; + uint32_t screenSize; + }; + + enum { + SDKVERSION_ANY = 0 + }; + + enum { + MINORVERSION_ANY = 0 + }; + + union { + struct { + uint16_t sdkVersion; + // For now minorVersion must always be 0!!! Its meaning + // is currently undefined. + uint16_t minorVersion; + }; + uint32_t version; + }; + + inline void copyFromDeviceNoSwap(const ResTable_config& o) { + const size_t size = dtohl(o.size); + if (size >= sizeof(ResTable_config)) { + *this = o; + } else { + memcpy(this, &o, size); + memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size); + } + } + + inline void copyFromDtoH(const ResTable_config& o) { + copyFromDeviceNoSwap(o); + size = sizeof(ResTable_config); + mcc = dtohs(mcc); + mnc = dtohs(mnc); + density = dtohs(density); + screenWidth = dtohs(screenWidth); + screenHeight = dtohs(screenHeight); + sdkVersion = dtohs(sdkVersion); + minorVersion = dtohs(minorVersion); + } + + inline void swapHtoD() { + size = htodl(size); + mcc = htods(mcc); + mnc = htods(mnc); + density = htods(density); + screenWidth = htods(screenWidth); + screenHeight = htods(screenHeight); + sdkVersion = htods(sdkVersion); + minorVersion = htods(minorVersion); + } + + inline int compare(const ResTable_config& o) const { + int32_t diff = (int32_t)(imsi - o.imsi); + if (diff != 0) return diff; + diff = (int32_t)(locale - o.locale); + if (diff != 0) return diff; + diff = (int32_t)(screenType - o.screenType); + if (diff != 0) return diff; + diff = (int32_t)(input - o.input); + if (diff != 0) return diff; + diff = (int32_t)(screenSize - o.screenSize); + if (diff != 0) return diff; + diff = (int32_t)(version - o.version); + return (int)diff; + } + + // Flags indicating a set of config values. These flag constants must + // match the corresponding ones in android.content.pm.ActivityInfo and + // attrs_manifest.xml. + enum { + CONFIG_MCC = 0x0001, + CONFIG_MNC = 0x0002, + CONFIG_LOCALE = 0x0004, + CONFIG_TOUCHSCREEN = 0x0008, + CONFIG_KEYBOARD = 0x0010, + CONFIG_KEYBOARD_HIDDEN = 0x0020, + CONFIG_NAVIGATION = 0x0040, + CONFIG_ORIENTATION = 0x0080, + CONFIG_DENSITY = 0x0100, + CONFIG_SCREEN_SIZE = 0x0200, + CONFIG_VERSION = 0x0400 + }; + + // Compare two configuration, returning CONFIG_* flags set for each value + // that is different. + inline int diff(const ResTable_config& o) const { + int diffs = 0; + if (mcc != o.mcc) diffs |= CONFIG_MCC; + if (mnc != o.mnc) diffs |= CONFIG_MNC; + if (locale != o.locale) diffs |= CONFIG_LOCALE; + if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION; + if (density != o.density) diffs |= CONFIG_DENSITY; + if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN; + if (((inputFlags^o.inputFlags)&MASK_KEYSHIDDEN) != 0) diffs |= CONFIG_KEYBOARD_HIDDEN; + if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD; + if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION; + if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE; + if (version != o.version) diffs |= CONFIG_VERSION; + return diffs; + } + + // Return true if 'this' is more specific than 'o'. Optionally, if + // 'requested' is null, then they will also be compared against the + // requested configuration and true will only be returned if 'this' + // is a better candidate than 'o' for the configuration. This assumes that + // match() has already been used to remove any configurations that don't + // match the requested configuration at all; if they are not first filtered, + // non-matching results can be considered better than matching ones. + inline bool + isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const { + // The order of the following tests defines the importance of one + // configuration parameter over another. Those tests first are more + // important, trumping any values in those following them. + if (imsi != 0 && (!requested || requested->imsi != 0)) { + if (mcc != 0 && (!requested || requested->mcc != 0)) { + if (o.mcc == 0) { + return true; + } + } + if (mnc != 0 && (!requested || requested->mnc != 0)) { + if (o.mnc == 0) { + return true; + } + } + } + if (locale != 0 && (!requested || requested->locale != 0)) { + if (language[0] != 0 && (!requested || requested->language[0] != 0)) { + if (o.language[0] == 0) { + return true; + } + } + if (country[0] != 0 && (!requested || requested->country[0] != 0)) { + if (o.country[0] == 0) { + return true; + } + } + } + if (screenType != 0 && (!requested || requested->screenType != 0)) { + if (orientation != 0 && (!requested || requested->orientation != 0)) { + if (o.orientation == 0) { + return true; + } + } + if (density != 0 && (!requested || requested->density != 0)) { + if (o.density == 0) { + return true; + } + } + if (touchscreen != 0 && (!requested || requested->touchscreen != 0)) { + if (o.touchscreen == 0) { + return true; + } + } + } + if (input != 0 && (!requested || requested->input != 0)) { + const int keysHidden = inputFlags&MASK_KEYSHIDDEN; + const int reqKeysHidden = requested + ? requested->inputFlags&MASK_KEYSHIDDEN : 0; + if (keysHidden != 0 && reqKeysHidden != 0) { + const int oKeysHidden = o.inputFlags&MASK_KEYSHIDDEN; + //LOGI("isBetterThan keysHidden: cur=%d, given=%d, config=%d\n", + // keysHidden, oKeysHidden, reqKeysHidden); + if (oKeysHidden == 0) { + //LOGI("Better because 0!"); + return true; + } + // For compatibility, we count KEYSHIDDEN_NO as being + // the same as KEYSHIDDEN_SOFT. Here we disambiguate these + // may making an exact match more specific. + if (keysHidden == reqKeysHidden && oKeysHidden != reqKeysHidden) { + // The current configuration is an exact match, and + // the given one is not, so the current one is better. + //LOGI("Better because other not same!"); + return true; + } + } + if (keyboard != 0 && (!requested || requested->keyboard != 0)) { + if (o.keyboard == 0) { + return true; + } + } + if (navigation != 0 && (!requested || requested->navigation != 0)) { + if (o.navigation == 0) { + return true; + } + } + } + if (screenSize != 0 && (!requested || requested->screenSize != 0)) { + if (screenWidth != 0 && (!requested || requested->screenWidth != 0)) { + if (o.screenWidth == 0) { + return true; + } + } + if (screenHeight != 0 && (!requested || requested->screenHeight != 0)) { + if (o.screenHeight == 0) { + return true; + } + } + } + if (version != 0 && (!requested || requested->version != 0)) { + if (sdkVersion != 0 && (!requested || requested->sdkVersion != 0)) { + if (o.sdkVersion == 0) { + return true; + } + } + if (minorVersion != 0 && (!requested || requested->minorVersion != 0)) { + if (o.minorVersion == 0) { + return true; + } + } + } + return false; + } + + // Return true if 'this' can be considered a match for the parameters in + // 'settings'. + // Note this is asymetric. A default piece of data will match every request + // but a request for the default should not match odd specifics + // (ie, request with no mcc should not match a particular mcc's data) + // settings is the requested settings + inline bool match(const ResTable_config& settings) const { + if (imsi != 0) { + if ((settings.mcc != 0 && mcc != 0 + && mcc != settings.mcc) || + (settings.mcc == 0 && mcc != 0)) { + return false; + } + if ((settings.mnc != 0 && mnc != 0 + && mnc != settings.mnc) || + (settings.mnc == 0 && mnc != 0)) { + return false; + } + } + if (locale != 0) { + if (settings.language[0] != 0 && language[0] != 0 + && (language[0] != settings.language[0] + || language[1] != settings.language[1])) { + return false; + } + if (settings.country[0] != 0 && country[0] != 0 + && (country[0] != settings.country[0] + || country[1] != settings.country[1])) { + return false; + } + } + if (screenType != 0) { + if (settings.orientation != 0 && orientation != 0 + && orientation != settings.orientation) { + return false; + } + // Density not taken into account, always match, no matter what + // density is specified for the resource + if (settings.touchscreen != 0 && touchscreen != 0 + && touchscreen != settings.touchscreen) { + return false; + } + } + if (input != 0) { + const int keysHidden = inputFlags&MASK_KEYSHIDDEN; + const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN; + if (setKeysHidden != 0 && keysHidden != 0 + && keysHidden != setKeysHidden) { + // For compatibility, we count a request for KEYSHIDDEN_NO as also + // matching the more recent KEYSHIDDEN_SOFT. Basically + // KEYSHIDDEN_NO means there is some kind of keyboard available. + //LOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden); + if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) { + //LOGI("No match!"); + return false; + } + } + if (settings.keyboard != 0 && keyboard != 0 + && keyboard != settings.keyboard) { + return false; + } + if (settings.navigation != 0 && navigation != 0 + && navigation != settings.navigation) { + return false; + } + } + if (screenSize != 0) { + if (settings.screenWidth != 0 && screenWidth != 0 + && screenWidth != settings.screenWidth) { + return false; + } + if (settings.screenHeight != 0 && screenHeight != 0 + && screenHeight != settings.screenHeight) { + return false; + } + } + if (version != 0) { + if (settings.sdkVersion != 0 && sdkVersion != 0 + && sdkVersion != settings.sdkVersion) { + return false; + } + if (settings.minorVersion != 0 && minorVersion != 0 + && minorVersion != settings.minorVersion) { + return false; + } + } + return true; + } + + void getLocale(char str[6]) const { + memset(str, 0, 6); + if (language[0]) { + str[0] = language[0]; + str[1] = language[1]; + if (country[0]) { + str[2] = '_'; + str[3] = country[0]; + str[4] = country[1]; + } + } + } + + String8 toString() const { + char buf[200]; + sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x " + "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d", + mcc, mnc, + language[0] ? language[0] : '-', language[1] ? language[1] : '-', + country[0] ? country[0] : '-', country[1] ? country[1] : '-', + orientation, touchscreen, density, keyboard, navigation, inputFlags, + screenWidth, screenHeight, sdkVersion, minorVersion); + return String8(buf); + } +}; + +/** + * A specification of the resources defined by a particular type. + * + * There should be one of these chunks for each resource type. + * + * This structure is followed by an array of integers providing the set of + * configuation change flags (ResTable_config::CONFIG_*) that have multiple + * resources for that configuration. In addition, the high bit is set if that + * resource has been made public. + */ +struct ResTable_typeSpec +{ + struct ResChunk_header header; + + // The type identifier this chunk is holding. Type IDs start + // at 1 (corresponding to the value of the type bits in a + // resource identifier). 0 is invalid. + uint8_t id; + + // Must be 0. + uint8_t res0; + // Must be 0. + uint16_t res1; + + // Number of uint32_t entry configuration masks that follow. + uint32_t entryCount; + + enum { + // Additional flag indicating an entry is public. + SPEC_PUBLIC = 0x40000000 + }; +}; + +/** + * A collection of resource entries for a particular resource data + * type. Followed by an array of uint32_t defining the resource + * values, corresponding to the array of type strings in the + * ResTable_package::typeStrings string block. Each of these hold an + * index from entriesStart; a value of NO_ENTRY means that entry is + * not defined. + * + * There may be multiple of these chunks for a particular resource type, + * supply different configuration variations for the resource values of + * that type. + * + * It would be nice to have an additional ordered index of entries, so + * we can do a binary search if trying to find a resource by string name. + */ +struct ResTable_type +{ + struct ResChunk_header header; + + enum { + NO_ENTRY = 0xFFFFFFFF + }; + + // The type identifier this chunk is holding. Type IDs start + // at 1 (corresponding to the value of the type bits in a + // resource identifier). 0 is invalid. + uint8_t id; + + // Must be 0. + uint8_t res0; + // Must be 0. + uint16_t res1; + + // Number of uint32_t entry indices that follow. + uint32_t entryCount; + + // Offset from header where ResTable_entry data starts. + uint32_t entriesStart; + + // Configuration this collection of entries is designed for. + ResTable_config config; +}; + +/** + * This is the beginning of information about an entry in the resource + * table. It holds the reference to the name of this entry, and is + * immediately followed by one of: + * * A Res_value structures, if FLAG_COMPLEX is -not- set. + * * An array of ResTable_map structures, if FLAG_COMPLEX is set. + * These supply a set of name/value mappings of data. + */ +struct ResTable_entry +{ + // Number of bytes in this structure. + uint16_t size; + + enum { + // If set, this is a complex entry, holding a set of name/value + // mappings. It is followed by an array of ResTable_map structures. + FLAG_COMPLEX = 0x0001, + // If set, this resource has been declared public, so libraries + // are allowed to reference it. + FLAG_PUBLIC = 0x0002 + }; + uint16_t flags; + + // Reference into ResTable_package::keyStrings identifying this entry. + struct ResStringPool_ref key; +}; + +/** + * Extended form of a ResTable_entry for map entries, defining a parent map + * resource from which to inherit values. + */ +struct ResTable_map_entry : public ResTable_entry +{ + // Resource identifier of the parent mapping, or 0 if there is none. + ResTable_ref parent; + // Number of name/value pairs that follow for FLAG_COMPLEX. + uint32_t count; +}; + +/** + * A single name/value mapping that is part of a complex resource + * entry. + */ +struct ResTable_map +{ + // The resource identifier defining this mapping's name. For attribute + // resources, 'name' can be one of the following special resource types + // to supply meta-data about the attribute; for all other resource types + // it must be an attribute resource. + ResTable_ref name; + + // Special values for 'name' when defining attribute resources. + enum { + // This entry holds the attribute's type code. + ATTR_TYPE = Res_MAKEINTERNAL(0), + + // For integral attributes, this is the minimum value it can hold. + ATTR_MIN = Res_MAKEINTERNAL(1), + + // For integral attributes, this is the maximum value it can hold. + ATTR_MAX = Res_MAKEINTERNAL(2), + + // Localization of this resource is can be encouraged or required with + // an aapt flag if this is set + ATTR_L10N = Res_MAKEINTERNAL(3), + + // for plural support, see android.content.res.PluralRules#attrForQuantity(int) + ATTR_OTHER = Res_MAKEINTERNAL(4), + ATTR_ZERO = Res_MAKEINTERNAL(5), + ATTR_ONE = Res_MAKEINTERNAL(6), + ATTR_TWO = Res_MAKEINTERNAL(7), + ATTR_FEW = Res_MAKEINTERNAL(8), + ATTR_MANY = Res_MAKEINTERNAL(9) + + }; + + // Bit mask of allowed types, for use with ATTR_TYPE. + enum { + // No type has been defined for this attribute, use generic + // type handling. The low 16 bits are for types that can be + // handled generically; the upper 16 require additional information + // in the bag so can not be handled generically for TYPE_ANY. + TYPE_ANY = 0x0000FFFF, + + // Attribute holds a references to another resource. + TYPE_REFERENCE = 1<<0, + + // Attribute holds a generic string. + TYPE_STRING = 1<<1, + + // Attribute holds an integer value. ATTR_MIN and ATTR_MIN can + // optionally specify a constrained range of possible integer values. + TYPE_INTEGER = 1<<2, + + // Attribute holds a boolean integer. + TYPE_BOOLEAN = 1<<3, + + // Attribute holds a color value. + TYPE_COLOR = 1<<4, + + // Attribute holds a floating point value. + TYPE_FLOAT = 1<<5, + + // Attribute holds a dimension value, such as "20px". + TYPE_DIMENSION = 1<<6, + + // Attribute holds a fraction value, such as "20%". + TYPE_FRACTION = 1<<7, + + // Attribute holds an enumeration. The enumeration values are + // supplied as additional entries in the map. + TYPE_ENUM = 1<<16, + + // Attribute holds a bitmaks of flags. The flag bit values are + // supplied as additional entries in the map. + TYPE_FLAGS = 1<<17 + }; + + // Enum of localization modes, for use with ATTR_L10N. + enum { + L10N_NOT_REQUIRED = 0, + L10N_SUGGESTED = 1 + }; + + // This mapping's value. + Res_value value; +}; + +/** + * Convenience class for accessing data in a ResTable resource. + */ +class ResTable +{ +public: + ResTable(); + ResTable(const void* data, size_t size, void* cookie, + bool copyData=false); + ~ResTable(); + + status_t add(const void* data, size_t size, void* cookie, + bool copyData=false); + status_t add(Asset* asset, void* cookie, + bool copyData=false); + + status_t getError() const; + + void uninit(); + + struct resource_name + { + const char16_t* package; + size_t packageLen; + const char16_t* type; + size_t typeLen; + const char16_t* name; + size_t nameLen; + }; + + bool getResourceName(uint32_t resID, resource_name* outName) const; + + /** + * Retrieve the value of a resource. If the resource is found, returns a + * value >= 0 indicating the table it is in (for use with + * getTableStringBlock() and getTableCookie()) and fills in 'outValue'. If + * not found, returns a negative error code. + * + * Note that this function does not do reference traversal. If you want + * to follow references to other resources to get the "real" value to + * use, you need to call resolveReference() after this function. + * + * @param resID The desired resoruce identifier. + * @param outValue Filled in with the resource data that was found. + * + * @return ssize_t Either a >= 0 table index or a negative error code. + */ + ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false, + uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const; + + inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue, + uint32_t* outSpecFlags=NULL) const { + return getResource(res.ident, outValue, false, outSpecFlags, NULL); + } + + ssize_t resolveReference(Res_value* inOutValue, + ssize_t blockIndex, + uint32_t* outLastRef = NULL, + uint32_t* inoutTypeSpecFlags = NULL) const; + + enum { + TMP_BUFFER_SIZE = 16 + }; + const char16_t* valueToString(const Res_value* value, size_t stringBlock, + char16_t tmpBuffer[TMP_BUFFER_SIZE], + size_t* outLen); + + struct bag_entry { + ssize_t stringBlock; + ResTable_map map; + }; + + /** + * Retrieve the bag of a resource. If the resoruce is found, returns the + * number of bags it contains and 'outBag' points to an array of their + * values. If not found, a negative error code is returned. + * + * Note that this function -does- do reference traversal of the bag data. + * + * @param resID The desired resource identifier. + * @param outBag Filled inm with a pointer to the bag mappings. + * + * @return ssize_t Either a >= 0 bag count of negative error code. + */ + ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const; + + void unlockBag(const bag_entry* bag) const; + + void lock() const; + + ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag, + uint32_t* outTypeSpecFlags=NULL) const; + + void unlock() const; + + class Theme { + public: + Theme(const ResTable& table); + ~Theme(); + + inline const ResTable& getResTable() const { return mTable; } + + status_t applyStyle(uint32_t resID, bool force=false); + status_t setTo(const Theme& other); + + /** + * Retrieve a value in the theme. If the theme defines this + * value, returns a value >= 0 indicating the table it is in + * (for use with getTableStringBlock() and getTableCookie) and + * fills in 'outValue'. If not found, returns a negative error + * code. + * + * Note that this function does not do reference traversal. If you want + * to follow references to other resources to get the "real" value to + * use, you need to call resolveReference() after this function. + * + * @param resID A resource identifier naming the desired theme + * attribute. + * @param outValue Filled in with the theme value that was + * found. + * + * @return ssize_t Either a >= 0 table index or a negative error code. + */ + ssize_t getAttribute(uint32_t resID, Res_value* outValue, + uint32_t* outTypeSpecFlags = NULL) const; + + /** + * This is like ResTable::resolveReference(), but also takes + * care of resolving attribute references to the theme. + */ + ssize_t resolveAttributeReference(Res_value* inOutValue, + ssize_t blockIndex, uint32_t* outLastRef = NULL, + uint32_t* inoutTypeSpecFlags = NULL) const; + + void dumpToLog() const; + + private: + Theme(const Theme&); + Theme& operator=(const Theme&); + + struct theme_entry { + ssize_t stringBlock; + uint32_t typeSpecFlags; + Res_value value; + }; + struct type_info { + size_t numEntries; + theme_entry* entries; + }; + struct package_info { + size_t numTypes; + type_info types[]; + }; + + void free_package(package_info* pi); + package_info* copy_package(package_info* pi); + + const ResTable& mTable; + package_info* mPackages[Res_MAXPACKAGE]; + }; + + void setParameters(const ResTable_config* params); + void getParameters(ResTable_config* params) const; + + // Retrieve an identifier (which can be passed to getResource) + // for a given resource name. The 'name' can be fully qualified + // (<package>:<type>.<basename>) or the package or type components + // can be dropped if default values are supplied here. + // + // Returns 0 if no such resource was found, else a valid resource ID. + uint32_t identifierForName(const char16_t* name, size_t nameLen, + const char16_t* type = 0, size_t typeLen = 0, + const char16_t* defPackage = 0, + size_t defPackageLen = 0, + uint32_t* outTypeSpecFlags = NULL) const; + + static bool expandResourceRef(const uint16_t* refStr, size_t refLen, + String16* outPackage, + String16* outType, + String16* outName, + const String16* defType = NULL, + const String16* defPackage = NULL, + const char** outErrorMsg = NULL); + + static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue); + static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue); + + // Used with stringToValue. + class Accessor + { + public: + inline virtual ~Accessor() { } + + virtual uint32_t getCustomResource(const String16& package, + const String16& type, + const String16& name) const = 0; + virtual uint32_t getCustomResourceWithCreation(const String16& package, + const String16& type, + const String16& name, + const bool createIfNeeded = false) = 0; + virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0; + virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0; + virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0; + virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0; + virtual bool getAttributeEnum(uint32_t attrID, + const char16_t* name, size_t nameLen, + Res_value* outValue) = 0; + virtual bool getAttributeFlags(uint32_t attrID, + const char16_t* name, size_t nameLen, + Res_value* outValue) = 0; + virtual uint32_t getAttributeL10N(uint32_t attrID) = 0; + virtual bool getLocalizationSetting() = 0; + virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0; + }; + + // Convert a string to a resource value. Handles standard "@res", + // "#color", "123", and "0x1bd" types; performs escaping of strings. + // The resulting value is placed in 'outValue'; if it is a string type, + // 'outString' receives the string. If 'attrID' is supplied, the value is + // type checked against this attribute and it is used to perform enum + // evaluation. If 'acccessor' is supplied, it will be used to attempt to + // resolve resources that do not exist in this ResTable. If 'attrType' is + // supplied, the value will be type checked for this format if 'attrID' + // is not supplied or found. + bool stringToValue(Res_value* outValue, String16* outString, + const char16_t* s, size_t len, + bool preserveSpaces, bool coerceType, + uint32_t attrID = 0, + const String16* defType = NULL, + const String16* defPackage = NULL, + Accessor* accessor = NULL, + void* accessorCookie = NULL, + uint32_t attrType = ResTable_map::TYPE_ANY, + bool enforcePrivate = true) const; + + // Perform processing of escapes and quotes in a string. + static bool collectString(String16* outString, + const char16_t* s, size_t len, + bool preserveSpaces, + const char** outErrorMsg = NULL, + bool append = false); + + size_t getBasePackageCount() const; + const char16_t* getBasePackageName(size_t idx) const; + uint32_t getBasePackageId(size_t idx) const; + + size_t getTableCount() const; + const ResStringPool* getTableStringBlock(size_t index) const; + void* getTableCookie(size_t index) const; + + // Return the configurations (ResTable_config) that we know about + void getConfigurations(Vector<ResTable_config>* configs) const; + + void getLocales(Vector<String8>* locales) const; + +#ifndef HAVE_ANDROID_OS + void print() const; +#endif + +private: + struct Header; + struct Type; + struct Package; + struct PackageGroup; + struct bag_set; + + status_t add(const void* data, size_t size, void* cookie, + Asset* asset, bool copyData); + + ssize_t getResourcePackageIndex(uint32_t resID) const; + ssize_t getEntry( + const Package* package, int typeIndex, int entryIndex, + const ResTable_config* config, + const ResTable_type** outType, const ResTable_entry** outEntry, + const Type** outTypeClass) const; + status_t parsePackage( + const ResTable_package* const pkg, const Header* const header); + + mutable Mutex mLock; + + status_t mError; + + ResTable_config mParams; + + // Array of all resource tables. + Vector<Header*> mHeaders; + + // Array of packages in all resource tables. + Vector<PackageGroup*> mPackageGroups; + + // Mapping from resource package IDs to indices into the internal + // package array. + uint8_t mPackageMap[256]; +}; + +} // namespace android + +#endif // _LIBS_UTILS_RESOURCE_TYPES_H diff --git a/include/utils/SharedBuffer.h b/include/utils/SharedBuffer.h new file mode 100644 index 0000000..24508b0 --- /dev/null +++ b/include/utils/SharedBuffer.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SHARED_BUFFER_H +#define ANDROID_SHARED_BUFFER_H + +#include <stdint.h> +#include <sys/types.h> + +// --------------------------------------------------------------------------- + +namespace android { + +class SharedBuffer +{ +public: + + /* flags to use with release() */ + enum { + eKeepStorage = 0x00000001 + }; + + /*! allocate a buffer of size 'size' and acquire() it. + * call release() to free it. + */ + static SharedBuffer* alloc(size_t size); + + /*! free the memory associated with the SharedBuffer. + * Fails if there are any users associated with this SharedBuffer. + * In other words, the buffer must have been release by all its + * users. + */ + static ssize_t dealloc(const SharedBuffer* released); + + //! get the SharedBuffer from the data pointer + static inline const SharedBuffer* sharedBuffer(const void* data); + + //! access the data for read + inline const void* data() const; + + //! access the data for read/write + inline void* data(); + + //! get size of the buffer + inline size_t size() const; + + //! get back a SharedBuffer object from its data + static inline SharedBuffer* bufferFromData(void* data); + + //! get back a SharedBuffer object from its data + static inline const SharedBuffer* bufferFromData(const void* data); + + //! get the size of a SharedBuffer object from its data + static inline size_t sizeFromData(const void* data); + + //! edit the buffer (get a writtable, or non-const, version of it) + SharedBuffer* edit() const; + + //! edit the buffer, resizing if needed + SharedBuffer* editResize(size_t size) const; + + //! like edit() but fails if a copy is required + SharedBuffer* attemptEdit() const; + + //! resize and edit the buffer, loose it's content. + SharedBuffer* reset(size_t size) const; + + //! acquire/release a reference on this buffer + void acquire() const; + + /*! release a reference on this buffer, with the option of not + * freeing the memory associated with it if it was the last reference + * returns the previous reference count + */ + int32_t release(uint32_t flags = 0) const; + + //! returns wether or not we're the only owner + inline bool onlyOwner() const; + + +private: + inline SharedBuffer() { } + inline ~SharedBuffer() { } + inline SharedBuffer(const SharedBuffer&); + + // 16 bytes. must be sized to preserve correct alingment. + mutable int32_t mRefs; + size_t mSize; + uint32_t mReserved[2]; +}; + +// --------------------------------------------------------------------------- + +const SharedBuffer* SharedBuffer::sharedBuffer(const void* data) { + return data ? reinterpret_cast<const SharedBuffer *>(data)-1 : 0; +} + +const void* SharedBuffer::data() const { + return this + 1; +} + +void* SharedBuffer::data() { + return this + 1; +} + +size_t SharedBuffer::size() const { + return mSize; +} + +SharedBuffer* SharedBuffer::bufferFromData(void* data) +{ + return ((SharedBuffer*)data)-1; +} + +const SharedBuffer* SharedBuffer::bufferFromData(const void* data) +{ + return ((const SharedBuffer*)data)-1; +} + +size_t SharedBuffer::sizeFromData(const void* data) +{ + return (((const SharedBuffer*)data)-1)->mSize; +} + +bool SharedBuffer::onlyOwner() const { + return (mRefs == 1); +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_H diff --git a/include/utils/Socket.h b/include/utils/Socket.h new file mode 100644 index 0000000..8b7f406 --- /dev/null +++ b/include/utils/Socket.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Socket class. Modeled after Java classes. +// +#ifndef _RUNTIME_SOCKET_H +#define _RUNTIME_SOCKET_H + +#include <utils/inet_address.h> +#include <sys/types.h> + +namespace android { + +/* + * Basic socket class, needed to abstract away the differences between + * BSD sockets and WinSock. This establishes a streaming network + * connection (TCP/IP) to somebody. + */ +class Socket { +public: + Socket(void); + ~Socket(void); + + // Create a connection to somewhere. + // Return 0 on success. + int connect(const char* host, int port); + int connect(const InetAddress* addr, int port); + + + // Close the socket. Don't try to use this object again after + // calling this. Returns false on failure. + bool close(void); + + // If we created the socket without an address, we can use these + // to finish the connection. Returns 0 on success. + int bind(const SocketAddress& bindPoint); + int connect(const SocketAddress& endPoint); + + // Here we deviate from the traditional object-oriented fanciness + // and just provide read/write operators instead of getters for + // objects that abstract a stream. + // + // Standard read/write semantics. + int read(void* buf, ssize_t len) const; + int write(const void* buf, ssize_t len) const; + + // This must be called once, at program startup. + static bool bootInit(void); + static void finalShutdown(void); + +private: + // Internal function that establishes a connection. + int doConnect(const InetSocketAddress& addr); + + unsigned long mSock; // holds SOCKET or int + + static bool mBootInitialized; +}; + + +// debug -- unit tests +void TestSockets(void); + +}; // namespace android + +#endif // _RUNTIME_SOCKET_H diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h new file mode 100644 index 0000000..c8a6153 --- /dev/null +++ b/include/utils/SortedVector.h @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SORTED_VECTOR_H +#define ANDROID_SORTED_VECTOR_H + +#include <assert.h> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Vector.h> +#include <utils/VectorImpl.h> +#include <utils/TypeHelpers.h> + +// --------------------------------------------------------------------------- + +namespace android { + +template <class TYPE> +class SortedVector : private SortedVectorImpl +{ +public: + typedef TYPE value_type; + + /*! + * Constructors and destructors + */ + + SortedVector(); + SortedVector(const SortedVector<TYPE>& rhs); + virtual ~SortedVector(); + + /*! copy operator */ + const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const; + SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs); + + /* + * empty the vector + */ + + inline void clear() { VectorImpl::clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return VectorImpl::size(); } + //! returns wether or not the vector is empty + inline bool isEmpty() const { return VectorImpl::isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return VectorImpl::capacity(); } + //! setst the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } + + /*! + * C-style array access + */ + + //! read-only C-style access + inline const TYPE* array() const; + + //! read-write C-style access. BE VERY CAREFUL when modifying the array + //! you ust keep it sorted! You usually don't use this function. + TYPE* editArray(); + + //! finds the index of an item + ssize_t indexOf(const TYPE& item) const; + + //! finds where this item should be inserted + size_t orderOf(const TYPE& item) const; + + + /*! + * accessors + */ + + //! read-only access to an item at a given index + inline const TYPE& operator [] (size_t index) const; + //! alternate name for operator [] + inline const TYPE& itemAt(size_t index) const; + //! stack-usage of the vector. returns the top of the stack (last element) + const TYPE& top() const; + //! same as operator [], but allows to access the vector backward (from the end) with a negative index + const TYPE& mirrorItemAt(ssize_t index) const; + + /*! + * modifing the array + */ + + //! add an item in the right place (and replace the one that is there) + ssize_t add(const TYPE& item); + + //! editItemAt() MUST NOT change the order of this item + TYPE& editItemAt(size_t index) { + return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) ); + } + + //! merges a vector into this one + ssize_t merge(const Vector<TYPE>& vector); + ssize_t merge(const SortedVector<TYPE>& vector); + + //! removes an item + ssize_t remove(const TYPE&); + + //! remove several items + inline ssize_t removeItemsAt(size_t index, size_t count = 1); + //! remove one item + inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } + +protected: + virtual void do_construct(void* storage, size_t num) const; + virtual void do_destroy(void* storage, size_t num) const; + virtual void do_copy(void* dest, const void* from, size_t num) const; + virtual void do_splat(void* dest, const void* item, size_t num) const; + virtual void do_move_forward(void* dest, const void* from, size_t num) const; + virtual void do_move_backward(void* dest, const void* from, size_t num) const; + virtual int do_compare(const void* lhs, const void* rhs) const; +}; + + +// --------------------------------------------------------------------------- +// No user serviceable parts from here... +// --------------------------------------------------------------------------- + +template<class TYPE> inline +SortedVector<TYPE>::SortedVector() + : SortedVectorImpl(sizeof(TYPE), + ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) + |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) + |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) + |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + ) +{ +} + +template<class TYPE> inline +SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs) + : SortedVectorImpl(rhs) { +} + +template<class TYPE> inline +SortedVector<TYPE>::~SortedVector() { + finish_vector(); +} + +template<class TYPE> inline +SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) { + SortedVectorImpl::operator = (rhs); + return *this; +} + +template<class TYPE> inline +const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const { + SortedVectorImpl::operator = (rhs); + return *this; +} + +template<class TYPE> inline +const TYPE* SortedVector<TYPE>::array() const { + return static_cast<const TYPE *>(arrayImpl()); +} + +template<class TYPE> inline +TYPE* SortedVector<TYPE>::editArray() { + return static_cast<TYPE *>(editArrayImpl()); +} + + +template<class TYPE> inline +const TYPE& SortedVector<TYPE>::operator[](size_t index) const { + assert( index<size() ); + return *(array() + index); +} + +template<class TYPE> inline +const TYPE& SortedVector<TYPE>::itemAt(size_t index) const { + return operator[](index); +} + +template<class TYPE> inline +const TYPE& SortedVector<TYPE>::mirrorItemAt(ssize_t index) const { + assert( (index>0 ? index : -index)<size() ); + return *(array() + ((index<0) ? (size()-index) : index)); +} + +template<class TYPE> inline +const TYPE& SortedVector<TYPE>::top() const { + return *(array() + size() - 1); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::add(const TYPE& item) { + return SortedVectorImpl::add(&item); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const { + return SortedVectorImpl::indexOf(&item); +} + +template<class TYPE> inline +size_t SortedVector<TYPE>::orderOf(const TYPE& item) const { + return SortedVectorImpl::orderOf(&item); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) { + return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector)); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) { + return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector)); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::remove(const TYPE& item) { + return SortedVectorImpl::remove(&item); +} + +template<class TYPE> inline +ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) { + return VectorImpl::removeItemsAt(index, count); +} + +// --------------------------------------------------------------------------- + +template<class TYPE> +void SortedVector<TYPE>::do_construct(void* storage, size_t num) const { + construct_type( reinterpret_cast<TYPE*>(storage), num ); +} + +template<class TYPE> +void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const { + destroy_type( reinterpret_cast<TYPE*>(storage), num ); +} + +template<class TYPE> +void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const { + copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +template<class TYPE> +void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const { + splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); +} + +template<class TYPE> +void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { + move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +template<class TYPE> +void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { + move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +template<class TYPE> +int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const { + return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) ); +} + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_SORTED_VECTOR_H diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h new file mode 100644 index 0000000..cc0bebc --- /dev/null +++ b/include/utils/StopWatch.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STOPWATCH_H +#define ANDROID_STOPWATCH_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Timers.h> + +// --------------------------------------------------------------------------- + +namespace android { + +class StopWatch +{ +public: + StopWatch( const char *name, + int clock = SYSTEM_TIME_MONOTONIC, + uint32_t flags = 0); + ~StopWatch(); + + const char* name() const; + nsecs_t lap(); + nsecs_t elapsedTime() const; + +private: + const char* mName; + int mClock; + uint32_t mFlags; + + struct lap_t { + nsecs_t soFar; + nsecs_t thisLap; + }; + + nsecs_t mStartTime; + lap_t mLaps[8]; + int mNumLaps; +}; + + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STOPWATCH_H diff --git a/include/utils/String16.h b/include/utils/String16.h new file mode 100644 index 0000000..a2d22ee --- /dev/null +++ b/include/utils/String16.h @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRING16_H +#define ANDROID_STRING16_H + +#include <utils/Errors.h> +#include <utils/SharedBuffer.h> + +#include <stdint.h> +#include <sys/types.h> + +// --------------------------------------------------------------------------- + +extern "C" { + +typedef uint16_t char16_t; + +// Standard string functions on char16 strings. +int strcmp16(const char16_t *, const char16_t *); +int strncmp16(const char16_t *s1, const char16_t *s2, size_t n); +size_t strlen16(const char16_t *); +size_t strnlen16(const char16_t *, size_t); +char16_t *strcpy16(char16_t *, const char16_t *); +char16_t *strncpy16(char16_t *, const char16_t *, size_t); + +// Version of comparison that supports embedded nulls. +// This is different than strncmp() because we don't stop +// at a nul character and consider the strings to be different +// if the lengths are different (thus we need to supply the +// lengths of both strings). This can also be used when +// your string is not nul-terminated as it will have the +// equivalent result as strcmp16 (unlike strncmp16). +int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2); + +// Version of strzcmp16 for comparing strings in different endianness. +int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2); + +} + +// --------------------------------------------------------------------------- + +namespace android { + +class String8; +class TextOutput; + +//! This is a string holding UTF-16 characters. +class String16 +{ +public: + String16(); + String16(const String16& o); + String16(const String16& o, + size_t len, + size_t begin=0); + explicit String16(const char16_t* o); + explicit String16(const char16_t* o, size_t len); + explicit String16(const String8& o); + explicit String16(const char* o); + explicit String16(const char* o, size_t len); + + ~String16(); + + inline const char16_t* string() const; + inline size_t size() const; + + inline const SharedBuffer* sharedBuffer() const; + + void setTo(const String16& other); + status_t setTo(const char16_t* other); + status_t setTo(const char16_t* other, size_t len); + status_t setTo(const String16& other, + size_t len, + size_t begin=0); + + status_t append(const String16& other); + status_t append(const char16_t* other, size_t len); + + inline String16& operator=(const String16& other); + + inline String16& operator+=(const String16& other); + inline String16 operator+(const String16& other) const; + + status_t insert(size_t pos, const char16_t* chrs); + status_t insert(size_t pos, + const char16_t* chrs, size_t len); + + ssize_t findFirst(char16_t c) const; + ssize_t findLast(char16_t c) const; + + bool startsWith(const String16& prefix) const; + bool startsWith(const char16_t* prefix) const; + + status_t makeLower(); + + status_t replaceAll(char16_t replaceThis, + char16_t withThis); + + status_t remove(size_t len, size_t begin=0); + + inline int compare(const String16& other) const; + + inline bool operator<(const String16& other) const; + inline bool operator<=(const String16& other) const; + inline bool operator==(const String16& other) const; + inline bool operator!=(const String16& other) const; + inline bool operator>=(const String16& other) const; + inline bool operator>(const String16& other) const; + + inline bool operator<(const char16_t* other) const; + inline bool operator<=(const char16_t* other) const; + inline bool operator==(const char16_t* other) const; + inline bool operator!=(const char16_t* other) const; + inline bool operator>=(const char16_t* other) const; + inline bool operator>(const char16_t* other) const; + + inline operator const char16_t*() const; + +private: + const char16_t* mString; +}; + +TextOutput& operator<<(TextOutput& to, const String16& val); + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline int compare_type(const String16& lhs, const String16& rhs) +{ + return lhs.compare(rhs); +} + +inline int strictly_order_type(const String16& lhs, const String16& rhs) +{ + return compare_type(lhs, rhs) < 0; +} + +inline const char16_t* String16::string() const +{ + return mString; +} + +inline size_t String16::size() const +{ + return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1; +} + +inline const SharedBuffer* String16::sharedBuffer() const +{ + return SharedBuffer::bufferFromData(mString); +} + +inline String16& String16::operator=(const String16& other) +{ + setTo(other); + return *this; +} + +inline String16& String16::operator+=(const String16& other) +{ + append(other); + return *this; +} + +inline String16 String16::operator+(const String16& other) const +{ + String16 tmp; + tmp += other; + return tmp; +} + +inline int String16::compare(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()); +} + +inline bool String16::operator<(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) < 0; +} + +inline bool String16::operator<=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) <= 0; +} + +inline bool String16::operator==(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) == 0; +} + +inline bool String16::operator!=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) != 0; +} + +inline bool String16::operator>=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) >= 0; +} + +inline bool String16::operator>(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) > 0; +} + +inline bool String16::operator<(const char16_t* other) const +{ + return strcmp16(mString, other) < 0; +} + +inline bool String16::operator<=(const char16_t* other) const +{ + return strcmp16(mString, other) <= 0; +} + +inline bool String16::operator==(const char16_t* other) const +{ + return strcmp16(mString, other) == 0; +} + +inline bool String16::operator!=(const char16_t* other) const +{ + return strcmp16(mString, other) != 0; +} + +inline bool String16::operator>=(const char16_t* other) const +{ + return strcmp16(mString, other) >= 0; +} + +inline bool String16::operator>(const char16_t* other) const +{ + return strcmp16(mString, other) > 0; +} + +inline String16::operator const char16_t*() const +{ + return mString; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRING16_H diff --git a/include/utils/String8.h b/include/utils/String8.h new file mode 100644 index 0000000..c49faf6 --- /dev/null +++ b/include/utils/String8.h @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRING8_H +#define ANDROID_STRING8_H + +#include <utils/Errors.h> + +// Need this for the char16_t type; String8.h should not +// be depedent on the String16 class. +#include <utils/String16.h> + +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + +// --------------------------------------------------------------------------- + +namespace android { + +class TextOutput; + +//! This is a string holding UTF-8 characters. +class String8 +{ +public: + String8(); + String8(const String8& o); + explicit String8(const char* o); + explicit String8(const char* o, size_t numChars); + + explicit String8(const String16& o); + explicit String8(const char16_t* o); + explicit String8(const char16_t* o, size_t numChars); + + ~String8(); + + inline const char* string() const; + inline size_t size() const; + inline size_t length() const; + inline size_t bytes() const; + + inline const SharedBuffer* sharedBuffer() const; + + void setTo(const String8& other); + status_t setTo(const char* other); + status_t setTo(const char* other, size_t numChars); + status_t setTo(const char16_t* other, size_t numChars); + + status_t append(const String8& other); + status_t append(const char* other); + status_t append(const char* other, size_t numChars); + + inline String8& operator=(const String8& other); + inline String8& operator=(const char* other); + + inline String8& operator+=(const String8& other); + inline String8 operator+(const String8& other) const; + + inline String8& operator+=(const char* other); + inline String8 operator+(const char* other) const; + + inline int compare(const String8& other) const; + + inline bool operator<(const String8& other) const; + inline bool operator<=(const String8& other) const; + inline bool operator==(const String8& other) const; + inline bool operator!=(const String8& other) const; + inline bool operator>=(const String8& other) const; + inline bool operator>(const String8& other) const; + + inline bool operator<(const char* other) const; + inline bool operator<=(const char* other) const; + inline bool operator==(const char* other) const; + inline bool operator!=(const char* other) const; + inline bool operator>=(const char* other) const; + inline bool operator>(const char* other) const; + + inline operator const char*() const; + + char* lockBuffer(size_t size); + void unlockBuffer(); + status_t unlockBuffer(size_t size); + + // return the index of the first byte of other in this at or after + // start, or -1 if not found + ssize_t find(const char* other, size_t start = 0) const; + + void toLower(); + void toLower(size_t start, size_t numChars); + void toUpper(); + void toUpper(size_t start, size_t numChars); + + /* + * These methods operate on the string as if it were a path name. + */ + + /* + * Set the filename field to a specific value. + * + * Normalizes the filename, removing a trailing '/' if present. + */ + void setPathName(const char* name); + void setPathName(const char* name, size_t numChars); + + /* + * Get just the filename component. + * + * "/tmp/foo/bar.c" --> "bar.c" + */ + String8 getPathLeaf(void) const; + + /* + * Remove the last (file name) component, leaving just the directory + * name. + * + * "/tmp/foo/bar.c" --> "/tmp/foo" + * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX + * "bar.c" --> "" + */ + String8 getPathDir(void) const; + + /* + * Retrieve the front (root dir) component. Optionally also return the + * remaining components. + * + * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c") + * "/tmp" --> "tmp" (remain = "") + * "bar.c" --> "bar.c" (remain = "") + */ + String8 walkPath(String8* outRemains = NULL) const; + + /* + * Return the filename extension. This is the last '.' and up to + * four characters that follow it. The '.' is included in case we + * decide to expand our definition of what constitutes an extension. + * + * "/tmp/foo/bar.c" --> ".c" + * "/tmp" --> "" + * "/tmp/foo.bar/baz" --> "" + * "foo.jpeg" --> ".jpeg" + * "foo." --> "" + */ + String8 getPathExtension(void) const; + + /* + * Return the path without the extension. Rules for what constitutes + * an extension are described in the comment for getPathExtension(). + * + * "/tmp/foo/bar.c" --> "/tmp/foo/bar" + */ + String8 getBasePath(void) const; + + /* + * Add a component to the pathname. We guarantee that there is + * exactly one path separator between the old path and the new. + * If there is no existing name, we just copy the new name in. + * + * If leaf is a fully qualified path (i.e. starts with '/', it + * replaces whatever was there before. + */ + String8& appendPath(const char* leaf); + String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); } + + /* + * Like appendPath(), but does not affect this string. Returns a new one instead. + */ + String8 appendPathCopy(const char* leaf) const + { String8 p(*this); p.appendPath(leaf); return p; } + String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); } + + /* + * Converts all separators in this string to /, the default path separator. + * + * If the default OS separator is backslash, this converts all + * backslashes to slashes, in-place. Otherwise it does nothing. + * Returns self. + */ + String8& convertToResPath(); + +private: + status_t real_append(const char* other, size_t numChars); + char* find_extension(void) const; + + const char* mString; +}; + +TextOutput& operator<<(TextOutput& to, const String16& val); + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline int compare_type(const String8& lhs, const String8& rhs) +{ + return lhs.compare(rhs); +} + +inline int strictly_order_type(const String8& lhs, const String8& rhs) +{ + return compare_type(lhs, rhs) < 0; +} + +inline const char* String8::string() const +{ + return mString; +} + +inline size_t String8::length() const +{ + return SharedBuffer::sizeFromData(mString)-1; +} + +inline size_t String8::size() const +{ + return length(); +} + +inline size_t String8::bytes() const +{ + return SharedBuffer::sizeFromData(mString)-1; +} + +inline const SharedBuffer* String8::sharedBuffer() const +{ + return SharedBuffer::bufferFromData(mString); +} + +inline String8& String8::operator=(const String8& other) +{ + setTo(other); + return *this; +} + +inline String8& String8::operator=(const char* other) +{ + setTo(other); + return *this; +} + +inline String8& String8::operator+=(const String8& other) +{ + append(other); + return *this; +} + +inline String8 String8::operator+(const String8& other) const +{ + String8 tmp; + tmp += other; + return tmp; +} + +inline String8& String8::operator+=(const char* other) +{ + append(other); + return *this; +} + +inline String8 String8::operator+(const char* other) const +{ + String8 tmp; + tmp += other; + return tmp; +} + +inline int String8::compare(const String8& other) const +{ + return strcmp(mString, other.mString); +} + +inline bool String8::operator<(const String8& other) const +{ + return strcmp(mString, other.mString) < 0; +} + +inline bool String8::operator<=(const String8& other) const +{ + return strcmp(mString, other.mString) <= 0; +} + +inline bool String8::operator==(const String8& other) const +{ + return strcmp(mString, other.mString) == 0; +} + +inline bool String8::operator!=(const String8& other) const +{ + return strcmp(mString, other.mString) != 0; +} + +inline bool String8::operator>=(const String8& other) const +{ + return strcmp(mString, other.mString) >= 0; +} + +inline bool String8::operator>(const String8& other) const +{ + return strcmp(mString, other.mString) > 0; +} + +inline bool String8::operator<(const char* other) const +{ + return strcmp(mString, other) < 0; +} + +inline bool String8::operator<=(const char* other) const +{ + return strcmp(mString, other) <= 0; +} + +inline bool String8::operator==(const char* other) const +{ + return strcmp(mString, other) == 0; +} + +inline bool String8::operator!=(const char* other) const +{ + return strcmp(mString, other) != 0; +} + +inline bool String8::operator>=(const char* other) const +{ + return strcmp(mString, other) >= 0; +} + +inline bool String8::operator>(const char* other) const +{ + return strcmp(mString, other) > 0; +} + +inline String8::operator const char*() const +{ + return mString; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRING8_H diff --git a/include/utils/SystemClock.h b/include/utils/SystemClock.h new file mode 100644 index 0000000..7c319be --- /dev/null +++ b/include/utils/SystemClock.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_SYSTEMCLOCK_H +#define ANDROID_UTILS_SYSTEMCLOCK_H + +#include <stdint.h> +#include <sys/types.h> + +namespace android { + +int setCurrentTimeMillis(int64_t millis); +int64_t uptimeMillis(); +int64_t elapsedRealtime(); + +}; // namespace android + +#endif // ANDROID_UTILS_SYSTEMCLOCK_H + diff --git a/include/utils/TextOutput.h b/include/utils/TextOutput.h new file mode 100644 index 0000000..d8d86ba --- /dev/null +++ b/include/utils/TextOutput.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TEXTOUTPUT_H +#define ANDROID_TEXTOUTPUT_H + +#include <utils/Errors.h> + +#include <stdint.h> +#include <string.h> + +// --------------------------------------------------------------------------- +namespace android { + +class TextOutput +{ +public: + TextOutput() { } + virtual ~TextOutput() { } + + virtual status_t print(const char* txt, size_t len) = 0; + virtual void moveIndent(int delta) = 0; + + class Bundle { + public: + inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); } + inline ~Bundle() { mTO.popBundle(); } + private: + TextOutput& mTO; + }; + + virtual void pushBundle() = 0; + virtual void popBundle() = 0; +}; + +// --------------------------------------------------------------------------- + +// Text output stream for printing to the log (via utils/Log.h). +extern TextOutput& alog; + +// Text output stream for printing to stdout. +extern TextOutput& aout; + +// Text output stream for printing to stderr. +extern TextOutput& aerr; + +typedef TextOutput& (*TextOutputManipFunc)(TextOutput&); + +TextOutput& endl(TextOutput& to); +TextOutput& indent(TextOutput& to); +TextOutput& dedent(TextOutput& to); + +TextOutput& operator<<(TextOutput& to, const char* str); +TextOutput& operator<<(TextOutput& to, char); // writes raw character +TextOutput& operator<<(TextOutput& to, bool); +TextOutput& operator<<(TextOutput& to, int); +TextOutput& operator<<(TextOutput& to, long); +TextOutput& operator<<(TextOutput& to, unsigned int); +TextOutput& operator<<(TextOutput& to, unsigned long); +TextOutput& operator<<(TextOutput& to, long long); +TextOutput& operator<<(TextOutput& to, unsigned long long); +TextOutput& operator<<(TextOutput& to, float); +TextOutput& operator<<(TextOutput& to, double); +TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func); +TextOutput& operator<<(TextOutput& to, const void*); + +class TypeCode +{ +public: + inline TypeCode(uint32_t code); + inline ~TypeCode(); + + inline uint32_t typeCode() const; + +private: + uint32_t mCode; +}; + +TextOutput& operator<<(TextOutput& to, const TypeCode& val); + +class HexDump +{ +public: + HexDump(const void *buf, size_t size, size_t bytesPerLine=16); + inline ~HexDump(); + + inline HexDump& setBytesPerLine(size_t bytesPerLine); + inline HexDump& setSingleLineCutoff(int32_t bytes); + inline HexDump& setAlignment(size_t alignment); + inline HexDump& setCArrayStyle(bool enabled); + + inline const void* buffer() const; + inline size_t size() const; + inline size_t bytesPerLine() const; + inline int32_t singleLineCutoff() const; + inline size_t alignment() const; + inline bool carrayStyle() const; + +private: + const void* mBuffer; + size_t mSize; + size_t mBytesPerLine; + int32_t mSingleLineCutoff; + size_t mAlignment; + bool mCArrayStyle; +}; + +TextOutput& operator<<(TextOutput& to, const HexDump& val); + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline TextOutput& endl(TextOutput& to) +{ + to.print("\n", 1); + return to; +} + +inline TextOutput& indent(TextOutput& to) +{ + to.moveIndent(1); + return to; +} + +inline TextOutput& dedent(TextOutput& to) +{ + to.moveIndent(-1); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, const char* str) +{ + to.print(str, strlen(str)); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, char c) +{ + to.print(&c, 1); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func) +{ + return (*func)(to); +} + +inline TypeCode::TypeCode(uint32_t code) : mCode(code) { } +inline TypeCode::~TypeCode() { } +inline uint32_t TypeCode::typeCode() const { return mCode; } + +inline HexDump::~HexDump() { } + +inline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) { + mBytesPerLine = bytesPerLine; return *this; +} +inline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) { + mSingleLineCutoff = bytes; return *this; +} +inline HexDump& HexDump::setAlignment(size_t alignment) { + mAlignment = alignment; return *this; +} +inline HexDump& HexDump::setCArrayStyle(bool enabled) { + mCArrayStyle = enabled; return *this; +} + +inline const void* HexDump::buffer() const { return mBuffer; } +inline size_t HexDump::size() const { return mSize; } +inline size_t HexDump::bytesPerLine() const { return mBytesPerLine; } +inline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; } +inline size_t HexDump::alignment() const { return mAlignment; } +inline bool HexDump::carrayStyle() const { return mCArrayStyle; } + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_TEXTOUTPUT_H diff --git a/include/utils/TimeUtils.h b/include/utils/TimeUtils.h new file mode 100644 index 0000000..b19e021 --- /dev/null +++ b/include/utils/TimeUtils.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TIME_H +#define ANDROID_TIME_H + +#include <time.h> +#include <cutils/tztime.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/time.h> +#include <utils/String8.h> +#include <utils/String16.h> + +namespace android { + +/* + * This class is the core implementation of the android.util.Time java + * class. It doesn't implement some of the methods that are implemented + * in Java. They could be done here, but it's not expected that this class + * will be used. If that assumption is incorrect, feel free to update this + * file. The reason to do it here is to not mix the implementation of this + * class and the jni glue code. + */ +class Time +{ +public: + struct tm t; + + // this object doesn't own this string + const char *timezone; + + enum { + SEC = 1, + MIN = 2, + HOUR = 3, + MDAY = 4, + MON = 5, + YEAR = 6, + WDAY = 7, + YDAY = 8 + }; + + static int compare(Time& a, Time& b); + + Time(); + + void switchTimezone(const char *timezone); + String8 format(const char *format, const struct strftime_locale *locale) const; + void format2445(short* buf, bool hasTime) const; + String8 toString() const; + void setToNow(); + int64_t toMillis(bool ignoreDst); + void set(int64_t millis); + + inline void set(int sec, int min, int hour, int mday, int mon, int year, + int isdst) + { + this->t.tm_sec = sec; + this->t.tm_min = min; + this->t.tm_hour = hour; + this->t.tm_mday = mday; + this->t.tm_mon = mon; + this->t.tm_year = year; + this->t.tm_isdst = isdst; +#ifdef HAVE_TM_GMTOFF + this->t.tm_gmtoff = 0; +#endif + this->t.tm_wday = 0; + this->t.tm_yday = 0; + } +}; + +}; // namespace android + +#endif // ANDROID_TIME_H diff --git a/include/utils/TimerProbe.h b/include/utils/TimerProbe.h new file mode 100644 index 0000000..f2e32b2 --- /dev/null +++ b/include/utils/TimerProbe.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TIMER_PROBE_H +#define ANDROID_TIMER_PROBE_H + +#if 0 && defined(HAVE_POSIX_CLOCKS) +#define ENABLE_TIMER_PROBE 1 +#else +#define ENABLE_TIMER_PROBE 0 +#endif + +#if ENABLE_TIMER_PROBE + +#include <time.h> +#include <sys/time.h> +#include <utils/Vector.h> + +#define TIMER_PROBE(tag) \ + static int _timer_slot_; \ + android::TimerProbe probe(tag, &_timer_slot_) +#define TIMER_PROBE_END() probe.end() +#else +#define TIMER_PROBE(tag) +#define TIMER_PROBE_END() +#endif + +#if ENABLE_TIMER_PROBE +namespace android { + +class TimerProbe { +public: + TimerProbe(const char tag[], int* slot); + void end(); + ~TimerProbe(); +private: + struct Bucket { + int mStart, mReal, mProcess, mThread, mCount; + const char* mTag; + int* mSlotPtr; + int mIndent; + }; + static Vector<Bucket> gBuckets; + static TimerProbe* gExecuteChain; + static int gIndent; + static timespec gRealBase; + TimerProbe* mNext; + static uint32_t ElapsedTime(const timespec& start, const timespec& end); + void print(const timespec& r, const timespec& p, const timespec& t) const; + timespec mRealStart, mPStart, mTStart; + const char* mTag; + int mIndent; + int mBucket; +}; + +}; // namespace android + +#endif +#endif diff --git a/include/utils/Timers.h b/include/utils/Timers.h new file mode 100644 index 0000000..9610399 --- /dev/null +++ b/include/utils/Timers.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Timer functions. +// +#ifndef _LIBS_UTILS_TIMERS_H +#define _LIBS_UTILS_TIMERS_H + +#include <stdint.h> +#include <sys/types.h> +#include <sys/time.h> + +// ------------------------------------------------------------------ +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int64_t nsecs_t; // nano-seconds + +static inline nsecs_t seconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000000; +} + +static inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000; +} + +static inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000; +} + +static inline nsecs_t nanoseconds_to_seconds(nsecs_t secs) +{ + return secs/1000000000; +} + +static inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs) +{ + return secs/1000000; +} + +static inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs) +{ + return secs/1000; +} + +static inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);} +static inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);} +static inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);} +static inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);} +static inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);} +static inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);} + +static inline nsecs_t seconds(nsecs_t v) { return s2ns(v); } +static inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); } +static inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); } + +enum { + SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock + SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point + SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock + SYSTEM_TIME_THREAD = 3 // high-resolution per-thread clock +}; + +// return the system-time according to the specified clock +#ifdef __cplusplus +nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC); +#else +nsecs_t systemTime(int clock); +#endif // def __cplusplus + +// return the system-time according to the specified clock +int sleepForInterval(long interval, struct timeval* pNextTick); + +#ifdef __cplusplus +} // extern "C" +#endif + +// ------------------------------------------------------------------ +// C++ API + +#ifdef __cplusplus + +namespace android { +/* + * Time the duration of something. + * + * Includes some timeval manipulation functions. + */ +class DurationTimer { +public: + DurationTimer(void) {} + ~DurationTimer(void) {} + + // Start the timer. + void start(void); + // Stop the timer. + void stop(void); + // Get the duration in microseconds. + long long durationUsecs(void) const; + + // Subtract two timevals. Returns the difference (ptv1-ptv2) in + // microseconds. + static long long subtractTimevals(const struct timeval* ptv1, + const struct timeval* ptv2); + + // Add the specified amount of time to the timeval. + static void addToTimeval(struct timeval* ptv, long usec); + +private: + struct timeval mStartWhen; + struct timeval mStopWhen; +}; + +}; // android +#endif // def __cplusplus + +#endif // _LIBS_UTILS_TIMERS_H diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h new file mode 100644 index 0000000..c04c37f --- /dev/null +++ b/include/utils/TypeHelpers.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TYPE_HELPERS_H +#define ANDROID_TYPE_HELPERS_H + +#include <new> +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + +// --------------------------------------------------------------------------- + +namespace android { + +/* + * Types traits + */ + +template <typename T> struct trait_trivial_ctor { enum { value = false }; }; +template <typename T> struct trait_trivial_dtor { enum { value = false }; }; +template <typename T> struct trait_trivial_copy { enum { value = false }; }; +template <typename T> struct trait_trivial_assign{ enum { value = false }; }; + +template <typename T> struct trait_pointer { enum { value = false }; }; +template <typename T> struct trait_pointer<T*> { enum { value = true }; }; + +#define ANDROID_BASIC_TYPES_TRAITS( T ) \ + template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ + template<> struct trait_trivial_assign< T >{ enum { value = true }; }; + +#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ + template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ + template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ + template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ + template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; + +template <typename TYPE> +struct traits { + enum { + is_pointer = trait_pointer<TYPE>::value, + has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value, + has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value, + has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value, + has_trivial_assign = is_pointer || trait_trivial_assign<TYPE>::value + }; +}; + +template <typename T, typename U> +struct aggregate_traits { + enum { + is_pointer = false, + has_trivial_ctor = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor, + has_trivial_dtor = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor, + has_trivial_copy = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy, + has_trivial_assign = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign + }; +}; + +// --------------------------------------------------------------------------- + +/* + * basic types traits + */ + +ANDROID_BASIC_TYPES_TRAITS( void ); +ANDROID_BASIC_TYPES_TRAITS( bool ); +ANDROID_BASIC_TYPES_TRAITS( char ); +ANDROID_BASIC_TYPES_TRAITS( unsigned char ); +ANDROID_BASIC_TYPES_TRAITS( short ); +ANDROID_BASIC_TYPES_TRAITS( unsigned short ); +ANDROID_BASIC_TYPES_TRAITS( int ); +ANDROID_BASIC_TYPES_TRAITS( unsigned int ); +ANDROID_BASIC_TYPES_TRAITS( long ); +ANDROID_BASIC_TYPES_TRAITS( unsigned long ); +ANDROID_BASIC_TYPES_TRAITS( long long ); +ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); +ANDROID_BASIC_TYPES_TRAITS( float ); +ANDROID_BASIC_TYPES_TRAITS( double ); + +// --------------------------------------------------------------------------- + + +/* + * compare and order types + */ + +template<typename TYPE> inline +int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { + return (lhs < rhs) ? 1 : 0; +} + +template<typename TYPE> inline +int compare_type(const TYPE& lhs, const TYPE& rhs) { + return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); +} + +/* + * create, destroy, copy and assign types... + */ + +template<typename TYPE> inline +void construct_type(TYPE* p, size_t n) { + if (!traits<TYPE>::has_trivial_ctor) { + while (n--) { + new(p++) TYPE; + } + } +} + +template<typename TYPE> inline +void destroy_type(TYPE* p, size_t n) { + if (!traits<TYPE>::has_trivial_dtor) { + while (n--) { + p->~TYPE(); + p++; + } + } +} + +template<typename TYPE> inline +void copy_type(TYPE* d, const TYPE* s, size_t n) { + if (!traits<TYPE>::has_trivial_copy) { + while (n--) { + new(d) TYPE(*s); + d++, s++; + } + } else { + memcpy(d,s,n*sizeof(TYPE)); + } +} + +template<typename TYPE> inline +void assign_type(TYPE* d, const TYPE* s, size_t n) { + if (!traits<TYPE>::has_trivial_assign) { + while (n--) { + *d++ = *s++; + } + } else { + memcpy(d,s,n*sizeof(TYPE)); + } +} + +template<typename TYPE> inline +void splat_type(TYPE* where, const TYPE* what, size_t n) { + if (!traits<TYPE>::has_trivial_copy) { + while (n--) { + new(where) TYPE(*what); + where++; + } + } else { + while (n--) { + *where++ = *what; + } + } +} + +template<typename TYPE> inline +void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { + if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { + d += n; + s += n; + while (n--) { + --d, --s; + if (!traits<TYPE>::has_trivial_copy) { + new(d) TYPE(*s); + } else { + *d = *s; + } + if (!traits<TYPE>::has_trivial_dtor) { + s->~TYPE(); + } + } + } else { + memmove(d,s,n*sizeof(TYPE)); + } +} + +template<typename TYPE> inline +void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { + if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { + while (n--) { + if (!traits<TYPE>::has_trivial_copy) { + new(d) TYPE(*s); + } else { + *d = *s; + } + if (!traits<TYPE>::has_trivial_dtor) { + s->~TYPE(); + } + d++, s++; + } + } else { + memmove(d,s,n*sizeof(TYPE)); + } +} +// --------------------------------------------------------------------------- + +/* + * a key/value pair + */ + +template <typename KEY, typename VALUE> +struct key_value_pair_t { + KEY key; + VALUE value; + key_value_pair_t() { } + key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } + key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } + key_value_pair_t(const KEY& k) : key(k) { } + inline bool operator < (const key_value_pair_t& o) const { + return strictly_order_type(key, o.key); + } +}; + +template<> +template <typename K, typename V> +struct trait_trivial_ctor< key_value_pair_t<K, V> > +{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; }; +template<> +template <typename K, typename V> +struct trait_trivial_dtor< key_value_pair_t<K, V> > +{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; }; +template<> +template <typename K, typename V> +struct trait_trivial_copy< key_value_pair_t<K, V> > +{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; }; +template<> +template <typename K, typename V> +struct trait_trivial_assign< key_value_pair_t<K, V> > +{ enum { value = aggregate_traits<K,V>::has_trivial_assign};}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_TYPE_HELPERS_H diff --git a/include/utils/Vector.h b/include/utils/Vector.h new file mode 100644 index 0000000..be365d8 --- /dev/null +++ b/include/utils/Vector.h @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VECTOR_H +#define ANDROID_VECTOR_H + +#include <new> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Log.h> +#include <utils/VectorImpl.h> +#include <utils/TypeHelpers.h> + +// --------------------------------------------------------------------------- + +namespace android { + +/*! + * The main templated vector class ensuring type safety + * while making use of VectorImpl. + * This is the class users want to use. + */ + +template <class TYPE> +class Vector : private VectorImpl +{ +public: + typedef TYPE value_type; + + /*! + * Constructors and destructors + */ + + Vector(); + Vector(const Vector<TYPE>& rhs); + virtual ~Vector(); + + /*! copy operator */ + const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const; + Vector<TYPE>& operator = (const Vector<TYPE>& rhs); + + /* + * empty the vector + */ + + inline void clear() { VectorImpl::clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return VectorImpl::size(); } + //! returns wether or not the vector is empty + inline bool isEmpty() const { return VectorImpl::isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return VectorImpl::capacity(); } + //! setst the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } + + /*! + * C-style array access + */ + + //! read-only C-style access + inline const TYPE* array() const; + //! read-write C-style access + TYPE* editArray(); + + /*! + * accessors + */ + + //! read-only access to an item at a given index + inline const TYPE& operator [] (size_t index) const; + //! alternate name for operator [] + inline const TYPE& itemAt(size_t index) const; + //! stack-usage of the vector. returns the top of the stack (last element) + const TYPE& top() const; + //! same as operator [], but allows to access the vector backward (from the end) with a negative index + const TYPE& mirrorItemAt(ssize_t index) const; + + /*! + * modifing the array + */ + + //! copy-on write support, grants write access to an item + TYPE& editItemAt(size_t index); + //! grants right acces to the top of the stack (last element) + TYPE& editTop(); + + /*! + * append/insert another vector + */ + + //! insert another vector at a given index + ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index); + + //! append another vector at the end of this one + ssize_t appendVector(const Vector<TYPE>& vector); + + + /*! + * add/insert/replace items + */ + + //! insert one or several items initialized with their default constructor + inline ssize_t insertAt(size_t index, size_t numItems = 1); + //! insert on onr several items initialized from a prototype item + ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1); + //! pop the top of the stack (removes the last element). No-op if the stack's empty + inline void pop(); + //! pushes an item initialized with its default constructor + inline void push(); + //! pushes an item on the top of the stack + void push(const TYPE& item); + //! same as push() but returns the index the item was added at (or an error) + inline ssize_t add(); + //! same as push() but returns the index the item was added at (or an error) + ssize_t add(const TYPE& item); + //! replace an item with a new one initialized with its default constructor + inline ssize_t replaceAt(size_t index); + //! replace an item with a new one + ssize_t replaceAt(const TYPE& item, size_t index); + + /*! + * remove items + */ + + //! remove several items + inline ssize_t removeItemsAt(size_t index, size_t count = 1); + //! remove one item + inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } + + /*! + * sort (stable) the array + */ + + typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs); + typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state); + + inline status_t sort(compar_t cmp); + inline status_t sort(compar_r_t cmp, void* state); + +protected: + virtual void do_construct(void* storage, size_t num) const; + virtual void do_destroy(void* storage, size_t num) const; + virtual void do_copy(void* dest, const void* from, size_t num) const; + virtual void do_splat(void* dest, const void* item, size_t num) const; + virtual void do_move_forward(void* dest, const void* from, size_t num) const; + virtual void do_move_backward(void* dest, const void* from, size_t num) const; +}; + + +// --------------------------------------------------------------------------- +// No user serviceable parts from here... +// --------------------------------------------------------------------------- + +template<class TYPE> inline +Vector<TYPE>::Vector() + : VectorImpl(sizeof(TYPE), + ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) + |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) + |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) + |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + ) +{ +} + +template<class TYPE> inline +Vector<TYPE>::Vector(const Vector<TYPE>& rhs) + : VectorImpl(rhs) { +} + +template<class TYPE> inline +Vector<TYPE>::~Vector() { + finish_vector(); +} + +template<class TYPE> inline +Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) { + VectorImpl::operator = (rhs); + return *this; +} + +template<class TYPE> inline +const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const { + VectorImpl::operator = (rhs); + return *this; +} + +template<class TYPE> inline +const TYPE* Vector<TYPE>::array() const { + return static_cast<const TYPE *>(arrayImpl()); +} + +template<class TYPE> inline +TYPE* Vector<TYPE>::editArray() { + return static_cast<TYPE *>(editArrayImpl()); +} + + +template<class TYPE> inline +const TYPE& Vector<TYPE>::operator[](size_t index) const { + LOG_FATAL_IF( index>=size(), + "itemAt: index %d is past size %d", (int)index, (int)size() ); + return *(array() + index); +} + +template<class TYPE> inline +const TYPE& Vector<TYPE>::itemAt(size_t index) const { + return operator[](index); +} + +template<class TYPE> inline +const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const { + LOG_FATAL_IF( (index>0 ? index : -index)>=size(), + "mirrorItemAt: index %d is past size %d", + (int)index, (int)size() ); + return *(array() + ((index<0) ? (size()-index) : index)); +} + +template<class TYPE> inline +const TYPE& Vector<TYPE>::top() const { + return *(array() + size() - 1); +} + +template<class TYPE> inline +TYPE& Vector<TYPE>::editItemAt(size_t index) { + return *( static_cast<TYPE *>(editItemLocation(index)) ); +} + +template<class TYPE> inline +TYPE& Vector<TYPE>::editTop() { + return *( static_cast<TYPE *>(editItemLocation(size()-1)) ); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) { + return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) { + return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector)); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) { + return VectorImpl::insertAt(&item, index, numItems); +} + +template<class TYPE> inline +void Vector<TYPE>::push(const TYPE& item) { + return VectorImpl::push(&item); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::add(const TYPE& item) { + return VectorImpl::add(&item); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) { + return VectorImpl::replaceAt(&item, index); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) { + return VectorImpl::insertAt(index, numItems); +} + +template<class TYPE> inline +void Vector<TYPE>::pop() { + VectorImpl::pop(); +} + +template<class TYPE> inline +void Vector<TYPE>::push() { + VectorImpl::push(); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::add() { + return VectorImpl::add(); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::replaceAt(size_t index) { + return VectorImpl::replaceAt(index); +} + +template<class TYPE> inline +ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) { + return VectorImpl::removeItemsAt(index, count); +} + +template<class TYPE> inline +status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) { + return VectorImpl::sort((VectorImpl::compar_t)cmp); +} + +template<class TYPE> inline +status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) { + return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state); +} + +// --------------------------------------------------------------------------- + +template<class TYPE> +void Vector<TYPE>::do_construct(void* storage, size_t num) const { + construct_type( reinterpret_cast<TYPE*>(storage), num ); +} + +template<class TYPE> +void Vector<TYPE>::do_destroy(void* storage, size_t num) const { + destroy_type( reinterpret_cast<TYPE*>(storage), num ); +} + +template<class TYPE> +void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const { + copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +template<class TYPE> +void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const { + splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); +} + +template<class TYPE> +void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { + move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +template<class TYPE> +void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { + move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); +} + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_H diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h new file mode 100644 index 0000000..2525229 --- /dev/null +++ b/include/utils/VectorImpl.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VECTOR_IMPL_H +#define ANDROID_VECTOR_IMPL_H + +#include <assert.h> +#include <stdint.h> +#include <sys/types.h> +#include <utils/Errors.h> + +// --------------------------------------------------------------------------- +// No user serviceable parts in here... +// --------------------------------------------------------------------------- + +namespace android { + +/*! + * Implementation of the guts of the vector<> class + * this ensures backward binary compatibility and + * reduces code size. + * For performance reasons, we expose mStorage and mCount + * so these fields are set in stone. + * + */ + +class VectorImpl +{ +public: + enum { // flags passed to the ctor + HAS_TRIVIAL_CTOR = 0x00000001, + HAS_TRIVIAL_DTOR = 0x00000002, + HAS_TRIVIAL_COPY = 0x00000004, + HAS_TRIVIAL_ASSIGN = 0x00000008 + }; + + VectorImpl(size_t itemSize, uint32_t flags); + VectorImpl(const VectorImpl& rhs); + virtual ~VectorImpl(); + + /*! must be called from subclasses destructor */ + void finish_vector(); + + VectorImpl& operator = (const VectorImpl& rhs); + + /*! C-style array access */ + inline const void* arrayImpl() const { return mStorage; } + void* editArrayImpl(); + + /*! vector stats */ + inline size_t size() const { return mCount; } + inline bool isEmpty() const { return mCount == 0; } + size_t capacity() const; + ssize_t setCapacity(size_t size); + + /*! append/insert another vector */ + ssize_t insertVectorAt(const VectorImpl& vector, size_t index); + ssize_t appendVector(const VectorImpl& vector); + + /*! add/insert/replace items */ + ssize_t insertAt(size_t where, size_t numItems = 1); + ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); + void pop(); + void push(); + void push(const void* item); + ssize_t add(); + ssize_t add(const void* item); + ssize_t replaceAt(size_t index); + ssize_t replaceAt(const void* item, size_t index); + + /*! remove items */ + ssize_t removeItemsAt(size_t index, size_t count = 1); + void clear(); + + const void* itemLocation(size_t index) const; + void* editItemLocation(size_t index); + + typedef int (*compar_t)(const void* lhs, const void* rhs); + typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state); + status_t sort(compar_t cmp); + status_t sort(compar_r_t cmp, void* state); + +protected: + size_t itemSize() const; + void release_storage(); + + virtual void do_construct(void* storage, size_t num) const = 0; + virtual void do_destroy(void* storage, size_t num) const = 0; + virtual void do_copy(void* dest, const void* from, size_t num) const = 0; + virtual void do_splat(void* dest, const void* item, size_t num) const = 0; + virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; + virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; + + // take care of FBC... + virtual void reservedVectorImpl1(); + virtual void reservedVectorImpl2(); + virtual void reservedVectorImpl3(); + virtual void reservedVectorImpl4(); + virtual void reservedVectorImpl5(); + virtual void reservedVectorImpl6(); + virtual void reservedVectorImpl7(); + virtual void reservedVectorImpl8(); + +private: + void* _grow(size_t where, size_t amount); + void _shrink(size_t where, size_t amount); + + inline void _do_construct(void* storage, size_t num) const; + inline void _do_destroy(void* storage, size_t num) const; + inline void _do_copy(void* dest, const void* from, size_t num) const; + inline void _do_splat(void* dest, const void* item, size_t num) const; + inline void _do_move_forward(void* dest, const void* from, size_t num) const; + inline void _do_move_backward(void* dest, const void* from, size_t num) const; + + // These 2 fields are exposed in the inlines below, + // so they're set in stone. + void * mStorage; // base address of the vector + size_t mCount; // number of items + + const uint32_t mFlags; + const size_t mItemSize; +}; + + + +class SortedVectorImpl : public VectorImpl +{ +public: + SortedVectorImpl(size_t itemSize, uint32_t flags); + SortedVectorImpl(const VectorImpl& rhs); + virtual ~SortedVectorImpl(); + + SortedVectorImpl& operator = (const SortedVectorImpl& rhs); + + //! finds the index of an item + ssize_t indexOf(const void* item) const; + + //! finds where this item should be inserted + size_t orderOf(const void* item) const; + + //! add an item in the right place (or replaces it if there is one) + ssize_t add(const void* item); + + //! merges a vector into this one + ssize_t merge(const VectorImpl& vector); + ssize_t merge(const SortedVectorImpl& vector); + + //! removes an item + ssize_t remove(const void* item); + +protected: + virtual int do_compare(const void* lhs, const void* rhs) const = 0; + + // take care of FBC... + virtual void reservedSortedVectorImpl1(); + virtual void reservedSortedVectorImpl2(); + virtual void reservedSortedVectorImpl3(); + virtual void reservedSortedVectorImpl4(); + virtual void reservedSortedVectorImpl5(); + virtual void reservedSortedVectorImpl6(); + virtual void reservedSortedVectorImpl7(); + virtual void reservedSortedVectorImpl8(); + +private: + ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; + + // these are made private, because they can't be used on a SortedVector + // (they don't have an implementation either) + ssize_t add(); + void pop(); + void push(); + void push(const void* item); + ssize_t insertVectorAt(const VectorImpl& vector, size_t index); + ssize_t appendVector(const VectorImpl& vector); + ssize_t insertAt(size_t where, size_t numItems = 1); + ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); + ssize_t replaceAt(size_t index); + ssize_t replaceAt(const void* item, size_t index); +}; + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_IMPL_H diff --git a/include/utils/ZipEntry.h b/include/utils/ZipEntry.h new file mode 100644 index 0000000..e4698df --- /dev/null +++ b/include/utils/ZipEntry.h @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Zip archive entries. +// +// The ZipEntry class is tightly meshed with the ZipFile class. +// +#ifndef __LIBS_ZIPENTRY_H +#define __LIBS_ZIPENTRY_H + +#include "Errors.h" + +#include <stdlib.h> +#include <stdio.h> + +namespace android { + +class ZipFile; + +/* + * ZipEntry objects represent a single entry in a Zip archive. + * + * You can use one of these to get or set information about an entry, but + * there are no functions here for accessing the data itself. (We could + * tuck a pointer to the ZipFile in here for convenience, but that raises + * the likelihood of using ZipEntry objects after discarding the ZipFile.) + * + * File information is stored in two places: next to the file data (the Local + * File Header, and possibly a Data Descriptor), and at the end of the file + * (the Central Directory Entry). The two must be kept in sync. + */ +class ZipEntry { +public: + friend class ZipFile; + + ZipEntry(void) + : mDeleted(false), mMarked(false) + {} + ~ZipEntry(void) {} + + /* + * Returns "true" if the data is compressed. + */ + bool isCompressed(void) const { + return mCDE.mCompressionMethod != kCompressStored; + } + int getCompressionMethod(void) const { return mCDE.mCompressionMethod; } + + /* + * Return the uncompressed length. + */ + off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; } + + /* + * Return the compressed length. For uncompressed data, this returns + * the same thing as getUncompresesdLen(). + */ + off_t getCompressedLen(void) const { return mCDE.mCompressedSize; } + + /* + * Return the absolute file offset of the start of the compressed or + * uncompressed data. + */ + off_t getFileOffset(void) const { + return mCDE.mLocalHeaderRelOffset + + LocalFileHeader::kLFHLen + + mLFH.mFileNameLength + + mLFH.mExtraFieldLength; + } + + /* + * Return the data CRC. + */ + unsigned long getCRC32(void) const { return mCDE.mCRC32; } + + /* + * Return file modification time in UNIX seconds-since-epoch. + */ + time_t getModWhen(void) const; + + /* + * Return the archived file name. + */ + const char* getFileName(void) const { return (const char*) mCDE.mFileName; } + + /* + * Application-defined "mark". Can be useful when synchronizing the + * contents of an archive with contents on disk. + */ + bool getMarked(void) const { return mMarked; } + void setMarked(bool val) { mMarked = val; } + + /* + * Some basic functions for raw data manipulation. "LE" means + * Little Endian. + */ + static inline unsigned short getShortLE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8); + } + static inline unsigned long getLongLE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + } + static inline void putShortLE(unsigned char* buf, short val) { + buf[0] = (unsigned char) val; + buf[1] = (unsigned char) (val >> 8); + } + static inline void putLongLE(unsigned char* buf, long val) { + buf[0] = (unsigned char) val; + buf[1] = (unsigned char) (val >> 8); + buf[2] = (unsigned char) (val >> 16); + buf[3] = (unsigned char) (val >> 24); + } + + /* defined for Zip archives */ + enum { + kCompressStored = 0, // no compression + // shrunk = 1, + // reduced 1 = 2, + // reduced 2 = 3, + // reduced 3 = 4, + // reduced 4 = 5, + // imploded = 6, + // tokenized = 7, + kCompressDeflated = 8, // standard deflate + // Deflate64 = 9, + // lib imploded = 10, + // reserved = 11, + // bzip2 = 12, + }; + + /* + * Deletion flag. If set, the entry will be removed on the next + * call to "flush". + */ + bool getDeleted(void) const { return mDeleted; } + +protected: + /* + * Initialize the structure from the file, which is pointing at + * our Central Directory entry. + */ + status_t initFromCDE(FILE* fp); + + /* + * Initialize the structure for a new file. We need the filename + * and comment so that we can properly size the LFH area. The + * filename is mandatory, the comment is optional. + */ + void initNew(const char* fileName, const char* comment); + + /* + * Initialize the structure with the contents of a ZipEntry from + * another file. + */ + status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry); + + /* + * Add some pad bytes to the LFH. We do this by adding or resizing + * the "extra" field. + */ + status_t addPadding(int padding); + + /* + * Set information about the data for this entry. + */ + void setDataInfo(long uncompLen, long compLen, unsigned long crc32, + int compressionMethod); + + /* + * Set the modification date. + */ + void setModWhen(time_t when); + + /* + * Return the offset of the local file header. + */ + off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; } + + /* + * Set the offset of the local file header, relative to the start of + * the current file. + */ + void setLFHOffset(off_t offset) { + mCDE.mLocalHeaderRelOffset = (long) offset; + } + + /* mark for deletion; used by ZipFile::remove() */ + void setDeleted(void) { mDeleted = true; } + +private: + /* these are private and not defined */ + ZipEntry(const ZipEntry& src); + ZipEntry& operator=(const ZipEntry& src); + + /* returns "true" if the CDE and the LFH agree */ + bool compareHeaders(void) const; + void copyCDEtoLFH(void); + + bool mDeleted; // set if entry is pending deletion + bool mMarked; // app-defined marker + + /* + * Every entry in the Zip archive starts off with one of these. + */ + class LocalFileHeader { + public: + LocalFileHeader(void) : + mVersionToExtract(0), + mGPBitFlag(0), + mCompressionMethod(0), + mLastModFileTime(0), + mLastModFileDate(0), + mCRC32(0), + mCompressedSize(0), + mUncompressedSize(0), + mFileNameLength(0), + mExtraFieldLength(0), + mFileName(NULL), + mExtraField(NULL) + {} + virtual ~LocalFileHeader(void) { + delete[] mFileName; + delete[] mExtraField; + } + + status_t read(FILE* fp); + status_t write(FILE* fp); + + // unsigned long mSignature; + unsigned short mVersionToExtract; + unsigned short mGPBitFlag; + unsigned short mCompressionMethod; + unsigned short mLastModFileTime; + unsigned short mLastModFileDate; + unsigned long mCRC32; + unsigned long mCompressedSize; + unsigned long mUncompressedSize; + unsigned short mFileNameLength; + unsigned short mExtraFieldLength; + unsigned char* mFileName; + unsigned char* mExtraField; + + enum { + kSignature = 0x04034b50, + kLFHLen = 30, // LocalFileHdr len, excl. var fields + }; + + void dump(void) const; + }; + + /* + * Every entry in the Zip archive has one of these in the "central + * directory" at the end of the file. + */ + class CentralDirEntry { + public: + CentralDirEntry(void) : + mVersionMadeBy(0), + mVersionToExtract(0), + mGPBitFlag(0), + mCompressionMethod(0), + mLastModFileTime(0), + mLastModFileDate(0), + mCRC32(0), + mCompressedSize(0), + mUncompressedSize(0), + mFileNameLength(0), + mExtraFieldLength(0), + mFileCommentLength(0), + mDiskNumberStart(0), + mInternalAttrs(0), + mExternalAttrs(0), + mLocalHeaderRelOffset(0), + mFileName(NULL), + mExtraField(NULL), + mFileComment(NULL) + {} + virtual ~CentralDirEntry(void) { + delete[] mFileName; + delete[] mExtraField; + delete[] mFileComment; + } + + status_t read(FILE* fp); + status_t write(FILE* fp); + + // unsigned long mSignature; + unsigned short mVersionMadeBy; + unsigned short mVersionToExtract; + unsigned short mGPBitFlag; + unsigned short mCompressionMethod; + unsigned short mLastModFileTime; + unsigned short mLastModFileDate; + unsigned long mCRC32; + unsigned long mCompressedSize; + unsigned long mUncompressedSize; + unsigned short mFileNameLength; + unsigned short mExtraFieldLength; + unsigned short mFileCommentLength; + unsigned short mDiskNumberStart; + unsigned short mInternalAttrs; + unsigned long mExternalAttrs; + unsigned long mLocalHeaderRelOffset; + unsigned char* mFileName; + unsigned char* mExtraField; + unsigned char* mFileComment; + + void dump(void) const; + + enum { + kSignature = 0x02014b50, + kCDELen = 46, // CentralDirEnt len, excl. var fields + }; + }; + + enum { + //kDataDescriptorSignature = 0x08074b50, // currently unused + kDataDescriptorLen = 16, // four 32-bit fields + + kDefaultVersion = 20, // need deflate, nothing much else + kDefaultMadeBy = 0x0317, // 03=UNIX, 17=spec v2.3 + kUsesDataDescr = 0x0008, // GPBitFlag bit 3 + }; + + LocalFileHeader mLFH; + CentralDirEntry mCDE; +}; + +}; // namespace android + +#endif // __LIBS_ZIPENTRY_H diff --git a/include/utils/ZipFile.h b/include/utils/ZipFile.h new file mode 100644 index 0000000..44df5bb --- /dev/null +++ b/include/utils/ZipFile.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// General-purpose Zip archive access. This class allows both reading and +// writing to Zip archives, including deletion of existing entries. +// +#ifndef __LIBS_ZIPFILE_H +#define __LIBS_ZIPFILE_H + +#include "ZipEntry.h" +#include "Vector.h" +#include "Errors.h" +#include <stdio.h> + +namespace android { + +/* + * Manipulate a Zip archive. + * + * Some changes will not be visible in the until until "flush" is called. + * + * The correct way to update a file archive is to make all changes to a + * copy of the archive in a temporary file, and then unlink/rename over + * the original after everything completes. Because we're only interested + * in using this for packaging, we don't worry about such things. Crashing + * after making changes and before flush() completes could leave us with + * an unusable Zip archive. + */ +class ZipFile { +public: + ZipFile(void) + : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false) + {} + ~ZipFile(void) { + if (!mReadOnly) + flush(); + if (mZipFp != NULL) + fclose(mZipFp); + discardEntries(); + } + + /* + * Open a new or existing archive. + */ + typedef enum { + kOpenReadOnly = 0x01, + kOpenReadWrite = 0x02, + kOpenCreate = 0x04, // create if it doesn't exist + kOpenTruncate = 0x08, // if it exists, empty it + }; + status_t open(const char* zipFileName, int flags); + + /* + * Add a file to the end of the archive. Specify whether you want the + * library to try to store it compressed. + * + * If "storageName" is specified, the archive will use that instead + * of "fileName". + * + * If there is already an entry with the same name, the call fails. + * Existing entries with the same name must be removed first. + * + * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. + */ + status_t add(const char* fileName, int compressionMethod, + ZipEntry** ppEntry) + { + return add(fileName, fileName, compressionMethod, ppEntry); + } + status_t add(const char* fileName, const char* storageName, + int compressionMethod, ZipEntry** ppEntry) + { + return addCommon(fileName, NULL, 0, storageName, + ZipEntry::kCompressStored, + compressionMethod, ppEntry); + } + + /* + * Add a file that is already compressed with gzip. + * + * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. + */ + status_t addGzip(const char* fileName, const char* storageName, + ZipEntry** ppEntry) + { + return addCommon(fileName, NULL, 0, storageName, + ZipEntry::kCompressDeflated, + ZipEntry::kCompressDeflated, ppEntry); + } + + /* + * Add a file from an in-memory data buffer. + * + * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. + */ + status_t add(const void* data, size_t size, const char* storageName, + int compressionMethod, ZipEntry** ppEntry) + { + return addCommon(NULL, data, size, storageName, + ZipEntry::kCompressStored, + compressionMethod, ppEntry); + } + + /* + * Add an entry by copying it from another zip file. If "padding" is + * nonzero, the specified number of bytes will be added to the "extra" + * field in the header. + * + * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. + */ + status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, + int padding, ZipEntry** ppEntry); + + /* + * Mark an entry as having been removed. It is not actually deleted + * from the archive or our internal data structures until flush() is + * called. + */ + status_t remove(ZipEntry* pEntry); + + /* + * Flush changes. If mNeedCDRewrite is set, this writes the central dir. + */ + status_t flush(void); + + /* + * Expand the data into the buffer provided. The buffer must hold + * at least <uncompressed len> bytes. Variation expands directly + * to a file. + * + * Returns "false" if an error was encountered in the compressed data. + */ + //bool uncompress(const ZipEntry* pEntry, void* buf) const; + //bool uncompress(const ZipEntry* pEntry, FILE* fp) const; + void* uncompress(const ZipEntry* pEntry); + + /* + * Get an entry, by name. Returns NULL if not found. + * + * Does not return entries pending deletion. + */ + ZipEntry* getEntryByName(const char* fileName) const; + + /* + * Get the Nth entry in the archive. + * + * This will return an entry that is pending deletion. + */ + int getNumEntries(void) const { return mEntries.size(); } + ZipEntry* getEntryByIndex(int idx) const; + +private: + /* these are private and not defined */ + ZipFile(const ZipFile& src); + ZipFile& operator=(const ZipFile& src); + + class EndOfCentralDir { + public: + EndOfCentralDir(void) : + mDiskNumber(0), + mDiskWithCentralDir(0), + mNumEntries(0), + mTotalNumEntries(0), + mCentralDirSize(0), + mCentralDirOffset(0), + mCommentLen(0), + mComment(NULL) + {} + virtual ~EndOfCentralDir(void) { + delete[] mComment; + } + + status_t readBuf(const unsigned char* buf, int len); + status_t write(FILE* fp); + + //unsigned long mSignature; + unsigned short mDiskNumber; + unsigned short mDiskWithCentralDir; + unsigned short mNumEntries; + unsigned short mTotalNumEntries; + unsigned long mCentralDirSize; + unsigned long mCentralDirOffset; // offset from first disk + unsigned short mCommentLen; + unsigned char* mComment; + + enum { + kSignature = 0x06054b50, + kEOCDLen = 22, // EndOfCentralDir len, excl. comment + + kMaxCommentLen = 65535, // longest possible in ushort + kMaxEOCDSearch = kMaxCommentLen + EndOfCentralDir::kEOCDLen, + + }; + + void dump(void) const; + }; + + + /* read all entries in the central dir */ + status_t readCentralDir(void); + + /* crunch deleted entries out */ + status_t crunchArchive(void); + + /* clean up mEntries */ + void discardEntries(void); + + /* common handler for all "add" functions */ + status_t addCommon(const char* fileName, const void* data, size_t size, + const char* storageName, int sourceType, int compressionMethod, + ZipEntry** ppEntry); + + /* copy all of "srcFp" into "dstFp" */ + status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32); + /* copy all of "data" into "dstFp" */ + status_t copyDataToFp(FILE* dstFp, + const void* data, size_t size, unsigned long* pCRC32); + /* copy some of "srcFp" into "dstFp" */ + status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length, + unsigned long* pCRC32); + /* like memmove(), but on parts of a single file */ + status_t filemove(FILE* fp, off_t dest, off_t src, size_t n); + /* compress all of "srcFp" into "dstFp", using Deflate */ + status_t compressFpToFp(FILE* dstFp, FILE* srcFp, + const void* data, size_t size, unsigned long* pCRC32); + + /* get modification date from a file descriptor */ + time_t getModTime(int fd); + + /* + * We use stdio FILE*, which gives us buffering but makes dealing + * with files >2GB awkward. Until we support Zip64, we're fine. + */ + FILE* mZipFp; // Zip file pointer + + /* one of these per file */ + EndOfCentralDir mEOCD; + + /* did we open this read-only? */ + bool mReadOnly; + + /* set this when we trash the central dir */ + bool mNeedCDRewrite; + + /* + * One ZipEntry per entry in the zip file. I'm using pointers instead + * of objects because it's easier than making operator= work for the + * classes and sub-classes. + */ + Vector<ZipEntry*> mEntries; +}; + +}; // namespace android + +#endif // __LIBS_ZIPFILE_H diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h new file mode 100644 index 0000000..30e0036 --- /dev/null +++ b/include/utils/ZipFileCRO.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// C API for ead-only access to Zip archives, with minimal heap allocation. +// +#ifndef __LIBS_ZIPFILECRO_H +#define __LIBS_ZIPFILECRO_H + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Trivial typedef to ensure that ZipFileCRO is not treated as a simple integer. + */ +typedef void* ZipFileCRO; + +/* + * Trivial typedef to ensure that ZipEntryCRO is not treated as a simple + * integer. We use NULL to indicate an invalid value. + */ +typedef void* ZipEntryCRO; + +extern ZipFileCRO ZipFileXRO_open(const char* path); + +extern void ZipFileCRO_destroy(ZipFileCRO zip); + +extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip, + const char* fileName); + +extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry, + int* pMethod, long* pUncompLen, + long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32); + +extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd); + +#ifdef __cplusplus +} +#endif + +#endif /*__LIBS_ZIPFILECRO_H*/ diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h new file mode 100644 index 0000000..51c4f2f --- /dev/null +++ b/include/utils/ZipFileRO.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Read-only access to Zip archives, with minimal heap allocation. +// +// This is similar to the more-complete ZipFile class, but no attempt +// has been made to make them interchangeable. This class operates under +// a very different set of assumptions and constraints. +// +#ifndef __LIBS_ZIPFILERO_H +#define __LIBS_ZIPFILERO_H + +#include "Errors.h" +#include "FileMap.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +namespace android { + +/* + * Trivial typedef to ensure that ZipEntryRO is not treated as a simple + * integer. We use NULL to indicate an invalid value. + */ +typedef void* ZipEntryRO; + +/* + * Open a Zip archive for reading. + * + * We want "open" and "find entry by name" to be fast operations, and we + * want to use as little memory as possible. We memory-map the file, + * and load a hash table with pointers to the filenames (which aren't + * null-terminated). The other fields are at a fixed offset from the + * filename, so we don't need to extract those (but we do need to byte-read + * and endian-swap them every time we want them). + * + * To speed comparisons when doing a lookup by name, we could make the mapping + * "private" (copy-on-write) and null-terminate the filenames after verifying + * the record structure. However, this requires a private mapping of + * every page that the Central Directory touches. Easier to tuck a copy + * of the string length into the hash table entry. + */ +class ZipFileRO { +public: + ZipFileRO() + : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL) + {} + ~ZipFileRO() { + free(mHashTable); + if (mFileMap) + mFileMap->release(); + if (mFd >= 0) + close(mFd); + } + + /* + * Open an archive. + */ + status_t open(const char* zipFileName); + + /* + * Find an entry, by name. Returns the entry identifier, or NULL if + * not found. + * + * If two entries have the same name, one will be chosen at semi-random. + */ + ZipEntryRO findEntryByName(const char* fileName) const; + + /* + * Return the #of entries in the Zip archive. + */ + int getNumEntries(void) const { + return mNumEntries; + } + + /* + * Return the Nth entry. Zip file entries are not stored in sorted + * order, and updated entries may appear at the end, so anyone walking + * the archive needs to avoid making ordering assumptions. We take + * that further by returning the Nth non-empty entry in the hash table + * rather than the Nth entry in the archive. + * + * Valid values are [0..numEntries). + * + * [This is currently O(n). If it needs to be fast we can allocate an + * additional data structure or provide an iterator interface.] + */ + ZipEntryRO findEntryByIndex(int idx) const; + + /* + * Copy the filename into the supplied buffer. Returns 0 on success, + * -1 if "entry" is invalid, or the filename length if it didn't fit. The + * length, and the returned string, include the null-termination. + */ + int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const; + + /* + * Get the vital stats for an entry. Pass in NULL pointers for anything + * you don't need. + * + * "*pOffset" holds the Zip file offset of the entry's data. + * + * Returns "false" if "entry" is bogus or if the data in the Zip file + * appears to be bad. + */ + bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen, + long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const; + + /* + * Create a new FileMap object that maps a subset of the archive. For + * an uncompressed entry this effectively provides a pointer to the + * actual data, for a compressed entry this provides the input buffer + * for inflate(). + */ + FileMap* createEntryFileMap(ZipEntryRO entry) const; + + /* + * Uncompress the data into a buffer. Depending on the compression + * format, this is either an "inflate" operation or a memcpy. + * + * Use "uncompLen" from getEntryInfo() to determine the required + * buffer size. + * + * Returns "true" on success. + */ + bool uncompressEntry(ZipEntryRO entry, void* buffer) const; + + /* + * Uncompress the data to an open file descriptor. + */ + bool uncompressEntry(ZipEntryRO entry, int fd) const; + + /* Zip compression methods we support */ + enum { + kCompressStored = 0, // no compression + kCompressDeflated = 8, // standard deflate + }; + + /* + * Utility function: uncompress deflated data, buffer to buffer. + */ + static bool inflateBuffer(void* outBuf, const void* inBuf, + long uncompLen, long compLen); + + /* + * Utility function: uncompress deflated data, buffer to fd. + */ + static bool inflateBuffer(int fd, const void* inBuf, + long uncompLen, long compLen); + + /* + * Some basic functions for raw data manipulation. "LE" means + * Little Endian. + */ + static inline unsigned short get2LE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8); + } + static inline unsigned long get4LE(const unsigned char* buf) { + return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + } + +private: + /* these are private and not defined */ + ZipFileRO(const ZipFileRO& src); + ZipFileRO& operator=(const ZipFileRO& src); + + /* parse the archive, prepping internal structures */ + bool parseZipArchive(void); + + /* add a new entry to the hash table */ + void addToHash(const char* str, int strLen, unsigned int hash); + + /* compute string hash code */ + static unsigned int computeHash(const char* str, int len); + + /* convert a ZipEntryRO back to a hash table index */ + int entryToIndex(const ZipEntryRO entry) const; + + /* + * One entry in the hash table. + */ + typedef struct HashEntry { + const char* name; + unsigned short nameLen; + //unsigned int hash; + } HashEntry; + + /* open Zip archive */ + int mFd; + + /* mapped file */ + FileMap* mFileMap; + + /* number of entries in the Zip archive */ + int mNumEntries; + + /* + * We know how many entries are in the Zip archive, so we have a + * fixed-size hash table. We probe for an empty slot. + */ + int mHashTableSize; + HashEntry* mHashTable; +}; + +}; // namespace android + +#endif /*__LIBS_ZIPFILERO_H*/ diff --git a/include/utils/ZipUtils.h b/include/utils/ZipUtils.h new file mode 100644 index 0000000..42c42b6 --- /dev/null +++ b/include/utils/ZipUtils.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Miscellaneous zip/gzip utility functions. +// +#ifndef __LIBS_ZIPUTILS_H +#define __LIBS_ZIPUTILS_H + +#include <stdio.h> + +namespace android { + +/* + * Container class for utility functions, primarily for namespace reasons. + */ +class ZipUtils { +public: + /* + * General utility function for uncompressing "deflate" data from a file + * to a buffer. + */ + static bool inflateToBuffer(int fd, void* buf, long uncompressedLen, + long compressedLen); + static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen, + long compressedLen); + + /* + * Someday we might want to make this generic and handle bzip2 ".bz2" + * files too. + * + * We could declare gzip to be a sub-class of zip that has exactly + * one always-compressed entry, but we currently want to treat Zip + * and gzip as distinct, so there's no value. + * + * The zlib library has some gzip utilities, but it has no interface + * for extracting the uncompressed length of the file (you do *not* + * want to gzseek to the end). + * + * Pass in a seeked file pointer for the gzip file. If this is a gzip + * file, we set our return values appropriately and return "true" with + * the file seeked to the start of the compressed data. + */ + static bool examineGzip(FILE* fp, int* pCompressionMethod, + long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32); + +private: + ZipUtils() {} + ~ZipUtils() {} +}; + +}; // namespace android + +#endif /*__LIBS_ZIPUTILS_H*/ diff --git a/include/utils/ashmem.h b/include/utils/ashmem.h new file mode 100644 index 0000000..0854775 --- /dev/null +++ b/include/utils/ashmem.h @@ -0,0 +1,41 @@ +/* utils/ashmem.h + ** + ** Copyright 2008 The Android Open Source Project + ** + ** This file is dual licensed. It may be redistributed and/or modified + ** under the terms of the Apache 2.0 License OR version 2 of the GNU + ** General Public License. + */ + +#ifndef _UTILS_ASHMEM_H +#define _UTILS_ASHMEM_H + +#include <linux/limits.h> +#include <linux/ioctl.h> + +#define ASHMEM_NAME_LEN 256 + +#define ASHMEM_NAME_DEF "dev/ashmem" + +/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ +#define ASHMEM_NOT_REAPED 0 +#define ASHMEM_WAS_REAPED 1 + +/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */ +#define ASHMEM_NOW_UNPINNED 0 +#define ASHMEM_NOW_PINNED 1 + +#define __ASHMEMIOC 0x77 + +#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) +#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) +#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) +#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) +#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) +#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) +#define ASHMEM_PIN _IO(__ASHMEMIOC, 7) +#define ASHMEM_UNPIN _IO(__ASHMEMIOC, 8) +#define ASHMEM_ISPINNED _IO(__ASHMEMIOC, 9) +#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) + +#endif /* _UTILS_ASHMEM_H */ diff --git a/include/utils/executablepath.h b/include/utils/executablepath.h new file mode 100644 index 0000000..c979432 --- /dev/null +++ b/include/utils/executablepath.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UTILS_EXECUTABLEPATH_H +#define _UTILS_EXECUTABLEPATH_H + +#include <limits.h> + +// returns the path to this executable +#if __cplusplus +extern "C" +#endif +void executablepath(char s[PATH_MAX]); + +#endif // _UTILS_EXECUTABLEPATH_H diff --git a/include/utils/inet_address.h b/include/utils/inet_address.h new file mode 100644 index 0000000..dbd8672 --- /dev/null +++ b/include/utils/inet_address.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Internet address classes. Modeled after Java classes. +// +#ifndef _RUNTIME_INET_ADDRESS_H +#define _RUNTIME_INET_ADDRESS_H + +#ifdef HAVE_ANDROID_OS +#error DO NOT USE THIS FILE IN THE DEVICE BUILD +#endif + + +namespace android { + +/* + * This class holds Internet addresses. Perhaps more useful is its + * ability to look up addresses by name. + * + * Invoke one of the static factory methods to create a new object. + */ +class InetAddress { +public: + virtual ~InetAddress(void); + + // create from w.x.y.z or foo.bar.com notation + static InetAddress* getByName(const char* host); + + // copy-construction + InetAddress(const InetAddress& orig); + + const void* getAddress(void) const { return mAddress; } + int getAddressLength(void) const { return mLength; } + const char* getHostName(void) const { return mName; } + +private: + InetAddress(void); + // assignment (private) + InetAddress& operator=(const InetAddress& addr); + + // use a void* here so we don't have to expose actual socket headers + void* mAddress; // this is really a ptr to sockaddr_in + int mLength; + char* mName; +}; + + +/* + * Base class for socket addresses. + */ +class SocketAddress { +public: + SocketAddress() {} + virtual ~SocketAddress() {} +}; + + +/* + * Internet address class. This combines an InetAddress with a port. + */ +class InetSocketAddress : public SocketAddress { +public: + InetSocketAddress() : + mAddress(0), mPort(-1) + {} + ~InetSocketAddress(void) { + delete mAddress; + } + + // Create an address with a host wildcard (useful for servers). + bool create(int port); + // Create an address with the specified host and port. + bool create(const InetAddress* addr, int port); + // Create an address with the specified host and port. Does the + // hostname lookup. + bool create(const char* host, int port); + + const InetAddress* getAddress(void) const { return mAddress; } + const int getPort(void) const { return mPort; } + const char* getHostName(void) const { return mAddress->getHostName(); } + +private: + InetAddress* mAddress; + int mPort; +}; + +}; // namespace android + +#endif // _RUNTIME_INET_ADDRESS_H diff --git a/include/utils/misc.h b/include/utils/misc.h new file mode 100644 index 0000000..62e84b4 --- /dev/null +++ b/include/utils/misc.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Handy utility functions and portability code. +// +#ifndef _LIBS_UTILS_MISC_H +#define _LIBS_UTILS_MISC_H + +#include <sys/time.h> +#include "utils/Endian.h" + +namespace android { + +/* get #of elements in a static array */ +#ifndef NELEM +# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) +#endif + +/* + * Make a copy of the string, using "new[]" instead of "malloc". Free the + * string with delete[]. + * + * Returns NULL if "str" is NULL. + */ +char* strdupNew(const char* str); + +/* + * Concatenate an argument vector into a single string. If argc is >= 0 + * it will be used; if it's < 0 then the last element in the arg vector + * must be NULL. + * + * This inserts a space between each argument. + * + * This does not automatically add double quotes around arguments with + * spaces in them. This practice is necessary for Win32, because Win32's + * CreateProcess call is stupid. + * + * The caller should delete[] the returned string. + */ +char* concatArgv(int argc, const char* const argv[]); + +/* + * Count up the number of arguments in "argv". The count does not include + * the final NULL entry. + */ +int countArgv(const char* const argv[]); + +/* + * Some utility functions for working with files. These could be made + * part of a "File" class. + */ +typedef enum FileType { + kFileTypeUnknown = 0, + kFileTypeNonexistent, // i.e. ENOENT + kFileTypeRegular, + kFileTypeDirectory, + kFileTypeCharDev, + kFileTypeBlockDev, + kFileTypeFifo, + kFileTypeSymlink, + kFileTypeSocket, +} FileType; +/* get the file's type; follows symlinks */ +FileType getFileType(const char* fileName); +/* get the file's modification date; returns -1 w/errno set on failure */ +time_t getFileModDate(const char* fileName); + +/* + * Round up to the nearest power of 2. Handy for hash tables. + */ +unsigned int roundUpPower2(unsigned int val); + +void strreverse(char* begin, char* end); +void k_itoa(int value, char* str, int base); +char* itoa(int val, int base); + +}; // namespace android + +#endif // _LIBS_UTILS_MISC_H diff --git a/include/utils/ported.h b/include/utils/ported.h new file mode 100644 index 0000000..eb3be01 --- /dev/null +++ b/include/utils/ported.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Standard functions ported to the current platform. Note these are NOT +// in the "android" namespace. +// +#ifndef _LIBS_UTILS_PORTED_H +#define _LIBS_UTILS_PORTED_H + +#include <sys/time.h> // for timeval + +#ifdef __cplusplus +extern "C" { +#endif + +/* library replacement functions */ +#if defined(NEED_GETTIMEOFDAY) +int gettimeofday(struct timeval* tv, struct timezone* tz); +#endif +#if defined(NEED_USLEEP) +void usleep(unsigned long usec); +#endif +#if defined(NEED_PIPE) +int pipe(int filedes[2]); +#endif +#if defined(NEED_SETENV) +int setenv(const char* name, const char* value, int overwrite); +void unsetenv(const char* name); +char* getenv(const char* name); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _LIBS_UTILS_PORTED_H diff --git a/include/utils/string_array.h b/include/utils/string_array.h new file mode 100644 index 0000000..064dda2 --- /dev/null +++ b/include/utils/string_array.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Sortable array of strings. STL-ish, but STL-free. +// +#ifndef _LIBS_UTILS_STRING_ARRAY_H +#define _LIBS_UTILS_STRING_ARRAY_H + +#include <stdlib.h> +#include <string.h> + +namespace android { + +// +// An expanding array of strings. Add, get, sort, delete. +// +class StringArray { +public: + StringArray() + : mMax(0), mCurrent(0), mArray(NULL) + {} + virtual ~StringArray() { + for (int i = 0; i < mCurrent; i++) + delete[] mArray[i]; + delete[] mArray; + } + + // + // Add a string. A copy of the string is made. + // + bool push_back(const char* str) { + if (mCurrent >= mMax) { + char** tmp; + + if (mMax == 0) + mMax = 16; // initial storage + else + mMax *= 2; + + tmp = new char*[mMax]; + if (tmp == NULL) + return false; + + memcpy(tmp, mArray, mCurrent * sizeof(char*)); + delete[] mArray; + mArray = tmp; + } + + int len = strlen(str); + mArray[mCurrent] = new char[len+1]; + memcpy(mArray[mCurrent], str, len+1); + mCurrent++; + + return true; + } + + // + // Delete an entry. + // + void erase(int idx) { + if (idx < 0 || idx >= mCurrent) + return; + delete[] mArray[idx]; + if (idx < mCurrent-1) { + memmove(&mArray[idx], &mArray[idx+1], + (mCurrent-1 - idx) * sizeof(char*)); + } + mCurrent--; + } + + // + // Sort the array. + // + void sort(int (*compare)(const void*, const void*)) { + qsort(mArray, mCurrent, sizeof(char*), compare); + } + + // + // Pass this to the sort routine to do an ascending alphabetical sort. + // + static int cmpAscendingAlpha(const void* pstr1, const void* pstr2) { + return strcmp(*(const char**)pstr1, *(const char**)pstr2); + } + + // + // Get the #of items in the array. + // + inline int size(void) const { return mCurrent; } + + // + // Return entry N. + // [should use operator[] here] + // + const char* getEntry(int idx) const { + if (idx < 0 || idx >= mCurrent) + return NULL; + return mArray[idx]; + } + + // + // Set entry N to specified string. + // [should use operator[] here] + // + void setEntry(int idx, const char* str) { + if (idx < 0 || idx >= mCurrent) + return; + delete[] mArray[idx]; + int len = strlen(str); + mArray[idx] = new char[len+1]; + memcpy(mArray[idx], str, len+1); + } + +private: + int mMax; + int mCurrent; + char** mArray; +}; + +}; // namespace android + +#endif // _LIBS_UTILS_STRING_ARRAY_H diff --git a/include/utils/threads.h b/include/utils/threads.h new file mode 100644 index 0000000..7dca810 --- /dev/null +++ b/include/utils/threads.h @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_THREADS_H +#define _LIBS_UTILS_THREADS_H + +#include <stdint.h> +#include <sys/types.h> +#include <time.h> + +// ------------------------------------------------------------------ +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* android_thread_id_t; + +typedef int (*android_thread_func_t)(void*); + +enum { + /* + * *********************************************** + * ** Keep in sync with android.os.Process.java ** + * *********************************************** + * + * This maps directly to the "nice" priorites we use in Android. + * A thread priority should be chosen inverse-proportinally to + * the amount of work the thread is expected to do. The more work + * a thread will do, the less favorable priority it should get so that + * it doesn't starve the system. Threads not behaving properly might + * be "punished" by the kernel. + * Use the levels below when appropriate. Intermediate values are + * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below. + */ + ANDROID_PRIORITY_LOWEST = 19, + + /* use for background tasks */ + ANDROID_PRIORITY_BACKGROUND = 10, + + /* most threads run at normal priority */ + ANDROID_PRIORITY_NORMAL = 0, + + /* threads currently running a UI that the user is interacting with */ + ANDROID_PRIORITY_FOREGROUND = -2, + + /* the main UI thread has a slightly more favorable priority */ + ANDROID_PRIORITY_DISPLAY = -4, + + /* ui service treads might want to run at a urgent display (uncommon) */ + ANDROID_PRIORITY_URGENT_DISPLAY = -8, + + /* all normal audio threads */ + ANDROID_PRIORITY_AUDIO = -16, + + /* service audio threads (uncommon) */ + ANDROID_PRIORITY_URGENT_AUDIO = -19, + + /* should never be used in practice. regular process might not + * be allowed to use this level */ + ANDROID_PRIORITY_HIGHEST = -20, + + ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, + ANDROID_PRIORITY_MORE_FAVORABLE = -1, + ANDROID_PRIORITY_LESS_FAVORABLE = +1, +}; + +// Create and run a new thread. +extern int androidCreateThread(android_thread_func_t, void *); + +// Create thread with lots of parameters +extern int androidCreateThreadEtc(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +// Get some sort of unique identifier for the current thread. +extern android_thread_id_t androidGetThreadId(); + +// Low-level thread creation -- never creates threads that can +// interact with the Java VM. +extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +// Used by the Java Runtime to control how threads are created, so that +// they can be proper and lovely Java threads. +typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +extern void androidSetCreateThreadFunc(android_create_thread_fn func); + +#ifdef __cplusplus +} +#endif + +// ------------------------------------------------------------------ +// C++ API + +#ifdef __cplusplus + +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/Timers.h> + +namespace android { + +typedef android_thread_id_t thread_id_t; + +typedef android_thread_func_t thread_func_t; + +enum { + PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, + PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, + PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, + PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, + PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, + PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, + PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, + PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, + PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, + PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, + PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, + PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, +}; + +// Create and run a new thread. +inline bool createThread(thread_func_t f, void *a) { + return androidCreateThread(f, a) ? true : false; +} + +// Create thread with lots of parameters +inline bool createThreadEtc(thread_func_t entryFunction, + void *userData, + const char* threadName = "android:unnamed_thread", + int32_t threadPriority = PRIORITY_DEFAULT, + size_t threadStackSize = 0, + thread_id_t *threadId = 0) +{ + return androidCreateThreadEtc(entryFunction, userData, threadName, + threadPriority, threadStackSize, threadId) ? true : false; +} + +// Get some sort of unique identifier for the current thread. +inline thread_id_t getThreadId() { + return androidGetThreadId(); +} + +/* + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class Mutex { +public: + Mutex(); + Mutex(const char* name); + ~Mutex(); + + // lock or unlock the mutex + status_t lock(); + void unlock(); + + // lock if possible; returns 0 on success, error otherwise + status_t tryLock(); + + // Manages the mutex automatically. It'll be locked when Autolock is + // 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(); } + private: + Mutex* mpMutex; + }; + +private: + friend class Condition; + + // A mutex cannot be copied + Mutex(const Mutex&); + Mutex& operator = (const Mutex&); + void _init(); + + void* mState; +}; + +/* + * Automatic mutex. Declare one of these at the top of a function. + * When the function returns, it will go out of scope, and release the + * mutex. + */ + +typedef Mutex::Autolock AutoMutex; + + +/* + * Condition variable class. The implementation is system-dependent. + * + * Condition variables are paired up with mutexes. Lock the mutex, + * call wait(), then either re-wait() if things aren't quite what you want, + * or unlock the mutex and continue. All threads calling wait() must + * use the same mutex for a given Condition. + */ +class Condition { +public: + Condition(); + ~Condition(); + // Wait on the condition variable. Lock the mutex before calling. + status_t wait(Mutex& mutex); + // Wait on the condition variable until the given time. Lock the mutex + // before calling. + status_t wait(Mutex& mutex, nsecs_t abstime); + // same with relative timeout + status_t waitRelative(Mutex& mutex, nsecs_t reltime); + // Signal the condition variable, allowing one thread to continue. + void signal(); + // Signal the condition variable, allowing all threads to continue. + void broadcast(); + +private: + void* mState; +}; + + +/* + * Read/write lock. The resource can have multiple readers or one writer, + * but can't be read and written at the same time. + * + * The same thread should not call a lock function while it already has + * a lock. (Should be okay for multiple readers.) + */ +class ReadWriteLock { +public: + ReadWriteLock() + : mNumReaders(0), mNumWriters(0) + {} + ~ReadWriteLock() {} + + void lockForRead(); + bool tryLockForRead(); + void unlockForRead(); + + void lockForWrite(); + bool tryLockForWrite(); + void unlockForWrite(); + +private: + int mNumReaders; + int mNumWriters; + + Mutex mLock; + Condition mReadWaiter; + Condition mWriteWaiter; +#if defined(PRINT_RENDER_TIMES) + DurationTimer mDebugTimer; +#endif +}; + + +/* + * This is our spiffy thread object! + */ + +class Thread : virtual public RefBase +{ +public: + // Create a Thread object, but doesn't create or start the associated + // thread. See the run() method. + Thread(bool canCallJava = true); + virtual ~Thread(); + + // Start the thread in threadLoop() which needs to be implemented. + virtual status_t run( const char* name = 0, + int32_t priority = PRIORITY_DEFAULT, + size_t stack = 0); + + // Ask this object's thread to exit. This function is asynchronous, when the + // function returns the thread might still be running. Of course, this + // function can be called from a different thread. + virtual void requestExit(); + + // Good place to do one-time initializations + virtual status_t readyToRun(); + + // Call requestExit() and wait until this object's thread exits. + // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call + // this function from this object's thread. Will return WOULD_BLOCK in + // that case. + status_t requestExitAndWait(); + +protected: + // exitPending() returns true if requestExit() has been called. + bool exitPending() const; + +private: + // Derived class must implemtent 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. + // 2) once: if threadLoop() returns false, the thread will exit upon return. + virtual bool threadLoop() = 0; + +private: + Thread& operator=(const Thread&); + static int _threadLoop(void* user); + const bool mCanCallJava; + thread_id_t mThread; + Mutex mLock; + Condition mThreadExitedCondition; + status_t mStatus; + volatile bool mExitPending; + volatile bool mRunning; + sp<Thread> mHoldSelf; +}; + + +}; // namespace android + +#endif // __cplusplus + +#endif // _LIBS_UTILS_THREADS_H |