diff options
Diffstat (limited to 'include')
98 files changed, 3492 insertions, 3443 deletions
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h index 09f0de1..22c9b72 100644 --- a/include/android_runtime/AndroidRuntime.h +++ b/include/android_runtime/AndroidRuntime.h @@ -30,7 +30,9 @@ namespace android { - + +class CursorWindow; + class AndroidRuntime { public: @@ -122,6 +124,8 @@ private: // Returns the Unix file descriptor for a ParcelFileDescriptor object extern int getParcelFileDescriptorFD(JNIEnv* env, jobject object); +extern CursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow); + } #endif diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h index 5dbec59..990143b 100644 --- a/include/android_runtime/android_app_NativeActivity.h +++ b/include/android_runtime/android_app_NativeActivity.h @@ -83,7 +83,7 @@ public: bool preDispatchEvent(AInputEvent* event); - void finishEvent(AInputEvent* event, bool handled); + void finishEvent(AInputEvent* event, bool handled, bool didDefaultHandling); // ---------------------------------------------------------- diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h new file mode 100644 index 0000000..f0b2909 --- /dev/null +++ b/include/binder/CursorWindow.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID__DATABASE_WINDOW_H +#define _ANDROID__DATABASE_WINDOW_H + +#include <cutils/log.h> +#include <stddef.h> +#include <stdint.h> + +#include <binder/IMemory.h> +#include <utils/RefBase.h> + +#define DEFAULT_WINDOW_SIZE 4096 +#define WINDOW_ALLOCATION_SIZE 4096 + +#define ROW_SLOT_CHUNK_NUM_ROWS 16 + +// Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS, +// with an offset after the rows that points to the next chunk +#define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t)) + + +#if LOG_NDEBUG + +#define IF_LOG_WINDOW() if (false) +#define LOG_WINDOW(...) + +#else + +#define IF_LOG_WINDOW() IF_LOG(LOG_DEBUG, "CursorWindow") +#define LOG_WINDOW(...) LOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__) + +#endif + + +// When defined to true strings are stored as UTF8, otherwise they're UTF16 +#define WINDOW_STORAGE_UTF8 1 + +// When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window +#define WINDOW_STORAGE_INLINE_NUMERICS 1 + +namespace android { + +typedef struct +{ + uint32_t numRows; + uint32_t numColumns; +} window_header_t; + +typedef struct +{ + uint32_t offset; +} row_slot_t; + +typedef struct +{ + uint8_t type; + union { + double d; + int64_t l; + struct { + uint32_t offset; + uint32_t size; + } buffer; + } data; +} __attribute__((packed)) field_slot_t; + +#define FIELD_TYPE_NULL 0 +#define FIELD_TYPE_INTEGER 1 +#define FIELD_TYPE_FLOAT 2 +#define FIELD_TYPE_STRING 3 +#define FIELD_TYPE_BLOB 4 + +/** + * This class stores a set of rows from a database in a buffer. The begining of the + * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by + * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case + * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a + * field_slot_t per column, which has the size, offset, and type of the data for that field. + * Note that the data types come from sqlite3.h. + */ +class CursorWindow +{ +public: + CursorWindow(size_t maxSize); + CursorWindow(){} + bool setMemory(const sp<IMemory>&); + ~CursorWindow(); + + bool initBuffer(bool localOnly); + sp<IMemory> getMemory() {return mMemory;} + + size_t size() {return mSize;} + uint8_t * data() {return mData;} + uint32_t getNumRows() {return mHeader->numRows;} + uint32_t getNumColumns() {return mHeader->numColumns;} + void freeLastRow() { + if (mHeader->numRows > 0) { + mHeader->numRows--; + } + } + bool setNumColumns(uint32_t numColumns) + { + uint32_t cur = mHeader->numColumns; + if (cur > 0 && cur != numColumns) { + LOGE("Trying to go from %d columns to %d", cur, numColumns); + return false; + } + mHeader->numColumns = numColumns; + return true; + } + + int32_t freeSpace(); + + void clear(); + + /** + * Allocate a row slot and its directory. The returned + * pointer points to the begining of the row's directory + * or NULL if there wasn't room. The directory is + * initialied with NULL entries for each field. + */ + field_slot_t * allocRow(); + + /** + * Allocate a portion of the window. Returns the offset + * of the allocation, or 0 if there isn't enough space. + * If aligned is true, the allocation gets 4 byte alignment. + */ + uint32_t alloc(size_t size, bool aligned = false); + + uint32_t read_field_slot(int row, int column, field_slot_t * slot); + + /** + * Copy data into the window at the given offset. + */ + void copyIn(uint32_t offset, uint8_t const * data, size_t size); + void copyIn(uint32_t offset, int64_t data); + void copyIn(uint32_t offset, double data); + + void copyOut(uint32_t offset, uint8_t * data, size_t size); + int64_t copyOutLong(uint32_t offset); + double copyOutDouble(uint32_t offset); + + bool putLong(unsigned int row, unsigned int col, int64_t value); + bool putDouble(unsigned int row, unsigned int col, double value); + bool putNull(unsigned int row, unsigned int col); + + bool getLong(unsigned int row, unsigned int col, int64_t * valueOut); + bool getDouble(unsigned int row, unsigned int col, double * valueOut); + bool getNull(unsigned int row, unsigned int col, bool * valueOut); + + uint8_t * offsetToPtr(uint32_t offset) {return mData + offset;} + + row_slot_t * allocRowSlot(); + + row_slot_t * getRowSlot(int row); + + /** + * return NULL if Failed to find rowSlot or + * Invalid rowSlot + */ + field_slot_t * getFieldSlotWithCheck(int row, int column); + field_slot_t * getFieldSlot(int row, int column) + { + int fieldDirOffset = getRowSlot(row)->offset; + return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column; + } + +private: + uint8_t * mData; + size_t mSize; + size_t mMaxSize; + window_header_t * mHeader; + sp<IMemory> mMemory; + + /** + * Offset of the lowest unused data byte in the array. + */ + uint32_t mFreeOffset; +}; + +}; // namespace android + +#endif diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h index b54718f..3378d97 100644 --- a/include/binder/IPCThreadState.h +++ b/include/binder/IPCThreadState.h @@ -33,6 +33,7 @@ class IPCThreadState { public: static IPCThreadState* self(); + static IPCThreadState* selfOrNull(); // self(), but won't instantiate sp<ProcessState> process(); diff --git a/include/camera/Camera.h b/include/camera/Camera.h index e734c38..e5f7e62 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -19,11 +19,10 @@ #include <utils/Timers.h> #include <camera/ICameraClient.h> +#include <gui/ISurfaceTexture.h> namespace android { -class ISurface; - /* * A set of bit masks for specifying how the received preview frames are * handled before the previewCallback() call. @@ -96,11 +95,19 @@ enum { // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during // preview. CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3, + + // cmdType to disable/enable shutter sound. + // In sendCommand passing arg1 = 0 will disable, + // while passing arg1 = 1 will enable the shutter sound. + CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4, + + // cmdType to play recording sound. + CAMERA_CMD_PLAY_RECORDING_SOUND = 5, }; // camera fatal errors enum { - CAMERA_ERROR_UKNOWN = 1, + CAMERA_ERROR_UNKNOWN = 1, CAMERA_ERROR_SERVER_DIED = 100 }; @@ -166,9 +173,11 @@ public: status_t getStatus() { return mStatus; } - // pass the buffered ISurface to the camera service + // pass the buffered Surface to the camera service status_t setPreviewDisplay(const sp<Surface>& surface); - status_t setPreviewDisplay(const sp<ISurface>& surface); + + // pass the buffered ISurfaceTexture to the camera service + status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture); // start preview mode, must call setPreviewDisplay first status_t startPreview(); @@ -209,6 +218,15 @@ public: // send command to camera driver status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); + // return the total number of available video buffers. + int32_t getNumberOfVideoBuffers() const; + + // return the individual video buffer corresponding to the given index. + sp<IMemory> getVideoBuffer(int32_t index) const; + + // tell camera hal to store meta data or real YUV in video buffers. + status_t storeMetaDataInBuffers(bool enabled); + void setListener(const sp<CameraListener>& listener); void setPreviewCallbackFlags(int preview_callback_flag); diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h index 35c5aa1..86bd849 100644 --- a/include/camera/CameraHardwareInterface.h +++ b/include/camera/CameraHardwareInterface.h @@ -18,15 +18,16 @@ #define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H #include <binder/IMemory.h> +#include <ui/egl/android_natives.h> #include <utils/RefBase.h> #include <surfaceflinger/ISurface.h> +#include <ui/android_native_buffer.h> +#include <ui/GraphicBuffer.h> #include <camera/Camera.h> #include <camera/CameraParameters.h> namespace android { -class Overlay; - /** * The size of image for display. */ @@ -86,8 +87,8 @@ class CameraHardwareInterface : public virtual RefBase { public: virtual ~CameraHardwareInterface() { } - /** Return the IMemoryHeap for the preview image heap */ - virtual sp<IMemoryHeap> getPreviewHeap() const = 0; + /** Set the ANativeWindow to which preview frames are sent */ + virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf) = 0; /** Return the IMemoryHeap for the raw image heap */ virtual sp<IMemoryHeap> getRawHeap() const = 0; @@ -111,6 +112,13 @@ public: /** * Disable a message, or a set of messages. + * + * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal + * should not rely on its client to call releaseRecordingFrame() to release + * video recording frames sent out by the cameral hal before and after the + * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not + * modify/access any video recording frame after calling + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). */ virtual void disableMsgType(int32_t msgType) = 0; @@ -127,12 +135,6 @@ public: virtual status_t startPreview() = 0; /** - * Only used if overlays are used for camera preview. - */ - virtual bool useOverlay() {return false;} - virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;} - - /** * Stop a previously started preview. */ virtual void stopPreview() = 0; @@ -143,9 +145,89 @@ public: virtual bool previewEnabled() = 0; /** + * Retrieve the total number of available buffers from camera hal for passing + * video frame data in a recording session. Must be called again if a new + * recording session is started. + * + * This method should be called after startRecording(), since + * the some camera hal may choose to allocate the video buffers only after + * recording is started. + * + * Some camera hal may not implement this method, and 0 can be returned to + * indicate that this feature is not available. + * + * @return the number of video buffers that camera hal makes available. + * Zero (0) is returned to indicate that camera hal does not support + * this feature. + */ + virtual int32_t getNumberOfVideoBuffers() const { return 0; } + + /** + * Retrieve the video buffer corresponding to the given index in a + * recording session. Must be called again if a new recording session + * is started. + * + * It allows a client to retrieve all video buffers that camera hal makes + * available to passing video frame data by calling this method with all + * valid index values. The valid index value ranges from 0 to n, where + * n = getNumberOfVideoBuffers() - 1. With an index outside of the valid + * range, 0 must be returned. This method should be called after + * startRecording(). + * + * The video buffers should NOT be modified/released by camera hal + * until stopRecording() is called and all outstanding video buffers + * previously sent out via CAMERA_MSG_VIDEO_FRAME have been released + * via releaseVideoBuffer(). + * + * @param index an index to retrieve the corresponding video buffer. + * + * @return the video buffer corresponding to the given index. + */ + virtual sp<IMemory> getVideoBuffer(int32_t index) const { return 0; } + + /** + * Request the camera hal to store meta data or real YUV data in + * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a + * recording session. If it is not called, the default camera + * hal behavior is to store real YUV data in the video buffers. + * + * This method should be called before startRecording() in order + * to be effective. + * + * If meta data is stored in the video buffers, it is up to the + * receiver of the video buffers to interpret the contents and + * to find the actual frame data with the help of the meta data + * in the buffer. How this is done is outside of the scope of + * this method. + * + * Some camera hal may not support storing meta data in the video + * buffers, but all camera hal should support storing real YUV data + * in the video buffers. If the camera hal does not support storing + * the meta data in the video buffers when it is requested to do + * do, INVALID_OPERATION must be returned. It is very useful for + * the camera hal to pass meta data rather than the actual frame + * data directly to the video encoder, since the amount of the + * uncompressed frame data can be very large if video size is large. + * + * @param enable if true to instruct the camera hal to store + * meta data in the video buffers; false to instruct + * the camera hal to store real YUV data in the video + * buffers. + * + * @return OK on success. + */ + virtual status_t storeMetaDataInBuffers(bool enable) { + return enable? INVALID_OPERATION: OK; + } + + /** * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME * message is sent with the corresponding frame. Every record frame must be released - * by calling releaseRecordingFrame(). + * by a cameral hal client via releaseRecordingFrame() before the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility + * to manage the life-cycle of the video recording frames, and the client must + * not modify/access any video recording frames. */ virtual status_t startRecording() = 0; @@ -161,6 +243,13 @@ public: /** * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. + * + * It is camera hal client's responsibility to release video recording + * frames sent out by the camera hal before the camera hal receives + * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives + * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's + * responsibility of managing the life-cycle of the video recording + * frames. */ virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0; diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 4e770fd..431aaa47 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -59,6 +59,35 @@ public: void setPreviewSize(int width, int height); void getPreviewSize(int *width, int *height) const; void getSupportedPreviewSizes(Vector<Size> &sizes) const; + + // Set the dimensions in pixels to the given width and height + // for video frames. The given width and height must be one + // of the supported dimensions returned from + // getSupportedVideoSizes(). Must not be called if + // getSupportedVideoSizes() returns an empty Vector of Size. + void setVideoSize(int width, int height); + // Retrieve the current dimensions (width and height) + // in pixels for video frames, which must be one of the + // supported dimensions returned from getSupportedVideoSizes(). + // Must not be called if getSupportedVideoSizes() returns an + // empty Vector of Size. + void getVideoSize(int *width, int *height) const; + // Retrieve a Vector of supported dimensions (width and height) + // in pixels for video frames. If sizes returned from the method + // is empty, the camera does not support calls to setVideoSize() + // or getVideoSize(). In adddition, it also indicates that + // the camera only has a single output, and does not have + // separate output for video frames and preview frame. + void getSupportedVideoSizes(Vector<Size> &sizes) const; + // Retrieve the preferred preview size (width and height) in pixels + // for video recording. The given width and height must be one of + // supported preview sizes returned from getSupportedPreviewSizes(). + // Must not be called if getSupportedVideoSizes() returns an empty + // Vector of Size. If getSupportedVideoSizes() returns an empty + // Vector of Size, the width and height returned from this method + // is invalid, and is "-1x-1". + void getPreferredPreviewSizeForVideo(int *width, int *height) const; + void setPreviewFrameRate(int fps); int getPreviewFrameRate() const; void getPreviewFpsRange(int *min_fps, int *max_fps) const; @@ -288,6 +317,31 @@ public: // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only. static const char KEY_FOCUS_DISTANCES[]; + // The current dimensions in pixels (width x height) for video frames. + // The width and height must be one of the supported sizes retrieved + // via KEY_SUPPORTED_VIDEO_SIZES. + // Example value: "1280x720". Read/write. + static const char KEY_VIDEO_SIZE[]; + // A list of the supported dimensions in pixels (width x height) + // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in + // frameworks/base/include/camera/Camera.h. + // Example: "176x144,1280x720". Read only. + static const char KEY_SUPPORTED_VIDEO_SIZES[]; + + // Preferred preview frame size in pixels for video recording. + // The width and height must be one of the supported sizes retrieved + // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when + // getSupportedVideoSizes() does not return an empty Vector of Size. + // Camcorder applications are recommended to set the preview size + // to a value that is not larger than the preferred preview size. + // In other words, the product of the width and height of the + // preview size should not be larger than that of the preferred + // preview size. In addition, we recommend to choos a preview size + // that has the same aspect ratio as the resolution of video to be + // recorded. + // Example value: "800x600". Read only. + static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[]; + // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in // frameworks/base/include/camera/Camera.h. // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only. @@ -361,7 +415,10 @@ public: // for barcode reading. static const char SCENE_MODE_BARCODE[]; - // Formats for setPreviewFormat and setPictureFormat. + // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT, + // and KEY_VIDEO_FRAME_FORMAT + // Planar variant of the YUV420 color format + static const char PIXEL_FORMAT_YUV420P[]; static const char PIXEL_FORMAT_YUV422SP[]; static const char PIXEL_FORMAT_YUV420SP[]; // NV21 static const char PIXEL_FORMAT_YUV422I[]; // YUY2 diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h index 6fcf9e5..b2310a6 100644 --- a/include/camera/ICamera.h +++ b/include/camera/ICamera.h @@ -20,10 +20,11 @@ #include <utils/RefBase.h> #include <binder/IInterface.h> #include <binder/Parcel.h> -#include <surfaceflinger/ISurface.h> +#include <surfaceflinger/Surface.h> #include <binder/IMemory.h> #include <utils/String8.h> #include <camera/Camera.h> +#include <gui/ISurfaceTexture.h> namespace android { @@ -45,8 +46,12 @@ public: // allow other processes to use this ICamera interface virtual status_t unlock() = 0; - // pass the buffered ISurface to the camera service - virtual status_t setPreviewDisplay(const sp<ISurface>& surface) = 0; + // pass the buffered Surface to the camera service + virtual status_t setPreviewDisplay(const sp<Surface>& surface) = 0; + + // pass the buffered ISurfaceTexture to the camera service + virtual status_t setPreviewTexture( + const sp<ISurfaceTexture>& surfaceTexture) = 0; // set the preview callback flag to affect how the received frames from // preview are handled. @@ -90,6 +95,15 @@ public: // send command to camera driver virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; + + // return the total number of available video buffers + virtual int32_t getNumberOfVideoBuffers() const = 0; + + // return the individual video buffer corresponding to the given index. + virtual sp<IMemory> getVideoBuffer(int32_t index) const = 0; + + // tell the camera hal to store meta data or real YUV data in video buffers. + virtual status_t storeMetaDataInBuffers(bool enabled) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/diskusage/dirsize.h b/include/diskusage/dirsize.h new file mode 100644 index 0000000..34236c0 --- /dev/null +++ b/include/diskusage/dirsize.h @@ -0,0 +1,30 @@ +/* + * + * 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 __LIBDISKUSAGE_DIRSIZE_H +#define __LIBDISKUSAGE_DIRSIZE_H + +#include <stdint.h> + +__BEGIN_DECLS + +int64_t stat_size(struct stat *s); +int64_t calculate_dir_size(int dfd); + +__END_DECLS + +#endif /* __LIBDISKUSAGE_DIRSIZE_H */ diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h index 004556f..085ebf1 100644 --- a/include/drm/DrmManagerClient.h +++ b/include/drm/DrmManagerClient.h @@ -69,7 +69,7 @@ public: * @return * Handle for the decryption session */ - DecryptHandle* openDecryptSession(int fd, int offset, int length); + DecryptHandle* openDecryptSession(int fd, off64_t offset, off64_t length); /** * Open the decrypt session to decrypt the given protected content @@ -113,7 +113,7 @@ public: * @return status_t * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure */ - status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int position); + status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int64_t position); /** * Initialize decryption for the given unit of the protected content @@ -167,7 +167,7 @@ public: * * @return Number of bytes read. Returns -1 for Failure. */ - ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off_t offset); + ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset); /** * Validates whether an action on the DRM content is allowed or not. diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h index c5765a9..1758cdd 100644 --- a/include/drm/drm_framework_common.h +++ b/include/drm/drm_framework_common.h @@ -217,6 +217,10 @@ public: * POSIX based Decrypt API set for container based DRM */ static const int CONTAINER_BASED = 0x02; + /** + * Decrypt API for Widevine streams + */ + static const int WV_BASED = 0x3; }; /** diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h new file mode 100644 index 0000000..77d37f1 --- /dev/null +++ b/include/gui/ISurfaceTexture.h @@ -0,0 +1,91 @@ +/* + * 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 ANDROID_GUI_ISURFACETEXTURE_H +#define ANDROID_GUI_ISURFACETEXTURE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +#include <binder/IInterface.h> + +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> + +namespace android { +// ---------------------------------------------------------------------------- + +class ISurfaceTexture : public IInterface +{ +public: + DECLARE_META_INTERFACE(SurfaceTexture); + + // requestBuffer requests a new buffer for the given index. The server (i.e. + // the ISurfaceTexture implementation) assigns the newly created buffer to + // the given slot index, and the client is expected to mirror the + // slot->buffer mapping so that it's not necessary to transfer a + // GraphicBuffer for every dequeue operation. + virtual sp<GraphicBuffer> requestBuffer(int slot, uint32_t w, uint32_t h, + uint32_t format, uint32_t usage) = 0; + + // setBufferCount sets the number of buffer slots available. Calling this + // will also cause all buffer slots to be emptied. The caller should empty + // its mirrored copy of the buffer slots when calling this method. + virtual status_t setBufferCount(int bufferCount) = 0; + + // dequeueBuffer requests a new buffer slot for the client to use. Ownership + // of the slot is transfered to the client, meaning that the server will not + // use the contents of the buffer associated with that slot. The slot index + // returned may or may not contain a buffer. If the slot is empty the client + // should call requestBuffer to assign a new buffer to that slot. The client + // is expected to either call cancelBuffer on the dequeued slot or to fill + // in the contents of its associated buffer contents and call queueBuffer. + virtual status_t dequeueBuffer(int *slot) = 0; + + // queueBuffer indicates that the client has finished filling in the + // contents of the buffer associated with slot and transfers ownership of + // that slot back to the server. It is not valid to call queueBuffer on a + // slot that is not owned by the client or one for which a buffer associated + // via requestBuffer. + virtual status_t queueBuffer(int slot) = 0; + + // cancelBuffer indicates that the client does not wish to fill in the + // buffer associated with slot and transfers ownership of the slot back to + // the server. + virtual void cancelBuffer(int slot) = 0; + + virtual status_t setCrop(const Rect& reg) = 0; + virtual status_t setTransform(uint32_t transform) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceTexture : public BnInterface<ISurfaceTexture> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_ISURFACETEXTURE_H diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h new file mode 100644 index 0000000..cbc15d8 --- /dev/null +++ b/include/gui/SurfaceTexture.h @@ -0,0 +1,142 @@ +/* + * 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 ANDROID_GUI_SURFACETEXTURE_H +#define ANDROID_GUI_SURFACETEXTURE_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> + +#include <gui/ISurfaceTexture.h> + +#include <ui/GraphicBuffer.h> + +#include <utils/threads.h> + +#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" + +namespace android { +// ---------------------------------------------------------------------------- + +class SurfaceTexture : public BnSurfaceTexture { +public: + enum { MIN_BUFFER_SLOTS = 3 }; + enum { NUM_BUFFER_SLOTS = 32 }; + + // tex indicates the name OpenGL texture to which images are to be streamed. + // This texture name cannot be changed once the SurfaceTexture is created. + SurfaceTexture(GLuint tex); + + virtual ~SurfaceTexture(); + + // setBufferCount updates the number of available buffer slots. After + // calling this all buffer slots are both unallocated and owned by the + // SurfaceTexture object (i.e. they are not owned by the client). + virtual status_t setBufferCount(int bufferCount); + + virtual sp<GraphicBuffer> requestBuffer(int buf, uint32_t w, uint32_t h, + uint32_t format, uint32_t usage); + + // dequeueBuffer gets the next buffer slot index for the client to use. If a + // buffer slot is available then that slot index is written to the location + // pointed to by the buf argument and a status of OK is returned. If no + // slot is available then a status of -EBUSY is returned and buf is + // unmodified. + virtual status_t dequeueBuffer(int *buf); + + virtual status_t queueBuffer(int buf); + virtual void cancelBuffer(int buf); + virtual status_t setCrop(const Rect& reg); + virtual status_t setTransform(uint32_t transform); + + // updateTexImage sets the image contents of the target texture to that of + // the most recently queued buffer. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + status_t updateTexImage(); + +private: + + // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for + // all slots. + void freeAllBuffers(); + + // createImage creates a new EGLImage from a GraphicBuffer. + EGLImageKHR createImage(EGLDisplay dpy, + const sp<GraphicBuffer>& graphicBuffer); + + enum { INVALID_BUFFER_SLOT = -1 }; + + struct BufferSlot { + // mGraphicBuffer points to the buffer allocated for this slot or is NULL + // if no buffer has been allocated. + sp<GraphicBuffer> mGraphicBuffer; + + // mEglImage is the EGLImage created from mGraphicBuffer. + EGLImageKHR mEglImage; + + // mEglDisplay is the EGLDisplay used to create mEglImage. + EGLDisplay mEglDisplay; + + // mOwnedByClient indicates whether the slot is currently accessible to a + // client and should not be used by the SurfaceTexture object. It gets + // set to true when dequeueBuffer returns the slot and is reset to false + // when the client calls either queueBuffer or cancelBuffer on the slot. + bool mOwnedByClient; + }; + + // mSlots is the array of buffer slots that must be mirrored on the client + // side. This allows buffer ownership to be transferred between the client + // and server without sending a GraphicBuffer over binder. The entire array + // is initialized to NULL at construction time, and buffers are allocated + // for a slot when requestBuffer is called with that slot's index. + BufferSlot mSlots[NUM_BUFFER_SLOTS]; + + // mBufferCount is the number of buffer slots that the client and server + // must maintain. It defaults to MIN_BUFFER_SLOTS and can be changed by + // calling setBufferCount. + int mBufferCount; + + // mCurrentTexture is the buffer slot index of the buffer that is currently + // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, + // indicating that no buffer slot is currently bound to the texture. Note, + // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean + // that no buffer is bound to the texture. A call to setBufferCount will + // reset mCurrentTexture to INVALID_BUFFER_SLOT. + int mCurrentTexture; + + // mLastQueued is the buffer slot index of the most recently enqueued buffer. + // At construction time it is initialized to INVALID_BUFFER_SLOT, and is + // updated each time queueBuffer is called. + int mLastQueued; + + // mTexName is the name of the OpenGL texture to which streamed images will + // be bound when updateTexImage is called. It is set at construction time + // changed with a call to setTexName. + const GLuint mTexName; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of SurfaceTexture objects. It must be locked whenever the + // member variables are accessed. + Mutex mMutex; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SURFACETEXTURE_H diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h new file mode 100644 index 0000000..dd1d490 --- /dev/null +++ b/include/gui/SurfaceTextureClient.h @@ -0,0 +1,118 @@ +/* + * 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 ANDROID_GUI_SURFACETEXTURECLIENT_H +#define ANDROID_GUI_SURFACETEXTURECLIENT_H + +#include <gui/ISurfaceTexture.h> +#include <gui/SurfaceTexture.h> + +#include <ui/egl/android_natives.h> + +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class SurfaceTextureClient + : public EGLNativeBase<ANativeWindow, SurfaceTextureClient, RefBase> +{ +public: + SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture); + +private: + + // can't be copied + SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs); + SurfaceTextureClient(const SurfaceTextureClient& rhs); + + // ANativeWindow hooks + static int setSwapInterval(ANativeWindow* window, int interval); + static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer); + static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer); + static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer); + static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer); + static int query(ANativeWindow* window, int what, int* value); + static int perform(ANativeWindow* window, int operation, ...); + + int setSwapInterval(int interval); + int dequeueBuffer(android_native_buffer_t** buffer); + int lockBuffer(android_native_buffer_t* buffer); + int queueBuffer(android_native_buffer_t* buffer); + int cancelBuffer(android_native_buffer_t* buffer); + int query(int what, int* value); + int perform(int operation, va_list args); + + int dispatchSetUsage(va_list args); + int dispatchConnect(va_list args); + int dispatchDisconnect(va_list args); + int dispatchSetCrop(va_list args); + int dispatchSetBufferCount(va_list args); + int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersTransform(va_list args); + + int connect(int api); + int disconnect(int api); + int setUsage(uint32_t reqUsage); + int setCrop(Rect const* rect); + int setBufferCount(int bufferCount); + int setBuffersGeometry(int w, int h, int format); + int setBuffersTransform(int transform); + + void freeAllBuffers(); + + enum { MIN_BUFFER_SLOTS = SurfaceTexture::MIN_BUFFER_SLOTS }; + enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS }; + enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; + + // mSurfaceTexture is the interface to the surface texture server. All + // operations on the surface texture client ultimately translate into + // interactions with the server using this interface. + sp<ISurfaceTexture> mSurfaceTexture; + + // mSlots stores the buffers that have been allocated for each buffer slot. + // It is initialized to null pointers, and gets filled in with the result of + // ISurfaceTexture::requestBuffer when the client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + sp<GraphicBuffer> mSlots[NUM_BUFFER_SLOTS]; + + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; + + // mReqHeight is the buffer height that will be requested at the next deuque + // operation. It is initialized to 1. + uint32_t mReqHeight; + + // mReqFormat is the buffer pixel format that will be requested at the next + // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. + uint32_t mReqFormat; + + // mReqUsage is the set of buffer usage flags that will be requested + // at the next deuque operation. It is initialized to 0. + uint32_t mReqUsage; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of SurfaceTexture objects. It must be locked whenever the + // member variables are accessed. + Mutex mMutex; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACETEXTURECLIENT_H diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index c967efb..cda2be0 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -403,7 +403,7 @@ public: static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen); protected: - volatile int32_t mEnabled; // enable state + bool mEnabled; // enable state int32_t mSessionId; // audio session ID int32_t mPriority; // priority for effect control status_t mStatus; // effect status @@ -412,6 +412,7 @@ protected: void* mUserData; // client context for callback function effect_descriptor_t mDescriptor; // effect descriptor int32_t mId; // system wide unique effect engine instance ID + Mutex mLock; // Mutex for mEnabled access private: diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 38e3d44..5f7cd90 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -356,7 +356,7 @@ private: sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; sp<ClientRecordThread> mClientRecordThread; - Mutex mRecordThreadLock; + Mutex mLock; uint32_t mFrameCount; diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 9fd905f..1e29d82 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -156,6 +156,7 @@ public: MODE_NORMAL = 0, MODE_RINGTONE, MODE_IN_CALL, + MODE_IN_COMMUNICATION, NUM_MODES // not a valid entry, denotes end-of-list }; @@ -262,11 +263,15 @@ public: DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, DEVICE_OUT_AUX_DIGITAL = 0x400, + DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, + DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, DEVICE_OUT_DEFAULT = 0x8000, DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET | DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET | DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_DEFAULT), + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | + DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | + DEVICE_OUT_DEFAULT), DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), @@ -309,6 +314,8 @@ public: FORCE_WIRED_ACCESSORY, FORCE_BT_CAR_DOCK, FORCE_BT_DESK_DOCK, + FORCE_ANALOG_DOCK, + FORCE_DIGITAL_DOCK, NUM_FORCE_CONFIG, FORCE_DEFAULT = FORCE_NONE }; @@ -466,7 +473,7 @@ public: AudioParameter(const String8& keyValuePairs); virtual ~AudioParameter(); - // reserved parameter keys for changeing standard parameters with setParameters() function. + // reserved parameter keys for changing standard parameters with setParameters() function. // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input // configuration changes and act accordingly. // keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices @@ -474,11 +481,14 @@ public: // keyFormat: to change audio format, value is an int in AudioSystem::audio_format // keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels // keyFrameCount: to change audio output frame count, value is an int + // keyInputSource: to change audio input source, value is an int in audio_source + // (defined in media/mediarecorder.h) static const char *keyRouting; static const char *keySamplingRate; static const char *keyFormat; static const char *keyChannels; static const char *keyFrameCount; + static const char *keyInputSource; String8 toString(); diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 4475d4a..813a905 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -480,6 +480,7 @@ private: uint32_t mFlags; int mSessionId; int mAuxEffectId; + Mutex mLock; }; diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h index 16fb43c..b97c22e 100644 --- a/include/media/EffectApi.h +++ b/include/media/EffectApi.h @@ -602,9 +602,9 @@ enum audio_device_e { // Audio mode enum audio_mode_e { - AUDIO_MODE_NORMAL, // phone idle - AUDIO_MODE_RINGTONE, // phone ringing - AUDIO_MODE_IN_CALL // phone call connected + AUDIO_MODE_NORMAL, // device idle + AUDIO_MODE_RINGTONE, // device ringing + AUDIO_MODE_IN_CALL // audio call connected (VoIP or telephony) }; // Values for "accessMode" field of buffer_config_t: diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 9baba8e..e517cf0 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -33,8 +33,7 @@ public: virtual status_t setDataSource(const char* srcUrl) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual status_t setMode(int mode) = 0; - virtual status_t getMode(int* mode) const = 0; - virtual sp<IMemory> captureFrame() = 0; + virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0; virtual sp<IMemory> extractAlbumArt() = 0; virtual const char* extractMetadata(int keyCode) = 0; }; diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index af9a7ed..bba7ed7 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -25,6 +25,7 @@ namespace android { class Parcel; class ISurface; +class Surface; class IMediaPlayer: public IInterface { @@ -33,7 +34,7 @@ public: virtual void disconnect() = 0; - virtual status_t setVideoSurface(const sp<ISurface>& surface) = 0; + virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepareAsync() = 0; virtual status_t start() = 0; virtual status_t stop() = 0; @@ -46,8 +47,6 @@ public: virtual status_t setAudioStreamType(int type) = 0; virtual status_t setLooping(int loop) = 0; virtual status_t setVolume(float leftVolume, float rightVolume) = 0; - virtual status_t suspend() = 0; - virtual status_t resume() = 0; virtual status_t setAuxEffectSendLevel(float level) = 0; virtual status_t attachAuxEffect(int effectId) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 9416ca1..0bfb166 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -32,6 +32,7 @@ namespace android { class IMediaRecorder; class IOMX; +struct IStreamSource; class IMediaPlayerService: public IInterface { @@ -45,6 +46,11 @@ public: int audioSessionId = 0) = 0; virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId) = 0; + + virtual sp<IMediaPlayer> create( + pid_t pid, const sp<IMediaPlayerClient> &client, + const sp<IStreamSource> &source, int audioSessionId) = 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<IOMX> getOMX() = 0; diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h index 54adca8..28be7c1 100644 --- a/include/media/IMediaRecorder.h +++ b/include/media/IMediaRecorder.h @@ -22,7 +22,7 @@ namespace android { -class ISurface; +class Surface; class ICamera; class IMediaRecorderClient; @@ -32,7 +32,7 @@ public: DECLARE_META_INTERFACE(MediaRecorder); virtual status_t setCamera(const sp<ICamera>& camera) = 0; - virtual status_t setPreviewSurface(const sp<ISurface>& surface) = 0; + virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0; virtual status_t setVideoSource(int vs) = 0; virtual status_t setAudioSource(int as) = 0; virtual status_t setOutputFormat(int of) = 0; @@ -40,6 +40,7 @@ public: virtual status_t setAudioEncoder(int ae) = 0; virtual status_t setOutputFile(const char* path) = 0; virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setOutputFileAuxiliary(int fd) = 0; virtual status_t setVideoSize(int width, int height) = 0; virtual status_t setVideoFrameRate(int frames_per_second) = 0; virtual status_t setParameters(const String8& params) = 0; @@ -68,4 +69,3 @@ public: }; // namespace android #endif // ANDROID_IMEDIARECORDER_H - diff --git a/include/media/IOMX.h b/include/media/IOMX.h index f794766..cb36bbb 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -19,6 +19,7 @@ #define ANDROID_IOMX_H_ #include <binder/IInterface.h> +#include <ui/GraphicBuffer.h> #include <utils/List.h> #include <utils/String8.h> @@ -78,10 +79,20 @@ public: node_id node, OMX_INDEXTYPE index, const void *params, size_t size) = 0; + virtual status_t storeMetaDataInBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; + + virtual status_t enableGraphicBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) = 0; + virtual status_t useGraphicBuffer( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0; + // This API clearly only makes sense if the caller lives in the // same process as the callee, i.e. is the media_server, as the // returned "buffer_data" pointer is just that, a pointer into local @@ -109,33 +120,6 @@ public: node_id node, const char *parameter_name, OMX_INDEXTYPE *index) = 0; - - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight, - int32_t rotationDegrees) = 0; - - // Note: These methods are _not_ virtual, it exists as a wrapper around - // the virtual "createRenderer" method above facilitating extraction - // of the ISurface from a regular Surface or a java Surface object. - sp<IOMXRenderer> createRenderer( - const sp<Surface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight, - int32_t rotationDegrees); - - sp<IOMXRenderer> createRendererFromJavaSurface( - JNIEnv *env, jobject javaSurface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight, - int32_t rotationDegrees); }; struct omx_message { @@ -182,13 +166,6 @@ public: virtual void onMessage(const omx_message &msg) = 0; }; -class IOMXRenderer : public IInterface { -public: - DECLARE_META_INTERFACE(OMXRenderer); - - virtual void render(IOMX::buffer_id buffer) = 0; -}; - //////////////////////////////////////////////////////////////////////////////// class BnOMX : public BnInterface<IOMX> { @@ -205,13 +182,6 @@ public: uint32_t flags = 0); }; -class BnOMXRenderer : public BnInterface<IOMXRenderer> { -public: - virtual status_t onTransact( - uint32_t code, const Parcel &data, Parcel *reply, - uint32_t flags = 0); -}; - } // namespace android #endif // ANDROID_IOMX_H_ diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h new file mode 100644 index 0000000..4b698e6 --- /dev/null +++ b/include/media/IStreamSource.h @@ -0,0 +1,68 @@ +/* + * 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 ANDROID_ISTREAMSOURCE_H_ + +#define ANDROID_ISTREAMSOURCE_H_ + +#include <binder/IInterface.h> + +namespace android { + +struct AMessage; +struct IMemory; +struct IStreamListener; + +struct IStreamSource : public IInterface { + DECLARE_META_INTERFACE(StreamSource); + + virtual void setListener(const sp<IStreamListener> &listener) = 0; + virtual void setBuffers(const Vector<sp<IMemory> > &buffers) = 0; + + virtual void onBufferAvailable(size_t index) = 0; +}; + +struct IStreamListener : public IInterface { + DECLARE_META_INTERFACE(StreamListener); + + enum Command { + EOS, + DISCONTINUITY, + }; + + virtual void queueBuffer(size_t index, size_t size) = 0; + + virtual void issueCommand( + Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// + +struct BnStreamSource : public BnInterface<IStreamSource> { + virtual status_t onTransact( + uint32_t code, const Parcel &data, Parcel *reply, + uint32_t flags = 0); +}; + +struct BnStreamListener : public BnInterface<IStreamListener> { + virtual status_t onTransact( + uint32_t code, const Parcel &data, Parcel *reply, + uint32_t flags = 0); +}; + +} // namespace android + +#endif // ANDROID_ISTREAMSOURCE_H_ diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index ff57774..717849d 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -33,8 +33,7 @@ public: virtual status_t setDataSource(const char *url) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual status_t setMode(int mode) = 0; - virtual status_t getMode(int* mode) const = 0; - virtual VideoFrame* captureFrame() = 0; + virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0; virtual MediaAlbumArt* extractAlbumArt() = 0; virtual const char* extractMetadata(int keyCode) = 0; }; @@ -67,7 +66,7 @@ public: } virtual status_t getMode(int* mode) const { *mode = mMode; return NO_ERROR; } - virtual VideoFrame* captureFrame() { return NULL; } + virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) { return NULL; } virtual MediaAlbumArt* extractAlbumArt() { return NULL; } virtual const char* extractMetadata(int keyCode) { return NULL; } diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 0521709..c0963a6 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -33,13 +33,15 @@ namespace android { class Parcel; class ISurface; +class Surface; template<typename T> class SortedVector; enum player_type { PV_PLAYER = 1, SONIVOX_PLAYER = 2, - STAGEFRIGHT_PLAYER = 4, + STAGEFRIGHT_PLAYER = 3, + NU_PLAYER = 4, // Test players are available only in the 'test' and 'eng' builds. // The shared library with the test player is passed passed as an // argument to the 'test:' url in the setDataSource call. @@ -105,7 +107,12 @@ public: const KeyedVector<String8, String8> *headers = NULL) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; - virtual status_t setVideoSurface(const sp<ISurface>& surface) = 0; + + virtual status_t setDataSource(const sp<IStreamSource> &source) { + return INVALID_OPERATION; + } + + virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepare() = 0; virtual status_t prepareAsync() = 0; virtual status_t start() = 0; @@ -118,8 +125,6 @@ public: virtual status_t reset() = 0; virtual status_t setLooping(int loop) = 0; virtual player_type playerType() = 0; - virtual status_t suspend() { return INVALID_OPERATION; } - virtual status_t resume() { return INVALID_OPERATION; } virtual void setNotifyCallback(void* cookie, notify_callback_f notifyFunc) { mCookie = cookie; mNotify = notifyFunc; } diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h index c3cd361..aa97874 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -25,7 +25,20 @@ namespace android { enum camcorder_quality { CAMCORDER_QUALITY_LOW = 0, - CAMCORDER_QUALITY_HIGH = 1 + CAMCORDER_QUALITY_HIGH = 1, + CAMCORDER_QUALITY_QCIF = 2, + CAMCORDER_QUALITY_CIF = 3, + CAMCORDER_QUALITY_480P = 4, + CAMCORDER_QUALITY_720P = 5, + CAMCORDER_QUALITY_1080P = 6, + + CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000, + CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001, + CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002, + CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003, + CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004, + CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005, + CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006 }; enum video_decoder { @@ -68,6 +81,12 @@ public: camcorder_quality quality) const; /** + * Returns true if a profile for the given camera at the given quality exists, + * or false if not. + */ + bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const; + + /** * Returns the output file formats supported. */ Vector<output_format> getOutputFileFormats() const; @@ -252,6 +271,8 @@ private: Vector<int> mLevels; }; + int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const; + // Debug static void logVideoCodec(const VideoCodec& codec); static void logAudioCodec(const AudioCodec& codec); @@ -281,8 +302,25 @@ private: // If the xml configuration file does not exist, use hard-coded values static MediaProfiles* createDefaultInstance(); - static CamcorderProfile *createDefaultCamcorderLowProfile(); - static CamcorderProfile *createDefaultCamcorderHighProfile(); + + static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality); + static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality); + static void createDefaultCamcorderLowProfiles( + MediaProfiles::CamcorderProfile **lowProfile, + MediaProfiles::CamcorderProfile **lowSpecificProfile); + static void createDefaultCamcorderHighProfiles( + MediaProfiles::CamcorderProfile **highProfile, + MediaProfiles::CamcorderProfile **highSpecificProfile); + + static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality); + static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality); + static void createDefaultCamcorderTimeLapseLowProfiles( + MediaProfiles::CamcorderProfile **lowTimeLapseProfile, + MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile); + static void createDefaultCamcorderTimeLapseHighProfiles( + MediaProfiles::CamcorderProfile **highTimeLapseProfile, + MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile); + static void createDefaultCamcorderProfiles(MediaProfiles *profiles); static void createDefaultVideoEncoders(MediaProfiles *profiles); static void createDefaultAudioEncoders(MediaProfiles *profiles); diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h index 5e9e368..c42346e 100644 --- a/include/media/MediaRecorderBase.h +++ b/include/media/MediaRecorderBase.h @@ -22,7 +22,7 @@ namespace android { -class ISurface; +class Surface; struct MediaRecorderBase { MediaRecorderBase() {} @@ -37,9 +37,10 @@ struct MediaRecorderBase { virtual status_t setVideoSize(int width, int height) = 0; virtual status_t setVideoFrameRate(int frames_per_second) = 0; virtual status_t setCamera(const sp<ICamera>& camera) = 0; - virtual status_t setPreviewSurface(const sp<ISurface>& surface) = 0; + virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0; virtual status_t setOutputFile(const char *path) = 0; virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0; + virtual status_t setOutputFileAuxiliary(int fd) {return INVALID_OPERATION;} virtual status_t setParameters(const String8& params) = 0; virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0; virtual status_t prepare() = 0; diff --git a/include/media/PVMediaRecorder.h b/include/media/PVMediaRecorder.h deleted file mode 100644 index c091c39..0000000 --- a/include/media/PVMediaRecorder.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - ** - ** Copyright 2008, The Android Open Source Project - ** - ** Licensed under the Apache License, Version 2.0 (the "License"); - ** you may not use this file except in compliance with the License. - ** You may obtain a copy of the License at - ** - ** http://www.apache.org/licenses/LICENSE-2.0 - ** - ** Unless required by applicable law or agreed to in writing, software - ** distributed under the License is distributed on an "AS IS" BASIS, - ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ** See the License for the specific language governing permissions and - ** limitations under the License. - */ - -#ifndef ANDROID_PVMEDIARECORDER_H -#define ANDROID_PVMEDIARECORDER_H - -#include <media/IMediaRecorderClient.h> -#include <media/MediaRecorderBase.h> - -namespace android { - -class ISurface; -class ICamera; -class AuthorDriverWrapper; - -class PVMediaRecorder : public MediaRecorderBase { -public: - PVMediaRecorder(); - virtual ~PVMediaRecorder(); - - virtual status_t init(); - virtual status_t setAudioSource(audio_source as); - virtual status_t setVideoSource(video_source vs); - virtual status_t setOutputFormat(output_format of); - virtual status_t setAudioEncoder(audio_encoder ae); - virtual status_t setVideoEncoder(video_encoder ve); - virtual status_t setVideoSize(int width, int height); - virtual status_t setVideoFrameRate(int frames_per_second); - virtual status_t setCamera(const sp<ICamera>& camera); - virtual status_t setPreviewSurface(const sp<ISurface>& surface); - virtual status_t setOutputFile(const char *path); - virtual status_t setOutputFile(int fd, int64_t offset, int64_t length); - virtual status_t setParameters(const String8& params); - virtual status_t setListener(const sp<IMediaRecorderClient>& listener); - virtual status_t prepare(); - virtual status_t start(); - virtual status_t stop(); - virtual status_t close(); - virtual status_t reset(); - virtual status_t getMaxAmplitude(int *max); - virtual status_t dump(int fd, const Vector<String16>& args) const; - -private: - status_t doStop(); - - AuthorDriverWrapper* mAuthorDriverWrapper; - - PVMediaRecorder(const PVMediaRecorder &); - PVMediaRecorder &operator=(const PVMediaRecorder &); -}; - -}; // namespace android - -#endif // ANDROID_PVMEDIARECORDER_H - diff --git a/include/media/PVMetadataRetriever.h b/include/media/PVMetadataRetriever.h deleted file mode 100644 index c202dfe..0000000 --- a/include/media/PVMetadataRetriever.h +++ /dev/null @@ -1,51 +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 ANDROID_PVMETADATARETRIEVER_H -#define ANDROID_PVMETADATARETRIEVER_H - -#include <utils/Errors.h> -#include <media/MediaMetadataRetrieverInterface.h> -#include <private/media/VideoFrame.h> - -namespace android { - -class MetadataDriver; - -class PVMetadataRetriever : public MediaMetadataRetrieverInterface -{ -public: - PVMetadataRetriever(); - virtual ~PVMetadataRetriever(); - - virtual status_t setDataSource(const char *url); - virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setMode(int mode); - virtual status_t getMode(int* mode) const; - virtual VideoFrame* captureFrame(); - virtual MediaAlbumArt* extractAlbumArt(); - virtual const char* extractMetadata(int keyCode); - -private: - mutable Mutex mLock; - MetadataDriver* mMetadataDriver; - char* mDataSourcePath; -}; - -}; // namespace android - -#endif // ANDROID_PVMETADATARETRIEVER_H diff --git a/include/media/PVPlayer.h b/include/media/PVPlayer.h deleted file mode 100644 index df50981..0000000 --- a/include/media/PVPlayer.h +++ /dev/null @@ -1,90 +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 ANDROID_PVPLAYER_H -#define ANDROID_PVPLAYER_H - -#include <utils/Errors.h> -#include <media/MediaPlayerInterface.h> -#include <media/Metadata.h> - -#define MAX_OPENCORE_INSTANCES 25 - -#ifdef MAX_OPENCORE_INSTANCES -#include <cutils/atomic.h> -#endif - -class PlayerDriver; - -namespace android { - -class PVPlayer : public MediaPlayerInterface -{ -public: - PVPlayer(); - virtual ~PVPlayer(); - - virtual status_t initCheck(); - - virtual status_t setDataSource( - const char *url, const KeyedVector<String8, String8> *headers); - - virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setVideoSurface(const sp<ISurface>& surface); - virtual status_t prepare(); - virtual status_t prepareAsync(); - virtual status_t start(); - virtual status_t stop(); - virtual status_t pause(); - virtual bool isPlaying(); - virtual status_t seekTo(int msec); - virtual status_t getCurrentPosition(int *msec); - virtual status_t getDuration(int *msec); - virtual status_t reset(); - virtual status_t setLooping(int loop); - virtual player_type playerType() { return PV_PLAYER; } - virtual status_t invoke(const Parcel& request, Parcel *reply); - virtual status_t getMetadata( - const SortedVector<media::Metadata::Type>& ids, - Parcel *records); - - // make available to PlayerDriver - void sendEvent(int msg, int ext1=0, int ext2=0) { MediaPlayerBase::sendEvent(msg, ext1, ext2); } - -private: - static void do_nothing(status_t s, void *cookie, bool cancelled) { } - static void run_init(status_t s, void *cookie, bool cancelled); - static void run_set_video_surface(status_t s, void *cookie, bool cancelled); - static void run_set_audio_output(status_t s, void *cookie, bool cancelled); - static void run_prepare(status_t s, void *cookie, bool cancelled); - static void check_for_live_streaming(status_t s, void *cookie, bool cancelled); - - PlayerDriver* mPlayerDriver; - char * mDataSourcePath; - bool mIsDataSourceSet; - sp<ISurface> mSurface; - int mSharedFd; - status_t mInit; - int mDuration; - -#ifdef MAX_OPENCORE_INSTANCES - static volatile int32_t sNumInstances; -#endif -}; - -}; // namespace android - -#endif // ANDROID_PVPLAYER_H diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index ddc07f6..03dd52d 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -82,8 +82,7 @@ public: status_t setDataSource(const char* dataSourceUrl); status_t setDataSource(int fd, int64_t offset, int64_t length); status_t setMode(int mode); - status_t getMode(int* mode); - sp<IMemory> captureFrame(); + sp<IMemory> getFrameAtTime(int64_t timeUs, int option); sp<IMemory> extractAlbumArt(); const char* extractMetadata(int keyCode); diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 207191d..88b0c3e 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -169,8 +169,6 @@ public: 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); - status_t suspend(); - status_t resume(); status_t setAudioSessionId(int sessionId); int getAudioSessionId(); status_t setAuxEffectSendLevel(float level); diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 5ab1640..a710546 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -44,7 +44,8 @@ enum audio_source { AUDIO_SOURCE_VOICE_CALL = 4, AUDIO_SOURCE_CAMCORDER = 5, AUDIO_SOURCE_VOICE_RECOGNITION = 6, - AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_RECOGNITION, + AUDIO_SOURCE_VOICE_COMMUNICATION = 7, + AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION, AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type }; @@ -173,6 +174,7 @@ public: status_t setAudioEncoder(int ae); status_t setOutputFile(const char* path); status_t setOutputFile(int fd, int64_t offset, int64_t length); + status_t setOutputFileAuxiliary(int fd); status_t setVideoSize(int width, int height); status_t setVideoFrameRate(int frames_per_second); status_t setParameters(const String8& params); @@ -199,6 +201,7 @@ private: bool mIsAudioEncoderSet; bool mIsVideoEncoderSet; bool mIsOutputFileSet; + bool mIsAuxiliaryOutputFileSet; Mutex mLock; Mutex mNotifyLock; }; diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h index 0d397ac..df5be32 100644 --- a/include/media/mediascanner.h +++ b/include/media/mediascanner.h @@ -38,8 +38,7 @@ struct MediaScanner { typedef bool (*ExceptionCheck)(void* env); virtual status_t processDirectory( - const char *path, const char *extensions, - MediaScannerClient &client, + const char *path, MediaScannerClient &client, ExceptionCheck exceptionCheck, void *exceptionEnv); void setLocale(const char *locale); @@ -55,9 +54,8 @@ private: char *mLocale; status_t doProcessDirectory( - char *path, int pathRemaining, const char *extensions, - MediaScannerClient &client, ExceptionCheck exceptionCheck, - void *exceptionEnv); + char *path, int pathRemaining, MediaScannerClient &client, + ExceptionCheck exceptionCheck, void *exceptionEnv); MediaScanner(const MediaScanner &); MediaScanner &operator=(const MediaScanner &); @@ -73,7 +71,8 @@ public: bool addStringTag(const char* name, const char* value); void endFile(); - virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; + virtual bool scanFile(const char* path, long long lastModified, + long long fileSize, bool isDirectory) = 0; virtual bool handleStringTag(const char* name, const char* value) = 0; virtual bool setMimeType(const char* mimeType) = 0; virtual bool addNoMediaFolder(const char* path) = 0; diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h new file mode 100644 index 0000000..4599d70 --- /dev/null +++ b/include/media/stagefright/ACodec.h @@ -0,0 +1,157 @@ +#ifndef A_CODEC_H_ + +#define A_CODEC_H_ + +#include <stdint.h> +#include <android/native_window.h> +#include <media/IOMX.h> +#include <media/stagefright/foundation/AHierarchicalStateMachine.h> + +namespace android { + +struct ABuffer; +struct MemoryDealer; + +struct ACodec : public AHierarchicalStateMachine { + enum { + kWhatFillThisBuffer = 'fill', + kWhatDrainThisBuffer = 'drai', + kWhatEOS = 'eos ', + kWhatShutdownCompleted = 'scom', + kWhatFlushCompleted = 'fcom', + kWhatOutputFormatChanged = 'outC', + }; + + ACodec(); + + void setNotificationMessage(const sp<AMessage> &msg); + void initiateSetup(const sp<AMessage> &msg); + void signalFlush(); + void signalResume(); + void initiateShutdown(); + +protected: + virtual ~ACodec(); + +private: + struct BaseState; + struct UninitializedState; + struct LoadedToIdleState; + struct IdleToExecutingState; + struct ExecutingState; + struct OutputPortSettingsChangedState; + struct ExecutingToIdleState; + struct IdleToLoadedState; + struct ErrorState; + struct FlushingState; + + enum { + kWhatSetup = 'setu', + kWhatOMXMessage = 'omx ', + kWhatInputBufferFilled = 'inpF', + kWhatOutputBufferDrained = 'outD', + kWhatShutdown = 'shut', + kWhatFlush = 'flus', + kWhatResume = 'resm', + kWhatDrainDeferredMessages = 'drai', + }; + + enum { + kPortIndexInput = 0, + kPortIndexOutput = 1 + }; + + struct BufferInfo { + enum Status { + OWNED_BY_US, + OWNED_BY_COMPONENT, + OWNED_BY_UPSTREAM, + OWNED_BY_DOWNSTREAM, + OWNED_BY_NATIVE_WINDOW, + }; + + IOMX::buffer_id mBufferID; + Status mStatus; + + sp<ABuffer> mData; + sp<GraphicBuffer> mGraphicBuffer; + }; + + sp<AMessage> mNotify; + + sp<UninitializedState> mUninitializedState; + sp<LoadedToIdleState> mLoadedToIdleState; + sp<IdleToExecutingState> mIdleToExecutingState; + sp<ExecutingState> mExecutingState; + sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState; + sp<ExecutingToIdleState> mExecutingToIdleState; + sp<IdleToLoadedState> mIdleToLoadedState; + sp<ErrorState> mErrorState; + sp<FlushingState> mFlushingState; + + AString mComponentName; + sp<IOMX> mOMX; + IOMX::node_id mNode; + sp<MemoryDealer> mDealer[2]; + + sp<ANativeWindow> mNativeWindow; + + Vector<BufferInfo> mBuffers[2]; + bool mPortEOS[2]; + + List<sp<AMessage> > mDeferredQueue; + + bool mSentFormat; + + status_t allocateBuffersOnPort(OMX_U32 portIndex); + status_t freeBuffersOnPort(OMX_U32 portIndex); + status_t freeBuffer(OMX_U32 portIndex, size_t i); + + status_t allocateOutputBuffersFromNativeWindow(); + status_t cancelBufferToNativeWindow(BufferInfo *info); + status_t freeOutputBuffersOwnedByNativeWindow(); + BufferInfo *dequeueBufferFromNativeWindow(); + + BufferInfo *findBufferByID( + uint32_t portIndex, IOMX::buffer_id bufferID, + ssize_t *index = NULL); + + void setComponentRole(bool isEncoder, const char *mime); + void configureCodec(const char *mime, const sp<AMessage> &msg); + + status_t setVideoPortFormatType( + OMX_U32 portIndex, + OMX_VIDEO_CODINGTYPE compressionFormat, + OMX_COLOR_FORMATTYPE colorFormat); + + status_t setSupportedOutputFormat(); + + status_t setupVideoDecoder( + const char *mime, int32_t width, int32_t height); + + status_t setVideoFormatOnPort( + OMX_U32 portIndex, + int32_t width, int32_t height, + OMX_VIDEO_CODINGTYPE compressionFormat); + + status_t setupAACDecoder(int32_t numChannels, int32_t sampleRate); + status_t setMinBufferSize(OMX_U32 portIndex, size_t size); + + status_t initNativeWindow(); + + // Returns true iff all buffers on the given port have status OWNED_BY_US. + bool allYourBuffersAreBelongToUs(OMX_U32 portIndex); + + bool allYourBuffersAreBelongToUs(); + + void deferMessage(const sp<AMessage> &msg); + void processDeferredMessages(); + + void sendFormatChange(); + + DISALLOW_EVIL_CONSTRUCTORS(ACodec); +}; + +} // namespace android + +#endif // A_CODEC_H_ diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h index aa965e1..62d57b4 100644 --- a/include/media/stagefright/AMRWriter.h +++ b/include/media/stagefright/AMRWriter.h @@ -44,7 +44,7 @@ protected: virtual ~AMRWriter(); private: - FILE *mFile; + int mFd; status_t mInitCheck; sp<MediaSource> mSource; bool mStarted; diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index 3192d03..794355b 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -20,39 +20,167 @@ #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaSource.h> +#include <camera/ICamera.h> +#include <camera/CameraParameters.h> #include <utils/List.h> #include <utils/RefBase.h> -#include <utils/threads.h> namespace android { -class ICamera; class IMemory; class Camera; +class Surface; class CameraSource : public MediaSource, public MediaBufferObserver { public: + /** + * Factory method to create a new CameraSource using the current + * settings (such as video size, frame rate, color format, etc) + * from the default camera. + * + * @return NULL on error. + */ static CameraSource *Create(); - static CameraSource *CreateFromCamera(const sp<Camera> &camera); + + /** + * Factory method to create a new CameraSource. + * + * @param camera the video input frame data source. If it is NULL, + * we will try to connect to the camera with the given + * cameraId. + * + * @param cameraId the id of the camera that the source will connect + * to if camera is NULL; otherwise ignored. + * + * @param videoSize the dimension (in pixels) of the video frame + * @param frameRate the target frames per second + * @param surface the preview surface for display where preview + * frames are sent to + * @param storeMetaDataInVideoBuffers true to request the camera + * source to store meta data in video buffers; false to + * request the camera source to store real YUV frame data + * in the video buffers. The camera source may not support + * storing meta data in video buffers, if so, a request + * to do that will NOT be honored. To find out whether + * meta data is actually being stored in video buffers + * during recording, call isMetaDataStoredInVideoBuffers(). + * + * @return NULL on error. + */ + static CameraSource *CreateFromCamera(const sp<ICamera> &camera, + int32_t cameraId, + Size videoSize, + int32_t frameRate, + const sp<Surface>& surface, + bool storeMetaDataInVideoBuffers = false); virtual ~CameraSource(); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + /** + * Check whether a CameraSource object is properly initialized. + * Must call this method before stop(). + * @return OK if initialization has successfully completed. + */ + virtual status_t initCheck() const; + + /** + * Returns the MetaData associated with the CameraSource, + * including: + * kKeyColorFormat: YUV color format of the video frames + * kKeyWidth, kKeyHeight: dimension (in pixels) of the video frames + * kKeySampleRate: frame rate in frames per second + * kKeyMIMEType: always fixed to be MEDIA_MIMETYPE_VIDEO_RAW + */ virtual sp<MetaData> getFormat(); - virtual status_t read( - MediaBuffer **buffer, const ReadOptions *options = NULL); + /** + * Retrieve the total number of video buffers available from + * this source. + * + * This method is useful if these video buffers are used + * for passing video frame data to other media components, + * such as OMX video encoders, in order to eliminate the + * memcpy of the data. + * + * @return the total numbner of video buffers. Returns 0 to + * indicate that this source does not make the video + * buffer information availalble. + */ + size_t getNumberOfVideoBuffers() const; + + /** + * Retrieve the individual video buffer available from + * this source. + * + * @param index the index corresponding to the video buffer. + * Valid range of the index is [0, n], where n = + * getNumberOfVideoBuffers() - 1. + * + * @return the video buffer corresponding to the given index. + * If index is out of range, 0 should be returned. + */ + sp<IMemory> getVideoBuffer(size_t index) const; + + /** + * Tell whether this camera source stores meta data or real YUV + * frame data in video buffers. + * + * @return true if meta data is stored in the video + * buffers; false if real YUV data is stored in + * the video buffers. + */ + bool isMetaDataStoredInVideoBuffers() const; virtual void signalBufferReturned(MediaBuffer* buffer); -private: - friend class CameraSourceListener; +protected: + enum CameraFlags { + FLAGS_SET_CAMERA = 1L << 0, + FLAGS_HOT_CAMERA = 1L << 1, + }; + + int32_t mCameraFlags; + Size mVideoSize; + int32_t mVideoFrameRate; + int32_t mColorFormat; + status_t mInitCheck; - sp<Camera> mCamera; + sp<Camera> mCamera; + sp<Surface> mSurface; sp<MetaData> mMeta; + int64_t mStartTimeUs; + int32_t mNumFramesReceived; + int64_t mLastFrameTimestampUs; + bool mStarted; + + CameraSource(const sp<ICamera>& camera, int32_t cameraId, + Size videoSize, int32_t frameRate, + const sp<Surface>& surface, + bool storeMetaDataInVideoBuffers); + + virtual void startCameraRecording(); + virtual void stopCameraRecording(); + virtual void releaseRecordingFrame(const sp<IMemory>& frame); + + // Returns true if need to skip the current frame. + // Called from dataCallbackTimestamp. + virtual bool skipCurrentFrame(int64_t timestampUs) {return false;} + + // Callback called when still camera raw data is available. + virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) {} + + virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, + const sp<IMemory> &data); + +private: + friend class CameraSourceListener; + Mutex mLock; Condition mFrameAvailableCondition; Condition mFrameCompleteCondition; @@ -60,25 +188,35 @@ private: List<sp<IMemory> > mFramesBeingEncoded; List<int64_t> mFrameTimes; - int64_t mStartTimeUs; int64_t mFirstFrameTimeUs; - int64_t mLastFrameTimestampUs; - int32_t mNumFramesReceived; int32_t mNumFramesEncoded; int32_t mNumFramesDropped; int32_t mNumGlitches; int64_t mGlitchDurationThresholdUs; bool mCollectStats; - bool mStarted; - - CameraSource(const sp<Camera> &camera); - - void dataCallbackTimestamp( - int64_t timestampUs, int32_t msgType, const sp<IMemory> &data); + bool mIsMetaDataStoredInVideoBuffers; void releaseQueuedFrames(); void releaseOneRecordingFrame(const sp<IMemory>& frame); + + status_t init(const sp<ICamera>& camera, int32_t cameraId, + Size videoSize, int32_t frameRate, + bool storeMetaDataInVideoBuffers); + status_t isCameraAvailable(const sp<ICamera>& camera, int32_t cameraId); + status_t isCameraColorFormatSupported(const CameraParameters& params); + status_t configureCamera(CameraParameters* params, + int32_t width, int32_t height, + int32_t frameRate); + + status_t checkVideoSize(const CameraParameters& params, + int32_t width, int32_t height); + + status_t checkFrameRate(const CameraParameters& params, + int32_t frameRate); + + void releaseCamera(); + CameraSource(const CameraSource &); CameraSource &operator=(const CameraSource &); }; diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h new file mode 100644 index 0000000..0e5d534 --- /dev/null +++ b/include/media/stagefright/CameraSourceTimeLapse.h @@ -0,0 +1,243 @@ +/* + * 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 CAMERA_SOURCE_TIME_LAPSE_H_ + +#define CAMERA_SOURCE_TIME_LAPSE_H_ + +#include <pthread.h> + +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class ICamera; +class IMemory; +class Camera; + +class CameraSourceTimeLapse : public CameraSource { +public: + static CameraSourceTimeLapse *CreateFromCamera( + const sp<ICamera> &camera, + int32_t cameraId, + Size videoSize, + int32_t videoFrameRate, + const sp<Surface>& surface, + int64_t timeBetweenTimeLapseFrameCaptureUs); + + virtual ~CameraSourceTimeLapse(); + + // If the frame capture interval is large, read will block for a long time. + // Due to the way the mediaRecorder framework works, a stop() call from + // mediaRecorder waits until the read returns, causing a long wait for + // stop() to return. To avoid this, we can make read() return a copy of the + // last read frame with the same time stamp frequently. This keeps the + // read() call from blocking too long. Calling this function quickly + // captures another frame, keeps its copy, and enables this mode of read() + // returning quickly. + void startQuickReadReturns(); + +private: + // If true, will use still camera takePicture() for time lapse frames + // If false, will use the videocamera frames instead. + bool mUseStillCameraForTimeLapse; + + // Size of picture taken from still camera. This may be larger than the size + // of the video, as still camera may not support the exact video resolution + // demanded. See setPictureSizeToClosestSupported(). + int32_t mPictureWidth; + int32_t mPictureHeight; + + // size of the encoded video. + int32_t mVideoWidth; + int32_t mVideoHeight; + + // True if we need to crop the still camera image to get the video frame. + bool mNeedCropping; + + // Start location of the cropping rectangle. + int32_t mCropRectStartX; + int32_t mCropRectStartY; + + // Time between capture of two frames during time lapse recording + // Negative value indicates that timelapse is disabled. + int64_t mTimeBetweenTimeLapseFrameCaptureUs; + + // Time between two frames in final video (1/frameRate) + int64_t mTimeBetweenTimeLapseVideoFramesUs; + + // Real timestamp of the last encoded time lapse frame + int64_t mLastTimeLapseFrameRealTimestampUs; + + // Thread id of thread which takes still picture and sleeps in a loop. + pthread_t mThreadTimeLapse; + + // Variable set in dataCallbackTimestamp() to help skipCurrentFrame() + // to know if current frame needs to be skipped. + bool mSkipCurrentFrame; + + // Lock for accessing mCameraIdle + Mutex mCameraIdleLock; + + // Condition variable to wait on if camera is is not yet idle. Once the + // camera gets idle, this variable will be signalled. + Condition mCameraIdleCondition; + + // True if camera is in preview mode and ready for takePicture(). + // False after a call to takePicture() but before the final compressed + // data callback has been called and preview has been restarted. + volatile bool mCameraIdle; + + // True if stop() is waiting for camera to get idle, i.e. for the last + // takePicture() to complete. This is needed so that dataCallbackTimestamp() + // can return immediately. + volatile bool mStopWaitingForIdleCamera; + + // Lock for accessing quick stop variables. + Mutex mQuickStopLock; + + // Condition variable to wake up still picture thread. + Condition mTakePictureCondition; + + // mQuickStop is set to true if we use quick read() returns, otherwise it is set + // to false. Once in this mode read() return a copy of the last read frame + // with the same time stamp. See startQuickReadReturns(). + volatile bool mQuickStop; + + // Forces the next frame passed to dataCallbackTimestamp() to be read + // as a time lapse frame. Used by startQuickReadReturns() so that the next + // frame wakes up any blocking read. + volatile bool mForceRead; + + // Stores a copy of the MediaBuffer read in the last read() call after + // mQuickStop was true. + MediaBuffer* mLastReadBufferCopy; + + // Status code for last read. + status_t mLastReadStatus; + + CameraSourceTimeLapse( + const sp<ICamera> &camera, + int32_t cameraId, + Size videoSize, + int32_t videoFrameRate, + const sp<Surface>& surface, + int64_t timeBetweenTimeLapseFrameCaptureUs); + + // Wrapper over CameraSource::signalBufferReturned() to implement quick stop. + // It only handles the case when mLastReadBufferCopy is signalled. Otherwise + // it calls the base class' function. + virtual void signalBufferReturned(MediaBuffer* buffer); + + // Wrapper over CameraSource::read() to implement quick stop. + virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); + + // For still camera case starts a thread which calls camera's takePicture() + // in a loop. For video camera case, just starts the camera's video recording. + virtual void startCameraRecording(); + + // For still camera case joins the thread created in startCameraRecording(). + // For video camera case, just stops the camera's video recording. + virtual void stopCameraRecording(); + + // For still camera case don't need to do anything as memory is locally + // allocated with refcounting. + // For video camera case just tell the camera to release the frame. + virtual void releaseRecordingFrame(const sp<IMemory>& frame); + + // 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); + + // Handles the callback to handle raw frame data from the still camera. + // Creates a copy of the frame data as the camera can reuse the frame memory + // once this callback returns. The function also sets a new timstamp corresponding + // to one frame time ahead of the last encoded frame's time stamp. It then + // calls dataCallbackTimestamp() of the base class with the copied data and the + // modified timestamp, which will think that it recieved the frame from a video + // camera and proceed as usual. + virtual void dataCallback(int32_t msgType, const sp<IMemory> &data); + + // In the video camera case calls skipFrameAndModifyTimeStamp() to modify + // timestamp and set mSkipCurrentFrame. + // Then it calls the base CameraSource::dataCallbackTimestamp() + virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, + const sp<IMemory> &data); + + // Convenience function to fill mLastReadBufferCopy from the just read + // buffer. + void fillLastReadBufferCopy(MediaBuffer& sourceBuffer); + + // If the passed in size (width x height) is a supported video/preview size, + // the function sets the camera's video/preview size to it and returns true. + // Otherwise returns false. + bool trySettingVideoSize(int32_t width, int32_t height); + + // The still camera may not support the demanded video width and height. + // We look for the supported picture sizes from the still camera and + // choose the smallest one with either dimensions higher than the corresponding + // video dimensions. The still picture will be cropped to get the video frame. + // The function returns true if the camera supports picture sizes greater than + // or equal to the passed in width and height, and false otherwise. + bool setPictureSizeToClosestSupported(int32_t width, int32_t height); + + // Computes the offset of the rectangle from where to start cropping the + // still image into the video frame. We choose the center of the image to be + // cropped. The offset is stored in (mCropRectStartX, mCropRectStartY). + bool computeCropRectangleOffset(); + + // Crops the source data into a smaller image starting at + // (mCropRectStartX, mCropRectStartY) and of the size of the video frame. + // The data is returned into a newly allocated IMemory. + sp<IMemory> cropYUVImage(const sp<IMemory> &source_data); + + // When video camera is used for time lapse capture, returns true + // until enough time has passed for the next time lapse frame. When + // the frame needs to be encoded, it returns false and also modifies + // the time stamp to be one frame time ahead of the last encoded + // frame's time stamp. + bool skipFrameAndModifyTimeStamp(int64_t *timestampUs); + + // Wrapper to enter threadTimeLapseEntry() + static void *ThreadTimeLapseWrapper(void *me); + + // Runs a loop which sleeps until a still picture is required + // and then calls mCamera->takePicture() to take the still picture. + // Used only in the case mUseStillCameraForTimeLapse = true. + void threadTimeLapseEntry(); + + // Wrapper to enter threadStartPreview() + static void *ThreadStartPreviewWrapper(void *me); + + // Starts the camera's preview. + void threadStartPreview(); + + // Starts thread ThreadStartPreviewWrapper() for restarting preview. + // Needs to be done in a thread so that dataCallback() which calls this function + // can return, and the camera can know that takePicture() is done. + void restartPreview(); + + // Creates a copy of source_data into a new memory of final type MemoryBase. + sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data); + + CameraSourceTimeLapse(const CameraSourceTimeLapse &); + CameraSourceTimeLapse &operator=(const CameraSourceTimeLapse &); +}; + +} // namespace android + +#endif // CAMERA_SOURCE_TIME_LAPSE_H_ diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h index bc3f464..2ae8a5b 100644 --- a/include/media/stagefright/ColorConverter.h +++ b/include/media/stagefright/ColorConverter.h @@ -21,6 +21,7 @@ #include <sys/types.h> #include <stdint.h> +#include <utils/Errors.h> #include <OMX_Video.h> @@ -32,36 +33,48 @@ struct ColorConverter { bool isValid() const; - void convert( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + status_t convert( + const void *srcBits, + size_t srcWidth, size_t srcHeight, + size_t srcCropLeft, size_t srcCropTop, + size_t srcCropRight, size_t srcCropBottom, + void *dstBits, + size_t dstWidth, size_t dstHeight, + size_t dstCropLeft, size_t dstCropTop, + size_t dstCropRight, size_t dstCropBottom); private: + struct BitmapParams { + BitmapParams( + void *bits, + size_t width, size_t height, + size_t cropLeft, size_t cropTop, + size_t cropRight, size_t cropBottom); + + size_t cropWidth() const; + size_t cropHeight() const; + + void *mBits; + size_t mWidth, mHeight; + size_t mCropLeft, mCropTop, mCropRight, mCropBottom; + }; + OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat; uint8_t *mClip; uint8_t *initClip(); - void convertCbYCrY( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); - - void convertYUV420Planar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); - - void convertQCOMYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); - - void convertYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + status_t convertCbYCrY( + const BitmapParams &src, const BitmapParams &dst); + + status_t convertYUV420Planar( + const BitmapParams &src, const BitmapParams &dst); + + status_t convertQCOMYUV420SemiPlanar( + const BitmapParams &src, const BitmapParams &dst); + + status_t convertYUV420SemiPlanar( + const BitmapParams &src, const BitmapParams &dst); ColorConverter(const ColorConverter &); ColorConverter &operator=(const ColorConverter &); diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index d0b9fcd..d4f1733 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -48,13 +48,13 @@ public: virtual status_t initCheck() const = 0; - virtual ssize_t readAt(off_t offset, void *data, size_t size) = 0; + virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0; // Convenience methods: - bool getUInt16(off_t offset, uint16_t *x); + bool getUInt16(off64_t offset, uint16_t *x); // May return ERROR_UNSUPPORTED. - virtual status_t getSize(off_t *size); + virtual status_t getSize(off64_t *size); virtual uint32_t flags() { return 0; @@ -80,6 +80,9 @@ public: } virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {}; + virtual String8 getUri() { + return String8(); + } protected: virtual ~DataSource() {} diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index 4307263..72a0403 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -34,9 +34,9 @@ public: virtual status_t initCheck() const; - virtual ssize_t readAt(off_t offset, void *data, size_t size); + virtual ssize_t readAt(off64_t offset, void *data, size_t size); - virtual status_t getSize(off_t *size); + virtual status_t getSize(off64_t *size); virtual DecryptHandle* DrmInitialization(DrmManagerClient *client); @@ -46,7 +46,6 @@ protected: virtual ~FileSource(); private: - FILE *mFile; int mFd; int64_t mOffset; int64_t mLength; @@ -59,7 +58,7 @@ private: int64_t mDrmBufSize; unsigned char *mDrmBuf; - ssize_t readAtDRM(off_t offset, void *data, size_t size); + ssize_t readAtDRM(off64_t offset, void *data, size_t size); FileSource(const FileSource &); FileSource &operator=(const FileSource &); diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h index 63f11d1..17908b4 100644 --- a/include/media/stagefright/HardwareAPI.h +++ b/include/media/stagefright/HardwareAPI.h @@ -19,28 +19,76 @@ #define HARDWARE_API_H_ #include <media/stagefright/OMXPluginBase.h> -#include <media/stagefright/VideoRenderer.h> -#include <surfaceflinger/ISurface.h> +#include <ui/android_native_buffer.h> #include <utils/RefBase.h> #include <OMX_Component.h> -extern android::VideoRenderer *createRenderer( - const android::sp<android::ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - -extern android::VideoRenderer *createRendererWithRotation( - const android::sp<android::ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees); +namespace android { + +// A pointer to this struct is passed to the OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension +// is given. +// +// When Android native buffer use is disabled for a port (the default state), +// the OMX node should operate as normal, and expect UseBuffer calls to set its +// buffers. This is the mode that will be used when CPU access to the buffer is +// required. +// +// When Android native buffer use has been enabled for a given port, the video +// color format for the port is to be interpreted as an Android pixel format +// rather than an OMX color format. The node should then expect to receive +// UseAndroidNativeBuffer calls (via OMX_SetParameter) rather than UseBuffer +// calls for that port. +struct EnableAndroidNativeBuffersParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL enable; +}; + +// A pointer to this struct is passed to OMX_SetParameter() when the extension +// index "OMX.google.android.index.storeMetaDataInBuffers" +// is given. +// +// When meta data is stored in the video buffers passed between OMX clients +// and OMX components, interpretation of the buffer data is up to the +// buffer receiver, and the data may or may not be the actual video data, but +// some information helpful for the receiver to locate the actual data. +// The buffer receiver thus needs to know how to interpret what is stored +// in these buffers, with mechanisms pre-determined externally. How to +// interpret the meta data is outside of the scope of this method. +// +// Currently, this is specifically used to pass meta data from video source +// (camera component, for instance) to video encoder to avoid memcpying of +// input video frame data. To do this, bStoreMetaDta is set to OMX_TRUE. +// If bStoreMetaData is set to false, real YUV frame data will be stored +// in the buffers. In addition, if no OMX_SetParameter() call is made +// with the corresponding extension index, real YUV data is stored +// in the buffers. +struct StoreMetaDataInBuffersParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bStoreMetaData; +}; + +// A pointer to this struct is passed to OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is +// given. This call will only be performed if a prior call was made with the +// 'OMX.google.android.index.enableAndroidNativeBuffers' extension index, +// enabling use of Android native buffers. +struct UseAndroidNativeBufferParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_PTR pAppPrivate; + OMX_BUFFERHEADERTYPE **bufferHeader; + const sp<android_native_buffer_t>& nativeBuffer; +}; + +} // namespace android extern android::OMXPluginBase *createOMXPlugin(); #endif // HARDWARE_API_H_ - diff --git a/include/media/stagefright/JPEGSource.h b/include/media/stagefright/JPEGSource.h index 9d0a700..1b7e91b 100644 --- a/include/media/stagefright/JPEGSource.h +++ b/include/media/stagefright/JPEGSource.h @@ -42,9 +42,9 @@ private: sp<DataSource> mSource; MediaBufferGroup *mGroup; bool mStarted; - off_t mSize; + off64_t mSize; int32_t mWidth, mHeight; - off_t mOffset; + off64_t mOffset; status_t parseJPEG(); diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 7bf07eb..f7618e9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -61,20 +61,21 @@ protected: private: class Track; - FILE *mFile; + int mFd; + status_t mInitCheck; bool mUse4ByteNalLength; bool mUse32BitOffset; bool mIsFileSizeLimitExplicitlyRequested; bool mPaused; bool mStarted; - off_t mOffset; + off64_t mOffset; off_t mMdatOffset; uint8_t *mMoovBoxBuffer; - off_t mMoovBoxBufferOffset; + off64_t mMoovBoxBufferOffset; bool mWriteMoovBoxToMemory; - off_t mFreeBoxOffset; + off64_t mFreeBoxOffset; bool mStreamableFile; - off_t mEstimatedMoovBoxSize; + off64_t mEstimatedMoovBoxSize; uint32_t mInterleaveDurationUs; int32_t mTimeScale; int64_t mStartTimestampUs; @@ -83,7 +84,7 @@ private: List<Track *> mTracks; - List<off_t> mBoxes; + List<off64_t> mBoxes; void setStartTimestampUs(int64_t timeUs); int64_t getStartTimestampUs(); // Not const @@ -145,10 +146,10 @@ private: void unlock(); // Acquire lock before calling these methods - off_t addSample_l(MediaBuffer *buffer); - off_t addLengthPrefixedSample_l(MediaBuffer *buffer); + off64_t addSample_l(MediaBuffer *buffer); + off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); - inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream); + inline size_t write(const void *ptr, size_t size, size_t nmemb); bool exceedsFileSizeLimit(); bool use32BitFileOffset() const; bool exceedsFileDurationLimit(); diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h index 339e6fb..c1c4f94 100644 --- a/include/media/stagefright/MediaBuffer.h +++ b/include/media/stagefright/MediaBuffer.h @@ -25,6 +25,7 @@ namespace android { +class GraphicBuffer; class MediaBuffer; class MediaBufferObserver; class MetaData; @@ -48,6 +49,8 @@ public: MediaBuffer(size_t size); + MediaBuffer(const sp<GraphicBuffer>& graphicBuffer); + // Decrements the reference count and returns the buffer to its // associated MediaBufferGroup if the reference count drops to 0. void release(); @@ -63,6 +66,8 @@ public: void set_range(size_t offset, size_t length); + sp<GraphicBuffer> graphicBuffer() const; + sp<MetaData> meta_data(); // Clears meta data and resets the range to the full extent. @@ -94,6 +99,7 @@ private: void *mData; size_t mSize, mRangeOffset, mRangeLength; + sp<GraphicBuffer> mGraphicBuffer; bool mOwnsData; diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 92ce068..2d50ca5 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -44,6 +44,8 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_OGG; extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA; extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS; +extern const char *MEDIA_MIMETYPE_CONTAINER_WVM; + } // namespace android #endif // MEDIA_DEFS_H_ diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index dafc621..a31395e 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -78,31 +78,18 @@ struct MediaSource : public RefBase { void clearSeekTo(); bool getSeekTo(int64_t *time_us, SeekMode *mode) const; - // Option allows encoder to skip some frames until the specified - // time stamp. - // To prevent from being abused, when the skipFrame timestamp is - // found to be more than 1 second later than the current timestamp, - // an error will be returned from read(). - void clearSkipFrame(); - bool getSkipFrame(int64_t *timeUs) const; - void setSkipFrame(int64_t timeUs); - void setLateBy(int64_t lateness_us); int64_t getLateBy() const; private: enum Options { - // Bit map kSeekTo_Option = 1, - kSkipFrame_Option = 2, }; uint32_t mOptions; int64_t mSeekTimeUs; SeekMode mSeekMode; int64_t mLatenessUs; - - int64_t mSkipFrameUntilTimeUs; }; // Causes this source to suspend pulling data from its upstream source diff --git a/include/media/stagefright/MediaSourceSplitter.h b/include/media/stagefright/MediaSourceSplitter.h new file mode 100644 index 0000000..568f4c2 --- /dev/null +++ b/include/media/stagefright/MediaSourceSplitter.h @@ -0,0 +1,193 @@ +/* + * 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. + */ + +// This class provides a way to split a single media source into multiple sources. +// The constructor takes in the real mediaSource and createClient() can then be +// used to create multiple sources served from this real mediaSource. +// +// Usage: +// - Create MediaSourceSplitter by passing in a real mediaSource from which +// multiple duplicate channels are needed. +// - Create a client using createClient() and use it as any other mediaSource. +// +// Note that multiple clients can be created using createClient() and +// started/stopped in any order. MediaSourceSplitter stops the real source only +// when all clients have been stopped. +// +// If a new client is created/started after some existing clients have already +// started, the new client will start getting its read frames from the current +// time. + +#ifndef MEDIA_SOURCE_SPLITTER_H_ + +#define MEDIA_SOURCE_SPLITTER_H_ + +#include <media/stagefright/MediaSource.h> +#include <utils/threads.h> +#include <utils/Vector.h> +#include <utils/RefBase.h> + +namespace android { + +class MediaBuffer; +class MetaData; + +class MediaSourceSplitter : public RefBase { +public: + // Constructor + // mediaSource: The real mediaSource. The class keeps a reference to it to + // implement the various clients. + MediaSourceSplitter(sp<MediaSource> mediaSource); + + ~MediaSourceSplitter(); + + // Creates a new client of base type MediaSource. Multiple clients can be + // created which get their data through the same real mediaSource. These + // clients can then be used like any other MediaSource, all of which provide + // data from the same real source. + sp<MediaSource> createClient(); + +private: + // Total number of clients created through createClient(). + int32_t mNumberOfClients; + + // reference to the real MediaSource passed to the constructor. + sp<MediaSource> mSource; + + // Stores pointer to the MediaBuffer read from the real MediaSource. + // All clients use this to implement the read() call. + MediaBuffer *mLastReadMediaBuffer; + + // Status code for read from the real MediaSource. All clients return + // this for their read(). + status_t mLastReadStatus; + + // Boolean telling whether the real MediaSource has started. + bool mSourceStarted; + + // List of booleans, one for each client, storing whether the corresponding + // client's start() has been called. + Vector<bool> mClientsStarted; + + // Stores the number of clients which are currently started. + int32_t mNumberOfClientsStarted; + + // Since different clients call read() asynchronously, we need to keep track + // of what data is currently read into the mLastReadMediaBuffer. + // mCurrentReadBit stores the bit for the current read buffer. This bit + // flips each time a new buffer is read from the source. + // mClientsDesiredReadBit stores the bit for the next desired read buffer + // for each client. This bit flips each time read() is completed for this + // client. + bool mCurrentReadBit; + Vector<bool> mClientsDesiredReadBit; + + // Number of clients whose current read has been completed. + int32_t mNumberOfCurrentReads; + + // Boolean telling whether the last read has been completed for all clients. + // The variable is reset to false each time buffer is read from the real + // source. + bool mLastReadCompleted; + + // A global mutex for access to critical sections. + Mutex mLock; + + // Condition variable for waiting on read from source to complete. + Condition mReadFromSourceCondition; + + // Condition variable for waiting on all client's last read to complete. + Condition mAllReadsCompleteCondition; + + // Functions used by Client to implement the MediaSource interface. + + // If the real source has not been started yet by any client, starts it. + status_t start(int clientId, MetaData *params); + + // Stops the real source after all clients have called stop(). + status_t stop(int clientId); + + // returns the real source's getFormat(). + sp<MetaData> getFormat(int clientId); + + // If the client's desired buffer has already been read into + // mLastReadMediaBuffer, points the buffer to that. Otherwise if it is the + // master client, reads the buffer from source or else waits for the master + // client to read the buffer and uses that. + status_t read(int clientId, + MediaBuffer **buffer, const MediaSource::ReadOptions *options = NULL); + + // Not implemented right now. + status_t pause(int clientId); + + // Function which reads a buffer from the real source into + // mLastReadMediaBuffer + void readFromSource_lock(const MediaSource::ReadOptions *options); + + // Waits until read from the real source has been completed. + // _lock means that the function should be called when the thread has already + // obtained the lock for the mutex mLock. + void waitForReadFromSource_lock(int32_t clientId); + + // Waits until all clients have read the current buffer in + // mLastReadCompleted. + void waitForAllClientsLastRead_lock(int32_t clientId); + + // Each client calls this after it completes its read(). Once all clients + // have called this for the current buffer, the function calls + // mAllReadsCompleteCondition.broadcast() to signal the waiting clients. + void signalReadComplete_lock(bool readAborted); + + // Make these constructors private. + MediaSourceSplitter(); + MediaSourceSplitter(const MediaSourceSplitter &); + MediaSourceSplitter &operator=(const MediaSourceSplitter &); + + // This class implements the MediaSource interface. Each client stores a + // reference to the parent MediaSourceSplitter and uses it to complete the + // various calls. + class Client : public MediaSource { + public: + // Constructor stores reference to the parent MediaSourceSplitter and it + // client id. + Client(sp<MediaSourceSplitter> splitter, int32_t clientId); + + // MediaSource interface + virtual status_t start(MetaData *params = NULL); + + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + + virtual status_t pause(); + + private: + // Refernce to the parent MediaSourceSplitter + sp<MediaSourceSplitter> mSplitter; + + // Id of this client. + int32_t mClientId; + }; + + friend class Client; +}; + +} // namespace android + +#endif // MEDIA_SOURCE_SPLITTER_H_ diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index ea2fa52..5170a2c 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -32,12 +32,17 @@ enum { kKeyMIMEType = 'mime', // cstring kKeyWidth = 'widt', // int32_t kKeyHeight = 'heig', // int32_t + + // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1) + kKeyCropRect = 'crop', + kKeyRotation = 'rotA', // int32_t (angle in degrees) kKeyIFramesInterval = 'ifiv', // int32_t kKeyStride = 'strd', // int32_t kKeySliceHeight = 'slht', // int32_t kKeyChannelCount = '#chn', // int32_t - kKeySampleRate = 'srte', // int32_t (also video frame rate) + kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz) + kKeyFrameRate = 'frmR', // int32_t (video frame rate fps) kKeyBitRate = 'brte', // int32_t (bps) kKeyESDS = 'esds', // raw data kKeyAVCC = 'avcc', // raw data @@ -94,7 +99,6 @@ enum { // Track authoring progress status // kKeyTrackTimeStatus is used to track progress in elapsed time kKeyTrackTimeStatus = 'tktm', // int64_t - kKeyRotationDegree = 'rdge', // int32_t (clockwise, in degree) kKeyNotRealTime = 'ntrt', // bool (int32_t) @@ -104,6 +108,9 @@ enum { kKeyValidSamples = 'valD', // int32_t kKeyIsUnreadable = 'unre', // bool (int32_t) + + // An indication that a video buffer has been rendered. + kKeyRendered = 'rend', // bool (int32_t) }; enum { @@ -123,6 +130,7 @@ public: TYPE_INT64 = 'in64', TYPE_FLOAT = 'floa', TYPE_POINTER = 'ptr ', + TYPE_RECT = 'rect', }; void clear(); @@ -134,12 +142,22 @@ public: bool setFloat(uint32_t key, float value); bool setPointer(uint32_t key, void *value); + bool setRect( + uint32_t key, + int32_t left, int32_t top, + int32_t right, int32_t bottom); + bool findCString(uint32_t key, const char **value); bool findInt32(uint32_t key, int32_t *value); bool findInt64(uint32_t key, int64_t *value); bool findFloat(uint32_t key, float *value); bool findPointer(uint32_t key, void **value); + bool findRect( + uint32_t key, + int32_t *left, int32_t *top, + int32_t *right, int32_t *bottom); + bool setData(uint32_t key, uint32_t type, const void *data, size_t size); bool findData(uint32_t key, uint32_t *type, @@ -185,6 +203,10 @@ private: } }; + struct Rect { + int32_t mLeft, mTop, mRight, mBottom; + }; + KeyedVector<uint32_t, typed_data> mItems; // MetaData &operator=(const MetaData &); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index fed6761..f8daa4f 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -18,6 +18,7 @@ #define OMX_CODEC_H_ +#include <android/native_window.h> #include <media/IOMX.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaSource.h> @@ -38,13 +39,22 @@ struct OMXCodec : public MediaSource, // The client wants to access the output buffer's video // data for example for thumbnail extraction. kClientNeedsFramebuffer = 4, + + // Request for software or hardware codecs. If request + // can not be fullfilled, Create() returns NULL. + kSoftwareCodecsOnly = 8, + kHardwareCodecsOnly = 16, + + // Store meta data in video buffers + kStoreMetaDataInVideoBuffers = 32, }; static sp<MediaSource> Create( const sp<IOMX> &omx, const sp<MetaData> &meta, bool createEncoder, const sp<MediaSource> &source, const char *matchComponentName = NULL, - uint32_t flags = 0); + uint32_t flags = 0, + const sp<ANativeWindow> &nativeWindow = NULL); static void setComponentRole( const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, @@ -60,8 +70,6 @@ struct OMXCodec : public MediaSource, virtual status_t pause(); - void on_message(const omx_message &msg); - // from MediaBufferObserver virtual void signalBufferReturned(MediaBuffer *buffer); @@ -69,6 +77,13 @@ protected: virtual ~OMXCodec(); private: + + // Make sure mLock is accessible to OMXCodecObserver + friend class OMXCodecObserver; + + // Call this with mLock hold + void on_message(const omx_message &msg); + enum State { DEAD, LOADED, @@ -109,12 +124,18 @@ private: kAvoidMemcopyInputRecordingFrames = 2048, kRequiresLargerEncoderOutputBuffer = 4096, kOutputBuffersAreUnreadable = 8192, - kStoreMetaDataInInputVideoBuffers = 16384, + }; + + enum BufferStatus { + OWNED_BY_US, + OWNED_BY_COMPONENT, + OWNED_BY_NATIVE_WINDOW, + OWNED_BY_CLIENT, }; struct BufferInfo { IOMX::buffer_id mBuffer; - bool mOwnedByComponent; + BufferStatus mStatus; sp<IMemory> mMem; size_t mSize; void *mData; @@ -151,7 +172,6 @@ private: int64_t mSeekTimeUs; ReadOptions::SeekMode mSeekMode; int64_t mTargetTimeUs; - int64_t mSkipTimeUs; MediaBuffer *mLeftOverBuffer; @@ -160,13 +180,23 @@ private: bool mPaused; + sp<ANativeWindow> mNativeWindow; + + // The index in each of the mPortBuffers arrays of the buffer that will be + // submitted to OMX next. This only applies when using buffers from a + // native window. + size_t mNextNativeBufferIndex[2]; + // A list of indices into mPortStatus[kPortIndexOutput] filled with data. List<size_t> mFilledBuffers; Condition mBufferFilled; + bool mIsMetaDataStoredInVideoBuffers; + OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, bool isEncoder, const char *mime, const char *componentName, - const sp<MediaSource> &source); + const sp<MediaSource> &source, + const sp<ANativeWindow> &nativeWindow); void addCodecSpecificData(const void *data, size_t size); void clearCodecSpecificData(); @@ -217,13 +247,20 @@ private: status_t allocateBuffers(); status_t allocateBuffersOnPort(OMX_U32 portIndex); + status_t allocateOutputBuffersFromNativeWindow(); + + status_t queueBufferToNativeWindow(BufferInfo *info); + status_t cancelBufferToNativeWindow(BufferInfo *info); + BufferInfo* dequeueBufferFromNativeWindow(); status_t freeBuffersOnPort( OMX_U32 portIndex, bool onlyThoseWeOwn = false); - void drainInputBuffer(IOMX::buffer_id buffer); + status_t freeBuffer(OMX_U32 portIndex, size_t bufIndex); + + bool drainInputBuffer(IOMX::buffer_id buffer); void fillOutputBuffer(IOMX::buffer_id buffer); - void drainInputBuffer(BufferInfo *info); + bool drainInputBuffer(BufferInfo *info); void fillOutputBuffer(BufferInfo *info); void drainInputBuffers(); @@ -251,6 +288,7 @@ private: status_t init(); void initOutputFormat(const sp<MetaData> &inputFormat); + status_t initNativeWindow(); void dumpPortStatus(OMX_U32 portIndex); @@ -265,6 +303,8 @@ private: uint32_t flags, Vector<String8> *matchingCodecs); + void restorePatchedDataPointer(BufferInfo *info); + OMXCodec(const OMXCodec &); OMXCodec &operator=(const OMXCodec &); }; @@ -277,6 +317,7 @@ struct CodecProfileLevel { struct CodecCapabilities { String8 mComponentName; Vector<CodecProfileLevel> mProfileLevels; + Vector<OMX_U32> mColorFormats; }; // Return a vector of componentNames with supported profile/level pairs diff --git a/include/media/stagefright/VideoRenderer.h b/include/media/stagefright/VideoRenderer.h deleted file mode 100644 index f80b277..0000000 --- a/include/media/stagefright/VideoRenderer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VIDEO_RENDERER_H_ - -#define VIDEO_RENDERER_H_ - -#include <sys/types.h> - -namespace android { - -class VideoRenderer { -public: - virtual ~VideoRenderer() {} - - virtual void render( - const void *data, size_t size, void *platformPrivate) = 0; - -protected: - VideoRenderer() {} - - VideoRenderer(const VideoRenderer &); - VideoRenderer &operator=(const VideoRenderer &); -}; - -} // namespace android - -#endif // VIDEO_RENDERER_H_ diff --git a/include/media/stagefright/VideoSourceDownSampler.h b/include/media/stagefright/VideoSourceDownSampler.h new file mode 100644 index 0000000..439918c --- /dev/null +++ b/include/media/stagefright/VideoSourceDownSampler.h @@ -0,0 +1,97 @@ +/* + * 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. + */ + +// VideoSourceDownSampler implements the MediaSource interface, +// downsampling frames provided from a real video source. + +#ifndef VIDEO_SOURCE_DOWN_SAMPLER_H_ + +#define VIDEO_SOURCE_DOWN_SAMPLER_H_ + +#include <media/stagefright/MediaSource.h> +#include <utils/RefBase.h> + +namespace android { + +class IMemory; +class MediaBuffer; +class MetaData; + +class VideoSourceDownSampler : public MediaSource { +public: + virtual ~VideoSourceDownSampler(); + + // Constructor: + // videoSource: The real video source which provides the original frames. + // width, height: The desired width, height. These should be less than or equal + // to those of the real video source. We then downsample the original frames to + // this size. + VideoSourceDownSampler(const sp<MediaSource> &videoSource, + int32_t width, int32_t height); + + // MediaSource interface + virtual status_t start(MetaData *params = NULL); + + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + + virtual status_t pause(); + +private: + // Reference to the real video source. + sp<MediaSource> mRealVideoSource; + + // Size of frames to be provided by this source. + int32_t mWidth; + int32_t mHeight; + + // Size of frames provided by the real source. + int32_t mRealSourceWidth; + int32_t mRealSourceHeight; + + // Down sampling paramters. + int32_t mDownSampleOffsetX; + int32_t mDownSampleOffsetY; + int32_t mDownSampleSkipX; + int32_t mDownSampleSkipY; + + // True if we need to crop the still video image to get the video frame. + bool mNeedDownSampling; + + // Meta data. This is a copy of the real source except for the width and + // height parameters. + sp<MetaData> mMeta; + + // Computes the offset, skip parameters for downsampling the original frame + // to the desired size. + void computeDownSamplingParameters(); + + // Downsamples the frame in sourceBuffer to size (mWidth x mHeight). A new + // buffer is created which stores the downsampled image. + void downSampleYUVImage(const MediaBuffer &sourceBuffer, MediaBuffer **buffer) const; + + // Disallow these. + VideoSourceDownSampler(const VideoSourceDownSampler &); + VideoSourceDownSampler &operator=(const VideoSourceDownSampler &); +}; + +} // namespace android + +#endif // VIDEO_SOURCE_DOWN_SAMPLER_H_ diff --git a/include/media/stagefright/YUVCanvas.h b/include/media/stagefright/YUVCanvas.h new file mode 100644 index 0000000..ff70923 --- /dev/null +++ b/include/media/stagefright/YUVCanvas.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +// YUVCanvas holds a reference to a YUVImage on which it can do various +// drawing operations. It provides various utility functions for filling, +// cropping, etc. + + +#ifndef YUV_CANVAS_H_ + +#define YUV_CANVAS_H_ + +#include <stdint.h> + +namespace android { + +class YUVImage; +class Rect; + +class YUVCanvas { +public: + + // Constructor takes in reference to a yuvImage on which it can do + // various drawing opreations. + YUVCanvas(YUVImage &yuvImage); + ~YUVCanvas(); + + // Fills the entire image with the given YUV values. + void FillYUV(uint8_t yValue, uint8_t uValue, uint8_t vValue); + + // Fills the rectangular region [startX,endX]x[startY,endY] with the given YUV values. + void FillYUVRectangle(const Rect& rect, + uint8_t yValue, uint8_t uValue, uint8_t vValue); + + // Copies the region [startX,endX]x[startY,endY] from srcImage into the + // canvas' target image (mYUVImage) starting at + // (destinationStartX,destinationStartY). + // Note that undefined behavior may occur if srcImage is same as the canvas' + // target image. + void CopyImageRect( + const Rect& srcRect, + int32_t destStartX, int32_t destStartY, + const YUVImage &srcImage); + + // Downsamples the srcImage into the canvas' target image (mYUVImage) + // The downsampling copies pixels from the source image starting at + // (srcOffsetX, srcOffsetY) to the target image, starting at (0, 0). + // For each X increment in the target image, skipX pixels are skipped + // in the source image. + // Similarly for each Y increment in the target image, skipY pixels + // are skipped in the source image. + void downsample( + int32_t srcOffsetX, int32_t srcOffsetY, + int32_t skipX, int32_t skipY, + const YUVImage &srcImage); + +private: + YUVImage& mYUVImage; + + YUVCanvas(const YUVCanvas &); + YUVCanvas &operator=(const YUVCanvas &); +}; + +} // namespace android + +#endif // YUV_CANVAS_H_ diff --git a/include/media/stagefright/YUVImage.h b/include/media/stagefright/YUVImage.h new file mode 100644 index 0000000..4e98618 --- /dev/null +++ b/include/media/stagefright/YUVImage.h @@ -0,0 +1,178 @@ +/* + * 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. + */ + +// A container class to hold YUV data and provide various utilities, +// e.g. to set/get pixel values. +// Supported formats: +// - YUV420 Planar +// - YUV420 Semi Planar +// +// Currently does not support variable strides. +// +// Implementation: Two simple abstractions are done to simplify access +// to YUV channels for different formats: +// - initializeYUVPointers() sets up pointers (mYdata, mUdata, mVdata) to +// point to the right start locations of the different channel data depending +// on the format. +// - getOffsets() returns the correct offset for the different channels +// depending on the format. +// Location of any pixel's YUV channels can then be easily computed using these. +// + +#ifndef YUV_IMAGE_H_ + +#define YUV_IMAGE_H_ + +#include <stdint.h> +#include <cstring> + +namespace android { + +class Rect; + +class YUVImage { +public: + // Supported YUV formats + enum YUVFormat { + YUV420Planar, + YUV420SemiPlanar + }; + + // Constructs an image with the given size, format. Also allocates and owns + // the required memory. + YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height); + + // Constructs an image with the given size, format. The memory is provided + // by the caller and we don't own it. + YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer); + + // Destructor to delete the memory if it owns it. + ~YUVImage(); + + // Returns the size of the buffer required to store the YUV data for the given + // format and geometry. Useful when the caller wants to allocate the requisite + // memory. + static size_t bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height); + + int32_t width() const {return mWidth;} + int32_t height() const {return mHeight;} + + // Returns true if pixel is the range [0, width-1] x [0, height-1] + // and false otherwise. + bool validPixel(int32_t x, int32_t y) const; + + // Get the pixel YUV value at pixel (x,y). + // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. + // Returns true if get was successful and false otherwise. + bool getPixelValue(int32_t x, int32_t y, + uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const; + + // Set the pixel YUV value at pixel (x,y). + // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. + // Returns true if set was successful and false otherwise. + bool setPixelValue(int32_t x, int32_t y, + uint8_t yValue, uint8_t uValue, uint8_t vValue); + + // Uses memcpy to copy an entire row of data + static void fastCopyRectangle420Planar( + const Rect& srcRect, + int32_t destStartX, int32_t destStartY, + const YUVImage &srcImage, YUVImage &destImage); + + // Uses memcpy to copy an entire row of data + static void fastCopyRectangle420SemiPlanar( + const Rect& srcRect, + int32_t destStartX, int32_t destStartY, + const YUVImage &srcImage, YUVImage &destImage); + + // Tries to use memcopy to copy entire rows of data. + // Returns false if fast copy is not possible for the passed image formats. + static bool fastCopyRectangle( + const Rect& srcRect, + int32_t destStartX, int32_t destStartY, + const YUVImage &srcImage, YUVImage &destImage); + + // Convert the given YUV value to RGB. + void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue, + uint8_t *r, uint8_t *g, uint8_t *b) const; + + // Write the image to a human readable PPM file. + // Returns true if write was succesful and false otherwise. + bool writeToPPM(const char *filename) const; + +private: + // YUV Format of the image. + YUVFormat mYUVFormat; + + int32_t mWidth; + int32_t mHeight; + + // Pointer to the memory buffer. + uint8_t *mBuffer; + + // Boolean telling whether we own the memory buffer. + bool mOwnBuffer; + + // Pointer to start of the Y data plane. + uint8_t *mYdata; + + // Pointer to start of the U data plane. Note that in case of interleaved formats like + // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane. + uint8_t *mUdata; + + // Pointer to start of the V data plane. Note that in case of interleaved formats like + // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane. + uint8_t *mVdata; + + // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for + // the given format and geometry. + // Returns true if initialize was succesful and false otherwise. + bool initializeYUVPointers(); + + // For the given pixel location, this returns the offset of the location of y, u and v + // data from the corresponding base pointers -- mYdata, mUdata, mVdata. + // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. + // Returns true if getting offsets was succesful and false otherwise. + bool getOffsets(int32_t x, int32_t y, + int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const; + + // Returns the offset increments incurred in going from one data row to the next data row + // for the YUV channels. Note that this corresponds to data rows and not pixel rows. + // E.g. depending on formats, U/V channels may have only one data row corresponding + // to two pixel rows. + bool getOffsetIncrementsPerDataRow( + int32_t *yDataOffsetIncrement, + int32_t *uDataOffsetIncrement, + int32_t *vDataOffsetIncrement) const; + + // Given the offset return the address of the corresponding channel's data. + uint8_t* getYAddress(int32_t offset) const; + uint8_t* getUAddress(int32_t offset) const; + uint8_t* getVAddress(int32_t offset) const; + + // Given the pixel location, returns the address of the corresponding channel's data. + // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. + bool getYUVAddresses(int32_t x, int32_t y, + uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const; + + // Disallow implicit casting and copying. + YUVImage(const YUVImage &); + YUVImage &operator=(const YUVImage &); +}; + +} // namespace android + +#endif // YUV_IMAGE_H_ diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h index 69021d8..eb5e494 100644 --- a/include/media/stagefright/foundation/ADebug.h +++ b/include/media/stagefright/foundation/ADebug.h @@ -32,6 +32,7 @@ namespace android { #define CHECK(condition) \ LOG_ALWAYS_FATAL_IF( \ !(condition), \ + "%s", \ __FILE__ ":" LITERAL_TO_STRING(__LINE__) \ " CHECK(" #condition ") failed.") @@ -58,10 +59,12 @@ MAKE_COMPARATOR(GT,>) do { \ AString ___res = Compare_##suffix(x, y); \ if (!___res.empty()) { \ - LOG_ALWAYS_FATAL( \ - __FILE__ ":" LITERAL_TO_STRING(__LINE__) \ - " CHECK_" #suffix "( " #x "," #y ") failed: %s", \ - ___res.c_str()); \ + AString ___full = \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) \ + " CHECK_" #suffix "( " #x "," #y ") failed: "; \ + ___full.append(___res); \ + \ + LOG_ALWAYS_FATAL("%s", ___full.c_str()); \ } \ } while (false) diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h new file mode 100644 index 0000000..b5786fb --- /dev/null +++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h @@ -0,0 +1,49 @@ +#ifndef A_HIERARCHICAL_STATE_MACHINE_H_ + +#define A_HIERARCHICAL_STATE_MACHINE_H_ + +#include <media/stagefright/foundation/AHandler.h> + +namespace android { + +struct AState : public RefBase { + AState(const sp<AState> &parentState = NULL); + + sp<AState> parentState(); + +protected: + virtual ~AState(); + + virtual void stateEntered(); + virtual void stateExited(); + + virtual bool onMessageReceived(const sp<AMessage> &msg) = 0; + +private: + friend struct AHierarchicalStateMachine; + + sp<AState> mParentState; + + DISALLOW_EVIL_CONSTRUCTORS(AState); +}; + +struct AHierarchicalStateMachine : public AHandler { + AHierarchicalStateMachine(); + +protected: + virtual ~AHierarchicalStateMachine(); + + virtual void onMessageReceived(const sp<AMessage> &msg); + + // Only to be called in response to a message. + void changeState(const sp<AState> &state); + +private: + sp<AState> mState; + + DISALLOW_EVIL_CONSTRUCTORS(AHierarchicalStateMachine); +}; + +} // namespace android + +#endif // A_HIERARCHICAL_STATE_MACHINE_H_ diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index c674cba..72dc730 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -26,16 +26,22 @@ namespace android { struct AString; +struct Parcel; struct AMessage : public RefBase { AMessage(uint32_t what = 0, ALooper::handler_id target = 0); + static sp<AMessage> FromParcel(const Parcel &parcel); + void writeToParcel(Parcel *parcel) const; + void setWhat(uint32_t what); uint32_t what() const; void setTarget(ALooper::handler_id target); ALooper::handler_id target() const; + void clear(); + void setInt32(const char *name, int32_t value); void setInt64(const char *name, int64_t value); void setSize(const char *name, size_t value); @@ -46,6 +52,10 @@ struct AMessage : public RefBase { void setObject(const char *name, const sp<RefBase> &obj); void setMessage(const char *name, const sp<AMessage> &obj); + void setRect( + const char *name, + int32_t left, int32_t top, int32_t right, int32_t bottom); + bool findInt32(const char *name, int32_t *value) const; bool findInt64(const char *name, int64_t *value) const; bool findSize(const char *name, size_t *value) const; @@ -56,8 +66,15 @@ struct AMessage : public RefBase { bool findObject(const char *name, sp<RefBase> *obj) const; bool findMessage(const char *name, sp<AMessage> *obj) const; + bool findRect( + const char *name, + int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const; + void post(int64_t delayUs = 0); + // Performs a deep-copy of "this", contained messages are in turn "dup'ed". + // Warning: RefBase items, i.e. "objects" are _not_ copied but only have + // their refcount incremented. sp<AMessage> dup() const; AString debugString(int32_t indent = 0) const; @@ -76,11 +93,16 @@ private: kTypeString, kTypeObject, kTypeMessage, + kTypeRect, }; uint32_t mWhat; ALooper::handler_id mTarget; + struct Rect { + int32_t mLeft, mTop, mRight, mBottom; + }; + struct Item { union { int32_t int32Value; @@ -91,6 +113,7 @@ private: void *ptrValue; RefBase *refValue; AString *stringValue; + Rect rectValue; } u; const char *mName; Type mType; @@ -102,7 +125,6 @@ private: Item mItems[kMaxNumItems]; size_t mNumItems; - void clear(); Item *allocateItem(const char *name); void freeItem(Item *item); const Item *findItem(const char *name, Type type) const; diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h index d6ae5e9..9d589cf 100644 --- a/include/private/surfaceflinger/SharedBufferStack.h +++ b/include/private/surfaceflinger/SharedBufferStack.h @@ -285,6 +285,8 @@ public: uint32_t getTransform(int buffer) const; status_t resize(int newNumBuffers); + status_t grow(int newNumBuffers); + status_t shrink(int newNumBuffers); SharedBufferStack::Statistics getStats() const; @@ -346,6 +348,14 @@ private: int mNumBuffers; BufferList mBufferList; + struct BuffersAvailableCondition : public ConditionBase { + int mNumBuffers; + inline BuffersAvailableCondition(SharedBufferServer* sbs, + int numBuffers); + inline bool operator()() const; + inline const char* name() const { return "BuffersAvailableCondition"; } + }; + struct UnlockUpdate : public UpdateBase { const int lockedBuffer; inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); diff --git a/include/private/ui/sw_gralloc_handle.h b/include/private/ui/sw_gralloc_handle.h deleted file mode 100644 index b3d333e..0000000 --- a/include/private/ui/sw_gralloc_handle.h +++ /dev/null @@ -1,83 +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 ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H -#define ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H - -#include <stdint.h> -#include <limits.h> -#include <sys/cdefs.h> -#include <hardware/gralloc.h> -#include <errno.h> - -#include <cutils/native_handle.h> - -namespace android { - -/*****************************************************************************/ - -struct sw_gralloc_handle_t : public native_handle -{ - // file-descriptors - int fd; - // ints - int magic; - int size; - int base; - int prot; - int pid; - - static const int sNumInts = 5; - static const int sNumFds = 1; - static const int sMagic = '_sgh'; - - sw_gralloc_handle_t() : - fd(-1), magic(sMagic), size(0), base(0), prot(0), pid(getpid()) - { - version = sizeof(native_handle); - numInts = sNumInts; - numFds = sNumFds; - } - ~sw_gralloc_handle_t() { - magic = 0; - } - - static int validate(const native_handle* h) { - const sw_gralloc_handle_t* hnd = (const sw_gralloc_handle_t*)h; - if (!h || h->version != sizeof(native_handle) || - h->numInts != sNumInts || h->numFds != sNumFds || - hnd->magic != sMagic) - { - return -EINVAL; - } - return 0; - } - - static status_t alloc(uint32_t w, uint32_t h, int format, - int usage, buffer_handle_t* handle, int32_t* stride); - static status_t free(sw_gralloc_handle_t* hnd); - static status_t registerBuffer(sw_gralloc_handle_t* hnd); - static status_t unregisterBuffer(sw_gralloc_handle_t* hnd); - static status_t lock(sw_gralloc_handle_t* hnd, int usage, - int l, int t, int w, int h, void** vaddr); - static status_t unlock(sw_gralloc_handle_t* hnd); -}; - -/*****************************************************************************/ - -}; // namespace android - -#endif /* ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H */ diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h index 51f9aeb..68ccd95 100644 --- a/include/storage/IMountService.h +++ b/include/storage/IMountService.h @@ -66,6 +66,7 @@ public: const sp<IObbActionListener>& token, const int32_t nonce) = 0; virtual bool isObbMounted(const String16& filename) = 0; virtual bool getMountedObbPath(const String16& filename, String16& path) = 0; + virtual int32_t decryptStorage(const String16& password) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h index ddbe03d..cd0ee40 100644 --- a/include/surfaceflinger/ISurface.h +++ b/include/surfaceflinger/ISurface.h @@ -34,18 +34,15 @@ namespace android { typedef int32_t SurfaceID; -class IMemoryHeap; -class OverlayRef; class GraphicBuffer; class ISurface : public IInterface { protected: enum { - REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION, - UNREGISTER_BUFFERS, - POST_BUFFER, // one-way transaction - CREATE_OVERLAY, + RESERVED0 = IBinder::FIRST_CALL_TRANSACTION, + RESERVED1, + RESERVED2, REQUEST_BUFFER, SET_BUFFER_COUNT, }; @@ -66,49 +63,6 @@ public: * sets the number of buffers dequeuable for this surface. */ virtual status_t setBufferCount(int bufferCount) = 0; - - // ------------------------------------------------------------------------ - // Deprecated... - // ------------------------------------------------------------------------ - - class BufferHeap { - public: - enum { - /* rotate source image */ - ROT_0 = 0, - ROT_90 = HAL_TRANSFORM_ROT_90, - ROT_180 = HAL_TRANSFORM_ROT_180, - ROT_270 = HAL_TRANSFORM_ROT_270, - }; - BufferHeap(); - - BufferHeap(uint32_t w, uint32_t h, - int32_t hor_stride, int32_t ver_stride, - PixelFormat format, const sp<IMemoryHeap>& heap); - - BufferHeap(uint32_t w, uint32_t h, - int32_t hor_stride, int32_t ver_stride, - PixelFormat format, uint32_t transform, uint32_t flags, - const sp<IMemoryHeap>& heap); - - ~BufferHeap(); - - uint32_t w; - uint32_t h; - int32_t hor_stride; - int32_t ver_stride; - PixelFormat format; - uint32_t transform; - uint32_t flags; - sp<IMemoryHeap> heap; - }; - - virtual status_t registerBuffers(const BufferHeap& buffers) = 0; - virtual void postBuffer(ssize_t offset) = 0; // one-way - virtual void unregisterBuffers() = 0; - - virtual sp<OverlayRef> createOverlay( - uint32_t w, uint32_t h, int32_t format, int32_t orientation) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index da4d56f..1bab7d7 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -42,7 +42,7 @@ public: eDestroyBackbuffer = 0x00000020, eSecure = 0x00000080, eNonPremultiplied = 0x00000100, - ePushBuffers = 0x00000200, + eOpaque = 0x00000400, eFXSurfaceNormal = 0x00000000, eFXSurfaceBlur = 0x00010000, @@ -121,7 +121,8 @@ public: virtual status_t captureScreen(DisplayID dpy, sp<IMemoryHeap>* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight) = 0; + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) = 0; virtual status_t turnElectronBeamOff(int32_t mode) = 0; virtual status_t turnElectronBeamOn(int32_t mode) = 0; @@ -130,6 +131,13 @@ public: * This is an ASYNCHRONOUS call. */ virtual void signal() const = 0; + + /* Create a new GraphicBuffer for the client to use. SurfaceFlinger will + * not maintain a reference to the GraphicBuffer, so the underlying native + * handle will be freed once the client references are released. + */ + virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, + PixelFormat format, uint32_t usage) const = 0; }; // ---------------------------------------------------------------------------- @@ -143,6 +151,7 @@ public: BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, CREATE_CONNECTION, CREATE_CLIENT_CONNECTION, + CREATE_GRAPHIC_BUFFER, GET_CBLK, OPEN_GLOBAL_TRANSACTION, CLOSE_GLOBAL_TRANSACTION, diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 22684db..2df8ca3 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -94,7 +94,7 @@ private: friend class SurfaceComposerClient; // camera and camcorder need access to the ISurface binder interface for preview - friend class Camera; + friend class CameraService; friend class MediaRecorder; // mediaplayer needs access to ISurface for display friend class MediaPlayer; @@ -173,11 +173,12 @@ private: * (eventually this should go away and be replaced by proper APIs) */ // camera and camcorder need access to the ISurface binder interface for preview - friend class Camera; + friend class CameraService; friend class MediaRecorder; // MediaPlayer needs access to ISurface for display friend class MediaPlayer; friend class IOMX; + friend class SoftwareRenderer; // this is just to be able to write some unit tests friend class Test; @@ -248,7 +249,7 @@ private: uint32_t *pWidth, uint32_t *pHeight, uint32_t *pFormat, uint32_t *pUsage) const; - static void cleanCachedSurfaces(); + static void cleanCachedSurfacesLocked(); class BufferInfo { uint32_t mWidth; @@ -314,4 +315,3 @@ private: }; // namespace android #endif // ANDROID_SF_SURFACE_H - diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h index a80832d..25b2ebf 100644 --- a/include/surfaceflinger/SurfaceComposerClient.h +++ b/include/surfaceflinger/SurfaceComposerClient.h @@ -183,6 +183,8 @@ public: // frees the previous screenshot and capture a new one status_t update(); status_t update(uint32_t reqWidth, uint32_t reqHeight); + status_t update(uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ); // release memory occupied by the screenshot void release(); diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h index c419efe..edd28a6 100644 --- a/include/ui/DisplayInfo.h +++ b/include/ui/DisplayInfo.h @@ -37,6 +37,15 @@ struct DisplayInfo { float ydpi; }; +/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */ +enum { + DISPLAY_ORIENTATION_0 = 0, + DISPLAY_ORIENTATION_90 = 1, + DISPLAY_ORIENTATION_180 = 2, + DISPLAY_ORIENTATION_270 = 3 +}; + + }; // namespace android #endif // ANDROID_COMPOSER_DISPLAY_INFO_H diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h deleted file mode 100644 index d78e35f..0000000 --- a/include/ui/EventHub.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -#ifndef _RUNTIME_EVENT_HUB_H -#define _RUNTIME_EVENT_HUB_H - -#include <android/input.h> -#include <utils/String8.h> -#include <utils/threads.h> -#include <utils/Log.h> -#include <utils/threads.h> -#include <utils/List.h> -#include <utils/Errors.h> - -#include <linux/input.h> - -/* These constants are not defined in linux/input.h but they are part of the multitouch - * input protocol. */ - -#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ -#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ -#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */ -#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */ -#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ -#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */ -#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ -#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device (finger, pen, ...) */ -#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ -#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ -#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ - -#define MT_TOOL_FINGER 0 /* Identifies a finger */ -#define MT_TOOL_PEN 1 /* Identifies a pen */ - -#define SYN_MT_REPORT 2 - -/* Convenience constants. */ - -#define BTN_FIRST 0x100 // first button scancode -#define BTN_LAST 0x15f // last button scancode - -struct pollfd; - -namespace android { - -class KeyLayoutMap; - -/* - * A raw event as retrieved from the EventHub. - */ -struct RawEvent { - nsecs_t when; - int32_t deviceId; - int32_t type; - int32_t scanCode; - int32_t keyCode; - int32_t value; - uint32_t flags; -}; - -/* Describes an absolute axis. */ -struct RawAbsoluteAxisInfo { - bool valid; // true if the information is valid, false otherwise - - int32_t minValue; // minimum value - int32_t maxValue; // maximum value - int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8 - int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise - - inline int32_t getRange() { return maxValue - minValue; } - - inline void clear() { - valid = false; - minValue = 0; - maxValue = 0; - flat = 0; - fuzz = 0; - } -}; - -/* - * Input device classes. - */ -enum { - /* The input device is a keyboard. */ - INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001, - - /* The input device is an alpha-numeric keyboard (not just a dial pad). */ - INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002, - - /* The input device is a touchscreen (either single-touch or multi-touch). */ - INPUT_DEVICE_CLASS_TOUCHSCREEN = 0x00000004, - - /* The input device is a trackball. */ - INPUT_DEVICE_CLASS_TRACKBALL = 0x00000008, - - /* The input device is a multi-touch touchscreen. */ - INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010, - - /* The input device is a directional pad (implies keyboard, has DPAD keys). */ - INPUT_DEVICE_CLASS_DPAD = 0x00000020, - - /* The input device is a gamepad (implies keyboard, has BUTTON keys). */ - INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040, - - /* The input device has switches. */ - INPUT_DEVICE_CLASS_SWITCH = 0x00000080, -}; - -/* - * Grand Central Station for events. - * - * The event hub aggregates input events received across all known input - * devices on the system, including devices that may be emulated by the simulator - * environment. In addition, the event hub generates fake input events to indicate - * when devices are added or removed. - * - * The event hub provies a stream of input events (via the getEvent function). - * It also supports querying the current actual state of input devices such as identifying - * which keys are currently down. Finally, the event hub keeps track of the capabilities of - * individual input devices, such as their class and the set of key codes that they support. - */ -class EventHubInterface : public virtual RefBase { -protected: - EventHubInterface() { } - virtual ~EventHubInterface() { } - -public: - // Synthetic raw event type codes produced when devices are added or removed. - enum { - // Sent when a device is added. - DEVICE_ADDED = 0x10000000, - // Sent when a device is removed. - DEVICE_REMOVED = 0x20000000, - // Sent when all added/removed devices from the most recent scan have been reported. - // This event is always sent at least once. - FINISHED_DEVICE_SCAN = 0x30000000, - }; - - virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0; - - virtual String8 getDeviceName(int32_t deviceId) const = 0; - - virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, - RawAbsoluteAxisInfo* outAxisInfo) const = 0; - - virtual status_t scancodeToKeycode(int32_t deviceId, int scancode, - int32_t* outKeycode, uint32_t* outFlags) const = 0; - - // exclude a particular device from opening - // this can be used to ignore input devices for sensors - virtual void addExcludedDevice(const char* deviceName) = 0; - - /* - * Wait for the next event to become available and return it. - * After returning, the EventHub holds onto a wake lock until the next call to getEvent. - * This ensures that the device will not go to sleep while the event is being processed. - * If the device needs to remain awake longer than that, then the caller is responsible - * for taking care of it (say, by poking the power manager user activity timer). - */ - virtual bool getEvent(RawEvent* outEvent) = 0; - - /* - * Query current input state. - */ - virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0; - virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0; - virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0; - - /* - * Examine key input devices for specific framework keycode support - */ - virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, - uint8_t* outFlags) const = 0; - - virtual void dump(String8& dump) = 0; -}; - -class EventHub : public EventHubInterface -{ -public: - EventHub(); - - status_t errorCheck() const; - - virtual uint32_t getDeviceClasses(int32_t deviceId) const; - - virtual String8 getDeviceName(int32_t deviceId) const; - - virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, - RawAbsoluteAxisInfo* outAxisInfo) const; - - virtual status_t scancodeToKeycode(int32_t deviceId, int scancode, - int32_t* outKeycode, uint32_t* outFlags) const; - - virtual void addExcludedDevice(const char* deviceName); - - virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const; - virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const; - virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const; - - virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags) const; - - virtual bool getEvent(RawEvent* outEvent); - - virtual void dump(String8& dump); - -protected: - virtual ~EventHub(); - -private: - bool openPlatformInput(void); - - int openDevice(const char *device); - int closeDevice(const char *device); - int scanDir(const char *dirname); - int readNotify(int nfd); - - status_t mError; - - struct device_t { - const int32_t id; - const String8 path; - String8 name; - uint32_t classes; - uint8_t* keyBitmask; - KeyLayoutMap* layoutMap; - String8 keylayoutFilename; - int fd; - device_t* next; - - device_t(int32_t _id, const char* _path, const char* name); - ~device_t(); - }; - - device_t* getDeviceLocked(int32_t deviceId) const; - bool hasKeycodeLocked(device_t* device, int keycode) const; - - int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const; - int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const; - int32_t getSwitchStateLocked(device_t* device, int32_t sw) const; - bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags) const; - - // Protect all internal state. - mutable Mutex mLock; - - bool mHaveFirstKeyboard; - int32_t mFirstKeyboardId; // the API is that the built-in keyboard is id 0, so map it - - struct device_ent { - device_t* device; - uint32_t seq; - }; - device_ent *mDevicesById; - int mNumDevicesById; - - device_t *mOpeningDevices; - device_t *mClosingDevices; - - device_t **mDevices; - struct pollfd *mFDs; - int mFDCount; - - bool mOpened; - bool mNeedToSendFinishedDeviceScan; - List<String8> mExcludedDevices; - - // device ids that report particular switches. -#ifdef EV_SW - int32_t mSwitches[SW_MAX + 1]; -#endif - - static const int INPUT_BUFFER_SIZE = 64; - struct input_event mInputBufferData[INPUT_BUFFER_SIZE]; - int32_t mInputBufferIndex; - int32_t mInputBufferCount; - int32_t mInputDeviceIndex; -}; - -}; // namespace android - -#endif // _RUNTIME_EVENT_HUB_H diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 2cd0911..16117ad 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -23,6 +23,7 @@ #include <EGL/egl.h> #include <utils/threads.h> +#include <utils/String8.h> #include <ui/Rect.h> #include <pixelflinger/pixelflinger.h> @@ -56,7 +57,9 @@ public: bool isUpdateOnDemand() const { return mUpdateOnDemand; } status_t setUpdateRectangle(const Rect& updateRect); status_t compositionComplete(); - + + void dump(String8& result); + // for debugging only int getCurrentBufferIndex() const; diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 0be26a7..8b256f4 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -26,8 +26,6 @@ #include <utils/Flattenable.h> #include <pixelflinger/pixelflinger.h> -#include <hardware/hardware.h> - struct android_native_buffer_t; namespace android { @@ -65,13 +63,6 @@ public: USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK }; - enum { - TRANSFORM_IDENTITY = 0, - TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, - TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, - TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270 - }; - GraphicBuffer(); // creates w * h buffer @@ -81,6 +72,9 @@ public: GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, uint32_t stride, native_handle_t* handle, bool keepOwnership); + // create a buffer from an existing android_native_buffer_t + GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership); + // return status status_t initCheck() const; @@ -88,7 +82,6 @@ public: uint32_t getHeight() const { return height; } uint32_t getStride() const { return stride; } uint32_t getUsage() const { return usage; } - uint32_t getTransform() const { return transform; } PixelFormat getPixelFormat() const { return format; } Rect getBounds() const { return Rect(width, height); } @@ -128,6 +121,7 @@ private: friend class Surface; friend class BpSurface; friend class BnSurface; + friend class SurfaceTextureClient; friend class LightRefBase<GraphicBuffer>; GraphicBuffer(const GraphicBuffer& rhs); GraphicBuffer& operator = (const GraphicBuffer& rhs); @@ -150,6 +144,10 @@ private: GraphicBufferMapper& mBufferMapper; ssize_t mInitCheck; int mIndex; + + // If we're wrapping another buffer then this reference will make sure it + // doesn't get freed. + sp<android_native_buffer_t> mWrappedBuffer; }; }; // namespace android diff --git a/include/ui/IOverlay.h b/include/ui/IOverlay.h deleted file mode 100644 index af3add1..0000000 --- a/include/ui/IOverlay.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_IOVERLAY_H -#define ANDROID_IOVERLAY_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <binder/IInterface.h> -#include <utils/RefBase.h> -#include <ui/PixelFormat.h> - -namespace android { - -class IOverlay : public IInterface -{ -public: - DECLARE_META_INTERFACE(Overlay); - - virtual void destroy() = 0; // one-way -}; - -// ---------------------------------------------------------------------------- - -class BnOverlay : public BnInterface<IOverlay> -{ -public: - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_IOVERLAY_H diff --git a/include/ui/Input.h b/include/ui/Input.h index 8c6018b..27f65bc 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -76,7 +76,7 @@ namespace android { */ enum { /* These flags originate in RawEvents and are generally set in the key map. - * See also labels for policy flags in KeycodeLabels.h. */ + * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */ POLICY_FLAG_WAKE = 0x00000001, POLICY_FLAG_WAKE_DROPPED = 0x00000002, @@ -87,6 +87,7 @@ enum { POLICY_FLAG_MENU = 0x00000040, POLICY_FLAG_LAUNCHER = 0x00000080, POLICY_FLAG_VIRTUAL = 0x00000100, + POLICY_FLAG_FUNCTION = 0x00000200, POLICY_FLAG_RAW_MASK = 0x0000ffff, @@ -496,6 +497,54 @@ private: KeyedVector<int32_t, MotionRange> mMotionRanges; }; +/* + * Identifies a device. + */ +struct InputDeviceIdentifier { + inline InputDeviceIdentifier() : + bus(0), vendor(0), product(0), version(0) { + } + + String8 name; + String8 location; + String8 uniqueId; + uint16_t bus; + uint16_t vendor; + uint16_t product; + uint16_t version; +}; + +/* Types of input device configuration files. */ +enum InputDeviceConfigurationFileType { + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ +}; + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The device identifier is used to construct several default configuration file + * names to try based on the device name, vendor, product, and version. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( + const InputDeviceIdentifier& deviceIdentifier, + InputDeviceConfigurationFileType type); + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The name is case-sensitive and is used to construct the filename to resolve. + * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByName( + const String8& name, InputDeviceConfigurationFileType type); } // namespace android diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h deleted file mode 100644 index 5f77cba..0000000 --- a/include/ui/InputDispatcher.h +++ /dev/null @@ -1,1083 +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_INPUT_DISPATCHER_H -#define _UI_INPUT_DISPATCHER_H - -#include <ui/Input.h> -#include <ui/InputTransport.h> -#include <utils/KeyedVector.h> -#include <utils/Vector.h> -#include <utils/threads.h> -#include <utils/Timers.h> -#include <utils/RefBase.h> -#include <utils/String8.h> -#include <utils/Looper.h> -#include <utils/Pool.h> -#include <utils/BitSet.h> - -#include <stddef.h> -#include <unistd.h> -#include <limits.h> - - -namespace android { - -/* - * Constants used to report the outcome of input event injection. - */ -enum { - /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */ - INPUT_EVENT_INJECTION_PENDING = -1, - - /* Injection succeeded. */ - INPUT_EVENT_INJECTION_SUCCEEDED = 0, - - /* Injection failed because the injector did not have permission to inject - * into the application with input focus. */ - INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1, - - /* Injection failed because there were no available input targets. */ - INPUT_EVENT_INJECTION_FAILED = 2, - - /* Injection failed due to a timeout. */ - INPUT_EVENT_INJECTION_TIMED_OUT = 3 -}; - -/* - * Constants used to determine the input event injection synchronization mode. - */ -enum { - /* Injection is asynchronous and is assumed always to be successful. */ - INPUT_EVENT_INJECTION_SYNC_NONE = 0, - - /* Waits for previous events to be dispatched so that the input dispatcher can determine - * whether input event injection willbe permitted based on the current input focus. - * Does not wait for the input event to finish processing. */ - INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1, - - /* Waits for the input event to be completely processed. */ - INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2, -}; - - -/* - * An input target specifies how an input event is to be dispatched to a particular window - * including the window's input channel, control flags, a timeout, and an X / Y offset to - * be added to input event coordinates to compensate for the absolute position of the - * window area. - */ -struct InputTarget { - enum { - /* This flag indicates that the event is being delivered to a foreground application. */ - FLAG_FOREGROUND = 0x01, - - /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside - * of the area of this target and so should instead be delivered as an - * AMOTION_EVENT_ACTION_OUTSIDE to this target. */ - FLAG_OUTSIDE = 0x02, - - /* This flag indicates that the target of a MotionEvent is partly or wholly - * obscured by another visible window above it. The motion event should be - * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ - FLAG_WINDOW_IS_OBSCURED = 0x04, - - /* This flag indicates that a motion event is being split across multiple windows. */ - FLAG_SPLIT = 0x08, - }; - - // The input channel to be targeted. - sp<InputChannel> inputChannel; - - // Flags for the input target. - int32_t flags; - - // The x and y offset to add to a MotionEvent as it is delivered. - // (ignored for KeyEvents) - float xOffset, yOffset; - - // The subset of pointer ids to include in motion events dispatched to this input target - // if FLAG_SPLIT is set. - BitSet32 pointerIds; -}; - - -/* - * An input window describes the bounds of a window that can receive input. - */ -struct InputWindow { - // Window flags from WindowManager.LayoutParams - enum { - FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, - FLAG_DIM_BEHIND = 0x00000002, - FLAG_BLUR_BEHIND = 0x00000004, - FLAG_NOT_FOCUSABLE = 0x00000008, - FLAG_NOT_TOUCHABLE = 0x00000010, - FLAG_NOT_TOUCH_MODAL = 0x00000020, - FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040, - FLAG_KEEP_SCREEN_ON = 0x00000080, - FLAG_LAYOUT_IN_SCREEN = 0x00000100, - FLAG_LAYOUT_NO_LIMITS = 0x00000200, - FLAG_FULLSCREEN = 0x00000400, - FLAG_FORCE_NOT_FULLSCREEN = 0x00000800, - FLAG_DITHER = 0x00001000, - FLAG_SECURE = 0x00002000, - FLAG_SCALED = 0x00004000, - FLAG_IGNORE_CHEEK_PRESSES = 0x00008000, - FLAG_LAYOUT_INSET_DECOR = 0x00010000, - FLAG_ALT_FOCUSABLE_IM = 0x00020000, - FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000, - FLAG_SHOW_WHEN_LOCKED = 0x00080000, - FLAG_SHOW_WALLPAPER = 0x00100000, - FLAG_TURN_SCREEN_ON = 0x00200000, - FLAG_DISMISS_KEYGUARD = 0x00400000, - FLAG_SPLIT_TOUCH = 0x00800000, - FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000, - FLAG_COMPATIBLE_WINDOW = 0x20000000, - FLAG_SYSTEM_ERROR = 0x40000000, - }; - - // Window types from WindowManager.LayoutParams - enum { - FIRST_APPLICATION_WINDOW = 1, - TYPE_BASE_APPLICATION = 1, - TYPE_APPLICATION = 2, - TYPE_APPLICATION_STARTING = 3, - LAST_APPLICATION_WINDOW = 99, - FIRST_SUB_WINDOW = 1000, - TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW, - TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1, - TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2, - TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3, - TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4, - LAST_SUB_WINDOW = 1999, - FIRST_SYSTEM_WINDOW = 2000, - TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW, - TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1, - TYPE_PHONE = FIRST_SYSTEM_WINDOW+2, - TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3, - TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4, - TYPE_TOAST = FIRST_SYSTEM_WINDOW+5, - TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6, - TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7, - TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8, - TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9, - TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10, - TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11, - TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12, - TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13, - TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14, - TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15, - LAST_SYSTEM_WINDOW = 2999, - }; - - sp<InputChannel> inputChannel; - String8 name; - int32_t layoutParamsFlags; - int32_t layoutParamsType; - nsecs_t dispatchingTimeout; - int32_t frameLeft; - int32_t frameTop; - int32_t frameRight; - int32_t frameBottom; - int32_t visibleFrameLeft; - int32_t visibleFrameTop; - int32_t visibleFrameRight; - int32_t visibleFrameBottom; - int32_t touchableAreaLeft; - int32_t touchableAreaTop; - int32_t touchableAreaRight; - int32_t touchableAreaBottom; - bool visible; - bool canReceiveKeys; - bool hasFocus; - bool hasWallpaper; - bool paused; - int32_t layer; - int32_t ownerPid; - int32_t ownerUid; - - bool touchableAreaContainsPoint(int32_t x, int32_t y) const; - bool frameContainsPoint(int32_t x, int32_t y) const; - - /* Returns true if the window is of a trusted type that is allowed to silently - * overlay other windows for the purpose of implementing the secure views feature. - * Trusted overlays, such as IME windows, can partly obscure other windows without causing - * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. - */ - bool isTrustedOverlay() const; -}; - - -/* - * A private handle type used by the input manager to track the window. - */ -class InputApplicationHandle : public RefBase { -protected: - InputApplicationHandle() { } - virtual ~InputApplicationHandle() { } -}; - - -/* - * An input application describes properties of an application that can receive input. - */ -struct InputApplication { - String8 name; - nsecs_t dispatchingTimeout; - sp<InputApplicationHandle> handle; -}; - - -/* - * Input dispatcher policy interface. - * - * The input reader policy is used by the input reader to interact with the Window Manager - * and other system components. - * - * The actual implementation is partially supported by callbacks into the DVM - * via JNI. This interface is also mocked in the unit tests. - */ -class InputDispatcherPolicyInterface : public virtual RefBase { -protected: - InputDispatcherPolicyInterface() { } - virtual ~InputDispatcherPolicyInterface() { } - -public: - /* Notifies the system that a configuration change has occurred. */ - virtual void notifyConfigurationChanged(nsecs_t when) = 0; - - /* Notifies the system that an application is not responding. - * Returns a new timeout to continue waiting, or 0 to abort dispatch. */ - virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputChannel>& inputChannel) = 0; - - /* Notifies the system that an input channel is unrecoverably broken. */ - virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0; - - /* Gets the key repeat initial timeout or -1 if automatic key repeating is disabled. */ - virtual nsecs_t getKeyRepeatTimeout() = 0; - - /* Gets the key repeat inter-key delay. */ - virtual nsecs_t getKeyRepeatDelay() = 0; - - /* Gets the maximum suggested event delivery rate per second. - * This value is used to throttle motion event movement actions on a per-device - * basis. It is not intended to be a hard limit. - */ - virtual int32_t getMaxEventsPerSecond() = 0; - - /* Intercepts a key event immediately before queueing it. - * The policy can use this method as an opportunity to perform power management functions - * and early event preprocessing such as updating policy flags. - * - * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event - * should be dispatched to applications. - */ - virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId, - int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode, - uint32_t& policyFlags) = 0; - - /* Intercepts a generic touch, trackball or other event before queueing it. - * The policy can use this method as an opportunity to perform power management functions - * and early event preprocessing such as updating policy flags. - * - * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event - * should be dispatched to applications. - */ - virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0; - - /* Allows the policy a chance to intercept a key before dispatching. */ - virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel, - const KeyEvent* keyEvent, uint32_t policyFlags) = 0; - - /* Notifies the policy about switch events. - */ - virtual void notifySwitch(nsecs_t when, - int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0; - - /* Poke user activity for an event dispatched to a window. */ - virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0; - - /* Checks whether a given application pid/uid has permission to inject input events - * into other applications. - * - * This method is special in that its implementation promises to be non-reentrant and - * is safe to call while holding other locks. (Most other methods make no such guarantees!) - */ - virtual bool checkInjectEventsPermissionNonReentrant( - int32_t injectorPid, int32_t injectorUid) = 0; -}; - - -/* Notifies the system about input events generated by the input reader. - * The dispatcher is expected to be mostly asynchronous. */ -class InputDispatcherInterface : public virtual RefBase { -protected: - InputDispatcherInterface() { } - virtual ~InputDispatcherInterface() { } - -public: - /* Dumps the state of the input dispatcher. - * - * This method may be called on any thread (usually by the input manager). */ - virtual void dump(String8& dump) = 0; - - /* Runs a single iteration of the dispatch loop. - * Nominally processes one queued event, a timeout, or a response from an input consumer. - * - * This method should only be called on the input dispatcher thread. - */ - virtual void dispatchOnce() = 0; - - /* Notifies the dispatcher about new events. - * - * These methods should only be called on the input reader thread. - */ - virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0; - virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, - int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0; - virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t flags, - int32_t metaState, int32_t edgeFlags, - uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, - float xPrecision, float yPrecision, nsecs_t downTime) = 0; - virtual void notifySwitch(nsecs_t when, - int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0; - - /* Injects an input event and optionally waits for sync. - * The synchronization mode determines whether the method blocks while waiting for - * input injection to proceed. - * Returns one of the INPUT_EVENT_INJECTION_XXX constants. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual int32_t injectInputEvent(const InputEvent* event, - int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0; - - /* Sets the list of input windows. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0; - - /* Sets the focused application. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual void setFocusedApplication(const InputApplication* inputApplication) = 0; - - /* Sets the input dispatching mode. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual void setInputDispatchMode(bool enabled, bool frozen) = 0; - - /* Registers or unregister input channels that may be used as targets for input events. - * If monitor is true, the channel will receive a copy of all input events. - * - * These methods may be called on any thread (usually by the input manager). - */ - virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) = 0; - virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0; -}; - -/* Dispatches events to input targets. Some functions of the input dispatcher, such as - * identifying input targets, are controlled by a separate policy object. - * - * IMPORTANT INVARIANT: - * Because the policy can potentially block or cause re-entrance into the input dispatcher, - * the input dispatcher never calls into the policy while holding its internal locks. - * The implementation is also carefully designed to recover from scenarios such as an - * input channel becoming unregistered while identifying input targets or processing timeouts. - * - * Methods marked 'Locked' must be called with the lock acquired. - * - * Methods marked 'LockedInterruptible' must be called with the lock acquired but - * may during the course of their execution release the lock, call into the policy, and - * then reacquire the lock. The caller is responsible for recovering gracefully. - * - * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa. - */ -class InputDispatcher : public InputDispatcherInterface { -protected: - virtual ~InputDispatcher(); - -public: - explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy); - - virtual void dump(String8& dump); - - virtual void dispatchOnce(); - - virtual void notifyConfigurationChanged(nsecs_t eventTime); - virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, - int32_t scanCode, int32_t metaState, nsecs_t downTime); - virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t flags, - int32_t metaState, int32_t edgeFlags, - uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, - float xPrecision, float yPrecision, nsecs_t downTime); - virtual void notifySwitch(nsecs_t when, - int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ; - - virtual int32_t injectInputEvent(const InputEvent* event, - int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis); - - virtual void setInputWindows(const Vector<InputWindow>& inputWindows); - virtual void setFocusedApplication(const InputApplication* inputApplication); - virtual void setInputDispatchMode(bool enabled, bool frozen); - - virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor); - virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel); - -private: - template <typename T> - struct Link { - T* next; - T* prev; - }; - - struct InjectionState { - mutable int32_t refCount; - - int32_t injectorPid; - int32_t injectorUid; - int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING - bool injectionIsAsync; // set to true if injection is not waiting for the result - int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress - }; - - struct EventEntry : Link<EventEntry> { - enum { - TYPE_SENTINEL, - TYPE_CONFIGURATION_CHANGED, - TYPE_KEY, - TYPE_MOTION - }; - - mutable int32_t refCount; - int32_t type; - nsecs_t eventTime; - uint32_t policyFlags; - InjectionState* injectionState; - - bool dispatchInProgress; // initially false, set to true while dispatching - - inline bool isInjected() { return injectionState != NULL; } - }; - - struct ConfigurationChangedEntry : EventEntry { - }; - - struct KeyEntry : EventEntry { - int32_t deviceId; - int32_t source; - int32_t action; - int32_t flags; - int32_t keyCode; - int32_t scanCode; - int32_t metaState; - int32_t repeatCount; - nsecs_t downTime; - - bool syntheticRepeat; // set to true for synthetic key repeats - - enum InterceptKeyResult { - INTERCEPT_KEY_RESULT_UNKNOWN, - INTERCEPT_KEY_RESULT_SKIP, - INTERCEPT_KEY_RESULT_CONTINUE, - }; - InterceptKeyResult interceptKeyResult; // set based on the interception result - }; - - struct MotionSample { - MotionSample* next; - - nsecs_t eventTime; - PointerCoords pointerCoords[MAX_POINTERS]; - }; - - struct MotionEntry : EventEntry { - int32_t deviceId; - int32_t source; - int32_t action; - int32_t flags; - int32_t metaState; - int32_t edgeFlags; - float xPrecision; - float yPrecision; - nsecs_t downTime; - uint32_t pointerCount; - int32_t pointerIds[MAX_POINTERS]; - - // Linked list of motion samples associated with this motion event. - MotionSample firstSample; - MotionSample* lastSample; - - uint32_t countSamples() const; - }; - - // Tracks the progress of dispatching a particular event to a particular connection. - struct DispatchEntry : Link<DispatchEntry> { - EventEntry* eventEntry; // the event to dispatch - int32_t targetFlags; - float xOffset; - float yOffset; - - // True if dispatch has started. - bool inProgress; - - // For motion events: - // Pointer to the first motion sample to dispatch in this cycle. - // Usually NULL to indicate that the list of motion samples begins at - // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous - // cycle and this pointer indicates the location of the first remainining sample - // to dispatch during the current cycle. - MotionSample* headMotionSample; - // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was - // unable to send all motion samples during this cycle. On the next cycle, - // headMotionSample will be initialized to tailMotionSample and tailMotionSample - // will be set to NULL. - MotionSample* tailMotionSample; - - inline bool hasForegroundTarget() const { - return targetFlags & InputTarget::FLAG_FOREGROUND; - } - - inline bool isSplit() const { - return targetFlags & InputTarget::FLAG_SPLIT; - } - }; - - // A command entry captures state and behavior for an action to be performed in the - // dispatch loop after the initial processing has taken place. It is essentially - // a kind of continuation used to postpone sensitive policy interactions to a point - // in the dispatch loop where it is safe to release the lock (generally after finishing - // the critical parts of the dispatch cycle). - // - // The special thing about commands is that they can voluntarily release and reacquire - // the dispatcher lock at will. Initially when the command starts running, the - // dispatcher lock is held. However, if the command needs to call into the policy to - // do some work, it can release the lock, do the work, then reacquire the lock again - // before returning. - // - // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch - // never calls into the policy while holding its lock. - // - // Commands are implicitly 'LockedInterruptible'. - struct CommandEntry; - typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry); - - class Connection; - struct CommandEntry : Link<CommandEntry> { - CommandEntry(); - ~CommandEntry(); - - Command command; - - // parameters for the command (usage varies by command) - sp<Connection> connection; - nsecs_t eventTime; - KeyEntry* keyEntry; - sp<InputChannel> inputChannel; - sp<InputApplicationHandle> inputApplicationHandle; - int32_t userActivityEventType; - }; - - // Generic queue implementation. - template <typename T> - struct Queue { - T headSentinel; - T tailSentinel; - - inline Queue() { - headSentinel.prev = NULL; - headSentinel.next = & tailSentinel; - tailSentinel.prev = & headSentinel; - tailSentinel.next = NULL; - } - - inline bool isEmpty() const { - return headSentinel.next == & tailSentinel; - } - - inline void enqueueAtTail(T* entry) { - T* last = tailSentinel.prev; - last->next = entry; - entry->prev = last; - entry->next = & tailSentinel; - tailSentinel.prev = entry; - } - - inline void enqueueAtHead(T* entry) { - T* first = headSentinel.next; - headSentinel.next = entry; - entry->prev = & headSentinel; - entry->next = first; - first->prev = entry; - } - - inline void dequeue(T* entry) { - entry->prev->next = entry->next; - entry->next->prev = entry->prev; - } - - inline T* dequeueAtHead() { - T* first = headSentinel.next; - dequeue(first); - return first; - } - - uint32_t count() const; - }; - - /* Allocates queue entries and performs reference counting as needed. */ - class Allocator { - public: - Allocator(); - - InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid); - ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime); - KeyEntry* obtainKeyEntry(nsecs_t eventTime, - int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, - int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, - int32_t repeatCount, nsecs_t downTime); - MotionEntry* obtainMotionEntry(nsecs_t eventTime, - int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, - int32_t flags, int32_t metaState, int32_t edgeFlags, - float xPrecision, float yPrecision, - nsecs_t downTime, uint32_t pointerCount, - const int32_t* pointerIds, const PointerCoords* pointerCoords); - DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry, - int32_t targetFlags, float xOffset, float yOffset); - CommandEntry* obtainCommandEntry(Command command); - - void releaseInjectionState(InjectionState* injectionState); - void releaseEventEntry(EventEntry* entry); - void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry); - void releaseKeyEntry(KeyEntry* entry); - void releaseMotionEntry(MotionEntry* entry); - void releaseDispatchEntry(DispatchEntry* entry); - void releaseCommandEntry(CommandEntry* entry); - - void recycleKeyEntry(KeyEntry* entry); - - void appendMotionSample(MotionEntry* motionEntry, - nsecs_t eventTime, const PointerCoords* pointerCoords); - - private: - Pool<InjectionState> mInjectionStatePool; - Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool; - Pool<KeyEntry> mKeyEntryPool; - Pool<MotionEntry> mMotionEntryPool; - Pool<MotionSample> mMotionSamplePool; - Pool<DispatchEntry> mDispatchEntryPool; - Pool<CommandEntry> mCommandEntryPool; - - void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime, - uint32_t policyFlags); - void releaseEventEntryInjectionState(EventEntry* entry); - }; - - /* Tracks dispatched key and motion event state so that cancelation events can be - * synthesized when events are dropped. */ - class InputState { - public: - // Specifies whether a given event will violate input state consistency. - enum Consistency { - // The event is consistent with the current input state. - CONSISTENT, - // The event is inconsistent with the current input state but applications - // will tolerate it. eg. Down followed by another down. - TOLERABLE, - // The event is inconsistent with the current input state and will probably - // cause applications to crash. eg. Up without prior down, move with - // unexpected number of pointers. - BROKEN - }; - - // Specifies the sources to cancel. - enum CancelationOptions { - CANCEL_ALL_EVENTS = 0, - CANCEL_POINTER_EVENTS = 1, - CANCEL_NON_POINTER_EVENTS = 2, - }; - - InputState(); - ~InputState(); - - // Returns true if there is no state to be canceled. - bool isNeutral() const; - - // Records tracking information for an event that has just been published. - // Returns whether the event is consistent with the current input state. - Consistency trackEvent(const EventEntry* entry); - - // Records tracking information for a key event that has just been published. - // Returns whether the event is consistent with the current input state. - Consistency trackKey(const KeyEntry* entry); - - // Records tracking information for a motion event that has just been published. - // Returns whether the event is consistent with the current input state. - Consistency trackMotion(const MotionEntry* entry); - - // Synthesizes cancelation events for the current state and resets the tracked state. - void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator, - Vector<EventEntry*>& outEvents, CancelationOptions options); - - // Clears the current state. - void clear(); - - private: - struct KeyMemento { - int32_t deviceId; - int32_t source; - int32_t keyCode; - int32_t scanCode; - nsecs_t downTime; - }; - - struct MotionMemento { - int32_t deviceId; - int32_t source; - float xPrecision; - float yPrecision; - nsecs_t downTime; - uint32_t pointerCount; - int32_t pointerIds[MAX_POINTERS]; - PointerCoords pointerCoords[MAX_POINTERS]; - - void setPointers(const MotionEntry* entry); - }; - - Vector<KeyMemento> mKeyMementos; - Vector<MotionMemento> mMotionMementos; - - static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options); - }; - - /* Manages the dispatch state associated with a single input channel. */ - class Connection : public RefBase { - protected: - virtual ~Connection(); - - public: - enum Status { - // Everything is peachy. - STATUS_NORMAL, - // An unrecoverable communication error has occurred. - STATUS_BROKEN, - // The input channel has been unregistered. - STATUS_ZOMBIE - }; - - Status status; - sp<InputChannel> inputChannel; - InputPublisher inputPublisher; - InputState inputState; - Queue<DispatchEntry> outboundQueue; - - nsecs_t lastEventTime; // the time when the event was originally captured - nsecs_t lastDispatchTime; // the time when the last event was dispatched - - explicit Connection(const sp<InputChannel>& inputChannel); - - inline const char* getInputChannelName() const { return inputChannel->getName().string(); } - - const char* getStatusLabel() const; - - // Finds a DispatchEntry in the outbound queue associated with the specified event. - // Returns NULL if not found. - DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const; - - // Gets the time since the current event was originally obtained from the input driver. - inline double getEventLatencyMillis(nsecs_t currentTime) const { - return (currentTime - lastEventTime) / 1000000.0; - } - - // Gets the time since the current event entered the outbound dispatch queue. - inline double getDispatchLatencyMillis(nsecs_t currentTime) const { - return (currentTime - lastDispatchTime) / 1000000.0; - } - - status_t initialize(); - }; - - enum DropReason { - DROP_REASON_NOT_DROPPED = 0, - DROP_REASON_POLICY = 1, - DROP_REASON_APP_SWITCH = 2, - DROP_REASON_DISABLED = 3, - }; - - sp<InputDispatcherPolicyInterface> mPolicy; - - Mutex mLock; - - Allocator mAllocator; - sp<Looper> mLooper; - - EventEntry* mPendingEvent; - Queue<EventEntry> mInboundQueue; - Queue<CommandEntry> mCommandQueue; - - Vector<EventEntry*> mTempCancelationEvents; - - void dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, nsecs_t keyRepeatDelay, - nsecs_t* nextWakeupTime); - - // Enqueues an inbound event. Returns true if mLooper->wake() should be called. - bool enqueueInboundEventLocked(EventEntry* entry); - - // Cleans up input state when dropping an inbound event. - void dropInboundEventLocked(EventEntry* entry, DropReason dropReason); - - // App switch latency optimization. - bool mAppSwitchSawKeyDown; - nsecs_t mAppSwitchDueTime; - - static bool isAppSwitchKeyCode(int32_t keyCode); - bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry); - bool isAppSwitchPendingLocked(); - void resetPendingAppSwitchLocked(bool handled); - - // All registered connections mapped by receive pipe file descriptor. - KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd; - - ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel); - - // Active connections are connections that have a non-empty outbound queue. - // We don't use a ref-counted pointer here because we explicitly abort connections - // during unregistration which causes the connection's outbound queue to be cleared - // and the connection itself to be deactivated. - Vector<Connection*> mActiveConnections; - - // Input channels that will receive a copy of all input events. - Vector<sp<InputChannel> > mMonitoringChannels; - - // Preallocated key event object used for policy inquiries. - KeyEvent mReusableKeyEvent; - - // Event injection and synchronization. - Condition mInjectionResultAvailableCondition; - bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid); - void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult); - - Condition mInjectionSyncFinishedCondition; - void incrementPendingForegroundDispatchesLocked(EventEntry* entry); - void decrementPendingForegroundDispatchesLocked(EventEntry* entry); - - // Throttling state. - struct ThrottleState { - nsecs_t minTimeBetweenEvents; - - nsecs_t lastEventTime; - int32_t lastDeviceId; - uint32_t lastSource; - - uint32_t originalSampleCount; // only collected during debugging - } mThrottleState; - - // Key repeat tracking. - struct KeyRepeatState { - KeyEntry* lastKeyEntry; // or null if no repeat - nsecs_t nextRepeatTime; - } mKeyRepeatState; - - void resetKeyRepeatLocked(); - KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime, nsecs_t keyRepeatTimeout); - - // Deferred command processing. - bool runCommandsLockedInterruptible(); - CommandEntry* postCommandLocked(Command command); - - // Inbound event processing. - void drainInboundQueueLocked(); - void releasePendingEventLocked(); - void releaseInboundEventLocked(EventEntry* entry); - - // Dispatch state. - bool mDispatchEnabled; - bool mDispatchFrozen; - - Vector<InputWindow> mWindows; - - const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel); - - // Focus tracking for keys, trackball, etc. - const InputWindow* mFocusedWindow; - - // Focus tracking for touch. - struct TouchedWindow { - const InputWindow* window; - int32_t targetFlags; - BitSet32 pointerIds; - sp<InputChannel> channel; - }; - struct TouchState { - bool down; - bool split; - Vector<TouchedWindow> windows; - - TouchState(); - ~TouchState(); - void reset(); - void copyFrom(const TouchState& other); - void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds); - void removeOutsideTouchWindows(); - const InputWindow* getFirstForegroundWindow(); - }; - - TouchState mTouchState; - TouchState mTempTouchState; - - // Focused application. - InputApplication* mFocusedApplication; - InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication - void releaseFocusedApplicationLocked(); - - // Dispatch inbound events. - bool dispatchConfigurationChangedLocked( - nsecs_t currentTime, ConfigurationChangedEntry* entry); - bool dispatchKeyLocked( - nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout, - DropReason* dropReason, nsecs_t* nextWakeupTime); - bool dispatchMotionLocked( - nsecs_t currentTime, MotionEntry* entry, - DropReason* dropReason, nsecs_t* nextWakeupTime); - void dispatchEventToCurrentInputTargetsLocked( - nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample); - - void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry); - void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry); - - // The input targets that were most recently identified for dispatch. - bool mCurrentInputTargetsValid; // false while targets are being recomputed - Vector<InputTarget> mCurrentInputTargets; - - enum InputTargetWaitCause { - INPUT_TARGET_WAIT_CAUSE_NONE, - INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY, - INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY, - }; - - InputTargetWaitCause mInputTargetWaitCause; - nsecs_t mInputTargetWaitStartTime; - nsecs_t mInputTargetWaitTimeoutTime; - bool mInputTargetWaitTimeoutExpired; - - // Finding targets for input events. - void resetTargetsLocked(); - void commitTargetsLocked(); - int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry, - const InputApplication* application, const InputWindow* window, - nsecs_t* nextWakeupTime); - void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout, - const sp<InputChannel>& inputChannel); - nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime); - void resetANRTimeoutsLocked(); - - int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry, - nsecs_t* nextWakeupTime); - int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry, - nsecs_t* nextWakeupTime); - - void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags, - BitSet32 pointerIds); - void addMonitoringTargetsLocked(); - void pokeUserActivityLocked(const EventEntry* eventEntry); - bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState); - bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const; - bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window); - String8 getApplicationWindowLabelLocked(const InputApplication* application, - const InputWindow* window); - - // Manage the dispatch cycle for a single connection. - // These methods are deliberately not Interruptible because doing all of the work - // with the mutex held makes it easier to ensure that connection invariants are maintained. - // If needed, the methods post commands to run later once the critical bits are done. - void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection, - EventEntry* eventEntry, const InputTarget* inputTarget, - bool resumeWithAppendedMotionSample); - void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection); - void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection); - void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection); - void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection); - void drainOutboundQueueLocked(Connection* connection); - static int handleReceiveCallback(int receiveFd, int events, void* data); - - void synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CancelationOptions options, const char* reason); - void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel, - InputState::CancelationOptions options, const char* reason); - void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection, - InputState::CancelationOptions options, const char* reason); - - // Splitting motion events across windows. - MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds); - - // Reset and drop everything the dispatcher is doing. - void resetAndDropEverythingLocked(const char* reason); - - // Dump state. - void dumpDispatchStateLocked(String8& dump); - void logDispatchStateLocked(); - - // Add or remove a connection to the mActiveConnections vector. - void activateConnectionLocked(Connection* connection); - void deactivateConnectionLocked(Connection* connection); - - // Interesting events that we might like to log or tell the framework about. - void onDispatchCycleStartedLocked( - nsecs_t currentTime, const sp<Connection>& connection); - void onDispatchCycleFinishedLocked( - nsecs_t currentTime, const sp<Connection>& connection); - void onDispatchCycleBrokenLocked( - nsecs_t currentTime, const sp<Connection>& connection); - void onANRLocked( - nsecs_t currentTime, const InputApplication* application, const InputWindow* window, - nsecs_t eventTime, nsecs_t waitStartTime); - - // Outbound policy interactions. - void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry); - void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry); - void doNotifyANRLockedInterruptible(CommandEntry* commandEntry); - void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry); - void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry); - - // Statistics gathering. - void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry, - int32_t injectionResult, nsecs_t timeSpentWaitingForApplication); -}; - -/* Enqueues and dispatches input events, endlessly. */ -class InputDispatcherThread : public Thread { -public: - explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher); - ~InputDispatcherThread(); - -private: - virtual bool threadLoop(); - - sp<InputDispatcherInterface> mDispatcher; -}; - -} // namespace android - -#endif // _UI_INPUT_DISPATCHER_H diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h deleted file mode 100644 index 568568b..0000000 --- a/include/ui/InputManager.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _UI_INPUT_MANAGER_H -#define _UI_INPUT_MANAGER_H - -/** - * Native input manager. - */ - -#include <ui/EventHub.h> -#include <ui/Input.h> -#include <utils/Errors.h> -#include <utils/Vector.h> -#include <utils/Timers.h> -#include <utils/RefBase.h> -#include <utils/String8.h> - -namespace android { - -class InputChannel; - -class InputReaderInterface; -class InputReaderPolicyInterface; -class InputReaderThread; - -class InputDispatcherInterface; -class InputDispatcherPolicyInterface; -class InputDispatcherThread; - -/* - * The input manager is the core of the system event processing. - * - * The input manager uses two threads. - * - * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events, - * applies policy, and posts messages to a queue managed by the DispatcherThread. - * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the - * queue and asynchronously dispatches them to applications. - * - * By design, the InputReaderThread class and InputDispatcherThread class do not share any - * internal state. Moreover, all communication is done one way from the InputReaderThread - * into the InputDispatcherThread and never the reverse. Both classes may interact with the - * InputDispatchPolicy, however. - * - * The InputManager class never makes any calls into Java itself. Instead, the - * InputDispatchPolicy is responsible for performing all external interactions with the - * system, including calling DVM services. - */ -class InputManagerInterface : public virtual RefBase { -protected: - InputManagerInterface() { } - virtual ~InputManagerInterface() { } - -public: - /* Starts the input manager threads. */ - virtual status_t start() = 0; - - /* Stops the input manager threads and waits for them to exit. */ - virtual status_t stop() = 0; - - /* Gets the input reader. */ - virtual sp<InputReaderInterface> getReader() = 0; - - /* Gets the input dispatcher. */ - virtual sp<InputDispatcherInterface> getDispatcher() = 0; -}; - -class InputManager : public InputManagerInterface { -protected: - virtual ~InputManager(); - -public: - InputManager( - const sp<EventHubInterface>& eventHub, - const sp<InputReaderPolicyInterface>& readerPolicy, - const sp<InputDispatcherPolicyInterface>& dispatcherPolicy); - - // (used for testing purposes) - InputManager( - const sp<InputReaderInterface>& reader, - const sp<InputDispatcherInterface>& dispatcher); - - virtual status_t start(); - virtual status_t stop(); - - virtual sp<InputReaderInterface> getReader(); - virtual sp<InputDispatcherInterface> getDispatcher(); - -private: - sp<InputReaderInterface> mReader; - sp<InputReaderThread> mReaderThread; - - sp<InputDispatcherInterface> mDispatcher; - sp<InputDispatcherThread> mDispatcherThread; - - void initialize(); -}; - -} // namespace android - -#endif // _UI_INPUT_MANAGER_H diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h deleted file mode 100644 index 49351b0..0000000 --- a/include/ui/InputReader.h +++ /dev/null @@ -1,927 +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_INPUT_READER_H -#define _UI_INPUT_READER_H - -#include <ui/EventHub.h> -#include <ui/Input.h> -#include <ui/InputDispatcher.h> -#include <utils/KeyedVector.h> -#include <utils/threads.h> -#include <utils/Timers.h> -#include <utils/RefBase.h> -#include <utils/String8.h> -#include <utils/BitSet.h> - -#include <stddef.h> -#include <unistd.h> - -namespace android { - -class InputDevice; -class InputMapper; - -/* Describes a virtual key. */ -struct VirtualKeyDefinition { - int32_t scanCode; - - // configured position data, specified in display coords - int32_t centerX; - int32_t centerY; - int32_t width; - int32_t height; -}; - - -/* Specifies input device calibration settings. */ -class InputDeviceCalibration { -public: - InputDeviceCalibration(); - - void clear(); - void addProperty(const String8& key, const String8& value); - - bool tryGetProperty(const String8& key, String8& outValue) const; - bool tryGetProperty(const String8& key, int32_t& outValue) const; - bool tryGetProperty(const String8& key, float& outValue) const; - -private: - KeyedVector<String8, String8> mProperties; -}; - - -/* - * Input reader policy interface. - * - * The input reader policy is used by the input reader to interact with the Window Manager - * and other system components. - * - * The actual implementation is partially supported by callbacks into the DVM - * via JNI. This interface is also mocked in the unit tests. - */ -class InputReaderPolicyInterface : public virtual RefBase { -protected: - InputReaderPolicyInterface() { } - virtual ~InputReaderPolicyInterface() { } - -public: - /* Display orientations. */ - enum { - ROTATION_0 = 0, - ROTATION_90 = 1, - ROTATION_180 = 2, - ROTATION_270 = 3 - }; - - /* Gets information about the display with the specified id. - * Returns true if the display info is available, false otherwise. - */ - virtual bool getDisplayInfo(int32_t displayId, - int32_t* width, int32_t* height, int32_t* orientation) = 0; - - /* Determines whether to turn on some hacks we have to improve the touch interaction with a - * certain device whose screen currently is not all that good. - */ - virtual bool filterTouchEvents() = 0; - - /* Determines whether to turn on some hacks to improve touch interaction with another device - * where touch coordinate data can get corrupted. - */ - virtual bool filterJumpyTouchEvents() = 0; - - /* Gets the configured virtual key definitions for an input device. */ - virtual void getVirtualKeyDefinitions(const String8& deviceName, - Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0; - - /* Gets the calibration for an input device. */ - virtual void getInputDeviceCalibration(const String8& deviceName, - InputDeviceCalibration& outCalibration) = 0; - - /* Gets the excluded device names for the platform. */ - virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0; -}; - - -/* Processes raw input events and sends cooked event data to an input dispatcher. */ -class InputReaderInterface : public virtual RefBase { -protected: - InputReaderInterface() { } - virtual ~InputReaderInterface() { } - -public: - /* Dumps the state of the input reader. - * - * This method may be called on any thread (usually by the input manager). */ - virtual void dump(String8& dump) = 0; - - /* Runs a single iteration of the processing loop. - * Nominally reads and processes one incoming message from the EventHub. - * - * This method should be called on the input reader thread. - */ - virtual void loopOnce() = 0; - - /* Gets the current input device configuration. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0; - - /* Gets information about the specified input device. - * Returns OK if the device information was obtained or NAME_NOT_FOUND if there - * was no such device. - * - * This method may be called on any thread (usually by the input manager). - */ - virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0; - - /* Gets the list of all registered device ids. */ - virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0; - - /* Query current input state. */ - virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, - int32_t scanCode) = 0; - virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, - int32_t keyCode) = 0; - virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, - int32_t sw) = 0; - - /* Determine whether physical keys exist for the given framework-domain key codes. */ - virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask, - size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0; -}; - - -/* Internal interface used by individual input devices to access global input device state - * and parameters maintained by the input reader. - */ -class InputReaderContext { -public: - InputReaderContext() { } - virtual ~InputReaderContext() { } - - virtual void updateGlobalMetaState() = 0; - virtual int32_t getGlobalMetaState() = 0; - - virtual InputReaderPolicyInterface* getPolicy() = 0; - virtual InputDispatcherInterface* getDispatcher() = 0; - virtual EventHubInterface* getEventHub() = 0; -}; - - -/* The input reader reads raw event data from the event hub and processes it into input events - * that it sends to the input dispatcher. Some functions of the input reader, such as early - * event filtering in low power states, are controlled by a separate policy object. - * - * IMPORTANT INVARIANT: - * Because the policy and dispatcher can potentially block or cause re-entrance into - * the input reader, the input reader never calls into other components while holding - * an exclusive internal lock whenever re-entrance can happen. - */ -class InputReader : public InputReaderInterface, protected InputReaderContext { -public: - InputReader(const sp<EventHubInterface>& eventHub, - const sp<InputReaderPolicyInterface>& policy, - const sp<InputDispatcherInterface>& dispatcher); - virtual ~InputReader(); - - virtual void dump(String8& dump); - - virtual void loopOnce(); - - virtual void getInputConfiguration(InputConfiguration* outConfiguration); - - virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo); - virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds); - - virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, - int32_t scanCode); - virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, - int32_t keyCode); - virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, - int32_t sw); - - virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask, - size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags); - -protected: - // These methods are protected virtual so they can be overridden and instrumented - // by test cases. - virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes); - -private: - sp<EventHubInterface> mEventHub; - sp<InputReaderPolicyInterface> mPolicy; - sp<InputDispatcherInterface> mDispatcher; - - virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); } - virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); } - virtual EventHubInterface* getEventHub() { return mEventHub.get(); } - - // This reader/writer lock guards the list of input devices. - // The writer lock must be held whenever the list of input devices is modified - // and then promptly released. - // The reader lock must be held whenever the list of input devices is traversed or an - // input device in the list is accessed. - // This lock only protects the registry and prevents inadvertent deletion of device objects - // that are in use. Individual devices are responsible for guarding their own internal state - // as needed for concurrent operation. - RWLock mDeviceRegistryLock; - KeyedVector<int32_t, InputDevice*> mDevices; - - // low-level input event decoding and device management - void process(const RawEvent* rawEvent); - - void addDevice(int32_t deviceId); - void removeDevice(int32_t deviceId); - void configureExcludedDevices(); - - void consumeEvent(const RawEvent* rawEvent); - - void handleConfigurationChanged(nsecs_t when); - - // state management for all devices - Mutex mStateLock; - - int32_t mGlobalMetaState; - virtual void updateGlobalMetaState(); - virtual int32_t getGlobalMetaState(); - - InputConfiguration mInputConfiguration; - void updateInputConfiguration(); - - // state queries - typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code); - int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code, - GetStateFunc getStateFunc); - bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags); -}; - - -/* Reads raw events from the event hub and processes them, endlessly. */ -class InputReaderThread : public Thread { -public: - InputReaderThread(const sp<InputReaderInterface>& reader); - virtual ~InputReaderThread(); - -private: - sp<InputReaderInterface> mReader; - - virtual bool threadLoop(); -}; - - -/* Represents the state of a single input device. */ -class InputDevice { -public: - InputDevice(InputReaderContext* context, int32_t id, const String8& name); - ~InputDevice(); - - inline InputReaderContext* getContext() { return mContext; } - inline int32_t getId() { return mId; } - inline const String8& getName() { return mName; } - inline uint32_t getSources() { return mSources; } - - inline bool isIgnored() { return mMappers.isEmpty(); } - - void dump(String8& dump); - void addMapper(InputMapper* mapper); - void configure(); - void reset(); - void process(const RawEvent* rawEvent); - - void getDeviceInfo(InputDeviceInfo* outDeviceInfo); - int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode); - int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode); - int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode); - bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags); - - int32_t getMetaState(); - - inline const InputDeviceCalibration& getCalibration() { - return mCalibration; - } - -private: - InputReaderContext* mContext; - int32_t mId; - - Vector<InputMapper*> mMappers; - - String8 mName; - uint32_t mSources; - - typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code); - int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc); - - InputDeviceCalibration mCalibration; -}; - - -/* An input mapper transforms raw input events into cooked event data. - * A single input device can have multiple associated input mappers in order to interpret - * different classes of events. - */ -class InputMapper { -public: - InputMapper(InputDevice* device); - virtual ~InputMapper(); - - inline InputDevice* getDevice() { return mDevice; } - inline int32_t getDeviceId() { return mDevice->getId(); } - inline const String8 getDeviceName() { return mDevice->getName(); } - inline InputReaderContext* getContext() { return mContext; } - inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); } - inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); } - inline EventHubInterface* getEventHub() { return mContext->getEventHub(); } - - virtual uint32_t getSources() = 0; - virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); - virtual void dump(String8& dump); - virtual void configure(); - virtual void reset(); - virtual void process(const RawEvent* rawEvent) = 0; - - virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode); - virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode); - virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode); - virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags); - - virtual int32_t getMetaState(); - -protected: - InputDevice* mDevice; - InputReaderContext* mContext; -}; - - -class SwitchInputMapper : public InputMapper { -public: - SwitchInputMapper(InputDevice* device); - virtual ~SwitchInputMapper(); - - virtual uint32_t getSources(); - virtual void process(const RawEvent* rawEvent); - - virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode); - -private: - void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue); -}; - - -class KeyboardInputMapper : public InputMapper { -public: - KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources, - int32_t keyboardType); - virtual ~KeyboardInputMapper(); - - virtual uint32_t getSources(); - virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); - virtual void dump(String8& dump); - virtual void reset(); - virtual void process(const RawEvent* rawEvent); - - virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode); - virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode); - virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags); - - virtual int32_t getMetaState(); - -private: - Mutex mLock; - - struct KeyDown { - int32_t keyCode; - int32_t scanCode; - }; - - int32_t mAssociatedDisplayId; - uint32_t mSources; - int32_t mKeyboardType; - - struct LockedState { - Vector<KeyDown> keyDowns; // keys that are down - int32_t metaState; - nsecs_t downTime; // time of most recent key down - } mLocked; - - void initializeLocked(); - - bool isKeyboardOrGamepadKey(int32_t scanCode); - - void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode, - uint32_t policyFlags); - - ssize_t findKeyDownLocked(int32_t scanCode); -}; - - -class TrackballInputMapper : public InputMapper { -public: - TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId); - virtual ~TrackballInputMapper(); - - virtual uint32_t getSources(); - virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); - virtual void dump(String8& dump); - virtual void reset(); - virtual void process(const RawEvent* rawEvent); - - virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode); - -private: - // Amount that trackball needs to move in order to generate a key event. - static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6; - - Mutex mLock; - - int32_t mAssociatedDisplayId; - - struct Accumulator { - enum { - FIELD_BTN_MOUSE = 1, - FIELD_REL_X = 2, - FIELD_REL_Y = 4 - }; - - uint32_t fields; - - bool btnMouse; - int32_t relX; - int32_t relY; - - inline void clear() { - fields = 0; - } - } mAccumulator; - - float mXScale; - float mYScale; - float mXPrecision; - float mYPrecision; - - struct LockedState { - bool down; - nsecs_t downTime; - } mLocked; - - void initializeLocked(); - - void sync(nsecs_t when); -}; - - -class TouchInputMapper : public InputMapper { -public: - TouchInputMapper(InputDevice* device, int32_t associatedDisplayId); - virtual ~TouchInputMapper(); - - virtual uint32_t getSources(); - virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); - virtual void dump(String8& dump); - virtual void configure(); - virtual void reset(); - - virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode); - virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode); - virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, - const int32_t* keyCodes, uint8_t* outFlags); - -protected: - Mutex mLock; - - struct VirtualKey { - int32_t keyCode; - int32_t scanCode; - uint32_t flags; - - // computed hit box, specified in touch screen coords based on known display size - int32_t hitLeft; - int32_t hitTop; - int32_t hitRight; - int32_t hitBottom; - - inline bool isHit(int32_t x, int32_t y) const { - return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom; - } - }; - - // Raw data for a single pointer. - struct PointerData { - uint32_t id; - int32_t x; - int32_t y; - int32_t pressure; - int32_t touchMajor; - int32_t touchMinor; - int32_t toolMajor; - int32_t toolMinor; - int32_t orientation; - - inline bool operator== (const PointerData& other) const { - return id == other.id - && x == other.x - && y == other.y - && pressure == other.pressure - && touchMajor == other.touchMajor - && touchMinor == other.touchMinor - && toolMajor == other.toolMajor - && toolMinor == other.toolMinor - && orientation == other.orientation; - } - inline bool operator!= (const PointerData& other) const { - return !(*this == other); - } - }; - - // Raw data for a collection of pointers including a pointer id mapping table. - struct TouchData { - uint32_t pointerCount; - PointerData pointers[MAX_POINTERS]; - BitSet32 idBits; - uint32_t idToIndex[MAX_POINTER_ID + 1]; - - void copyFrom(const TouchData& other) { - pointerCount = other.pointerCount; - idBits = other.idBits; - - for (uint32_t i = 0; i < pointerCount; i++) { - pointers[i] = other.pointers[i]; - - int id = pointers[i].id; - idToIndex[id] = other.idToIndex[id]; - } - } - - inline void clear() { - pointerCount = 0; - idBits.clear(); - } - }; - - int32_t mAssociatedDisplayId; - - // Immutable configuration parameters. - struct Parameters { - bool useBadTouchFilter; - bool useJumpyTouchFilter; - bool useAveragingTouchFilter; - } mParameters; - - // Immutable calibration parameters in parsed form. - struct Calibration { - // Touch Size - enum TouchSizeCalibration { - TOUCH_SIZE_CALIBRATION_DEFAULT, - TOUCH_SIZE_CALIBRATION_NONE, - TOUCH_SIZE_CALIBRATION_GEOMETRIC, - TOUCH_SIZE_CALIBRATION_PRESSURE, - }; - - TouchSizeCalibration touchSizeCalibration; - - // Tool Size - enum ToolSizeCalibration { - TOOL_SIZE_CALIBRATION_DEFAULT, - TOOL_SIZE_CALIBRATION_NONE, - TOOL_SIZE_CALIBRATION_GEOMETRIC, - TOOL_SIZE_CALIBRATION_LINEAR, - TOOL_SIZE_CALIBRATION_AREA, - }; - - ToolSizeCalibration toolSizeCalibration; - bool haveToolSizeLinearScale; - float toolSizeLinearScale; - bool haveToolSizeLinearBias; - float toolSizeLinearBias; - bool haveToolSizeAreaScale; - float toolSizeAreaScale; - bool haveToolSizeAreaBias; - float toolSizeAreaBias; - bool haveToolSizeIsSummed; - int32_t toolSizeIsSummed; - - // Pressure - enum PressureCalibration { - PRESSURE_CALIBRATION_DEFAULT, - PRESSURE_CALIBRATION_NONE, - PRESSURE_CALIBRATION_PHYSICAL, - PRESSURE_CALIBRATION_AMPLITUDE, - }; - enum PressureSource { - PRESSURE_SOURCE_DEFAULT, - PRESSURE_SOURCE_PRESSURE, - PRESSURE_SOURCE_TOUCH, - }; - - PressureCalibration pressureCalibration; - PressureSource pressureSource; - bool havePressureScale; - float pressureScale; - - // Size - enum SizeCalibration { - SIZE_CALIBRATION_DEFAULT, - SIZE_CALIBRATION_NONE, - SIZE_CALIBRATION_NORMALIZED, - }; - - SizeCalibration sizeCalibration; - - // Orientation - enum OrientationCalibration { - ORIENTATION_CALIBRATION_DEFAULT, - ORIENTATION_CALIBRATION_NONE, - ORIENTATION_CALIBRATION_INTERPOLATED, - }; - - OrientationCalibration orientationCalibration; - } mCalibration; - - // Raw axis information from the driver. - struct RawAxes { - RawAbsoluteAxisInfo x; - RawAbsoluteAxisInfo y; - RawAbsoluteAxisInfo pressure; - RawAbsoluteAxisInfo touchMajor; - RawAbsoluteAxisInfo touchMinor; - RawAbsoluteAxisInfo toolMajor; - RawAbsoluteAxisInfo toolMinor; - RawAbsoluteAxisInfo orientation; - } mRawAxes; - - // Current and previous touch sample data. - TouchData mCurrentTouch; - TouchData mLastTouch; - - // The time the primary pointer last went down. - nsecs_t mDownTime; - - struct LockedState { - Vector<VirtualKey> virtualKeys; - - // The surface orientation and width and height set by configureSurfaceLocked(). - int32_t surfaceOrientation; - int32_t surfaceWidth, surfaceHeight; - - // Translation and scaling factors, orientation-independent. - int32_t xOrigin; - float xScale; - float xPrecision; - - int32_t yOrigin; - float yScale; - float yPrecision; - - float geometricScale; - - float toolSizeLinearScale; - float toolSizeLinearBias; - float toolSizeAreaScale; - float toolSizeAreaBias; - - float pressureScale; - - float sizeScale; - - float orientationScale; - - // Oriented motion ranges for input device info. - struct OrientedRanges { - InputDeviceInfo::MotionRange x; - InputDeviceInfo::MotionRange y; - - bool havePressure; - InputDeviceInfo::MotionRange pressure; - - bool haveSize; - InputDeviceInfo::MotionRange size; - - bool haveTouchSize; - InputDeviceInfo::MotionRange touchMajor; - InputDeviceInfo::MotionRange touchMinor; - - bool haveToolSize; - InputDeviceInfo::MotionRange toolMajor; - InputDeviceInfo::MotionRange toolMinor; - - bool haveOrientation; - InputDeviceInfo::MotionRange orientation; - } orientedRanges; - - // Oriented dimensions and precision. - float orientedSurfaceWidth, orientedSurfaceHeight; - float orientedXPrecision, orientedYPrecision; - - struct CurrentVirtualKeyState { - bool down; - nsecs_t downTime; - int32_t keyCode; - int32_t scanCode; - } currentVirtualKey; - } mLocked; - - virtual void configureParameters(); - virtual void dumpParameters(String8& dump); - virtual void configureRawAxes(); - virtual void dumpRawAxes(String8& dump); - virtual bool configureSurfaceLocked(); - virtual void dumpSurfaceLocked(String8& dump); - virtual void configureVirtualKeysLocked(); - virtual void dumpVirtualKeysLocked(String8& dump); - virtual void parseCalibration(); - virtual void resolveCalibration(); - virtual void dumpCalibration(String8& dump); - - enum TouchResult { - // Dispatch the touch normally. - DISPATCH_TOUCH, - // Do not dispatch the touch, but keep tracking the current stroke. - SKIP_TOUCH, - // Do not dispatch the touch, and drop all information associated with the current stoke - // so the next movement will appear as a new down. - DROP_STROKE - }; - - void syncTouch(nsecs_t when, bool havePointerIds); - -private: - /* Maximum number of historical samples to average. */ - static const uint32_t AVERAGING_HISTORY_SIZE = 5; - - /* Slop distance for jumpy pointer detection. - * The vertical range of the screen divided by this is our epsilon value. */ - static const uint32_t JUMPY_EPSILON_DIVISOR = 212; - - /* Number of jumpy points to drop for touchscreens that need it. */ - static const uint32_t JUMPY_TRANSITION_DROPS = 3; - static const uint32_t JUMPY_DROP_LIMIT = 3; - - /* Maximum squared distance for averaging. - * If moving farther than this, turn of averaging to avoid lag in response. */ - static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75; - - struct AveragingTouchFilterState { - // Individual history tracks are stored by pointer id - uint32_t historyStart[MAX_POINTERS]; - uint32_t historyEnd[MAX_POINTERS]; - struct { - struct { - int32_t x; - int32_t y; - int32_t pressure; - } pointers[MAX_POINTERS]; - } historyData[AVERAGING_HISTORY_SIZE]; - } mAveragingTouchFilter; - - struct JumpyTouchFilterState { - uint32_t jumpyPointsDropped; - } mJumpyTouchFilter; - - struct PointerDistanceHeapElement { - uint32_t currentPointerIndex : 8; - uint32_t lastPointerIndex : 8; - uint64_t distance : 48; // squared distance - }; - - void initializeLocked(); - - TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags); - void dispatchTouches(nsecs_t when, uint32_t policyFlags); - void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch, - BitSet32 idBits, uint32_t changedId, uint32_t pointerCount, - int32_t motionEventAction); - - bool isPointInsideSurfaceLocked(int32_t x, int32_t y); - const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y); - - bool applyBadTouchFilter(); - bool applyJumpyTouchFilter(); - void applyAveragingTouchFilter(); - void calculatePointerIds(); -}; - - -class SingleTouchInputMapper : public TouchInputMapper { -public: - SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId); - virtual ~SingleTouchInputMapper(); - - virtual void reset(); - virtual void process(const RawEvent* rawEvent); - -protected: - virtual void configureRawAxes(); - -private: - struct Accumulator { - enum { - FIELD_BTN_TOUCH = 1, - FIELD_ABS_X = 2, - FIELD_ABS_Y = 4, - FIELD_ABS_PRESSURE = 8, - FIELD_ABS_TOOL_WIDTH = 16 - }; - - uint32_t fields; - - bool btnTouch; - int32_t absX; - int32_t absY; - int32_t absPressure; - int32_t absToolWidth; - - inline void clear() { - fields = 0; - } - } mAccumulator; - - bool mDown; - int32_t mX; - int32_t mY; - int32_t mPressure; - int32_t mToolWidth; - - void initialize(); - - void sync(nsecs_t when); -}; - - -class MultiTouchInputMapper : public TouchInputMapper { -public: - MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId); - virtual ~MultiTouchInputMapper(); - - virtual void reset(); - virtual void process(const RawEvent* rawEvent); - -protected: - virtual void configureRawAxes(); - -private: - struct Accumulator { - enum { - FIELD_ABS_MT_POSITION_X = 1, - FIELD_ABS_MT_POSITION_Y = 2, - FIELD_ABS_MT_TOUCH_MAJOR = 4, - FIELD_ABS_MT_TOUCH_MINOR = 8, - FIELD_ABS_MT_WIDTH_MAJOR = 16, - FIELD_ABS_MT_WIDTH_MINOR = 32, - FIELD_ABS_MT_ORIENTATION = 64, - FIELD_ABS_MT_TRACKING_ID = 128, - FIELD_ABS_MT_PRESSURE = 256, - }; - - uint32_t pointerCount; - struct Pointer { - uint32_t fields; - - int32_t absMTPositionX; - int32_t absMTPositionY; - int32_t absMTTouchMajor; - int32_t absMTTouchMinor; - int32_t absMTWidthMajor; - int32_t absMTWidthMinor; - int32_t absMTOrientation; - int32_t absMTTrackingId; - int32_t absMTPressure; - - inline void clear() { - fields = 0; - } - } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks - - inline void clear() { - pointerCount = 0; - pointers[0].clear(); - } - } mAccumulator; - - void initialize(); - - void sync(nsecs_t when); -}; - -} // namespace android - -#endif // _UI_INPUT_READER_H diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h index dc9e27a..119db81 100644 --- a/include/ui/InputTransport.h +++ b/include/ui/InputTransport.h @@ -250,12 +250,13 @@ public: status_t sendDispatchSignal(); /* Receives the finished signal from the consumer in reply to the original dispatch signal. + * Returns whether the consumer handled the message. * * Returns OK on success. * Returns WOULD_BLOCK if there is no signal present. * Other errors probably indicate that the channel is broken. */ - status_t receiveFinishedSignal(); + status_t receiveFinishedSignal(bool* outHandled); private: sp<InputChannel> mChannel; @@ -305,12 +306,12 @@ public: status_t consume(InputEventFactoryInterface* factory, InputEvent** outEvent); /* Sends a finished signal to the publisher to inform it that the current message is - * finished processing. + * finished processing and specifies whether the message was handled by the consumer. * * Returns OK on success. * Errors probably indicate that the channel is broken. */ - status_t sendFinishedSignal(); + status_t sendFinishedSignal(bool handled); /* Receives the dispatched signal from the publisher. * diff --git a/include/ui/KeyCharacterMap.h b/include/ui/KeyCharacterMap.h index bad2cf8..10a3810 100644 --- a/include/ui/KeyCharacterMap.h +++ b/include/ui/KeyCharacterMap.h @@ -18,55 +18,183 @@ #define _UI_KEY_CHARACTER_MAP_H #include <stdint.h> -#include <utils/Vector.h> -using namespace android; +#include <ui/Input.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/Tokenizer.h> +#include <utils/String8.h> +#include <utils/Unicode.h> -class KeyCharacterMap -{ +namespace android { + +/** + * Describes a mapping from Android key codes to characters. + * Also specifies other functions of the keyboard such as the keyboard type + * and key modifier semantics. + */ +class KeyCharacterMap { public: - ~KeyCharacterMap(); + enum KeyboardType { + KEYBOARD_TYPE_UNKNOWN = 0, + KEYBOARD_TYPE_NUMERIC = 1, + KEYBOARD_TYPE_PREDICTIVE = 2, + KEYBOARD_TYPE_ALPHA = 3, + KEYBOARD_TYPE_FULL = 4, + KEYBOARD_TYPE_SPECIAL_FUNCTION = 5, + }; - // see the javadoc for android.text.method.KeyCharacterMap for what - // these do - unsigned short get(int keycode, int meta); - unsigned short getNumber(int keycode); - unsigned short getMatch(int keycode, const unsigned short* chars, - int charsize, uint32_t modifiers); - unsigned short getDisplayLabel(int keycode); - bool getKeyData(int keycode, unsigned short *displayLabel, - unsigned short *number, unsigned short* results); - inline unsigned int getKeyboardType() { return m_type; } - bool getEvents(uint16_t* chars, size_t len, - Vector<int32_t>* keys, Vector<uint32_t>* modifiers); - - static KeyCharacterMap* load(int id); - - enum { - NUMERIC = 1, - Q14 = 2, - QWERTY = 3 // or AZERTY or whatever + // Substitute key code and meta state for fallback action. + struct FallbackAction { + int32_t keyCode; + int32_t metaState; }; -#define META_MASK 3 + ~KeyCharacterMap(); + + static status_t load(const String8& filename, KeyCharacterMap** outMap); + static status_t loadByDeviceId(int32_t deviceId, KeyCharacterMap** outMap); + + /* Gets the keyboard type. */ + int32_t getKeyboardType() const; + + /* Gets the primary character for this key as in the label physically printed on it. + * Returns 0 if none (eg. for non-printing keys). */ + char16_t getDisplayLabel(int32_t keyCode) const; + + /* Gets the Unicode character for the number or symbol generated by the key + * when the keyboard is used as a dialing pad. + * Returns 0 if no number or symbol is generated. + */ + char16_t getNumber(int32_t keyCode) const; + + /* Gets the Unicode character generated by the key and meta key modifiers. + * Returns 0 if no character is generated. + */ + char16_t getCharacter(int32_t keyCode, int32_t metaState) const; + + /* Gets the fallback action to use by default if the application does not + * handle the specified key. + * Returns true if an action was available, false if none. + */ + bool getFallbackAction(int32_t keyCode, int32_t metaState, + FallbackAction* outFallbackAction) const; + + /* Gets the first matching Unicode character that can be generated by the key, + * preferring the one with the specified meta key modifiers. + * Returns 0 if no matching character is generated. + */ + char16_t getMatch(int32_t keyCode, const char16_t* chars, + size_t numChars, int32_t metaState) const; + + /* Gets a sequence of key events that could plausibly generate the specified + * character sequence. Returns false if some of the characters cannot be generated. + */ + bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, + Vector<KeyEvent>& outEvents) const; private: - struct Key - { - int32_t keycode; - uint16_t display_label; - uint16_t number; - uint16_t data[META_MASK + 1]; + struct Behavior { + Behavior(); + + /* The next behavior in the list, or NULL if none. */ + Behavior* next; + + /* The meta key modifiers for this behavior. */ + int32_t metaState; + + /* The character to insert. */ + char16_t character; + + /* The fallback keycode if the key is not handled. */ + int32_t fallbackKeyCode; }; + struct Key { + Key(); + ~Key(); + + /* The single character label printed on the key, or 0 if none. */ + char16_t label; + + /* The number or symbol character generated by the key, or 0 if none. */ + char16_t number; + + /* The list of key behaviors sorted from most specific to least specific + * meta key binding. */ + Behavior* firstBehavior; + }; + + class Parser { + enum State { + STATE_TOP = 0, + STATE_KEY = 1, + }; + + enum { + PROPERTY_LABEL = 1, + PROPERTY_NUMBER = 2, + PROPERTY_META = 3, + }; + + struct Property { + inline Property(int32_t property = 0, int32_t metaState = 0) : + property(property), metaState(metaState) { } + + int32_t property; + int32_t metaState; + }; + + KeyCharacterMap* mMap; + Tokenizer* mTokenizer; + State mState; + int32_t mKeyCode; + + public: + Parser(KeyCharacterMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseType(); + status_t parseKey(); + status_t parseKeyProperty(); + status_t parseModifier(const String8& token, int32_t* outMetaState); + status_t parseCharacterLiteral(char16_t* outCharacter); + }; + + KeyedVector<int32_t, Key*> mKeys; + int mType; + KeyCharacterMap(); - static KeyCharacterMap* try_file(const char* filename); - Key* find_key(int keycode); - bool find_char(uint16_t c, uint32_t* key, uint32_t* mods); - unsigned int m_type; - unsigned int m_keyCount; - Key* m_keys; + bool getKey(int32_t keyCode, const Key** outKey) const; + bool getKeyBehavior(int32_t keyCode, int32_t metaState, + const Key** outKey, const Behavior** outBehavior) const; + + bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const; + + static void addKey(Vector<KeyEvent>& outEvents, + int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time); + static void addMetaKeys(Vector<KeyEvent>& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t* currentMetaState); + static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t keyCode, int32_t keyMetaState, + int32_t* currentMetaState); + static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t leftKeyCode, int32_t leftKeyMetaState, + int32_t rightKeyCode, int32_t rightKeyMetaState, + int32_t eitherKeyMetaState, + int32_t* currentMetaState); + static void addLockedMetaKey(Vector<KeyEvent>& outEvents, + int32_t deviceId, int32_t metaState, nsecs_t time, + int32_t keyCode, int32_t keyMetaState, + int32_t* currentMetaState); }; +} // namespace android + #endif // _UI_KEY_CHARACTER_MAP_H diff --git a/include/ui/KeyLayoutMap.h b/include/ui/KeyLayoutMap.h new file mode 100644 index 0000000..f0a6d00 --- /dev/null +++ b/include/ui/KeyLayoutMap.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UI_KEY_LAYOUT_MAP_H +#define _UI_KEY_LAYOUT_MAP_H + +#include <stdint.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/Tokenizer.h> + +namespace android { + +/** + * Describes a mapping from keyboard scan codes to Android key codes. + */ +class KeyLayoutMap { +public: + ~KeyLayoutMap(); + + static status_t load(const String8& filename, KeyLayoutMap** outMap); + + status_t map(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const; + status_t findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCodes) const; + +private: + struct Key { + int32_t keyCode; + uint32_t flags; + }; + + KeyedVector<int32_t,Key> mKeys; + + KeyLayoutMap(); + + class Parser { + KeyLayoutMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(KeyLayoutMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseKey(); + }; +}; + +} // namespace android + +#endif // _UI_KEY_LAYOUT_MAP_H diff --git a/include/ui/Keyboard.h b/include/ui/Keyboard.h new file mode 100644 index 0000000..50296e2 --- /dev/null +++ b/include/ui/Keyboard.h @@ -0,0 +1,120 @@ +/* + * 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_KEYBOARD_H +#define _UI_KEYBOARD_H + +#include <ui/Input.h> +#include <utils/Errors.h> +#include <utils/String8.h> +#include <utils/PropertyMap.h> + +namespace android { + +enum { + /* Device id of the built in keyboard. */ + DEVICE_ID_BUILT_IN_KEYBOARD = 0, + + /* Device id of a generic virtual keyboard with a full layout that can be used + * to synthesize key events. */ + DEVICE_ID_VIRTUAL_KEYBOARD = -1, +}; + +class KeyLayoutMap; +class KeyCharacterMap; + +/** + * Loads the key layout map and key character map for a keyboard device. + */ +class KeyMap { +public: + String8 keyLayoutFile; + KeyLayoutMap* keyLayoutMap; + + String8 keyCharacterMapFile; + KeyCharacterMap* keyCharacterMap; + + KeyMap(); + ~KeyMap(); + + status_t load(const InputDeviceIdentifier& deviceIdenfier, + const PropertyMap* deviceConfiguration); + + inline bool haveKeyLayout() const { + return !keyLayoutFile.isEmpty(); + } + + inline bool haveKeyCharacterMap() const { + return !keyCharacterMapFile.isEmpty(); + } + + inline bool isComplete() const { + return haveKeyLayout() && haveKeyCharacterMap(); + } + +private: + bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name); + status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name); + status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier, + const String8& name); + String8 getPath(const InputDeviceIdentifier& deviceIdentifier, + const String8& name, InputDeviceConfigurationFileType type); +}; + +/** + * Returns true if the keyboard is eligible for use as a built-in keyboard. + */ +extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier, + const PropertyMap* deviceConfiguration, const KeyMap* keyMap); + +/** + * Sets keyboard system properties. + */ +extern void setKeyboardProperties(int32_t deviceId, const InputDeviceIdentifier& deviceIdentifier, + const String8& keyLayoutFile, const String8& keyCharacterMapFile); + +/** + * Clears keyboard system properties. + */ +extern void clearKeyboardProperties(int32_t deviceId); + +/** + * Gets the key character map filename for a device using inspecting system properties + * and then falling back on a default key character map if necessary. + * Returns a NAME_NOT_FOUND if none found. + */ +extern status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFile); + +/** + * Gets a key code by its short form label, eg. "HOME". + * Returns 0 if unknown. + */ +extern int32_t getKeyCodeByLabel(const char* label); + +/** + * Gets a key flag by its short form label, eg. "WAKE". + * Returns 0 if unknown. + */ +extern uint32_t getKeyFlagByLabel(const char* label); + +/** + * Updates a meta state field when a key is pressed or released. + */ +extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); + +} // namespace android + +#endif // _UI_KEYBOARD_H diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h index f71d9cd..9b1a897 100755 --- a/include/ui/KeycodeLabels.h +++ b/include/ui/KeycodeLabels.h @@ -135,6 +135,83 @@ static const KeycodeLabel KEYCODES[] = { { "BUTTON_START", 108 }, { "BUTTON_SELECT", 109 }, { "BUTTON_MODE", 110 }, + { "ESCAPE", 111 }, + { "FORWARD_DEL", 112 }, + { "CTRL_LEFT", 113 }, + { "CTRL_RIGHT", 114 }, + { "CAPS_LOCK", 115 }, + { "SCROLL_LOCK", 116 }, + { "META_LEFT", 117 }, + { "META_RIGHT", 118 }, + { "FUNCTION", 119 }, + { "SYSRQ", 120 }, + { "BREAK", 121 }, + { "MOVE_HOME", 122 }, + { "MOVE_END", 123 }, + { "INSERT", 124 }, + { "FORWARD", 125 }, + { "MEDIA_PLAY", 126 }, + { "MEDIA_PAUSE", 127 }, + { "MEDIA_CLOSE", 128 }, + { "MEDIA_EJECT", 129 }, + { "MEDIA_RECORD", 130 }, + { "F1", 131 }, + { "F2", 132 }, + { "F3", 133 }, + { "F4", 134 }, + { "F5", 135 }, + { "F6", 136 }, + { "F7", 137 }, + { "F8", 138 }, + { "F9", 139 }, + { "F10", 140 }, + { "F11", 141 }, + { "F12", 142 }, + { "NUM_LOCK", 143 }, + { "NUMPAD_0", 144 }, + { "NUMPAD_1", 145 }, + { "NUMPAD_2", 146 }, + { "NUMPAD_3", 147 }, + { "NUMPAD_4", 148 }, + { "NUMPAD_5", 149 }, + { "NUMPAD_6", 150 }, + { "NUMPAD_7", 151 }, + { "NUMPAD_8", 152 }, + { "NUMPAD_9", 153 }, + { "NUMPAD_DIVIDE", 154 }, + { "NUMPAD_MULTIPLY", 155 }, + { "NUMPAD_SUBTRACT", 156 }, + { "NUMPAD_ADD", 157 }, + { "NUMPAD_DOT", 158 }, + { "NUMPAD_COMMA", 159 }, + { "NUMPAD_ENTER", 160 }, + { "NUMPAD_EQUALS", 161 }, + { "NUMPAD_LEFT_PAREN", 162 }, + { "NUMPAD_RIGHT_PAREN", 163 }, + { "VOLUME_MUTE", 164 }, + { "INFO", 165 }, + { "CHANNEL_UP", 166 }, + { "CHANNEL_DOWN", 167 }, + { "ZOOM_IN", 168 }, + { "ZOOM_OUT", 169 }, + { "TV", 170 }, + { "WINDOW", 171 }, + { "GUIDE", 172 }, + { "DVR", 173 }, + { "BOOKMARK", 174 }, + { "CAPTIONS", 175 }, + { "SETTINGS", 176 }, + { "TV_POWER", 177 }, + { "TV_INPUT", 178 }, + { "STB_POWER", 179 }, + { "STB_INPUT", 180 }, + { "AVR_POWER", 181 }, + { "AVR_INPUT", 182 }, + { "PROG_RED", 183 }, + { "PROG_GREEN", 184 }, + { "PROG_YELLOW", 185 }, + { "PROG_BLUE", 186 }, + { "APP_SWITCH", 187 }, // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. @@ -142,7 +219,7 @@ static const KeycodeLabel KEYCODES[] = { { NULL, 0 } }; -// See also policy flags in Input.h. +// NOTE: If you edit these flags, also edit policy flags in Input.h. static const KeycodeLabel FLAGS[] = { { "WAKE", 0x00000001 }, { "WAKE_DROPPED", 0x00000002 }, @@ -153,6 +230,7 @@ static const KeycodeLabel FLAGS[] = { { "MENU", 0x00000040 }, { "LAUNCHER", 0x00000080 }, { "VIRTUAL", 0x00000100 }, + { "FUNCTION", 0x00000200 }, { NULL, 0 } }; diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h deleted file mode 100644 index a9ae1c4..0000000 --- a/include/ui/Overlay.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_OVERLAY_H -#define ANDROID_OVERLAY_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <binder/IInterface.h> -#include <utils/RefBase.h> -#include <utils/threads.h> - -#include <ui/PixelFormat.h> -#include <ui/IOverlay.h> - -#include <hardware/overlay.h> - -namespace android { - -class IMemory; -class IMemoryHeap; - -// ---------------------------------------------------------------------------- - -class OverlayRef : public LightRefBase<OverlayRef> -{ -public: - OverlayRef(overlay_handle_t, const sp<IOverlay>&, - uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs); - - static sp<OverlayRef> readFromParcel(const Parcel& data); - static status_t writeToParcel(Parcel* reply, const sp<OverlayRef>& o); - -private: - friend class LightRefBase<OverlayRef>; - friend class Overlay; - - OverlayRef(); - virtual ~OverlayRef(); - - overlay_handle_t mOverlayHandle; - sp<IOverlay> mOverlayChannel; - uint32_t mWidth; - uint32_t mHeight; - int32_t mFormat; - int32_t mWidthStride; - int32_t mHeightStride; - bool mOwnHandle; -}; - -// ---------------------------------------------------------------------------- - -class Overlay : public virtual RefBase -{ -public: - Overlay(const sp<OverlayRef>& overlayRef); - - /* destroys this overlay */ - void destroy(); - - /* get the HAL handle for this overlay */ - overlay_handle_t getHandleRef() const; - - /* blocks until an overlay buffer is available and return that buffer. */ - status_t dequeueBuffer(overlay_buffer_t* buffer); - - /* release the overlay buffer and post it */ - status_t queueBuffer(overlay_buffer_t buffer); - - /* change the width and height of the overlay */ - status_t resizeInput(uint32_t width, uint32_t height); - - status_t setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) ; - - status_t getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) ; - - /* set the buffer attributes */ - status_t setParameter(int param, int value); - - /* returns the address of a given buffer if supported, NULL otherwise. */ - void* getBufferAddress(overlay_buffer_t buffer); - - /* get physical informations about the overlay */ - uint32_t getWidth() const; - uint32_t getHeight() const; - int32_t getFormat() const; - int32_t getWidthStride() const; - int32_t getHeightStride() const; - int32_t getBufferCount() const; - status_t getStatus() const; - -private: - virtual ~Overlay(); - - sp<OverlayRef> mOverlayRef; - overlay_data_device_t *mOverlayData; - status_t mStatus; -}; - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_OVERLAY_H diff --git a/include/ui/PowerManager.h b/include/ui/PowerManager.h index 5434b4f..dd80318 100644 --- a/include/ui/PowerManager.h +++ b/include/ui/PowerManager.h @@ -22,14 +22,10 @@ namespace android { enum { POWER_MANAGER_OTHER_EVENT = 0, - POWER_MANAGER_CHEEK_EVENT = 1, - POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either - // up events or LONG_TOUCH events. - POWER_MANAGER_LONG_TOUCH_EVENT = 3, - POWER_MANAGER_TOUCH_UP_EVENT = 4, - POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events. + POWER_MANAGER_BUTTON_EVENT = 1, + POWER_MANAGER_TOUCH_EVENT = 2, - POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code. + POWER_MANAGER_LAST_EVENT = POWER_MANAGER_TOUCH_EVENT, // Last valid event code. }; } // namespace android diff --git a/include/ui/VirtualKeyMap.h b/include/ui/VirtualKeyMap.h new file mode 100644 index 0000000..7813d9d --- /dev/null +++ b/include/ui/VirtualKeyMap.h @@ -0,0 +1,79 @@ +/* + * 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_VIRTUAL_KEY_MAP_H +#define _UI_VIRTUAL_KEY_MAP_H + +#include <stdint.h> + +#include <ui/Input.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/Tokenizer.h> +#include <utils/String8.h> +#include <utils/Unicode.h> + +namespace android { + +/* Describes a virtual key. */ +struct VirtualKeyDefinition { + int32_t scanCode; + + // configured position data, specified in display coords + int32_t centerX; + int32_t centerY; + int32_t width; + int32_t height; +}; + + +/** + * Describes a collection of virtual keys on a touch screen in terms of + * virtual scan codes and hit rectangles. + */ +class VirtualKeyMap { +public: + ~VirtualKeyMap(); + + static status_t load(const String8& filename, VirtualKeyMap** outMap); + + inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const { + return mVirtualKeys; + } + +private: + class Parser { + VirtualKeyMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(VirtualKeyMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + bool consumeFieldDelimiterAndSkipWhitespace(); + bool parseNextIntField(int32_t* outValue); + }; + + Vector<VirtualKeyDefinition> mVirtualKeys; + + VirtualKeyMap(); +}; + +} // namespace android + +#endif // _UI_KEY_CHARACTER_MAP_H diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h index a472824..402843e 100644 --- a/include/ui/android_native_buffer.h +++ b/include/ui/android_native_buffer.h @@ -51,12 +51,8 @@ typedef struct android_native_buffer_t int stride; int format; int usage; - - /* transformation as defined in hardware.h */ - uint8_t transform; - - uint8_t reserved_bytes[3]; - void* reserved[1]; + + void* reserved[2]; buffer_handle_t handle; diff --git a/include/utils/Asset.h b/include/utils/Asset.h index 2a09095..1fe0e06 100644 --- a/include/utils/Asset.h +++ b/include/utils/Asset.h @@ -23,9 +23,11 @@ #include <stdio.h> #include <sys/types.h> -#include "FileMap.h" -#include "String8.h" -#include "Errors.h" + +#include <utils/Compat.h> +#include <utils/Errors.h> +#include <utils/FileMap.h> +#include <utils/String8.h> namespace android { @@ -69,10 +71,10 @@ public: /* * Seek to the specified offset. "whence" uses the same values as - * lseek/fseek. Returns the new position on success, or (off_t) -1 + * lseek/fseek. Returns the new position on success, or (off64_t) -1 * on failure. */ - virtual off_t seek(off_t offset, int whence) = 0; + virtual off64_t seek(off64_t offset, int whence) = 0; /* * Close the asset, freeing all associated resources. @@ -87,26 +89,26 @@ public: /* * Get the total amount of data that can be read. */ - virtual off_t getLength(void) const = 0; + virtual off64_t getLength(void) const = 0; /* * Get the total amount of data that can be read from the current position. */ - virtual off_t getRemainingLength(void) const = 0; + virtual off64_t getRemainingLength(void) const = 0; /* * Open a new file descriptor that can be used to read this asset. * Returns -1 if you can not use the file descriptor (for example if the * asset is compressed). */ - virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0; - + virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0; + /* * Return whether this asset's buffer is allocated in RAM (not mmapped). * Note: not virtual so it is safe to call even when being destroyed. */ virtual bool isAllocated(void) const { return false; } - + /* * Get a string identifying the asset's source. This might be a full * path, it might be a colon-separated list of identifiers. @@ -120,7 +122,7 @@ protected: Asset(void); // constructor; only invoked indirectly /* handle common seek() housekeeping */ - off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn); + off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn); /* set the asset source string */ void setAssetSource(const String8& path) { mAssetSource = path; } @@ -153,7 +155,7 @@ private: * * The asset takes ownership of the file descriptor. */ - static Asset* createFromFileSegment(int fd, off_t offset, size_t length, + static Asset* createFromFileSegment(int fd, off64_t offset, size_t length, AccessMode mode); /* @@ -166,7 +168,7 @@ private: * This may not verify the validity of the compressed data until first * use. */ - static Asset* createFromCompressedData(int fd, off_t offset, + static Asset* createFromCompressedData(int fd, off64_t offset, int compressionMethod, size_t compressedLength, size_t uncompressedLength, AccessMode mode); #endif @@ -221,7 +223,7 @@ public: * * On success, the object takes ownership of "fd". */ - status_t openChunk(const char* fileName, int fd, off_t offset, size_t length); + status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length); /* * Use a memory-mapped region. @@ -234,18 +236,18 @@ public: * Standard Asset interfaces. */ virtual ssize_t read(void* buf, size_t count); - virtual off_t seek(off_t offset, int whence); + virtual off64_t seek(off64_t offset, int whence); virtual void close(void); virtual const void* getBuffer(bool wordAligned); - virtual off_t getLength(void) const { return mLength; } - virtual off_t getRemainingLength(void) const { return mLength-mOffset; } - virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const; + virtual off64_t getLength(void) const { return mLength; } + virtual off64_t getRemainingLength(void) const { return mLength-mOffset; } + virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const; virtual bool isAllocated(void) const { return mBuf != NULL; } private: - off_t mStart; // absolute file offset of start of chunk - off_t mLength; // length of the chunk - off_t mOffset; // current local offset, 0 == mStart + off64_t mStart; // absolute file offset of start of chunk + off64_t mLength; // length of the chunk + off64_t mOffset; // current local offset, 0 == mStart FILE* mFp; // for read/seek char* mFileName; // for opening @@ -276,7 +278,7 @@ public: * * On success, the object takes ownership of "fd". */ - status_t openChunk(int fd, off_t offset, int compressionMethod, + status_t openChunk(int fd, off64_t offset, int compressionMethod, size_t uncompressedLen, size_t compressedLen); /* @@ -291,19 +293,19 @@ public: * Standard Asset interfaces. */ virtual ssize_t read(void* buf, size_t count); - virtual off_t seek(off_t offset, int whence); + virtual off64_t seek(off64_t offset, int whence); virtual void close(void); virtual const void* getBuffer(bool wordAligned); - virtual off_t getLength(void) const { return mUncompressedLen; } - virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; } - virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; } + virtual off64_t getLength(void) const { return mUncompressedLen; } + virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; } + virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; } virtual bool isAllocated(void) const { return mBuf != NULL; } private: - off_t mStart; // offset to start of compressed data - off_t mCompressedLen; // length of the compressed data - off_t mUncompressedLen; // length of the uncompressed data - off_t mOffset; // current offset, 0 == start of uncomp data + off64_t mStart; // offset to start of compressed data + off64_t mCompressedLen; // length of the compressed data + off64_t mUncompressedLen; // length of the uncompressed data + off64_t mOffset; // current offset, 0 == start of uncomp data FileMap* mMap; // for memory-mapped input int mFd; // for file input diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h index c2c8ce5..8817120 100644 --- a/include/utils/CallStack.h +++ b/include/utils/CallStack.h @@ -50,7 +50,7 @@ public: void clear(); - void update(int32_t ignoreDepth=0, int32_t maxDepth=MAX_DEPTH); + void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH); // Dump a stack trace to the log void dump(const char* prefix = 0) const; diff --git a/include/utils/Compat.h b/include/utils/Compat.h new file mode 100644 index 0000000..1819266 --- /dev/null +++ b/include/utils/Compat.h @@ -0,0 +1,42 @@ +/* + * 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 __LIB_UTILS_COMPAT_H +#define __LIB_UTILS_COMPAT_H + +#include <unistd.h> + +/* Compatibility definitions for non-Linux (i.e., BSD-based) hosts. */ +#ifndef HAVE_OFF64_T +#if _FILE_OFFSET_BITS < 64 +#error "_FILE_OFFSET_BITS < 64; large files are not supported on this platform" +#endif /* _FILE_OFFSET_BITS < 64 */ + +typedef off_t off64_t; + +static inline off64_t lseek64(int fd, off64_t offset, int whence) { + return lseek(fd, offset, whence); +} + +#ifdef HAVE_PREAD +static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) { + return pread(fd, buf, nbytes, offset); +} +#endif + +#endif /* !HAVE_OFF64_T */ + +#endif /* __LIB_UTILS_COMPAT_H */ diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h index 8dfd3be..dfe6d51 100644 --- a/include/utils/FileMap.h +++ b/include/utils/FileMap.h @@ -22,6 +22,8 @@ #include <sys/types.h> +#include <utils/Compat.h> + #ifdef HAVE_WIN32_FILEMAP #include <windows.h> #endif @@ -55,7 +57,7 @@ public: * Returns "false" on failure. */ bool create(const char* origFileName, int fd, - off_t offset, size_t length, bool readOnly); + off64_t offset, size_t length, bool readOnly); /* * Return the name of the file this map came from, if known. @@ -75,7 +77,7 @@ public: /* * Get the data offset used to create this map. */ - off_t getDataOffset(void) const { return mDataOffset; } + off64_t getDataOffset(void) const { return mDataOffset; } /* * Get a "copy" of the object. @@ -118,7 +120,7 @@ private: char* mFileName; // original file name, if known void* mBasePtr; // base of mmap area; page aligned size_t mBaseLength; // length, measured from "mBasePtr" - off_t mDataOffset; // offset used when map was created + off64_t mDataOffset; // offset used when map was created void* mDataPtr; // start of requested data, offset from base size_t mDataLength; // length, measured from "mDataPtr" #ifdef HAVE_WIN32_FILEMAP diff --git a/include/utils/PropertyMap.h b/include/utils/PropertyMap.h new file mode 100644 index 0000000..a9e674f --- /dev/null +++ b/include/utils/PropertyMap.h @@ -0,0 +1,106 @@ +/* + * 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 _UTILS_PROPERTY_MAP_H +#define _UTILS_PROPERTY_MAP_H + +#include <utils/KeyedVector.h> +#include <utils/String8.h> +#include <utils/Errors.h> +#include <utils/Tokenizer.h> + +namespace android { + +/* + * Provides a mechanism for passing around string-based property key / value pairs + * and loading them from property files. + * + * The property files have the following simple structure: + * + * # Comment + * key = value + * + * Keys and values are any sequence of printable ASCII characters. + * The '=' separates the key from the value. + * The key and value may not contain whitespace. + * + * The '\' character is reserved for escape sequences and is not currently supported. + * The '"" character is reserved for quoting and is not currently supported. + * Files that contain the '\' or '"' character will fail to parse. + * + * The file must not contain duplicate keys. + * + * TODO Support escape sequences and quoted values when needed. + */ +class PropertyMap { +public: + /* Creates an empty property map. */ + PropertyMap(); + ~PropertyMap(); + + /* Clears the property map. */ + void clear(); + + /* Adds a property. + * Replaces the property with the same key if it is already present. + */ + void addProperty(const String8& key, const String8& value); + + /* Returns true if the property map contains the specified key. */ + bool hasProperty(const String8& key) const; + + /* Gets the value of a property and parses it. + * Returns true and sets outValue if the key was found and its value was parsed successfully. + * Otherwise returns false and does not modify outValue. (Also logs a warning.) + */ + bool tryGetProperty(const String8& key, String8& outValue) const; + bool tryGetProperty(const String8& key, bool& outValue) const; + bool tryGetProperty(const String8& key, int32_t& outValue) const; + bool tryGetProperty(const String8& key, float& outValue) const; + + /* Adds all values from the specified property map. */ + void addAll(const PropertyMap* map); + + /* Gets the underlying property map. */ + inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; } + + /* Loads a property map from a file. */ + static status_t load(const String8& filename, PropertyMap** outMap); + +private: + class Parser { + PropertyMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(PropertyMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseType(); + status_t parseKey(); + status_t parseKeyProperty(); + status_t parseModifier(const String8& token, int32_t* outMetaState); + status_t parseCharacterLiteral(char16_t* outCharacter); + }; + + KeyedVector<String8, String8> mProperties; +}; + +} // namespace android + +#endif // _UTILS_PROPERTY_MAP_H diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index da86da4..ed7f53d 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -1771,12 +1771,14 @@ public: * * @return ssize_t Either a >= 0 table index or a negative error code. */ - ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false, - uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const; + ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false, + uint16_t density = 0, + uint32_t* outSpecFlags = NULL, + ResTable_config* outConfig = NULL) const; inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue, uint32_t* outSpecFlags=NULL) const { - return getResource(res.ident, outValue, false, outSpecFlags, NULL); + return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL); } ssize_t resolveReference(Res_value* inOutValue, diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index 3b975b4..e1ee8eb 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -37,6 +37,11 @@ public: } return *instance; } + + static bool hasInstance() { + Mutex::Autolock _l(sLock); + return sInstance != 0; + } protected: ~Singleton() { }; diff --git a/include/utils/StreamingZipInflater.h b/include/utils/StreamingZipInflater.h index 16867d8..3ace5d5 100644 --- a/include/utils/StreamingZipInflater.h +++ b/include/utils/StreamingZipInflater.h @@ -21,6 +21,8 @@ #include <inttypes.h> #include <zlib.h> +#include <utils/Compat.h> + namespace android { class StreamingZipInflater { @@ -29,7 +31,7 @@ public: static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024; // Flavor that pages in the compressed data from a fd - StreamingZipInflater(int fd, off_t compDataStart, size_t uncompSize, size_t compSize); + StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize); // Flavor that gets the compressed data from an in-memory buffer StreamingZipInflater(class FileMap* dataMap, size_t uncompSize); @@ -43,7 +45,7 @@ public: // seeking backwards requires uncompressing fom the beginning, so is very // expensive. seeking forwards only requires uncompressing from the current // position to the destination. - off_t seekAbsolute(off_t absoluteInputPosition); + off64_t seekAbsolute(off64_t absoluteInputPosition); private: void initInflateState(); @@ -51,7 +53,7 @@ private: // where to find the uncompressed data int mFd; - off_t mInFileStart; // where the compressed data lives in the file + off64_t mInFileStart; // where the compressed data lives in the file class FileMap* mDataMap; z_stream mInflateState; @@ -63,7 +65,7 @@ private: size_t mOutTotalSize; // total uncompressed size of the blob // current output state bookkeeping - off_t mOutCurPosition; // current position in total offset + off64_t mOutCurPosition; // current position in total offset size_t mOutLastDecoded; // last decoded byte + 1 in mOutbuf size_t mOutDeliverable; // next undelivered byte of decoded output in mOutBuf diff --git a/include/utils/String16.h b/include/utils/String16.h index 07a0c11..584f53f 100644 --- a/include/utils/String16.h +++ b/include/utils/String16.h @@ -19,39 +19,12 @@ #include <utils/Errors.h> #include <utils/SharedBuffer.h> - -#include <stdint.h> -#include <sys/types.h> +#include <utils/Unicode.h> // --------------------------------------------------------------------------- extern "C" { -typedef uint16_t char16_t; - -// Standard string functions on char16 strings. -int strcmp16(const char16_t *, const char16_t *); -int strncmp16(const char16_t *s1, const char16_t *s2, size_t n); -size_t strlen16(const char16_t *); -size_t strnlen16(const char16_t *, size_t); -char16_t *strcpy16(char16_t *, const char16_t *); -char16_t *strncpy16(char16_t *, const char16_t *, size_t); - -// Version of comparison that supports embedded nulls. -// This is different than strncmp() because we don't stop -// at a nul character and consider the strings to be different -// if the lengths are different (thus we need to supply the -// lengths of both strings). This can also be used when -// your string is not nul-terminated as it will have the -// equivalent result as strcmp16 (unlike strncmp16). -int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2); - -// Version of strzcmp16 for comparing strings in different endianness. -int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2); - -// Convert UTF-8 to UTF-16 including surrogate pairs -void utf8_to_utf16(const uint8_t *src, size_t srcLen, char16_t* dst, const size_t dstLen); - } // --------------------------------------------------------------------------- diff --git a/include/utils/String8.h b/include/utils/String8.h index ef0b51a..6b49ff5 100644 --- a/include/utils/String8.h +++ b/include/utils/String8.h @@ -18,122 +18,17 @@ #define ANDROID_STRING8_H #include <utils/Errors.h> +#include <utils/SharedBuffer.h> +#include <utils/Unicode.h> -// Need this for the char16_t type; String8.h should not -// be depedent on the String16 class. -#include <utils/String16.h> - -#include <stdint.h> -#include <string.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- - -extern "C" { - -typedef uint32_t char32_t; - -size_t strlen32(const char32_t *); -size_t strnlen32(const char32_t *, size_t); - -/* - * Returns the length of "src" when "src" is valid UTF-8 string. - * Returns 0 if src is NULL, 0-length string or non UTF-8 string. - * This function should be used to determine whether "src" is valid UTF-8 - * characters with valid unicode codepoints. "src" must be null-terminated. - * - * If you are going to use other GetUtf... functions defined in this header - * with string which may not be valid UTF-8 with valid codepoint (form 0 to - * 0x10FFFF), you should use this function before calling others, since the - * other functions do not check whether the string is valid UTF-8 or not. - * - * If you do not care whether "src" is valid UTF-8 or not, you should use - * strlen() as usual, which should be much faster. - */ -size_t utf8_length(const char *src); - -/* - * Returns the UTF-32 length of "src". - */ -size_t utf32_length(const char *src, size_t src_len); - -/* - * Returns the UTF-8 length of "src". - */ -size_t utf8_length_from_utf16(const char16_t *src, size_t src_len); - -/* - * Returns the UTF-8 length of "src". - */ -size_t utf8_length_from_utf32(const char32_t *src, size_t src_len); - -/* - * Returns the unicode value at "index". - * Returns -1 when the index is invalid (equals to or more than "src_len"). - * If returned value is positive, it is able to be converted to char32_t, which - * is unsigned. Then, if "next_index" is not NULL, the next index to be used is - * stored in "next_index". "next_index" can be NULL. - */ -int32_t utf32_at(const char *src, size_t src_len, - size_t index, size_t *next_index); - -/* - * Stores a UTF-32 string converted from "src" in "dst", if "dst_length" is not - * large enough to store the string, the part of the "src" string is stored - * into "dst". - * Returns the size actually used for storing the string. - * "dst" is not null-terminated when dst_len is fully used (like strncpy). - */ -size_t utf8_to_utf32(const char* src, size_t src_len, - char32_t* dst, size_t dst_len); - -/* - * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not - * large enough to store the string, the part of the "src" string is stored - * into "dst" as much as possible. See the examples for more detail. - * Returns the size actually used for storing the string. - * dst" is not null-terminated when dst_len is fully used (like strncpy). - * - * Example 1 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" >= 7 - * -> - * Returned value == 6 - * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0 - * (note that "dst" is null-terminated) - * - * Example 2 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" == 5 - * -> - * Returned value == 3 - * "dst" becomes \xE3\x81\x82\0 - * (note that "dst" is null-terminated, but \u3044 is not stored in "dst" - * since "dst" does not have enough size to store the character) - * - * Example 3 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" == 6 - * -> - * Returned value == 6 - * "dst" becomes \xE3\x81\x82\xE3\x81\x84 - * (note that "dst" is NOT null-terminated, like strncpy) - */ -size_t utf32_to_utf8(const char32_t* src, size_t src_len, - char* dst, size_t dst_len); - -size_t utf16_to_utf8(const char16_t* src, size_t src_len, - char* dst, size_t dst_len); - -} +#include <string.h> // for strcmp +#include <stdarg.h> // --------------------------------------------------------------------------- namespace android { +class String16; class TextOutput; //! This is a string holding UTF-8 characters. Does not allow the value more @@ -152,14 +47,22 @@ public: explicit String8(const char32_t* o); explicit String8(const char32_t* o, size_t numChars); ~String8(); - + + static inline const String8 empty(); + + static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2))); + static String8 formatV(const char* fmt, va_list args); + inline const char* string() const; inline size_t size() const; inline size_t length() const; inline size_t bytes() const; + inline bool isEmpty() const; inline const SharedBuffer* sharedBuffer() const; + void clear(); + void setTo(const String8& other); status_t setTo(const char* other); status_t setTo(const char* other, size_t numChars); @@ -173,13 +76,14 @@ public: status_t appendFormat(const char* fmt, ...) __attribute__((format (printf, 2, 3))); + status_t appendFormatV(const char* fmt, va_list args); // Note that this function takes O(N) time to calculate the value. // No cache value is stored. size_t getUtf32Length() const; int32_t getUtf32At(size_t index, size_t *next_index) const; - size_t getUtf32(char32_t* dst, size_t dst_len) const; + void getUtf32(char32_t* dst) const; inline String8& operator=(const String8& other); inline String8& operator=(const char* other); @@ -330,6 +234,10 @@ inline int strictly_order_type(const String8& lhs, const String8& rhs) return compare_type(lhs, rhs) < 0; } +inline const String8 String8::empty() { + return String8(); +} + inline const char* String8::string() const { return mString; @@ -345,6 +253,11 @@ inline size_t String8::size() const return length(); } +inline bool String8::isEmpty() const +{ + return length() == 0; +} + inline size_t String8::bytes() const { return SharedBuffer::sizeFromData(mString)-1; diff --git a/include/utils/Tokenizer.h b/include/utils/Tokenizer.h new file mode 100644 index 0000000..c7db5fb --- /dev/null +++ b/include/utils/Tokenizer.h @@ -0,0 +1,125 @@ +/* + * 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 _UTILS_TOKENIZER_H +#define _UTILS_TOKENIZER_H + +#include <assert.h> +#include <utils/Errors.h> +#include <utils/FileMap.h> +#include <utils/String8.h> + +namespace android { + +/** + * A simple tokenizer for loading and parsing ASCII text files line by line. + */ +class Tokenizer { + Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length); + +public: + ~Tokenizer(); + + /** + * Opens a file and maps it into memory. + * + * Returns NO_ERROR and a tokenizer for the file, if successful. + * Otherwise returns an error and sets outTokenizer to NULL. + */ + static status_t open(const String8& filename, Tokenizer** outTokenizer); + + /** + * Returns true if at the end of the file. + */ + inline bool isEof() const { return mCurrent == getEnd(); } + + /** + * Returns true if at the end of the line or end of the file. + */ + inline bool isEol() const { return isEof() || *mCurrent == '\n'; } + + /** + * Gets the name of the file. + */ + inline String8 getFilename() const { return mFilename; } + + /** + * Gets a 1-based line number index for the current position. + */ + inline int32_t getLineNumber() const { return mLineNumber; } + + /** + * Formats a location string consisting of the filename and current line number. + * Returns a string like "MyFile.txt:33". + */ + String8 getLocation() const; + + /** + * Gets the character at the current position. + * Returns null at end of file. + */ + inline char peekChar() const { return isEof() ? '\0' : *mCurrent; } + + /** + * Gets the remainder of the current line as a string, excluding the newline character. + */ + String8 peekRemainderOfLine() const; + + /** + * Gets the character at the current position and advances past it. + * Returns null at end of file. + */ + inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); } + + /** + * Gets the next token on this line stopping at the specified delimiters + * or the end of the line whichever comes first and advances past it. + * Also stops at embedded nulls. + * Returns the token or an empty string if the current character is a delimiter + * or is at the end of the line. + */ + String8 nextToken(const char* delimiters); + + /** + * Advances to the next line. + * Does nothing if already at the end of the file. + */ + void nextLine(); + + /** + * Skips over the specified delimiters in the line. + * Also skips embedded nulls. + */ + void skipDelimiters(const char* delimiters); + +private: + Tokenizer(const Tokenizer& other); // not copyable + + String8 mFilename; + FileMap* mFileMap; + char* mBuffer; + size_t mLength; + + const char* mCurrent; + int32_t mLineNumber; + + inline const char* getEnd() const { return mBuffer + mLength; } + +}; + +} // namespace android + +#endif // _UTILS_TOKENIZER_H diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h new file mode 100644 index 0000000..6afb291 --- /dev/null +++ b/include/utils/Unicode.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UNICODE_H +#define ANDROID_UNICODE_H + +#include <sys/types.h> +#include <stdint.h> + +extern "C" { + +typedef uint32_t char32_t; +typedef uint16_t char16_t; + +// Standard string functions on char16_t strings. +int strcmp16(const char16_t *, const char16_t *); +int strncmp16(const char16_t *s1, const char16_t *s2, size_t n); +size_t strlen16(const char16_t *); +size_t strnlen16(const char16_t *, size_t); +char16_t *strcpy16(char16_t *, const char16_t *); +char16_t *strncpy16(char16_t *, const char16_t *, size_t); + +// Version of comparison that supports embedded nulls. +// This is different than strncmp() because we don't stop +// at a nul character and consider the strings to be different +// if the lengths are different (thus we need to supply the +// lengths of both strings). This can also be used when +// your string is not nul-terminated as it will have the +// equivalent result as strcmp16 (unlike strncmp16). +int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2); + +// Version of strzcmp16 for comparing strings in different endianness. +int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2); + +// Standard string functions on char32_t strings. +size_t strlen32(const char32_t *); +size_t strnlen32(const char32_t *, size_t); + +/** + * Measure the length of a UTF-32 string in UTF-8. If the string is invalid + * such as containing a surrogate character, -1 will be returned. + */ +ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len); + +/** + * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not + * large enough to store the string, the part of the "src" string is stored + * into "dst" as much as possible. See the examples for more detail. + * Returns the size actually used for storing the string. + * dst" is not null-terminated when dst_len is fully used (like strncpy). + * + * Example 1 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" >= 7 + * -> + * Returned value == 6 + * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0 + * (note that "dst" is null-terminated) + * + * Example 2 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" == 5 + * -> + * Returned value == 3 + * "dst" becomes \xE3\x81\x82\0 + * (note that "dst" is null-terminated, but \u3044 is not stored in "dst" + * since "dst" does not have enough size to store the character) + * + * Example 3 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" == 6 + * -> + * Returned value == 6 + * "dst" becomes \xE3\x81\x82\xE3\x81\x84 + * (note that "dst" is NOT null-terminated, like strncpy) + */ +void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst); + +/** + * Returns the unicode value at "index". + * Returns -1 when the index is invalid (equals to or more than "src_len"). + * If returned value is positive, it is able to be converted to char32_t, which + * is unsigned. Then, if "next_index" is not NULL, the next index to be used is + * stored in "next_index". "next_index" can be NULL. + */ +int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index); + + +/** + * Returns the UTF-8 length of UTF-16 string "src". + */ +ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len); + +/** + * Converts a UTF-16 string to UTF-8. The destination buffer must be large + * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added + * NULL terminator. + */ +void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst); + +/** + * Returns the length of "src" when "src" is valid UTF-8 string. + * Returns 0 if src is NULL or 0-length string. Returns -1 when the source + * is an invalid string. + * + * This function should be used to determine whether "src" is valid UTF-8 + * characters with valid unicode codepoints. "src" must be null-terminated. + * + * If you are going to use other utf8_to_... functions defined in this header + * with string which may not be valid UTF-8 with valid codepoint (form 0 to + * 0x10FFFF), you should use this function before calling others, since the + * other functions do not check whether the string is valid UTF-8 or not. + * + * If you do not care whether "src" is valid UTF-8 or not, you should use + * strlen() as usual, which should be much faster. + */ +ssize_t utf8_length(const char *src); + +/** + * Measure the length of a UTF-32 string. + */ +size_t utf8_to_utf32_length(const char *src, size_t src_len); + +/** + * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large + * enough to store the entire converted string as measured by + * utf8_to_utf32_length plus space for a NULL terminator. + */ +void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst); + +/** + * Returns the UTF-16 length of UTF-8 string "src". + */ +ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen); + +/** + * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer + * must be large enough to hold the result as measured by utf8_to_utf16_length + * plus an added NULL terminator. + */ +void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst); + +} + +#endif diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h index e38bf66..3e42a95 100644 --- a/include/utils/ZipFileCRO.h +++ b/include/utils/ZipFileCRO.h @@ -24,6 +24,8 @@ #include <stdlib.h> #include <unistd.h> +#include <utils/Compat.h> + #ifdef __cplusplus extern "C" { #endif @@ -48,7 +50,7 @@ extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip, extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry, int* pMethod, size_t* pUncompLen, - size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32); + size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32); extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd); diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h index 3c1f3ca..3a99979 100644 --- a/include/utils/ZipFileRO.h +++ b/include/utils/ZipFileRO.h @@ -30,6 +30,7 @@ #ifndef __LIBS_ZIPFILERO_H #define __LIBS_ZIPFILERO_H +#include <utils/Compat.h> #include <utils/Errors.h> #include <utils/FileMap.h> #include <utils/threads.h> @@ -128,7 +129,7 @@ public: * appears to be bad. */ bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen, - size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const; + size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const; /* * Create a new FileMap object that maps a subset of the archive. For @@ -231,7 +232,7 @@ private: int mNumEntries; /* CD directory offset in the Zip archive */ - off_t mDirectoryOffset; + off64_t mDirectoryOffset; /* * We know how many entries are in the Zip archive, so we have a |