diff options
Diffstat (limited to 'include')
45 files changed, 1092 insertions, 959 deletions
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h index 3378d97..691ba2f 100644 --- a/include/binder/IPCThreadState.h +++ b/include/binder/IPCThreadState.h @@ -41,6 +41,7 @@ public: int getCallingPid(); int getCallingUid(); + int getOrigCallingUid(); void setStrictModePolicy(int32_t policy); int32_t getStrictModePolicy() const; @@ -116,6 +117,7 @@ private: status_t mLastError; pid_t mCallingPid; uid_t mCallingUid; + uid_t mOrigCallingUid; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; }; diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h index b8fe46d..c47bbfb 100644 --- a/include/drm/DrmManagerClient.h +++ b/include/drm/DrmManagerClient.h @@ -66,19 +66,21 @@ public: * @param[in] fd File descriptor of the protected content to be decrypted * @param[in] offset Start position of the content * @param[in] length The length of the protected content + * @param[in] mime Mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length); + sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length, const char* mime); /** * Open the decrypt session to decrypt the given protected content * * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime Mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(const char* uri); + sp<DecryptHandle> openDecryptSession(const char* uri, const char* mime); /** * Close the decrypt session for the given handle diff --git a/include/gui/SensorChannel.h b/include/gui/BitTube.h index bb54618..76389a0 100644 --- a/include/gui/SensorChannel.h +++ b/include/gui/BitTube.h @@ -28,14 +28,15 @@ namespace android { // ---------------------------------------------------------------------------- class Parcel; -class SensorChannel : public RefBase +class BitTube : public RefBase { public: - SensorChannel(); - SensorChannel(const Parcel& data); - virtual ~SensorChannel(); + BitTube(); + BitTube(const Parcel& data); + virtual ~BitTube(); + status_t initCheck() const; int getFd() const; ssize_t write(void const* vaddr, size_t size); ssize_t read(void* vaddr, size_t size); diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h new file mode 100644 index 0000000..7bca8d6 --- /dev/null +++ b/include/gui/DisplayEventReceiver.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_DISPLAY_EVENT_H +#define ANDROID_GUI_DISPLAY_EVENT_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/Timers.h> + +#include <binder/IInterface.h> + +// ---------------------------------------------------------------------------- + +namespace android { + +// ---------------------------------------------------------------------------- + +class BitTube; +class IDisplayEventConnection; + +// ---------------------------------------------------------------------------- + +class DisplayEventReceiver { +public: + enum { + DISPLAY_EVENT_VSYNC = 'vsyn' + }; + + struct Event { + + struct Header { + uint32_t type; + nsecs_t timestamp; + }; + + struct VSync { + uint32_t count; + }; + + Header header; + union { + VSync vsync; + }; + }; + +public: + /* + * DisplayEventReceiver creates and registers an event connection with + * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate + * or requestNextVsync to receive them. + * Other events start being delivered immediately. + */ + DisplayEventReceiver(); + + /* + * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events + * stop being delivered immediately. Note that the queue could have + * some events pending. These will be delivered. + */ + ~DisplayEventReceiver(); + + /* + * initCheck returns the state of DisplayEventReceiver after construction. + */ + status_t initCheck() const; + + /* + * getFd returns the file descriptor to use to receive events. + * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this + * file-descriptor. + */ + int getFd() const; + + /* + * getEvents reads event from the queue and returns how many events were + * read. Returns 0 if there are no more events or a negative error code. + * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it + * should be destroyed and getEvents() shouldn't be called again. + */ + ssize_t getEvents(Event* events, size_t count); + static ssize_t getEvents(const sp<BitTube>& dataChannel, + Event* events, size_t count); + + /* + * setVsyncRate() sets the Event::VSync delivery rate. A value of + * 1 returns every Event::VSync. A value of 2 returns every other event, + * etc... a value of 0 returns no event unless requestNextVsync() has + * been called. + */ + status_t setVsyncRate(uint32_t count); + + /* + * requestNextVsync() schedules the next Event::VSync. It has no effect + * if the vsync rate is > 0. + */ + status_t requestNextVsync(); + +private: + sp<IDisplayEventConnection> mEventConnection; + sp<BitTube> mDataChannel; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_DISPLAY_EVENT_H diff --git a/include/gui/IDisplayEventConnection.h b/include/gui/IDisplayEventConnection.h new file mode 100644 index 0000000..86247de --- /dev/null +++ b/include/gui/IDisplayEventConnection.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H +#define ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +#include <binder/IInterface.h> + +namespace android { +// ---------------------------------------------------------------------------- + +class BitTube; + +class IDisplayEventConnection : public IInterface +{ +public: + + DECLARE_META_INTERFACE(DisplayEventConnection); + + /* + * getDataChannel() returns a BitTube where to receive the events from + */ + virtual sp<BitTube> getDataChannel() const = 0; + + /* + * setVsyncRate() sets the vsync event delivery rate. A value of + * 1 returns every vsync events. A value of 2 returns every other events, + * etc... a value of 0 returns no event unless requestNextVsync() has + * been called. + */ + virtual void setVsyncRate(uint32_t count) = 0; + + /* + * requestNextVsync() schedules the next vsync event. It has no effect + * if the vsync rate is > 0. + */ + virtual void requestNextVsync() = 0; // asynchronous +}; + +// ---------------------------------------------------------------------------- + +class BnDisplayEventConnection : public BnInterface<IDisplayEventConnection> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h index ed4e4cc..749065e 100644 --- a/include/gui/ISensorEventConnection.h +++ b/include/gui/ISensorEventConnection.h @@ -28,14 +28,14 @@ namespace android { // ---------------------------------------------------------------------------- -class SensorChannel; +class BitTube; class ISensorEventConnection : public IInterface { public: DECLARE_META_INTERFACE(SensorEventConnection); - virtual sp<SensorChannel> getSensorChannel() const = 0; + virtual sp<BitTube> getSensorChannel() const = 0; virtual status_t enableDisable(int handle, bool enabled) = 0; virtual status_t setEventRate(int handle, nsecs_t ns) = 0; }; diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h index 97dd391..ef7c6e3 100644 --- a/include/gui/SensorEventQueue.h +++ b/include/gui/SensorEventQueue.h @@ -24,7 +24,7 @@ #include <utils/RefBase.h> #include <utils/Timers.h> -#include <gui/SensorChannel.h> +#include <gui/BitTube.h> // ---------------------------------------------------------------------------- @@ -71,7 +71,7 @@ public: private: sp<Looper> getLooper() const; sp<ISensorEventConnection> mSensorEventConnection; - sp<SensorChannel> mSensorChannel; + sp<BitTube> mSensorChannel; mutable Mutex mLock; mutable sp<Looper> mLooper; }; diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 1417416..7b0b443 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -226,8 +226,8 @@ public: AudioEffect(const effect_uuid_t *type, const effect_uuid_t *uuid = NULL, int32_t priority = 0, - effect_callback_t cbf = 0, - void* user = 0, + effect_callback_t cbf = NULL, + void* user = NULL, int sessionId = 0, audio_io_handle_t io = 0 ); @@ -238,8 +238,8 @@ public: AudioEffect(const char *typeStr, const char *uuidStr = NULL, int32_t priority = 0, - effect_callback_t cbf = 0, - void* user = 0, + effect_callback_t cbf = NULL, + void* user = NULL, int sessionId = 0, audio_io_handle_t io = 0 ); @@ -260,8 +260,8 @@ public: status_t set(const effect_uuid_t *type, const effect_uuid_t *uuid = NULL, int32_t priority = 0, - effect_callback_t cbf = 0, - void* user = 0, + effect_callback_t cbf = NULL, + void* user = NULL, int sessionId = 0, audio_io_handle_t io = 0 ); diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 605680a..c8c5dba 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -22,7 +22,6 @@ #include <media/IAudioFlinger.h> #include <media/IAudioRecord.h> -#include <media/AudioTrack.h> #include <utils/RefBase.h> #include <utils/Errors.h> @@ -34,6 +33,8 @@ namespace android { +class audio_track_cblk_t; + // ---------------------------------------------------------------------------- class AudioRecord @@ -67,7 +68,7 @@ public: }; uint32_t flags; int channelCount; - int format; + audio_format_t format; size_t frameCount; size_t size; union { @@ -111,7 +112,7 @@ public: static status_t getMinFrameCount(int* frameCount, uint32_t sampleRate, - int format, + audio_format_t format, int channelCount); /* Constructs an uninitialized AudioRecord. No connection with @@ -148,14 +149,14 @@ public: RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE, }; - AudioRecord(int inputSource, + AudioRecord(audio_source_t inputSource, uint32_t sampleRate = 0, - int format = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channelMask = AUDIO_CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, - callback_t cbf = 0, - void* user = 0, + callback_t cbf = NULL, + void* user = NULL, int notificationFrames = 0, int sessionId = 0); @@ -174,14 +175,14 @@ public: * - NO_INIT: audio server or audio hardware not initialized * - PERMISSION_DENIED: recording is not allowed for the requesting process * */ - status_t set(int inputSource = 0, + status_t set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT, uint32_t sampleRate = 0, - int format = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channelMask = AUDIO_CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, - callback_t cbf = 0, - void* user = 0, + callback_t cbf = NULL, + void* user = NULL, int notificationFrames = 0, bool threadCanCallJava = false, int sessionId = 0); @@ -202,12 +203,12 @@ public: /* getters, see constructor */ - int format() const; + audio_format_t format() const; int channelCount() const; int channels() const; uint32_t frameCount() const; - int frameSize() const; - int inputSource() const; + size_t frameSize() const; + audio_source_t inputSource() const; /* After it's created the track is not active. Call start() to @@ -348,7 +349,7 @@ private: bool processAudioBuffer(const sp<ClientRecordThread>& thread); status_t openRecord_l(uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -364,10 +365,9 @@ private: uint32_t mFrameCount; audio_track_cblk_t* mCblk; - uint32_t mFormat; + audio_format_t mFormat; uint8_t mChannelCount; - uint8_t mInputSource; - uint8_t mReserved[2]; + audio_source_t mInputSource; status_t mStatus; uint32_t mLatency; @@ -385,6 +385,8 @@ private: uint32_t mChannelMask; audio_io_handle_t mInput; int mSessionId; + int mPreviousPriority; // before start() + int mPreviousSchedulingGroup; }; }; // namespace android diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 6a15f6e..74a1e62 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -55,19 +55,19 @@ public: static status_t getMasterMute(bool* mute); // set/get stream volume on specified output - static status_t setStreamVolume(int stream, float value, int output); - static status_t getStreamVolume(int stream, float* volume, int output); + static status_t setStreamVolume(audio_stream_type_t stream, float value, int output); + static status_t getStreamVolume(audio_stream_type_t stream, float* volume, int output); // mute/unmute stream - static status_t setStreamMute(int stream, bool mute); - static status_t getStreamMute(int stream, bool* mute); + static status_t setStreamMute(audio_stream_type_t stream, bool mute); + static status_t getStreamMute(audio_stream_type_t stream, bool* mute); - // set audio mode in audio hardware (see audio_mode_t) - static status_t setMode(int mode); + // set audio mode in audio hardware + static status_t setMode(audio_mode_t mode); // returns true in *state if tracks are active on the specified stream or has been active // in the past inPastMs milliseconds - static status_t isStreamActive(int stream, bool *state, uint32_t inPastMs = 0); + static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs = 0); // set/get audio hardware parameters. The function accepts a list of parameters // key value pairs in the form: key1=value1;key2=value2;... @@ -83,13 +83,19 @@ public: static float linearToLog(int volume); static int logToLinear(float volume); + static status_t getOutputSamplingRate(int* samplingRate, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + static status_t getOutputFrameCount(int* frameCount, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + static status_t getOutputLatency(uint32_t* latency, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + + // DEPRECATED static status_t getOutputSamplingRate(int* samplingRate, int stream = AUDIO_STREAM_DEFAULT); + + // DEPRECATED static status_t getOutputFrameCount(int* frameCount, int stream = AUDIO_STREAM_DEFAULT); - static status_t getOutputLatency(uint32_t* latency, int stream = AUDIO_STREAM_DEFAULT); - static bool routedToA2dpOutput(int streamType); + static bool routedToA2dpOutput(audio_stream_type_t streamType); - static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, + static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount, size_t* buffSize); static status_t setVoiceVolume(float volume); @@ -103,7 +109,7 @@ public: // - BAD_VALUE: invalid parameter // NOTE: this feature is not supported on all hardware platforms and it is // necessary to check returned status before using the returned values. - static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = AUDIO_STREAM_DEFAULT); + static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); static unsigned int getInputFramesLost(audio_io_handle_t ioHandle); @@ -128,7 +134,7 @@ public: class OutputDescriptor { public: OutputDescriptor() - : samplingRate(0), format(0), channels(0), frameCount(0), latency(0) {} + : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channels(0), frameCount(0), latency(0) {} uint32_t samplingRate; int32_t format; @@ -142,13 +148,12 @@ public: // static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address); static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address); - static status_t setPhoneState(int state); - static status_t setRingerMode(uint32_t mode, uint32_t mask); + static status_t setPhoneState(audio_mode_t state); static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage); static audio_io_handle_t getOutput(audio_stream_type_t stream, uint32_t samplingRate = 0, - uint32_t format = AUDIO_FORMAT_DEFAULT, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channels = AUDIO_CHANNEL_OUT_STEREO, audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT); static status_t startOutput(audio_io_handle_t output, @@ -158,9 +163,9 @@ public: audio_stream_type_t stream, int session = 0); static void releaseOutput(audio_io_handle_t output); - static audio_io_handle_t getInput(int inputSource, + static audio_io_handle_t getInput(audio_source_t inputSource, uint32_t samplingRate = 0, - uint32_t format = AUDIO_FORMAT_DEFAULT, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channels = AUDIO_CHANNEL_IN_MONO, audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0, int sessionId = 0); @@ -170,8 +175,12 @@ public: static status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax); - static status_t setStreamVolumeIndex(audio_stream_type_t stream, int index); - static status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index); + static status_t setStreamVolumeIndex(audio_stream_type_t stream, + int index, + audio_devices_t device); + static status_t getStreamVolumeIndex(audio_stream_type_t stream, + int *index, + audio_devices_t device); static uint32_t getStrategyForStream(audio_stream_type_t stream); static uint32_t getDevicesForStream(audio_stream_type_t stream); @@ -233,13 +242,13 @@ private: static size_t gInBuffSize; // previous parameters for recording buffer size queries static uint32_t gPrevInSamplingRate; - static int gPrevInFormat; + static audio_format_t gPrevInFormat; static int gPrevInChannelCount; static sp<IAudioPolicyService> gAudioPolicyService; // mapping between stream types and outputs - static DefaultKeyedVector<int, audio_io_handle_t> gStreamOutputMap; + static DefaultKeyedVector<audio_stream_type_t, audio_io_handle_t> gStreamOutputMap; // list of output descriptors containing cached parameters // (sampling rate, framecount, channel count...) static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index d1a8105..02c85cd 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -38,7 +38,7 @@ class audio_track_cblk_t; // ---------------------------------------------------------------------------- -class AudioTrack +class AudioTrack : virtual public RefBase { public: enum channel_index { @@ -69,21 +69,22 @@ public: MUTE = 0x00000001 }; uint32_t flags; - int format; + audio_format_t format; // but AUDIO_FORMAT_PCM_8_BIT -> AUDIO_FORMAT_PCM_16_BIT + // accessed directly by WebKit ANP callback int channelCount; // will be removed in the future, do not use size_t frameCount; size_t size; union { void* raw; - short* i16; - int8_t* i8; + short* i16; // signed 16-bit + int8_t* i8; // unsigned 8-bit, offset by 0x80 }; }; /* 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. + * invokes the callback when a new buffer becomes available or an underrun condition occurs. * Parameters: * * event: type of event notified (see enum AudioTrack::event_type). @@ -94,8 +95,8 @@ public: * 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_MARKER: pointer to an uint32_t containing the marker position in frames. + * - EVENT_NEW_POS: pointer to an uint32_t containing the new position in frames. * - EVENT_BUFFER_END: unused. */ @@ -109,7 +110,7 @@ public: */ static status_t getMinFrameCount(int* frameCount, - int streamType =-1, + audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT, uint32_t sampleRate = 0); /* Constructs an uninitialized AudioTrack. No connection with @@ -135,14 +136,27 @@ public: * flags: Reserved for future use. * cbf: Callback function. If not null, this function is called periodically * to request new PCM data. + * user: Context for use by the callback receiver. * 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. + * frames have been consumed from track input buffer. + * sessionId: Specific session ID, or zero to use default. */ - AudioTrack( int streamType, + AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate = 0, - int format = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, + int channelMask = 0, + int frameCount = 0, + uint32_t flags = 0, + callback_t cbf = NULL, + void* user = NULL, + int notificationFrames = 0, + int sessionId = 0); + + // DEPRECATED + explicit AudioTrack( int streamType, + uint32_t sampleRate = 0, + int format = AUDIO_FORMAT_DEFAULT, int channelMask = 0, int frameCount = 0, uint32_t flags = 0, @@ -152,46 +166,46 @@ public: int sessionId = 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 + * 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 + * PCM data must be present in memory before the AudioTrack is started. + * The write() and flush() methods are not supported in this case. + * It is recommended to pass a callback function to be notified of playback end by an * EVENT_UNDERRUN event. */ - AudioTrack( int streamType, + AudioTrack( audio_stream_type_t streamType, uint32_t sampleRate = 0, - int format = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, int channelMask = 0, const sp<IMemory>& sharedBuffer = 0, uint32_t flags = 0, - callback_t cbf = 0, - void* user = 0, + callback_t cbf = NULL, + void* user = NULL, int notificationFrames = 0, int sessionId = 0); /* Terminates the AudioTrack and unregisters it from AudioFlinger. - * Also destroys all resources assotiated with the AudioTrack. + * Also destroys all resources associated 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 + * - NO_ERROR: successful initialization + * - INVALID_OPERATION: AudioTrack is already initialized * - BAD_VALUE: invalid parameter (channels, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * */ - status_t set(int streamType =-1, + status_t set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT, uint32_t sampleRate = 0, - int format = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, int channelMask = 0, int frameCount = 0, uint32_t flags = 0, - callback_t cbf = 0, - void* user = 0, + callback_t cbf = NULL, + void* user = NULL, int notificationFrames = 0, const sp<IMemory>& sharedBuffer = 0, bool threadCanCallJava = false, @@ -199,13 +213,13 @@ public: /* Result of constructing the AudioTrack. This must be checked - * before using any AudioTrack API (except for set()), using + * before using any AudioTrack API (except for set()), because 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. + /* Returns this track's estimated latency in milliseconds. * This includes the latency due to AudioTrack buffer size, AudioMixer (if any) * and audio hardware driver. */ @@ -213,11 +227,16 @@ public: /* getters, see constructor */ - int streamType() const; - int format() const; + audio_stream_type_t streamType() const; + audio_format_t format() const; int channelCount() const; uint32_t frameCount() const; - int frameSize() const; + + /* Return channelCount * (bit depth per channel / 8). + * channelCount is determined from channelMask, and bit depth comes from format. + */ + size_t frameSize() const; + sp<IMemory>& sharedBuffer(); @@ -233,8 +252,8 @@ public: 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. + /* Flush a stopped track. All pending buffers are discarded. + * This function has no effect if the track is not stopped. */ void flush(); @@ -244,26 +263,25 @@ public: */ void pause(); - /* mute or unmutes this track. - * While mutted, the callback, if set, is still called. + /* Mute or unmute this track. + * While muted, the callback, if set, is still called. */ void mute(bool); bool muted() const; - - /* set volume for this track, mostly used for games' sound effects - * left and right volumes. Levels must be <= 1.0. + /* Set volume for this track, mostly used for games' sound effects + * left and right volumes. Levels must be >= 0.0 and <= 1.0. */ status_t setVolume(float left, float right); void getVolume(float* left, float* right); - /* set the send level for this track. An auxiliary effect should be attached - * to the track with attachEffect(). Level must be <= 1.0. + /* Set the send level for this track. An auxiliary effect should be attached + * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0. */ status_t setAuxEffectSendLevel(float level); void getAuxEffectSendLevel(float* level); - /* set sample rate for this track, mostly used for games' sound effects + /* Set sample rate for this track, mostly used for games' sound effects */ status_t setSampleRate(int sampleRate); uint32_t getSampleRate(); @@ -274,8 +292,8 @@ public: * * 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. + * 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() @@ -283,10 +301,9 @@ public: 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. + /* 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: @@ -301,10 +318,10 @@ public: 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. + /* 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: @@ -318,12 +335,11 @@ public: 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. + * 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 + * 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. @@ -335,12 +351,12 @@ public: * 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 + * - 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 + /* 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. * @@ -350,7 +366,7 @@ public: */ status_t reload(); - /* returns a handle on the audio output used by this AudioTrack. + /* Returns a handle on the audio output used by this AudioTrack. * * Parameters: * none. @@ -360,18 +376,17 @@ public: */ audio_io_handle_t getOutput(); - /* returns the unique ID associated to this track. + /* Returns the unique session ID associated with this track. * * Parameters: * none. * * Returned value: - * AudioTrack ID. + * AudioTrack session ID. */ int getSessionId(); - - /* Attach track auxiliary output to specified effect. Used effectId = 0 + /* Attach track auxiliary output to specified effect. Use effectId = 0 * to detach track from effect. * * Parameters: @@ -385,9 +400,9 @@ public: */ status_t attachAuxEffect(int effectId); - /* obtains a buffer of "frameCount" frames. The buffer must be + /* 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, + * STOPPED instead of NO_ERROR as long as there are buffers available, * 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 @@ -396,17 +411,16 @@ public: */ enum { - NO_MORE_BUFFERS = 0x80000001, + NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value 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 + * performance use callbacks. Return actual number of bytes written. * */ ssize_t write(const void* buffer, size_t size); @@ -436,9 +450,9 @@ private: }; bool processAudioBuffer(const sp<AudioTrackThread>& thread); - status_t createTrack_l(int streamType, + status_t createTrack_l(audio_stream_type_t streamType, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -449,6 +463,7 @@ private: status_t setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount); audio_io_handle_t getOutput_l(); status_t restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart); + bool stopped_l() const { return !mActive; } sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; @@ -459,8 +474,8 @@ private: uint32_t mFrameCount; audio_track_cblk_t* mCblk; - uint32_t mFormat; - uint8_t mStreamType; + audio_format_t mFormat; + audio_stream_type_t mStreamType; uint8_t mChannelCount; uint8_t mMuted; uint8_t mReserved; @@ -468,7 +483,7 @@ private: status_t mStatus; uint32_t mLatency; - volatile int32_t mActive; + bool mActive; // protected by mLock callback_t mCbf; void* mUserData; @@ -485,8 +500,10 @@ private: uint32_t mFlags; int mSessionId; int mAuxEffectId; - Mutex mLock; + mutable Mutex mLock; status_t mRestoreStatus; + int mPreviousPriority; // before start() + int mPreviousSchedulingGroup; }; diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 9e3cb7f..760595c 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -46,9 +46,9 @@ public: */ virtual sp<IAudioTrack> createTrack( pid_t pid, - int streamType, + audio_stream_type_t streamType, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -61,7 +61,7 @@ public: pid_t pid, int input, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -73,7 +73,7 @@ public: */ virtual uint32_t sampleRate(int output) const = 0; virtual int channelCount(int output) const = 0; - virtual uint32_t format(int output) const = 0; + virtual audio_format_t format(int output) const = 0; virtual size_t frameCount(int output) const = 0; virtual uint32_t latency(int output) const = 0; @@ -89,14 +89,14 @@ public: /* set/get stream type state. This will probably be used by * the preference panel, mostly. */ - virtual status_t setStreamVolume(int stream, float value, int output) = 0; - virtual status_t setStreamMute(int stream, bool muted) = 0; + virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output) = 0; + virtual status_t setStreamMute(audio_stream_type_t stream, bool muted) = 0; - virtual float streamVolume(int stream, int output) const = 0; - virtual bool streamMute(int stream) const = 0; + virtual float streamVolume(audio_stream_type_t stream, int output) const = 0; + virtual bool streamMute(audio_stream_type_t stream) const = 0; // set audio mode - virtual status_t setMode(int mode) = 0; + virtual status_t setMode(audio_mode_t mode) = 0; // mic mute/state virtual status_t setMicMute(bool state) = 0; @@ -109,11 +109,11 @@ public: 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; + virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) = 0; virtual int openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, - uint32_t *pFormat, + audio_format_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs, uint32_t flags) = 0; @@ -124,12 +124,12 @@ public: virtual int openInput(uint32_t *pDevices, uint32_t *pSamplingRate, - uint32_t *pFormat, + audio_format_t *pFormat, uint32_t *pChannels, - uint32_t acoustics) = 0; + audio_in_acoustics_t acoustics) = 0; virtual status_t closeInput(int input) = 0; - virtual status_t setStreamOutput(uint32_t stream, int output) = 0; + virtual status_t setStreamOutput(audio_stream_type_t stream, int output) = 0; virtual status_t setVoiceVolume(float volume) = 0; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 9807cbe..4d88297 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -45,13 +45,12 @@ public: const char *device_address) = 0; virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address) = 0; - virtual status_t setPhoneState(int state) = 0; - virtual status_t setRingerMode(uint32_t mode, uint32_t mask) = 0; + virtual status_t setPhoneState(audio_mode_t state) = 0; virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) = 0; virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0; virtual audio_io_handle_t getOutput(audio_stream_type_t stream, uint32_t samplingRate = 0, - uint32_t format = AUDIO_FORMAT_DEFAULT, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channels = 0, audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT) = 0; virtual status_t startOutput(audio_io_handle_t output, @@ -61,9 +60,9 @@ public: audio_stream_type_t stream, int session = 0) = 0; virtual void releaseOutput(audio_io_handle_t output) = 0; - virtual audio_io_handle_t getInput(int inputSource, + virtual audio_io_handle_t getInput(audio_source_t inputSource, uint32_t samplingRate = 0, - uint32_t format = AUDIO_FORMAT_DEFAULT, + audio_format_t format = AUDIO_FORMAT_DEFAULT, uint32_t channels = 0, audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0, int audioSession = 0) = 0; @@ -73,8 +72,12 @@ public: virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) = 0; - virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, int index) = 0; - virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index) = 0; + virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, + int index, + audio_devices_t device) = 0; + virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, + int *index, + audio_devices_t device) = 0; virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0; virtual uint32_t getDevicesForStream(audio_stream_type_t stream) = 0; virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0; @@ -85,7 +88,7 @@ public: int id) = 0; virtual status_t unregisterEffect(int id) = 0; virtual status_t setEffectEnabled(int id, bool enabled) = 0; - virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0; + virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0; virtual status_t queryDefaultPreProcessing(int audioSession, effect_descriptor_t *descriptors, uint32_t *count) = 0; diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h index 47d530b..b83e552 100644 --- a/include/media/IAudioTrack.h +++ b/include/media/IAudioTrack.h @@ -35,6 +35,9 @@ class IAudioTrack : public IInterface public: DECLARE_META_INTERFACE(AudioTrack); + /* Get this track's control block */ + virtual sp<IMemory> getCblk() const = 0; + /* After it's created the track is not active. Call start() to * make it active. If set, the callback will start being called. */ @@ -46,13 +49,13 @@ public: */ virtual void stop() = 0; - /* flush a stopped track. All pending buffers are discarded. - * This function has no effect if the track is not stoped. + /* Flush a stopped track. All pending buffers are discarded. + * This function has no effect if the track is not stopped. */ virtual void flush() = 0; - /* mute or unmutes this track. - * While mutted, the callback, if set, is still called. + /* Mute or unmute this track. + * While muted, the callback, if set, is still called. */ virtual void mute(bool) = 0; @@ -67,8 +70,6 @@ public: */ virtual status_t attachAuxEffect(int effectId) = 0; - /* get this tracks control block */ - virtual sp<IMemory> getCblk() const = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index e905903..6425886 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -21,6 +21,7 @@ #include <binder/IInterface.h> #include <binder/Parcel.h> #include <utils/KeyedVector.h> +#include <system/audio.h> namespace android { @@ -51,7 +52,7 @@ public: 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 setAudioStreamType(audio_stream_type_t type) = 0; virtual status_t setLooping(int loop) = 0; virtual status_t setVolume(float leftVolume, float rightVolume) = 0; virtual status_t setAuxEffectSendLevel(float level) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 93bbe13..4f46fcd 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -23,6 +23,7 @@ #include <utils/String8.h> #include <binder/IInterface.h> #include <binder/Parcel.h> +#include <system/audio.h> #include <media/IMediaPlayerClient.h> #include <media/IMediaPlayer.h> @@ -43,8 +44,8 @@ public: virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0; virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 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; + virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0; + virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0; virtual sp<IOMX> getOMX() = 0; // codecs and audio devices usage tracking for the battery app diff --git a/include/media/IOMX.h b/include/media/IOMX.h index c4cc947..a295e9a 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -42,10 +42,10 @@ public: typedef void *buffer_id; typedef void *node_id; - // Given the calling process' pid, returns true iff + // Given a node_id and the calling process' pid, returns true iff // the implementation of the OMX interface lives in the same // process. - virtual bool livesLocally(pid_t pid) = 0; + virtual bool livesLocally(node_id node, pid_t pid) = 0; struct ComponentInfo { String8 mName; diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h index 16764a9..491a950 100644 --- a/include/media/JetPlayer.h +++ b/include/media/JetPlayer.h @@ -65,7 +65,6 @@ public: private: - static int renderThread(void*); int render(); void fireUpdateOnStatusChange(); void fireEventsFromJetQueue(); @@ -95,8 +94,30 @@ private: S_JET_STATUS mJetStatus; S_JET_STATUS mPreviousJetStatus; - char mJetFilePath[256]; + char mJetFilePath[PATH_MAX]; + class JetPlayerThread : public Thread { + public: + JetPlayerThread(JetPlayer *player) : mPlayer(player) { + } + + protected: + virtual ~JetPlayerThread() {} + + private: + JetPlayer *mPlayer; + + bool threadLoop() { + int result; + result = mPlayer->render(); + return false; + } + + JetPlayerThread(const JetPlayerThread &); + JetPlayerThread &operator=(const JetPlayerThread &); + }; + + sp<JetPlayerThread> mThread; }; // end class JetPlayer diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 80f43a3..7beb176 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -85,7 +85,7 @@ public: // audio data. virtual status_t open( uint32_t sampleRate, int channelCount, - int format=AUDIO_FORMAT_PCM_16_BIT, + audio_format_t format=AUDIO_FORMAT_PCM_16_BIT, int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT, AudioCallback cb = NULL, void *cookie = NULL) = 0; @@ -199,7 +199,7 @@ public: virtual ~MediaPlayerHWInterface() {} virtual bool hardwareOutput() { return true; } virtual status_t setVolume(float leftVolume, float rightVolume) = 0; - virtual status_t setAudioStreamType(int streamType) = 0; + virtual status_t setAudioStreamType(audio_stream_type_t streamType) = 0; }; }; // namespace android diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h index 1ad1f26..df0c97e 100644 --- a/include/media/ToneGenerator.h +++ b/include/media/ToneGenerator.h @@ -151,10 +151,10 @@ public: NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; - ToneGenerator(int streamType, float volume, bool threadCanCallJava = false); + ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava = false); ~ToneGenerator(); - bool startTone(int toneType, int durationMs = -1); + bool startTone(tone_type toneType, int durationMs = -1); void stopTone(); bool isInited() { return (mState == TONE_IDLE)?false:true;} @@ -266,7 +266,7 @@ private: 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 + audio_stream_type_t mStreamType; // Audio stream used for output unsigned int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). bool initAudioTrack(); @@ -274,7 +274,7 @@ private: bool prepareWave(); unsigned int numWaves(unsigned int segmentIdx); void clearWaveGens(); - int getToneForRegion(int toneType); + tone_type getToneForRegion(tone_type toneType); // WaveGenerator generates a single sine wave class WaveGenerator { diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h index 5d2c874..60fa15b 100644 --- a/include/media/Visualizer.h +++ b/include/media/Visualizer.h @@ -66,8 +66,8 @@ public: * See AudioEffect constructor for details on parameters. */ Visualizer(int32_t priority = 0, - effect_callback_t cbf = 0, - void* user = 0, + effect_callback_t cbf = NULL, + void* user = NULL, int sessionId = 0); ~Visualizer(); @@ -143,7 +143,7 @@ private: void periodicCapture(); uint32_t initCaptureSize(); - Mutex mLock; + Mutex mCaptureLock; uint32_t mCaptureRate; uint32_t mCaptureSize; uint32_t mSampleRate; diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index e6a0cc5..00b7dd5 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -185,13 +185,13 @@ public: status_t getCurrentPosition(int *msec); status_t getDuration(int *msec); status_t reset(); - status_t setAudioStreamType(int type); + status_t setAudioStreamType(audio_stream_type_t type); status_t setLooping(int loop); bool isLooping(); status_t setVolume(float leftVolume, float rightVolume); void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL); - 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); + static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat); + static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat); status_t invoke(const Parcel& request, Parcel *reply); status_t setMetadataFilter(const Parcel& filter); status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata); @@ -223,7 +223,7 @@ private: int mSeekPosition; bool mPrepareSync; status_t mPrepareStatus; - int mStreamType; + audio_stream_type_t mStreamType; bool mLoop; float mLeftVolume; float mRightVolume; diff --git a/include/media/stagefright/AACWriter.h b/include/media/stagefright/AACWriter.h index fa3ab8a..49397ee 100644 --- a/include/media/stagefright/AACWriter.h +++ b/include/media/stagefright/AACWriter.h @@ -34,7 +34,7 @@ struct AACWriter : public MediaWriter { virtual status_t addSource(const sp<MediaSource> &source); virtual bool reachedEOS(); virtual status_t start(MetaData *params = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual status_t pause(); protected: @@ -66,6 +66,7 @@ private: bool exceedsFileSizeLimit(); bool exceedsFileDurationLimit(); status_t writeAdtsHeader(uint32_t frameLength); + status_t reset(); DISALLOW_EVIL_CONSTRUCTORS(AACWriter); }; diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h index 62d57b4..392f968 100644 --- a/include/media/stagefright/AMRWriter.h +++ b/include/media/stagefright/AMRWriter.h @@ -37,7 +37,7 @@ struct AMRWriter : public MediaWriter { virtual status_t addSource(const sp<MediaSource> &source); virtual bool reachedEOS(); virtual status_t start(MetaData *params = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual status_t pause(); protected: @@ -60,6 +60,7 @@ private: status_t threadFunc(); bool exceedsFileSizeLimit(); bool exceedsFileDurationLimit(); + status_t reset(); AMRWriter(const AMRWriter &); AMRWriter &operator=(const AMRWriter &); diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h index 19bd31b..79437bf 100644 --- a/include/media/stagefright/AudioSource.h +++ b/include/media/stagefright/AudioSource.h @@ -34,13 +34,13 @@ struct AudioSource : public MediaSource, public MediaBufferObserver { // Note that the "channels" parameter is _not_ the number of channels, // but a bitmask of audio_channels_t constants. AudioSource( - int inputSource, uint32_t sampleRate, + audio_source_t inputSource, uint32_t sampleRate, uint32_t channels = AUDIO_CHANNEL_IN_MONO); status_t initCheck() const; virtual status_t start(MetaData *params = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual sp<MetaData> getFormat(); // Returns the maximum amplitude since last call. @@ -97,6 +97,7 @@ private: void releaseQueuedFrames_l(); void waitOutstandingEncodingFrames_l(); + status_t reset(); AudioSource(const AudioSource &); AudioSource &operator=(const AudioSource &); diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index 446720b..5a35358 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -79,7 +79,7 @@ public: virtual ~CameraSource(); virtual status_t start(MetaData *params = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); @@ -163,7 +163,6 @@ protected: bool storeMetaDataInVideoBuffers); virtual void startCameraRecording(); - virtual void stopCameraRecording(); virtual void releaseRecordingFrame(const sp<IMemory>& frame); // Returns true if need to skip the current frame. @@ -220,7 +219,9 @@ private: status_t checkFrameRate(const CameraParameters& params, int32_t frameRate); + void stopCameraRecording(); void releaseCamera(); + status_t reset(); CameraSource(const CameraSource &); CameraSource &operator=(const CameraSource &); diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h index b060691..0936da2 100644 --- a/include/media/stagefright/CameraSourceTimeLapse.h +++ b/include/media/stagefright/CameraSourceTimeLapse.h @@ -121,9 +121,6 @@ private: // Wrapper over CameraSource::read() to implement quick stop. virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); - // For video camera case, just stops the camera's video recording. - virtual void stopCameraRecording(); - // mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current // frame needs to be skipped and this function just returns the value of mSkipCurrentFrame. virtual bool skipCurrentFrame(int64_t timestampUs); diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 713af92..00d583e 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -81,7 +81,7 @@ public: static void RegisterDefaultSniffers(); // for DRM - virtual sp<DecryptHandle> DrmInitialization() { + virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL) { return NULL; } virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {}; diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index 6cf86dc..d994cb3 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -38,7 +38,7 @@ public: virtual status_t getSize(off64_t *size); - virtual sp<DecryptHandle> DrmInitialization(); + virtual sp<DecryptHandle> DrmInitialization(const char *mime); virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h index e4c1c49..a7c9ecf 100644 --- a/include/media/stagefright/MPEG2TSWriter.h +++ b/include/media/stagefright/MPEG2TSWriter.h @@ -37,7 +37,7 @@ struct MPEG2TSWriter : public MediaWriter { virtual status_t addSource(const sp<MediaSource> &source); virtual status_t start(MetaData *param = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual status_t pause(); virtual bool reachedEOS(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -78,6 +78,7 @@ private: void writeAccessUnit(int32_t sourceIndex, const sp<ABuffer> &buffer); ssize_t internalWrite(const void *data, size_t size); + status_t reset(); DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSWriter); }; diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 77166ed..0409b30 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -37,7 +37,7 @@ public: virtual status_t addSource(const sp<MediaSource> &source); virtual status_t start(MetaData *param = NULL); - virtual status_t stop(); + virtual status_t stop() { return reset(); } virtual status_t pause(); virtual bool reachedEOS(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -184,6 +184,7 @@ private: void writeLongitude(int degreex10000); void sendSessionSummary(); void release(); + status_t reset(); MPEG4Writer(const MPEG4Writer &); MPEG4Writer &operator=(const MPEG4Writer &); diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index eb45237..94090ee 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -56,10 +56,10 @@ public: virtual uint32_t flags() const; // for DRM - virtual void setDrmFlag(bool flag) { + void setDrmFlag(bool flag) { mIsDrm = flag; }; - virtual bool getDrmFlag() { + bool getDrmFlag() { return mIsDrm; } virtual char* getDrmTrackInfo(size_t trackID, int *len) { diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 84f8282..4c30e04 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -172,6 +172,7 @@ private: uint32_t mFlags; bool mIsEncoder; + bool mIsVideo; char *mMIME; char *mComponentName; sp<MetaData> mOutputFormat; diff --git a/include/media/thread_init.h b/include/media/thread_init.h deleted file mode 100644 index 2feac86..0000000 --- a/include/media/thread_init.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef THREAD_INIT_H -#define THREAD_INIT_H - -bool InitializeForThread(); -void UninitializeForThread(); - -#endif /* THREAD_INIT_H*/ - diff --git a/include/private/gui/ComposerService.h b/include/private/gui/ComposerService.h new file mode 100644 index 0000000..d04491a --- /dev/null +++ b/include/private/gui/ComposerService.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H +#define ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Singleton.h> +#include <utils/StrongPointer.h> + + +namespace android { + +// --------------------------------------------------------------------------- + +class IMemoryHeap; +class ISurfaceComposer; +class surface_flinger_cblk_t; + +// --------------------------------------------------------------------------- + +class ComposerService : public Singleton<ComposerService> +{ + // these are constants + sp<ISurfaceComposer> mComposerService; + sp<IMemoryHeap> mServerCblkMemory; + surface_flinger_cblk_t volatile* mServerCblk; + ComposerService(); + friend class Singleton<ComposerService>; +public: + static sp<ISurfaceComposer> getComposerService(); + static surface_flinger_cblk_t const volatile * getControlBlock(); +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 20abd51..dd97ce4 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -59,8 +59,8 @@ 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; + Mutex lock; // sizeof(int) + Condition cv; // sizeof(int) volatile uint32_t user; volatile uint32_t server; uint32_t userBase; @@ -71,21 +71,28 @@ struct audio_track_cblk_t uint32_t loopStart; uint32_t loopEnd; int loopCount; - volatile union { - uint16_t volume[2]; - uint32_t volumeLR; - }; + + // Channel volumes are fixed point U4.12, so 0x1000 means 1.0. + // Left channel is in [0:15], right channel is in [16:31]. + // Always read and write the combined pair atomically. + // For AudioTrack only, not used by AudioRecord. +private: + uint32_t mVolumeLR; +public: + uint32_t sampleRate; // NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of // 16 bit because data is converted to 16 bit before being stored in buffer - uint8_t frameSize; + uint8_t frameSize; // would normally be size_t, but 8 bits is plenty uint8_t pad1; uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger uint16_t waitTimeMs; // Cumulated wait time - uint16_t sendLevel; +private: + uint16_t mSendLevel; // Fixed point U4.12 so 0x1000 means 1.0 +public: volatile int32_t flags; // Cache line boundary (32 bytes) @@ -98,6 +105,30 @@ struct audio_track_cblk_t uint32_t framesAvailable_l(); uint32_t framesReady(); bool tryLock(); + + // No barriers on the following operations, so the ordering of loads/stores + // with respect to other parameters is UNPREDICTABLE. That's considered safe. + + // for AudioTrack client only, caller must limit to 0.0 <= sendLevel <= 1.0 + void setSendLevel(float sendLevel) { + mSendLevel = uint16_t(sendLevel * 0x1000); + } + + // for AudioFlinger only; the return value must be validated by the caller + uint16_t getSendLevel_U4_12() const { + return mSendLevel; + } + + // for AudioTrack client only, caller must limit to 0 <= volumeLR <= 0x10001000 + void setVolumeLR(uint32_t volumeLR) { + mVolumeLR = volumeLR; + } + + // for AudioFlinger only; the return value must be validated by the caller + uint32_t getVolumeLR() const { + return mVolumeLR; + } + }; diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index 5eb09c7..58fd89d 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -33,8 +33,9 @@ namespace android { // ---------------------------------------------------------------------------- -class IMemoryHeap; class ComposerState; +class IDisplayEventConnection; +class IMemoryHeap; class ISurfaceComposer : public IInterface { @@ -124,13 +125,19 @@ public: uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ) = 0; + /* triggers screen off animation */ virtual status_t turnElectronBeamOff(int32_t mode) = 0; + + /* triggers screen on animation */ virtual status_t turnElectronBeamOn(int32_t mode) = 0; /* verify that an ISurfaceTexture was created by SurfaceFlinger. */ virtual bool authenticateSurfaceTexture( const sp<ISurfaceTexture>& surface) const = 0; + + /* return an IDisplayEventConnection */ + virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0; }; // ---------------------------------------------------------------------------- @@ -151,6 +158,7 @@ public: TURN_ELECTRON_BEAM_OFF, TURN_ELECTRON_BEAM_ON, AUTHENTICATE_SURFACE, + CREATE_DISPLAY_EVENT_CONNECTION, }; virtual status_t onTransact( uint32_t code, diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h index 8226abe..99affda 100644 --- a/include/surfaceflinger/SurfaceComposerClient.h +++ b/include/surfaceflinger/SurfaceComposerClient.h @@ -28,7 +28,6 @@ #include <utils/threads.h> #include <ui/PixelFormat.h> -#include <ui/Region.h> #include <surfaceflinger/Surface.h> @@ -39,30 +38,11 @@ namespace android { class DisplayInfo; class Composer; class IMemoryHeap; -class ISurfaceComposer; +class ISurfaceComposerClient; class Region; -class surface_flinger_cblk_t; -struct layer_state_t; // --------------------------------------------------------------------------- -class ComposerService : public Singleton<ComposerService> -{ - // these are constants - sp<ISurfaceComposer> mComposerService; - sp<IMemoryHeap> mServerCblkMemory; - surface_flinger_cblk_t volatile* mServerCblk; - ComposerService(); - friend class Singleton<ComposerService>; -public: - static sp<ISurfaceComposer> getComposerService(); - static surface_flinger_cblk_t const volatile * getControlBlock(); -}; - -// --------------------------------------------------------------------------- - -class Composer; - class SurfaceComposerClient : public RefBase { friend class Composer; diff --git a/include/ui/GraphicLog.h b/include/ui/GraphicLog.h deleted file mode 100644 index ee1b09a..0000000 --- a/include/ui/GraphicLog.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _UI_GRAPHIC_LOG_H -#define _UI_GRAPHIC_LOG_H - -#include <utils/Singleton.h> -#include <cutils/compiler.h> - -namespace android { - -class GraphicLog : public Singleton<GraphicLog> -{ - int32_t mEnabled; - static void logImpl(int32_t tag, int32_t buffer); - static void logImpl(int32_t tag, int32_t identity, int32_t buffer); - -public: - enum { - SF_APP_DEQUEUE_BEFORE = 60100, - SF_APP_DEQUEUE_AFTER = 60101, - SF_APP_LOCK_BEFORE = 60102, - SF_APP_LOCK_AFTER = 60103, - SF_APP_QUEUE = 60104, - - SF_REPAINT = 60105, - SF_COMPOSITION_COMPLETE = 60106, - SF_UNLOCK_CLIENTS = 60107, - SF_SWAP_BUFFERS = 60108, - SF_REPAINT_DONE = 60109, - - SF_FB_POST_BEFORE = 60110, - SF_FB_POST_AFTER = 60111, - SF_FB_DEQUEUE_BEFORE = 60112, - SF_FB_DEQUEUE_AFTER = 60113, - SF_FB_LOCK_BEFORE = 60114, - SF_FB_LOCK_AFTER = 60115, - }; - - inline void log(int32_t tag, int32_t buffer) { - if (CC_UNLIKELY(mEnabled)) - logImpl(tag, buffer); - } - inline void log(int32_t tag, int32_t identity, int32_t buffer) { - if (CC_UNLIKELY(mEnabled)) - logImpl(tag, identity, buffer); - } - - GraphicLog(); - - void setEnabled(bool enable); -}; - -} - -#endif // _UI_GRAPHIC_LOG_H - diff --git a/include/utils/BasicHashtable.h b/include/utils/BasicHashtable.h new file mode 100644 index 0000000..fdf9738 --- /dev/null +++ b/include/utils/BasicHashtable.h @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BASIC_HASHTABLE_H +#define ANDROID_BASIC_HASHTABLE_H + +#include <stdint.h> +#include <sys/types.h> +#include <utils/SharedBuffer.h> +#include <utils/TypeHelpers.h> + +namespace android { + +/* Implementation type. Nothing to see here. */ +class BasicHashtableImpl { +protected: + struct Bucket { + // The collision flag indicates that the bucket is part of a collision chain + // such that at least two entries both hash to this bucket. When true, we + // may need to seek further along the chain to find the entry. + static const uint32_t COLLISION = 0x80000000UL; + + // The present flag indicates that the bucket contains an initialized entry value. + static const uint32_t PRESENT = 0x40000000UL; + + // Mask for 30 bits worth of the hash code that are stored within the bucket to + // speed up lookups and rehashing by eliminating the need to recalculate the + // hash code of the entry's key. + static const uint32_t HASH_MASK = 0x3fffffffUL; + + // Combined value that stores the collision and present flags as well as + // a 30 bit hash code. + uint32_t cookie; + + // Storage for the entry begins here. + char entry[0]; + }; + + BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor, + size_t minimumInitialCapacity, float loadFactor); + BasicHashtableImpl(const BasicHashtableImpl& other); + + void dispose(); + + inline void edit() { + if (mBuckets && !SharedBuffer::bufferFromData(mBuckets)->onlyOwner()) { + clone(); + } + } + + void setTo(const BasicHashtableImpl& other); + void clear(); + + ssize_t next(ssize_t index) const; + ssize_t find(ssize_t index, hash_t hash, const void* __restrict__ key) const; + size_t add(hash_t hash, const void* __restrict__ entry); + void removeAt(size_t index); + void rehash(size_t minimumCapacity, float loadFactor); + + const size_t mBucketSize; // number of bytes per bucket including the entry + const bool mHasTrivialDestructor; // true if the entry type does not require destruction + size_t mCapacity; // number of buckets that can be filled before exceeding load factor + float mLoadFactor; // load factor + size_t mSize; // number of elements actually in the table + size_t mFilledBuckets; // number of buckets for which collision or present is true + size_t mBucketCount; // number of slots in the mBuckets array + void* mBuckets; // array of buckets, as a SharedBuffer + + inline const Bucket& bucketAt(const void* __restrict__ buckets, size_t index) const { + return *reinterpret_cast<const Bucket*>( + static_cast<const uint8_t*>(buckets) + index * mBucketSize); + } + + inline Bucket& bucketAt(void* __restrict__ buckets, size_t index) const { + return *reinterpret_cast<Bucket*>(static_cast<uint8_t*>(buckets) + index * mBucketSize); + } + + virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const = 0; + virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const = 0; + virtual void destroyBucketEntry(Bucket& bucket) const = 0; + +private: + void clone(); + + // Allocates a bucket array as a SharedBuffer. + void* allocateBuckets(size_t count) const; + + // Releases a bucket array's associated SharedBuffer. + void releaseBuckets(void* __restrict__ buckets, size_t count) const; + + // Destroys the contents of buckets (invokes destroyBucketEntry for each + // populated bucket if needed). + void destroyBuckets(void* __restrict__ buckets, size_t count) const; + + // Copies the content of buckets (copies the cookie and invokes copyBucketEntry + // for each populated bucket if needed). + void copyBuckets(const void* __restrict__ fromBuckets, + void* __restrict__ toBuckets, size_t count) const; + + // Determines the appropriate size of a bucket array to store a certain minimum + // number of entries and returns its effective capacity. + static void determineCapacity(size_t minimumCapacity, float loadFactor, + size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity); + + // Trim a hash code to 30 bits to match what we store in the bucket's cookie. + inline static hash_t trimHash(hash_t hash) { + return (hash & Bucket::HASH_MASK) ^ (hash >> 30); + } + + // Returns the index of the first bucket that is in the collision chain + // for the specified hash code, given the total number of buckets. + // (Primary hash) + inline static size_t chainStart(hash_t hash, size_t count) { + return hash % count; + } + + // Returns the increment to add to a bucket index to seek to the next bucket + // in the collision chain for the specified hash code, given the total number of buckets. + // (Secondary hash) + inline static size_t chainIncrement(hash_t hash, size_t count) { + return ((hash >> 7) | (hash << 25)) % (count - 1) + 1; + } + + // Returns the index of the next bucket that is in the collision chain + // that is defined by the specified increment, given the total number of buckets. + inline static size_t chainSeek(size_t index, size_t increment, size_t count) { + return (index + increment) % count; + } +}; + +/* + * A BasicHashtable stores entries that are indexed by hash code in place + * within an array. The basic operations are finding entries by key, + * adding new entries and removing existing entries. + * + * This class provides a very limited set of operations with simple semantics. + * It is intended to be used as a building block to construct more complex + * and interesting data structures such as HashMap. Think very hard before + * adding anything extra to BasicHashtable, it probably belongs at a + * higher level of abstraction. + * + * TKey: The key type. + * TEntry: The entry type which is what is actually stored in the array. + * + * TKey must support the following contract: + * bool operator==(const TKey& other) const; // return true if equal + * bool operator!=(const TKey& other) const; // return true if unequal + * + * TEntry must support the following contract: + * const TKey& getKey() const; // get the key from the entry + * + * This class supports storing entries with duplicate keys. Of course, it can't + * tell them apart during removal so only the first entry will be removed. + * We do this because it means that operations like add() can't fail. + */ +template <typename TKey, typename TEntry> +class BasicHashtable : private BasicHashtableImpl { +public: + /* Creates a hashtable with the specified minimum initial capacity. + * The underlying array will be created when the first entry is added. + * + * minimumInitialCapacity: The minimum initial capacity for the hashtable. + * Default is 0. + * loadFactor: The desired load factor for the hashtable, between 0 and 1. + * Default is 0.75. + */ + BasicHashtable(size_t minimumInitialCapacity = 0, float loadFactor = 0.75f); + + /* Copies a hashtable. + * The underlying storage is shared copy-on-write. + */ + BasicHashtable(const BasicHashtable& other); + + /* Clears and destroys the hashtable. + */ + virtual ~BasicHashtable(); + + /* Making this hashtable a copy of the other hashtable. + * The underlying storage is shared copy-on-write. + * + * other: The hashtable to copy. + */ + inline BasicHashtable<TKey, TEntry>& operator =(const BasicHashtable<TKey, TEntry> & other) { + setTo(other); + return *this; + } + + /* Returns the number of entries in the hashtable. + */ + inline size_t size() const { + return mSize; + } + + /* Returns the capacity of the hashtable, which is the number of elements that can + * added to the hashtable without requiring it to be grown. + */ + inline size_t capacity() const { + return mCapacity; + } + + /* Returns the number of buckets that the hashtable has, which is the size of its + * underlying array. + */ + inline size_t bucketCount() const { + return mBucketCount; + } + + /* Returns the load factor of the hashtable. */ + inline float loadFactor() const { + return mLoadFactor; + }; + + /* Returns a const reference to the entry at the specified index. + * + * index: The index of the entry to retrieve. Must be a valid index within + * the bounds of the hashtable. + */ + inline const TEntry& entryAt(size_t index) const { + return entryFor(bucketAt(mBuckets, index)); + } + + /* Returns a non-const reference to the entry at the specified index. + * + * index: The index of the entry to edit. Must be a valid index within + * the bounds of the hashtable. + */ + inline TEntry& editEntryAt(size_t index) { + edit(); + return entryFor(bucketAt(mBuckets, index)); + } + + /* Clears the hashtable. + * All entries in the hashtable are destroyed immediately. + * If you need to do something special with the entries in the hashtable then iterate + * over them and do what you need before clearing the hashtable. + */ + inline void clear() { + BasicHashtableImpl::clear(); + } + + /* Returns the index of the next entry in the hashtable given the index of a previous entry. + * If the given index is -1, then returns the index of the first entry in the hashtable, + * if there is one, or -1 otherwise. + * If the given index is not -1, then returns the index of the next entry in the hashtable, + * in strictly increasing order, or -1 if there are none left. + * + * index: The index of the previous entry that was iterated, or -1 to begin + * iteration at the beginning of the hashtable. + */ + inline ssize_t next(ssize_t index) const { + return BasicHashtableImpl::next(index); + } + + /* Finds the index of an entry with the specified key. + * If the given index is -1, then returns the index of the first matching entry, + * otherwise returns the index of the next matching entry. + * If the hashtable contains multiple entries with keys that match the requested + * key, then the sequence of entries returned is arbitrary. + * Returns -1 if no entry was found. + * + * index: The index of the previous entry with the specified key, or -1 to + * find the first matching entry. + * hash: The hashcode of the key. + * key: The key. + */ + inline ssize_t find(ssize_t index, hash_t hash, const TKey& key) const { + return BasicHashtableImpl::find(index, hash, &key); + } + + /* Adds the entry to the hashtable. + * Returns the index of the newly added entry. + * If an entry with the same key already exists, then a duplicate entry is added. + * If the entry will not fit, then the hashtable's capacity is increased and + * its contents are rehashed. See rehash(). + * + * hash: The hashcode of the key. + * entry: The entry to add. + */ + inline size_t add(hash_t hash, const TEntry& entry) { + return BasicHashtableImpl::add(hash, &entry); + } + + /* Removes the entry with the specified index from the hashtable. + * The entry is destroyed immediately. + * The index must be valid. + * + * The hashtable is not compacted after an item is removed, so it is legal + * to continue iterating over the hashtable using next() or find(). + * + * index: The index of the entry to remove. Must be a valid index within the + * bounds of the hashtable, and it must refer to an existing entry. + */ + inline void removeAt(size_t index) { + BasicHashtableImpl::removeAt(index); + } + + /* Rehashes the contents of the hashtable. + * Grows the hashtable to at least the specified minimum capacity or the + * current number of elements, whichever is larger. + * + * Rehashing causes all entries to be copied and the entry indices may change. + * Although the hash codes are cached by the hashtable, rehashing can be an + * expensive operation and should be avoided unless the hashtable's size + * needs to be changed. + * + * Rehashing is the only way to change the capacity or load factor of the + * hashtable once it has been created. It can be used to compact the + * hashtable by choosing a minimum capacity that is smaller than the current + * capacity (such as 0). + * + * minimumCapacity: The desired minimum capacity after rehashing. + * loadFactor: The desired load factor after rehashing. + */ + inline void rehash(size_t minimumCapacity, float loadFactor) { + BasicHashtableImpl::rehash(minimumCapacity, loadFactor); + } + +protected: + static inline const TEntry& entryFor(const Bucket& bucket) { + return reinterpret_cast<const TEntry&>(bucket.entry); + } + + static inline TEntry& entryFor(Bucket& bucket) { + return reinterpret_cast<TEntry&>(bucket.entry); + } + + virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const; + virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const; + virtual void destroyBucketEntry(Bucket& bucket) const; + +private: + // For dumping the raw contents of a hashtable during testing. + friend class BasicHashtableTest; + inline uint32_t cookieAt(size_t index) const { + return bucketAt(mBuckets, index).cookie; + } +}; + +template <typename TKey, typename TEntry> +BasicHashtable<TKey, TEntry>::BasicHashtable(size_t minimumInitialCapacity, float loadFactor) : + BasicHashtableImpl(sizeof(TEntry), traits<TEntry>::has_trivial_dtor, + minimumInitialCapacity, loadFactor) { +} + +template <typename TKey, typename TEntry> +BasicHashtable<TKey, TEntry>::BasicHashtable(const BasicHashtable<TKey, TEntry>& other) : + BasicHashtableImpl(other) { +} + +template <typename TKey, typename TEntry> +BasicHashtable<TKey, TEntry>::~BasicHashtable() { + dispose(); +} + +template <typename TKey, typename TEntry> +bool BasicHashtable<TKey, TEntry>::compareBucketKey(const Bucket& bucket, + const void* __restrict__ key) const { + return entryFor(bucket).getKey() == *static_cast<const TKey*>(key); +} + +template <typename TKey, typename TEntry> +void BasicHashtable<TKey, TEntry>::initializeBucketEntry(Bucket& bucket, + const void* __restrict__ entry) const { + if (!traits<TEntry>::has_trivial_copy) { + new (&entryFor(bucket)) TEntry(*(static_cast<const TEntry*>(entry))); + } else { + memcpy(&entryFor(bucket), entry, sizeof(TEntry)); + } +} + +template <typename TKey, typename TEntry> +void BasicHashtable<TKey, TEntry>::destroyBucketEntry(Bucket& bucket) const { + if (!traits<TEntry>::has_trivial_dtor) { + entryFor(bucket).~TEntry(); + } +} + +}; // namespace android + +#endif // ANDROID_BASIC_HASHTABLE_H diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h index 8817120..079e20c 100644 --- a/include/utils/CallStack.h +++ b/include/utils/CallStack.h @@ -21,6 +21,7 @@ #include <sys/types.h> #include <utils/String8.h> +#include <corkscrew/backtrace.h> // --------------------------------------------------------------------------- @@ -61,11 +62,8 @@ public: 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]; + size_t mCount; + backtrace_frame_t mStack[MAX_DEPTH]; }; }; // namespace android diff --git a/include/utils/GenerationCache.h b/include/utils/GenerationCache.h index bb9ddd6..40722d1 100644 --- a/include/utils/GenerationCache.h +++ b/include/utils/GenerationCache.h @@ -34,17 +34,17 @@ public: template<typename EntryKey, typename EntryValue> struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > { - Entry() { } - Entry(const Entry<EntryKey, EntryValue>& e): - key(e.key), value(e.value), parent(e.parent), child(e.child) { } - Entry(sp<Entry<EntryKey, EntryValue> > e): - key(e->key), value(e->value), parent(e->parent), child(e->child) { } + Entry(const Entry<EntryKey, EntryValue>& e) : + key(e.key), value(e.value), + parent(e.parent), child(e.child) { } + Entry(const EntryKey& key, const EntryValue& value) : + key(key), value(value) { } EntryKey key; EntryValue value; - sp<Entry<EntryKey, EntryValue> > parent; - sp<Entry<EntryKey, EntryValue> > child; + sp<Entry<EntryKey, EntryValue> > parent; // next older entry + sp<Entry<EntryKey, EntryValue> > child; // next younger entry }; // struct Entry /** @@ -62,23 +62,20 @@ public: void setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener); - void clear(); + size_t size() const; - bool contains(K key) const; - V get(K key); - K getKeyAt(uint32_t index) const; - bool put(K key, V value); - V remove(K key); - V removeOldest(); - V getValueAt(uint32_t index) const; + void clear(); - uint32_t size() const; + bool contains(const K& key) const; + const K& getKeyAt(size_t index) const; + const V& getValueAt(size_t index) const; - void addToCache(sp<Entry<K, V> > entry, K key, V value); - void attachToCache(sp<Entry<K, V> > entry); - void detachFromCache(sp<Entry<K, V> > entry); + const V& get(const K& key); + bool put(const K& key, const V& value); - V removeAt(ssize_t index); + void removeAt(ssize_t index); + bool remove(const K& key); + bool removeOldest(); private: KeyedVector<K, sp<Entry<K, V> > > mCache; @@ -88,11 +85,16 @@ private: sp<Entry<K, V> > mOldest; sp<Entry<K, V> > mYoungest; + + void attachToCache(const sp<Entry<K, V> >& entry); + void detachFromCache(const sp<Entry<K, V> >& entry); + + const V mNullValue; }; // class GenerationCache template<typename K, typename V> GenerationCache<K, V>::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), - mListener(NULL) { + mListener(NULL), mNullValue(NULL) { }; template<typename K, typename V> @@ -130,45 +132,44 @@ void GenerationCache<K, V>::clear() { } template<typename K, typename V> -bool GenerationCache<K, V>::contains(K key) const { +bool GenerationCache<K, V>::contains(const K& key) const { return mCache.indexOfKey(key) >= 0; } template<typename K, typename V> -K GenerationCache<K, V>::getKeyAt(uint32_t index) const { +const K& GenerationCache<K, V>::getKeyAt(size_t index) const { return mCache.keyAt(index); } template<typename K, typename V> -V GenerationCache<K, V>::getValueAt(uint32_t index) const { +const V& GenerationCache<K, V>::getValueAt(size_t index) const { return mCache.valueAt(index)->value; } template<typename K, typename V> -V GenerationCache<K, V>::get(K key) { +const V& GenerationCache<K, V>::get(const K& key) { ssize_t index = mCache.indexOfKey(key); if (index >= 0) { - sp<Entry<K, V> > entry = mCache.valueAt(index); - if (entry.get()) { - detachFromCache(entry); - attachToCache(entry); - return entry->value; - } + const sp<Entry<K, V> >& entry = mCache.valueAt(index); + detachFromCache(entry); + attachToCache(entry); + return entry->value; } - return NULL; + return mNullValue; } template<typename K, typename V> -bool GenerationCache<K, V>::put(K key, V value) { +bool GenerationCache<K, V>::put(const K& key, const V& value) { if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) { removeOldest(); } ssize_t index = mCache.indexOfKey(key); if (index < 0) { - sp<Entry<K, V> > entry = new Entry<K, V>; - addToCache(entry, key, value); + sp<Entry<K, V> > entry = new Entry<K, V>(key, value); + mCache.add(key, entry); + attachToCache(entry); return true; } @@ -176,49 +177,44 @@ bool GenerationCache<K, V>::put(K key, V value) { } template<typename K, typename V> -void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) { - entry->key = key; - entry->value = value; - mCache.add(key, entry); - attachToCache(entry); -} - -template<typename K, typename V> -V GenerationCache<K, V>::remove(K key) { +bool GenerationCache<K, V>::remove(const K& key) { ssize_t index = mCache.indexOfKey(key); if (index >= 0) { - return removeAt(index); + removeAt(index); + return true; } - return NULL; + return false; } template<typename K, typename V> -V GenerationCache<K, V>::removeAt(ssize_t index) { +void GenerationCache<K, V>::removeAt(ssize_t index) { sp<Entry<K, V> > entry = mCache.valueAt(index); if (mListener) { (*mListener)(entry->key, entry->value); } mCache.removeItemsAt(index, 1); detachFromCache(entry); - - return entry->value; } template<typename K, typename V> -V GenerationCache<K, V>::removeOldest() { +bool GenerationCache<K, V>::removeOldest() { if (mOldest.get()) { ssize_t index = mCache.indexOfKey(mOldest->key); if (index >= 0) { - return removeAt(index); + removeAt(index); + return true; } + ALOGE("GenerationCache: removeOldest failed to find the item in the cache " + "with the given key, but we know it must be in there. " + "Is the key comparator kaput?"); } - return NULL; + return false; } template<typename K, typename V> -void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) { +void GenerationCache<K, V>::attachToCache(const sp<Entry<K, V> >& entry) { if (!mYoungest.get()) { mYoungest = mOldest = entry; } else { @@ -229,20 +225,16 @@ void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) { } template<typename K, typename V> -void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) { +void GenerationCache<K, V>::detachFromCache(const sp<Entry<K, V> >& entry) { if (entry->parent.get()) { entry->parent->child = entry->child; + } else { + mOldest = entry->child; } if (entry->child.get()) { entry->child->parent = entry->parent; - } - - if (mOldest == entry) { - mOldest = entry->child; - } - - if (mYoungest == entry) { + } else { mYoungest = entry->parent; } diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 71e5324..c496da6 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -444,23 +444,31 @@ public: void uninit(); + // Return string entry as UTF16; if the pool is UTF8, the string will + // be converted before returning. 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; + // Note: returns null if the string pool is not UTF8. const char* string8At(size_t idx, size_t* outLen) const; + // Return string whether the pool is UTF8 or UTF16. Does not allow you + // to distinguish null. + const String8 string8ObjectAt(size_t idx) 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; + size_t styleCount() const; + size_t bytes() const; -#ifndef HAVE_ANDROID_OS + bool isSorted() const; bool isUTF8() const; -#endif private: status_t mError; @@ -746,7 +754,9 @@ private: /** * Header for a resource table. Its data contains a series of * additional chunks: - * * A ResStringPool_header containing all table values. + * * A ResStringPool_header containing all table values. This string pool + * contains all of the string values in the entire resource table (not + * the names of entries or type identifiers however). * * One or more ResTable_package chunks. * * Specific entries within a resource table can be uniquely identified @@ -843,6 +853,8 @@ struct ResTable_config DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM, DENSITY_TV = ACONFIGURATION_DENSITY_TV, DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH, + DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH, + DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH, DENSITY_NONE = ACONFIGURATION_DENSITY_NONE }; @@ -955,6 +967,7 @@ struct ResTable_config UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK, UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR, UI_MODE_TYPE_TELEVISION = ACONFIGURATION_UI_MODE_TYPE_TELEVISION, + UI_MODE_TYPE_APPLIANCE = ACONFIGURATION_UI_MODE_TYPE_APPLIANCE, // uiMode bits for the night switch. MASK_UI_MODE_NIGHT = 0x30, @@ -981,68 +994,15 @@ struct ResTable_config uint32_t screenSizeDp; }; - 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); - } - } + void copyFromDeviceNoSwap(const ResTable_config& o); - 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); - smallestScreenWidthDp = dtohs(smallestScreenWidthDp); - screenWidthDp = dtohs(screenWidthDp); - screenHeightDp = dtohs(screenHeightDp); - } - - 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); - smallestScreenWidthDp = htods(smallestScreenWidthDp); - screenWidthDp = htods(screenWidthDp); - screenHeightDp = htods(screenHeightDp); - } - - 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); - if (diff != 0) return diff; - diff = (int32_t)(screenLayout - o.screenLayout); - if (diff != 0) return diff; - diff = (int32_t)(uiMode - o.uiMode); - if (diff != 0) return diff; - diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp); - if (diff != 0) return diff; - diff = (int32_t)(screenSizeDp - o.screenSizeDp); - return (int)diff; - } + void copyFromDtoH(const ResTable_config& o); + void swapHtoD(); + + int compare(const ResTable_config& o) const; + int compareLogical(const ResTable_config& o) const; + // Flags indicating a set of config values. These flag constants must // match the corresponding ones in android.content.pm.ActivityInfo and // attrs_manifest.xml. @@ -1065,158 +1025,10 @@ struct ResTable_config // 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|MASK_NAVHIDDEN)) != 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; - if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT; - if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; - if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE; - if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; - return diffs; - } + int diff(const ResTable_config& o) const; // Return true if 'this' is more specific than 'o'. - inline bool - isMoreSpecificThan(const ResTable_config& o) 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 || o.imsi) { - if (mcc != o.mcc) { - if (!mcc) return false; - if (!o.mcc) return true; - } - - if (mnc != o.mnc) { - if (!mnc) return false; - if (!o.mnc) return true; - } - } - - if (locale || o.locale) { - if (language[0] != o.language[0]) { - if (!language[0]) return false; - if (!o.language[0]) return true; - } - - if (country[0] != o.country[0]) { - if (!country[0]) return false; - if (!o.country[0]) return true; - } - } - - if (smallestScreenWidthDp || o.smallestScreenWidthDp) { - if (smallestScreenWidthDp != o.smallestScreenWidthDp) { - if (!smallestScreenWidthDp) return false; - if (!o.smallestScreenWidthDp) return true; - } - } - - if (screenSizeDp || o.screenSizeDp) { - if (screenWidthDp != o.screenWidthDp) { - if (!screenWidthDp) return false; - if (!o.screenWidthDp) return true; - } - - if (screenHeightDp != o.screenHeightDp) { - if (!screenHeightDp) return false; - if (!o.screenHeightDp) return true; - } - } - - if (screenLayout || o.screenLayout) { - if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) { - if (!(screenLayout & MASK_SCREENSIZE)) return false; - if (!(o.screenLayout & MASK_SCREENSIZE)) return true; - } - if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) { - if (!(screenLayout & MASK_SCREENLONG)) return false; - if (!(o.screenLayout & MASK_SCREENLONG)) return true; - } - } - - if (orientation != o.orientation) { - if (!orientation) return false; - if (!o.orientation) return true; - } - - if (uiMode || o.uiMode) { - if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) { - if (!(uiMode & MASK_UI_MODE_TYPE)) return false; - if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true; - } - if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) { - if (!(uiMode & MASK_UI_MODE_NIGHT)) return false; - if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true; - } - } - - // density is never 'more specific' - // as the default just equals 160 - - if (touchscreen != o.touchscreen) { - if (!touchscreen) return false; - if (!o.touchscreen) return true; - } - - if (input || o.input) { - if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) { - if (!(inputFlags & MASK_KEYSHIDDEN)) return false; - if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true; - } - - if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) { - if (!(inputFlags & MASK_NAVHIDDEN)) return false; - if (!(o.inputFlags & MASK_NAVHIDDEN)) return true; - } - - if (keyboard != o.keyboard) { - if (!keyboard) return false; - if (!o.keyboard) return true; - } - - if (navigation != o.navigation) { - if (!navigation) return false; - if (!o.navigation) return true; - } - } - - if (screenSize || o.screenSize) { - if (screenWidth != o.screenWidth) { - if (!screenWidth) return false; - if (!o.screenWidth) return true; - } - - if (screenHeight != o.screenHeight) { - if (!screenHeight) return false; - if (!o.screenHeight) return true; - } - } - - if (version || o.version) { - if (sdkVersion != o.sdkVersion) { - if (!sdkVersion) return false; - if (!o.sdkVersion) return true; - } - - if (minorVersion != o.minorVersion) { - if (!minorVersion) return false; - if (!o.minorVersion) return true; - } - } - return false; - } + bool isMoreSpecificThan(const ResTable_config& o) const; // Return true if 'this' is a better match than 'o' for the 'requested' // configuration. This assumes that match() has already been used to @@ -1228,222 +1040,7 @@ struct ResTable_config // they are not equal then one must be generic because only generic and // '==requested' will pass the match() call. So if this is not generic, // it wins. If this IS generic, o wins (return false). - inline bool - isBetterThan(const ResTable_config& o, - const ResTable_config* requested) const { - if (requested) { - if (imsi || o.imsi) { - if ((mcc != o.mcc) && requested->mcc) { - return (mcc); - } - - if ((mnc != o.mnc) && requested->mnc) { - return (mnc); - } - } - - if (locale || o.locale) { - if ((language[0] != o.language[0]) && requested->language[0]) { - return (language[0]); - } - - if ((country[0] != o.country[0]) && requested->country[0]) { - return (country[0]); - } - } - - if (smallestScreenWidthDp || o.smallestScreenWidthDp) { - // The configuration closest to the actual size is best. - // We assume that larger configs have already been filtered - // out at this point. That means we just want the largest one. - return smallestScreenWidthDp >= o.smallestScreenWidthDp; - } - - if (screenSizeDp || o.screenSizeDp) { - // "Better" is based on the sum of the difference between both - // width and height from the requested dimensions. We are - // assuming the invalid configs (with smaller dimens) have - // already been filtered. Note that if a particular dimension - // is unspecified, we will end up with a large value (the - // difference between 0 and the requested dimension), which is - // good since we will prefer a config that has specified a - // dimension value. - int myDelta = 0, otherDelta = 0; - if (requested->screenWidthDp) { - myDelta += requested->screenWidthDp - screenWidthDp; - otherDelta += requested->screenWidthDp - o.screenWidthDp; - } - if (requested->screenHeightDp) { - myDelta += requested->screenHeightDp - screenHeightDp; - otherDelta += requested->screenHeightDp - o.screenHeightDp; - } - //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d", - // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp, - // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta); - return (myDelta <= otherDelta); - } - - if (screenLayout || o.screenLayout) { - if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0 - && (requested->screenLayout & MASK_SCREENSIZE)) { - // A little backwards compatibility here: undefined is - // considered equivalent to normal. But only if the - // requested size is at least normal; otherwise, small - // is better than the default. - int mySL = (screenLayout & MASK_SCREENSIZE); - int oSL = (o.screenLayout & MASK_SCREENSIZE); - int fixedMySL = mySL; - int fixedOSL = oSL; - if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) { - if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL; - if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL; - } - // For screen size, the best match is the one that is - // closest to the requested screen size, but not over - // (the not over part is dealt with in match() below). - if (fixedMySL == fixedOSL) { - // If the two are the same, but 'this' is actually - // undefined, then the other is really a better match. - if (mySL == 0) return false; - return true; - } - return fixedMySL >= fixedOSL; - } - if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0 - && (requested->screenLayout & MASK_SCREENLONG)) { - return (screenLayout & MASK_SCREENLONG); - } - } - - if ((orientation != o.orientation) && requested->orientation) { - return (orientation); - } - - if (uiMode || o.uiMode) { - if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0 - && (requested->uiMode & MASK_UI_MODE_TYPE)) { - return (uiMode & MASK_UI_MODE_TYPE); - } - if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0 - && (requested->uiMode & MASK_UI_MODE_NIGHT)) { - return (uiMode & MASK_UI_MODE_NIGHT); - } - } - - if (screenType || o.screenType) { - if (density != o.density) { - // density is tough. Any density is potentially useful - // because the system will scale it. Scaling down - // is generally better than scaling up. - // Default density counts as 160dpi (the system default) - // TODO - remove 160 constants - int h = (density?density:160); - int l = (o.density?o.density:160); - bool bImBigger = true; - if (l > h) { - int t = h; - h = l; - l = t; - bImBigger = false; - } - - int reqValue = (requested->density?requested->density:160); - if (reqValue >= h) { - // requested value higher than both l and h, give h - return bImBigger; - } - if (l >= reqValue) { - // requested value lower than both l and h, give l - return !bImBigger; - } - // saying that scaling down is 2x better than up - if (((2 * l) - reqValue) * h > reqValue * reqValue) { - return !bImBigger; - } else { - return bImBigger; - } - } - - if ((touchscreen != o.touchscreen) && requested->touchscreen) { - return (touchscreen); - } - } - - if (input || o.input) { - const int keysHidden = inputFlags & MASK_KEYSHIDDEN; - const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN; - if (keysHidden != oKeysHidden) { - const int reqKeysHidden = - requested->inputFlags & MASK_KEYSHIDDEN; - if (reqKeysHidden) { - - if (!keysHidden) return false; - if (!oKeysHidden) return true; - // For compatibility, we count KEYSHIDDEN_NO as being - // the same as KEYSHIDDEN_SOFT. Here we disambiguate - // these by making an exact match more specific. - if (reqKeysHidden == keysHidden) return true; - if (reqKeysHidden == oKeysHidden) return false; - } - } - - const int navHidden = inputFlags & MASK_NAVHIDDEN; - const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN; - if (navHidden != oNavHidden) { - const int reqNavHidden = - requested->inputFlags & MASK_NAVHIDDEN; - if (reqNavHidden) { - - if (!navHidden) return false; - if (!oNavHidden) return true; - } - } - - if ((keyboard != o.keyboard) && requested->keyboard) { - return (keyboard); - } - - if ((navigation != o.navigation) && requested->navigation) { - return (navigation); - } - } - - if (screenSize || o.screenSize) { - // "Better" is based on the sum of the difference between both - // width and height from the requested dimensions. We are - // assuming the invalid configs (with smaller sizes) have - // already been filtered. Note that if a particular dimension - // is unspecified, we will end up with a large value (the - // difference between 0 and the requested dimension), which is - // good since we will prefer a config that has specified a - // size value. - int myDelta = 0, otherDelta = 0; - if (requested->screenWidth) { - myDelta += requested->screenWidth - screenWidth; - otherDelta += requested->screenWidth - o.screenWidth; - } - if (requested->screenHeight) { - myDelta += requested->screenHeight - screenHeight; - otherDelta += requested->screenHeight - o.screenHeight; - } - return (myDelta <= otherDelta); - } - - if (version || o.version) { - if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) { - return (sdkVersion > o.sdkVersion); - } - - if ((minorVersion != o.minorVersion) && - requested->minorVersion) { - return (minorVersion); - } - } - - return false; - } - return isMoreSpecificThan(o); - } + bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const; // Return true if 'this' can be considered a match for the parameters in // 'settings'. @@ -1451,150 +1048,11 @@ struct ResTable_config // 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 (mcc != 0 && mcc != settings.mcc) { - return false; - } - if (mnc != 0 && mnc != settings.mnc) { - return false; - } - } - if (locale != 0) { - if (language[0] != 0 - && (language[0] != settings.language[0] - || language[1] != settings.language[1])) { - return false; - } - if (country[0] != 0 - && (country[0] != settings.country[0] - || country[1] != settings.country[1])) { - return false; - } - } - if (screenConfig != 0) { - const int screenSize = screenLayout&MASK_SCREENSIZE; - const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE; - // Any screen sizes for larger screens than the setting do not - // match. - if (screenSize != 0 && screenSize > setScreenSize) { - return false; - } - - const int screenLong = screenLayout&MASK_SCREENLONG; - const int setScreenLong = settings.screenLayout&MASK_SCREENLONG; - if (screenLong != 0 && screenLong != setScreenLong) { - return false; - } - - const int uiModeType = uiMode&MASK_UI_MODE_TYPE; - const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE; - if (uiModeType != 0 && uiModeType != setUiModeType) { - return false; - } - - const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT; - const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT; - if (uiModeNight != 0 && uiModeNight != setUiModeNight) { - return false; - } - - if (smallestScreenWidthDp != 0 - && smallestScreenWidthDp > settings.smallestScreenWidthDp) { - return false; - } - } - if (screenSizeDp != 0) { - if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) { - //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp); - return false; - } - if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) { - //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp); - return false; - } - } - if (screenType != 0) { - if (orientation != 0 && orientation != settings.orientation) { - return false; - } - // density always matches - we can scale it. See isBetterThan - if (touchscreen != 0 && touchscreen != settings.touchscreen) { - return false; - } - } - if (input != 0) { - const int keysHidden = inputFlags&MASK_KEYSHIDDEN; - const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN; - if (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. - //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden); - if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) { - //ALOGI("No match!"); - return false; - } - } - const int navHidden = inputFlags&MASK_NAVHIDDEN; - const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN; - if (navHidden != 0 && navHidden != setNavHidden) { - return false; - } - if (keyboard != 0 && keyboard != settings.keyboard) { - return false; - } - if (navigation != 0 && navigation != settings.navigation) { - return false; - } - } - if (screenSize != 0) { - if (screenWidth != 0 && screenWidth > settings.screenWidth) { - return false; - } - if (screenHeight != 0 && screenHeight > settings.screenHeight) { - return false; - } - } - if (version != 0) { - if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) { - return false; - } - if (minorVersion != 0 && minorVersion != settings.minorVersion) { - return false; - } - } - return true; - } + bool match(const ResTable_config& settings) const; - 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]; - } - } - } + void getLocale(char str[6]) const; - String8 toString() const { - char buf[200]; - sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d " - "kbd=%d nav=%d input=%d ssz=%dx%d sw%ddp w%ddp h%ddp sz=%d long=%d " - "ui=%d night=%d 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, smallestScreenWidthDp, screenWidthDp, screenHeightDp, - screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG, - uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT, - sdkVersion, minorVersion); - return String8(buf); - } + String8 toString() const; }; /** @@ -2053,8 +1511,14 @@ public: const char16_t* getBasePackageName(size_t idx) const; uint32_t getBasePackageId(size_t idx) const; + // Return the number of resource tables that the object contains. size_t getTableCount() const; + // Return the values string pool for the resource table at the given + // index. This string pool contains all of the strings for values + // contained in the resource table -- that is the item values themselves, + // but not the names their entries or types. const ResStringPool* getTableStringBlock(size_t index) const; + // Return unique cookie identifier for the given resource table. void* getTableCookie(size_t index) const; // Return the configurations (ResTable_config) that we know about diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h index a1663f3..1f2c2d5 100644 --- a/include/utils/TypeHelpers.h +++ b/include/utils/TypeHelpers.h @@ -213,6 +213,9 @@ void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { template <typename KEY, typename VALUE> struct key_value_pair_t { + typedef KEY key_t; + typedef VALUE value_t; + KEY key; VALUE value; key_value_pair_t() { } @@ -222,27 +225,64 @@ struct key_value_pair_t { inline bool operator < (const key_value_pair_t& o) const { return strictly_order_type(key, o.key); } + inline const KEY& getKey() const { + return key; + } + inline const VALUE& getValue() const { + return value; + } }; -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_move< key_value_pair_t<K, V> > { enum { value = aggregate_traits<K,V>::has_trivial_move }; }; // --------------------------------------------------------------------------- +/* + * Hash codes. + */ +typedef uint32_t hash_t; + +template <typename TKey> +hash_t hash_type(const TKey& key); + +/* Built-in hash code specializations. + * Assumes pointers are 32bit. */ +#define ANDROID_INT32_HASH(T) \ + template <> inline hash_t hash_type(const T& value) { return hash_t(value); } +#define ANDROID_INT64_HASH(T) \ + template <> inline hash_t hash_type(const T& value) { \ + return hash_t((value >> 32) ^ value); } +#define ANDROID_REINTERPRET_HASH(T, R) \ + template <> inline hash_t hash_type(const T& value) { \ + return hash_type(*reinterpret_cast<const R*>(&value)); } + +ANDROID_INT32_HASH(bool) +ANDROID_INT32_HASH(int8_t) +ANDROID_INT32_HASH(uint8_t) +ANDROID_INT32_HASH(int16_t) +ANDROID_INT32_HASH(uint16_t) +ANDROID_INT32_HASH(int32_t) +ANDROID_INT32_HASH(uint32_t) +ANDROID_INT64_HASH(int64_t) +ANDROID_INT64_HASH(uint64_t) +ANDROID_REINTERPRET_HASH(float, uint32_t) +ANDROID_REINTERPRET_HASH(double, uint64_t) + +template <typename T> inline hash_t hash_type(const T*& value) { + return hash_type(uintptr_t(value)); +} + }; // namespace android // --------------------------------------------------------------------------- diff --git a/include/utils/threads.h b/include/utils/threads.h index ab3e8cd..b4a8b7c 100644 --- a/include/utils/threads.h +++ b/include/utils/threads.h @@ -526,6 +526,12 @@ public: // Do not call from this object's thread; will return WOULD_BLOCK in that case. status_t join(); +#ifdef HAVE_ANDROID_OS + // Return the thread's kernel ID, same as the thread itself calling gettid() or + // androidGetTid(), or -1 if the thread is not running. + pid_t getTid() const; +#endif + protected: // exitPending() returns true if requestExit() has been called. bool exitPending() const; @@ -551,8 +557,10 @@ private: volatile bool mExitPending; volatile bool mRunning; sp<Thread> mHoldSelf; -#if HAVE_ANDROID_OS - int mTid; +#ifdef HAVE_ANDROID_OS + // legacy for debugging, not used by getTid() as it is set by the child thread + // and so is not initialized until the child reaches that point + pid_t mTid; #endif }; |