summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/android_runtime/AndroidRuntime.h3
-rw-r--r--include/android_runtime/android_app_NativeActivity.h149
-rw-r--r--include/android_runtime/android_content_res_Configuration.h36
-rw-r--r--include/android_runtime/android_view_Surface.h31
-rw-r--r--include/binder/BinderService.h60
-rw-r--r--include/binder/IInterface.h17
-rw-r--r--include/binder/IPCThreadState.h6
-rw-r--r--include/binder/Parcel.h31
-rw-r--r--include/camera/Camera.h31
-rw-r--r--include/camera/CameraHardwareInterface.h11
-rw-r--r--include/camera/CameraParameters.h84
-rw-r--r--include/camera/ICameraService.h10
-rw-r--r--include/gui/ISensorEventConnection.h57
-rw-r--r--include/gui/ISensorServer.h57
-rw-r--r--include/gui/Sensor.h91
-rw-r--r--include/gui/SensorChannel.h53
-rw-r--r--include/gui/SensorEventQueue.h82
-rw-r--r--include/gui/SensorManager.h63
-rw-r--r--include/media/AudioEffect.h470
-rw-r--r--include/media/AudioRecord.h30
-rw-r--r--include/media/AudioSystem.h29
-rw-r--r--include/media/AudioTrack.h63
-rw-r--r--include/media/EffectApi.h796
-rw-r--r--include/media/EffectBassBoostApi.h43
-rw-r--r--include/media/EffectEnvironmentalReverbApi.h69
-rw-r--r--include/media/EffectEqualizerApi.h58
-rw-r--r--include/media/EffectPresetReverbApi.h54
-rw-r--r--include/media/EffectVirtualizerApi.h43
-rw-r--r--include/media/EffectVisualizerApi.h56
-rw-r--r--include/media/EffectsFactoryApi.h221
-rw-r--r--include/media/IAudioFlinger.h29
-rw-r--r--include/media/IAudioPolicyService.h16
-rw-r--r--include/media/IAudioTrack.h5
-rw-r--r--include/media/IEffect.h60
-rw-r--r--include/media/IEffectClient.h54
-rw-r--r--include/media/IMediaPlayer.h2
-rw-r--r--include/media/IMediaPlayerService.h11
-rw-r--r--include/media/IMediaRecorder.h4
-rw-r--r--include/media/IMediaRecorderClient.h48
-rw-r--r--include/media/MediaPlayerInterface.h1
-rw-r--r--include/media/MediaProfiles.h35
-rw-r--r--include/media/MediaRecorderBase.h3
-rw-r--r--include/media/PVMediaRecorder.h5
-rw-r--r--include/media/Visualizer.h160
-rw-r--r--include/media/mediaplayer.h12
-rw-r--r--include/media/mediarecorder.h12
-rw-r--r--include/media/stagefright/AMRWriter.h14
-rw-r--r--include/media/stagefright/AudioSource.h16
-rw-r--r--include/media/stagefright/CachingDataSource.h66
-rw-r--r--include/media/stagefright/CameraSource.h31
-rw-r--r--include/media/stagefright/ColorConverter.h5
-rw-r--r--include/media/stagefright/HTTPDataSource.h103
-rw-r--r--include/media/stagefright/MPEG4Writer.h84
-rw-r--r--include/media/stagefright/MediaDefs.h5
-rw-r--r--include/media/stagefright/MediaSource.h33
-rw-r--r--include/media/stagefright/MediaWriter.h23
-rw-r--r--include/media/stagefright/MetaData.h33
-rw-r--r--include/media/stagefright/OMXCodec.h35
-rw-r--r--include/media/stagefright/foundation/AAtomizer.h51
-rw-r--r--include/media/stagefright/foundation/ABase.h25
-rw-r--r--include/media/stagefright/foundation/ABuffer.h71
-rw-r--r--include/media/stagefright/foundation/ADebug.h105
-rw-r--r--include/media/stagefright/foundation/AHandler.h56
-rw-r--r--include/media/stagefright/foundation/AHandlerReflector.h32
-rw-r--r--include/media/stagefright/foundation/ALooper.h80
-rw-r--r--include/media/stagefright/foundation/ALooperRoster.h54
-rw-r--r--include/media/stagefright/foundation/AMessage.h115
-rw-r--r--include/media/stagefright/foundation/AString.h94
-rw-r--r--include/media/stagefright/foundation/base64.h33
-rw-r--r--include/media/stagefright/foundation/hexdump.h29
-rw-r--r--include/private/README4
-rw-r--r--include/private/media/AudioEffectShared.h51
-rw-r--r--include/private/media/AudioTrackShared.h38
-rw-r--r--include/private/surfaceflinger/SharedBufferStack.h223
-rw-r--r--include/surfaceflinger/ISurface.h19
-rw-r--r--include/surfaceflinger/ISurfaceComposer.h8
-rw-r--r--include/surfaceflinger/ISurfaceComposerClient.h (renamed from include/surfaceflinger/ISurfaceFlingerClient.h)32
-rw-r--r--include/surfaceflinger/Surface.h144
-rw-r--r--include/surfaceflinger/SurfaceComposerClient.h56
-rw-r--r--include/ui/EventHub.h213
-rw-r--r--include/ui/FramebufferNativeWindow.h14
-rw-r--r--include/ui/GraphicBuffer.h13
-rw-r--r--include/ui/GraphicBufferAllocator.h2
-rw-r--r--include/ui/Input.h491
-rw-r--r--include/ui/InputDispatcher.h669
-rw-r--r--include/ui/InputManager.h172
-rw-r--r--include/ui/InputReader.h845
-rw-r--r--include/ui/InputTransport.h334
-rwxr-xr-x[-rw-r--r--]include/ui/KeycodeLabels.h125
-rw-r--r--include/ui/Rect.h33
-rw-r--r--include/ui/android_native_buffer.h9
-rw-r--r--include/ui/egl/android_natives.h133
-rw-r--r--include/utils/Asset.h11
-rw-r--r--include/utils/AssetManager.h22
-rw-r--r--include/utils/BitSet.h67
-rw-r--r--include/utils/Buffer.h107
-rw-r--r--include/utils/ObbFile.h91
-rw-r--r--include/utils/PollLoop.h197
-rw-r--r--include/utils/Pool.h71
-rw-r--r--include/utils/RefBase.h32
-rw-r--r--include/utils/ResourceTypes.h148
-rw-r--r--include/utils/Singleton.h8
-rw-r--r--include/utils/StopWatch.h2
-rw-r--r--include/utils/StreamingZipInflater.h82
-rw-r--r--include/utils/String8.h7
-rw-r--r--include/utils/Vector.h18
-rw-r--r--include/utils/VectorImpl.h6
-rw-r--r--include/utils/ZipFileCRO.h4
-rw-r--r--include/utils/ZipFileRO.h33
-rw-r--r--include/utils/threads.h90
110 files changed, 8195 insertions, 883 deletions
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index 99ab2f0..09f0de1 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -87,7 +87,7 @@ public:
virtual void onExit(int code);
/** create a new thread that is visible from Java */
- static void createJavaThread(const char* name, void (*start)(void *),
+ static android_thread_id_t createJavaThread(const char* name, void (*start)(void *),
void* arg);
/** return a pointer to the VM running in this process */
@@ -98,6 +98,7 @@ public:
private:
static int startReg(JNIEnv* env);
+ void parseExtraOpts(char* extraOptsBuf);
int startVm(JavaVM** pJavaVM, JNIEnv** pEnv);
Vector<JavaVMOption> mOptions;
diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h
new file mode 100644
index 0000000..c388ba8
--- /dev/null
+++ b/include/android_runtime/android_app_NativeActivity.h
@@ -0,0 +1,149 @@
+/*
+ * 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_APP_NATIVEACTIVITY_H
+#define _ANDROID_APP_NATIVEACTIVITY_H
+
+#include <ui/InputTransport.h>
+
+#include <android/native_activity.h>
+
+#include "jni.h"
+
+namespace android {
+
+extern void android_NativeActivity_setWindowFormat(
+ ANativeActivity* activity, int32_t format);
+
+extern void android_NativeActivity_setWindowFlags(
+ ANativeActivity* activity, int32_t values, int32_t mask);
+
+extern void android_NativeActivity_showSoftInput(
+ ANativeActivity* activity, int32_t flags);
+
+extern void android_NativeActivity_hideSoftInput(
+ ANativeActivity* activity, int32_t flags);
+
+} // namespace android
+
+
+/*
+ * NDK input queue API.
+ *
+ * Here is the event flow:
+ * 1. Event arrives in input consumer, and is returned by getEvent().
+ * 2. Application calls preDispatchEvent():
+ * a. Event is assigned a sequence ID and enqueued in mPreDispatchingKeys.
+ * b. Main thread picks up event, hands to input method.
+ * c. Input method eventually returns sequence # and whether it was handled.
+ * d. finishPreDispatch() is called to enqueue the information.
+ * e. next getEvent() call will:
+ * - finish any pre-dispatch events that the input method handled
+ * - return the next pre-dispatched event that the input method didn't handle.
+ * f. (A preDispatchEvent() call on this event will now return false).
+ * 3. Application calls finishEvent() with whether it was handled.
+ * - If handled is true, the event is finished.
+ * - If handled is false, the event is put on mUnhandledKeys, and:
+ * a. Main thread receives event from consumeUnhandledEvent().
+ * b. Java sends event through default key handler.
+ * c. event is finished.
+ */
+struct AInputQueue : public android::InputEventFactoryInterface {
+public:
+ /* Creates a consumer associated with an input channel. */
+ explicit AInputQueue(const android::sp<android::InputChannel>& channel, int workWrite);
+
+ /* Destroys the consumer and releases its input channel. */
+ ~AInputQueue();
+
+ void attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data);
+
+ void detachLooper();
+
+ int32_t hasEvents();
+
+ int32_t getEvent(AInputEvent** outEvent);
+
+ bool preDispatchEvent(AInputEvent* event);
+
+ void finishEvent(AInputEvent* event, bool handled);
+
+ // ----------------------------------------------------------
+
+ inline android::InputConsumer& getConsumer() { return mConsumer; }
+
+ void dispatchEvent(android::KeyEvent* event);
+
+ void finishPreDispatch(int seq, bool handled);
+
+ android::KeyEvent* consumeUnhandledEvent();
+ android::KeyEvent* consumePreDispatchingEvent(int* outSeq);
+
+ virtual android::KeyEvent* createKeyEvent();
+ virtual android::MotionEvent* createMotionEvent();
+
+ int mWorkWrite;
+
+private:
+ void doUnhandledKey(android::KeyEvent* keyEvent);
+ bool preDispatchKey(android::KeyEvent* keyEvent);
+ void wakeupDispatch();
+
+ android::InputConsumer mConsumer;
+ android::sp<android::PollLoop> mPollLoop;
+
+ int mDispatchKeyRead;
+ int mDispatchKeyWrite;
+
+ struct in_flight_event {
+ android::InputEvent* event;
+ int seq;
+ bool doFinish;
+ };
+
+ struct finish_pre_dispatch {
+ int seq;
+ bool handled;
+ };
+
+ android::Mutex mLock;
+
+ int mSeq;
+
+ // Cache of previously allocated key events.
+ android::Vector<android::KeyEvent*> mAvailKeyEvents;
+ // Cache of previously allocated motion events.
+ android::Vector<android::MotionEvent*> mAvailMotionEvents;
+
+ // All input events that are actively being processed.
+ android::Vector<in_flight_event> mInFlightEvents;
+
+ // Key events that the app didn't handle, and are pending for
+ // delivery to the activity's default key handling.
+ android::Vector<android::KeyEvent*> mUnhandledKeys;
+
+ // Keys that arrived in the Java framework and need to be
+ // dispatched to the app.
+ android::Vector<android::KeyEvent*> mDispatchingKeys;
+
+ // Key events that are pending to be pre-dispatched to the IME.
+ android::Vector<in_flight_event> mPreDispatchingKeys;
+
+ // Event sequence numbers that we have finished pre-dispatching.
+ android::Vector<finish_pre_dispatch> mFinishPreDispatches;
+};
+
+#endif // _ANDROID_APP_NATIVEACTIVITY_H
diff --git a/include/android_runtime/android_content_res_Configuration.h b/include/android_runtime/android_content_res_Configuration.h
new file mode 100644
index 0000000..2f5a982
--- /dev/null
+++ b/include/android_runtime/android_content_res_Configuration.h
@@ -0,0 +1,36 @@
+/*
+ * 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_CONTENT_RES_CONFIGURATION_H
+#define _ANDROID_CONTENT_RES_CONFIGURATION_H
+
+#include <utils/ResourceTypes.h>
+#include <android/configuration.h>
+
+#include "jni.h"
+
+struct AConfiguration : android::ResTable_config {
+};
+
+namespace android {
+
+extern void android_Configuration_getFromJava(
+ JNIEnv* env, jobject clazz, struct AConfiguration* out);
+
+} // namespace android
+
+
+#endif // _ANDROID_CONTENT_RES_CONFIGURATION_H
diff --git a/include/android_runtime/android_view_Surface.h b/include/android_runtime/android_view_Surface.h
new file mode 100644
index 0000000..c37932e
--- /dev/null
+++ b/include/android_runtime/android_view_Surface.h
@@ -0,0 +1,31 @@
+/*
+ * 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_VIEW_SURFACE_H
+#define _ANDROID_VIEW_SURFACE_H
+
+#include <android/native_window.h>
+
+#include "jni.h"
+
+namespace android {
+
+extern sp<ANativeWindow> android_Surface_getNativeWindow(
+ JNIEnv* env, jobject clazz);
+
+} // namespace android
+
+#endif // _ANDROID_VIEW_SURFACE_H
diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h
new file mode 100644
index 0000000..2316fef
--- /dev/null
+++ b/include/binder/BinderService.h
@@ -0,0 +1,60 @@
+/*
+ * 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_BINDER_SERVICE_H
+#define ANDROID_BINDER_SERVICE_H
+
+#include <stdint.h>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+template<typename SERVICE>
+class BinderService
+{
+public:
+ static status_t publish() {
+ sp<IServiceManager> sm(defaultServiceManager());
+ return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+ }
+
+ static void publishAndJoinThreadPool() {
+ sp<ProcessState> proc(ProcessState::self());
+ sp<IServiceManager> sm(defaultServiceManager());
+ sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+ ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool();
+ }
+
+ static void instantiate() { publish(); }
+
+ static status_t shutdown() {
+ return NO_ERROR;
+ }
+};
+
+
+}; // namespace android
+// ---------------------------------------------------------------------------
+#endif // ANDROID_BINDER_SERVICE_H
diff --git a/include/binder/IInterface.h b/include/binder/IInterface.h
index 273d922..5f9f69c 100644
--- a/include/binder/IInterface.h
+++ b/include/binder/IInterface.h
@@ -72,21 +72,24 @@ protected:
// ----------------------------------------------------------------------
#define DECLARE_META_INTERFACE(INTERFACE) \
- static const String16 descriptor; \
- static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \
- virtual const String16& getInterfaceDescriptor() const; \
+ static const android::String16 descriptor; \
+ static android::sp<I##INTERFACE> asInterface( \
+ const android::sp<android::IBinder>& obj); \
+ virtual const android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
- const String16 I##INTERFACE::descriptor(NAME); \
- const String16& I##INTERFACE::getInterfaceDescriptor() const { \
+ const android::String16 I##INTERFACE::descriptor(NAME); \
+ const android::String16& \
+ I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
- sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \
+ android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
+ const android::sp<android::IBinder>& obj) \
{ \
- sp<I##INTERFACE> intr; \
+ android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 3ab985d..04e24d2 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -40,6 +40,9 @@ public:
int getCallingPid();
int getCallingUid();
+
+ void setStrictModePolicy(int32_t policy);
+ int32_t getStrictModePolicy() const;
int64_t clearCallingIdentity();
void restoreCallingIdentity(int64_t token);
@@ -109,8 +112,9 @@ private:
status_t mLastError;
pid_t mCallingPid;
uid_t mCallingUid;
+ int32_t mStrictModePolicy;
};
-
+
}; // namespace android
// ---------------------------------------------------------------------------
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 66c34b2..32c9a1d5 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -26,11 +26,12 @@
// ---------------------------------------------------------------------------
namespace android {
+class Flattenable;
class IBinder;
+class IPCThreadState;
class ProcessState;
class String8;
class TextOutput;
-class Flattenable;
struct flat_binder_object; // defined in support_p/binder_module.h
@@ -56,9 +57,19 @@ public:
bool hasFileDescriptors() const;
+ // Writes the RPC header.
status_t writeInterfaceToken(const String16& interface);
- bool enforceInterface(const String16& interface) const;
- bool checkInterface(IBinder*) const;
+
+ // Parses the RPC header, returning true if the interface name
+ // in the header matches the expected interface from the caller.
+ //
+ // Additionally, enforceInterface does part of the work of
+ // propagating the StrictMode policy mask, populating the current
+ // IPCThreadState, which as an optimization may optionally be
+ // passed in.
+ bool enforceInterface(const String16& interface,
+ IPCThreadState* threadState = NULL) const;
+ bool checkInterface(IBinder*) const;
void freeData();
@@ -100,6 +111,11 @@ public:
status_t writeObject(const flat_binder_object& val, bool nullMetaData);
+ // Like Parcel.java's writeNoException(). Just writes a zero int32.
+ // Currently the native implementation doesn't do any of the StrictMode
+ // stack gathering and serialization that the Java implementation does.
+ status_t writeNoException();
+
void remove(size_t start, size_t amt);
status_t read(void* outData, size_t len) const;
@@ -122,7 +138,14 @@ public:
sp<IBinder> readStrongBinder() const;
wp<IBinder> readWeakBinder() const;
status_t read(Flattenable& val) const;
-
+
+ // Like Parcel.java's readExceptionCode(). Reads the first int32
+ // off of a Parcel's header, returning 0 or the negative error
+ // code on exceptions, but also deals with skipping over rich
+ // response headers. Callers should use this to read & parse the
+ // response headers rather than doing it by hand.
+ int32_t readExceptionCode() const;
+
// Retrieve native_handle from the parcel. This returns a copy of the
// parcel's native_handle (the caller takes ownership). The caller
// must free the native_handle with native_handle_close() and
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 57968e3..964700b 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -92,6 +92,32 @@ enum {
CAMERA_ERROR_SERVER_DIED = 100
};
+enum {
+ CAMERA_FACING_BACK = 0,
+ CAMERA_FACING_FRONT = 1 /* The camera faces to the user */
+};
+
+struct CameraInfo {
+
+ /**
+ * The direction that the camera faces to. It should be
+ * CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
+ */
+ int facing;
+
+ /**
+ * The orientation of the camera image. The value is the angle that the
+ * camera image needs to be rotated clockwise so it shows correctly on
+ * the display in its natural orientation. It should be 0, 90, 180, or 270.
+ *
+ * For example, suppose a device has a naturally tall screen, but the camera
+ * sensor is mounted in landscape. If the top side of the camera sensor is
+ * aligned with the right edge of the display in natural orientation, the
+ * value should be 90.
+ */
+ int orientation;
+};
+
class ICameraService;
class ICamera;
class Surface;
@@ -112,7 +138,10 @@ class Camera : public BnCameraClient, public IBinder::DeathRecipient
public:
// construct a camera client from an existing remote
static sp<Camera> create(const sp<ICamera>& camera);
- static sp<Camera> connect();
+ static int32_t getNumberOfCameras();
+ static status_t getCameraInfo(int cameraId,
+ struct CameraInfo* cameraInfo);
+ static sp<Camera> connect(int cameraId);
~Camera();
void init();
diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
index d877c74..1529db7 100644
--- a/include/camera/CameraHardwareInterface.h
+++ b/include/camera/CameraHardwareInterface.h
@@ -213,8 +213,15 @@ public:
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
};
-/** factory function to instantiate a camera hardware object */
-extern "C" sp<CameraHardwareInterface> openCameraHardware();
+/**
+ * The functions need to be provided by the camera HAL.
+ *
+ * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
+ * and openCameraHardware() is 0 to N-1.
+ */
+extern "C" int HAL_getNumberOfCameras();
+extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
+extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId);
}; // namespace android
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 5ea83a5..6a5d254 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -65,13 +65,15 @@ public:
// Supported preview frame sizes in pixels.
// Example value: "800x600,480x320". Read only.
static const char KEY_SUPPORTED_PREVIEW_SIZES[];
- // The image format for preview frames.
+ // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
+ // frameworks/base/include/camera/Camera.h.
// Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read/write.
static const char KEY_PREVIEW_FORMAT[];
// Supported image formats for preview frames.
// Example value: "yuv420sp,yuv422i-yuyv". Read only.
static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
- // Number of preview frames per second.
+ // Number of preview frames per second. This is the target frame rate. The
+ // actual frame rate depends on the driver.
// Example value: "15". Read/write.
static const char KEY_PREVIEW_FRAME_RATE[];
// Supported number of preview frames per second.
@@ -83,7 +85,8 @@ public:
// Supported dimensions for captured pictures in pixels.
// Example value: "2048x1536,1024x768". Read only.
static const char KEY_SUPPORTED_PICTURE_SIZES[];
- // The image format for captured pictures.
+ // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
+ // in frameworks/base/include/camera/Camera.h.
// Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
static const char KEY_PICTURE_FORMAT[];
// Supported image formats for captured pictures.
@@ -119,14 +122,17 @@ public:
// should not set default value for this parameter.
// Example value: "0" or "90" or "180" or "270". Write only.
static const char KEY_ROTATION[];
- // GPS latitude coordinate. This will be stored in JPEG EXIF header.
- // Example value: "25.032146". Write only.
+ // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
+ // JPEG EXIF header.
+ // Example value: "25.032146" or "-33.462809". Write only.
static const char KEY_GPS_LATITUDE[];
- // GPS longitude coordinate. This will be stored in JPEG EXIF header.
- // Example value: "121.564448". Write only.
+ // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
+ // in JPEG EXIF header.
+ // Example value: "121.564448" or "-70.660286". Write only.
static const char KEY_GPS_LONGITUDE[];
- // GPS altitude. This will be stored in JPEG EXIF header.
- // Example value: "21.0". Write only.
+ // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
+ // header.
+ // Example value: "21.0" or "-5". Write only.
static const char KEY_GPS_ALTITUDE[];
// GPS timestamp (UTC in seconds since January 1, 1970). This should be
// stored in JPEG EXIF header.
@@ -165,10 +171,9 @@ public:
// Supported flash modes.
// Example value: "auto,on,off". Read only.
static const char KEY_SUPPORTED_FLASH_MODES[];
- // Current focus mode. If the camera does not support auto-focus, the value
- // should be FOCUS_MODE_FIXED. If the focus mode is not FOCUS_MODE_FIXED or
- // or FOCUS_MODE_INFINITY, applications should call
- // CameraHardwareInterface.autoFocus to start the focus.
+ // Current focus mode. This will not be empty. Applications should call
+ // CameraHardwareInterface.autoFocus to start the focus if focus mode is
+ // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
// Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
static const char KEY_FOCUS_MODE[];
// Supported focus modes.
@@ -221,9 +226,47 @@ public:
// Example value: "true". Read only.
static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
+ // The distances (in meters) from the camera to where an object appears to
+ // be in focus. The object is sharpest at the optimal focus distance. The
+ // depth of field is the far focus distance minus near focus distance.
+ //
+ // Focus distances may change after starting auto focus, canceling auto
+ // focus, or starting the preview. Applications can read this anytime to get
+ // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
+ // focus distances may change from time to time.
+ //
+ // This is intended to estimate the distance between the camera and the
+ // subject. After autofocus, the subject distance may be within near and far
+ // focus distance. However, the precision depends on the camera hardware,
+ // autofocus algorithm, the focus area, and the scene. The error can be
+ // large and it should be only used as a reference.
+ //
+ // Far focus distance > optimal focus distance > near focus distance. If
+ // the far focus distance is infinity, the value should be "Infinity" (case
+ // sensitive). The format is three float values separated by commas. The
+ // first is near focus distance. The second is optimal focus distance. The
+ // third is far focus distance.
+ // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
+ static const char KEY_FOCUS_DISTANCES[];
+
+ // 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.
+ static const char KEY_VIDEO_FRAME_FORMAT[];
+
+ // Metering mode. This affects how camera determines exposure.
+ // Example value: "spot" or METERING_MODE_XXX constants. Read/write.
+ static const char KEY_METERING_MODE[];
+ // Supported metering modes.
+ // Example value: "center-weighted,frame-average,spot". Read only.
+ static const char KEY_SUPPORTED_METERING_MODES[];
+
// Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
static const char TRUE[];
+ // Value for KEY_FOCUS_DISTANCES.
+ static const char FOCUS_DISTANCE_INFINITY[];
+
// Values for white balance settings.
static const char WHITE_BALANCE_AUTO[];
static const char WHITE_BALANCE_INCANDESCENT[];
@@ -309,6 +352,21 @@ public:
// continuously. Applications should not call
// CameraHardwareInterface.autoFocus in this mode.
static const char FOCUS_MODE_EDOF[];
+ // Continuous auto focus mode. The camera continuously tries to focus. This
+ // is ideal for shooting video or shooting photo of moving object. Auto
+ // focus starts when the parameter is set. Applications should not call
+ // CameraHardwareInterface.autoFocus in this mode.
+ static const char FOCUS_MODE_CONTINUOUS[];
+
+ // The camera determines the exposure by giving more weight to the
+ // central part of the scene.
+ static const char METERING_MODE_CENTER_WEIGHTED[];
+ // The camera determines the exposure by averaging the entire scene,
+ // giving no weighting to any particular area.
+ static const char METERING_MODE_FRAME_AVERAGE[];
+ // The camera determines the exposure by a very small area of the scene,
+ // typically the center.
+ static const char METERING_MODE_SPOT[];
private:
DefaultKeyedVector<String8,String8> mMap;
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index 82b1283..7d70c1e 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -30,13 +30,19 @@ class ICameraService : public IInterface
{
public:
enum {
- CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+ GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION,
+ GET_CAMERA_INFO,
+ CONNECT
};
public:
DECLARE_META_INTERFACE(CameraService);
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient) = 0;
+ virtual int32_t getNumberOfCameras() = 0;
+ virtual status_t getCameraInfo(int cameraId,
+ struct CameraInfo* cameraInfo) = 0;
+ virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient,
+ int cameraId) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h
new file mode 100644
index 0000000..ed4e4cc
--- /dev/null
+++ b/include/gui/ISensorEventConnection.h
@@ -0,0 +1,57 @@
+/*
+ * 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_ISENSOR_EVENT_CONNECTION_H
+#define ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class SensorChannel;
+
+class ISensorEventConnection : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(SensorEventConnection);
+
+ virtual sp<SensorChannel> getSensorChannel() const = 0;
+ virtual status_t enableDisable(int handle, bool enabled) = 0;
+ virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorEventConnection : public BnInterface<ISensorEventConnection>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
new file mode 100644
index 0000000..9c8afc5
--- /dev/null
+++ b/include/gui/ISensorServer.h
@@ -0,0 +1,57 @@
+/*
+ * 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_ISENSORSERVER_H
+#define ANDROID_GUI_ISENSORSERVER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class Sensor;
+class ISensorEventConnection;
+
+class ISensorServer : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(SensorServer);
+
+ virtual Vector<Sensor> getSensorList() = 0;
+ virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorServer : public BnInterface<ISensorServer>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_ISENSORSERVER_H
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
new file mode 100644
index 0000000..2de07b1
--- /dev/null
+++ b/include/gui/Sensor.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_SENSOR_H
+#define ANDROID_GUI_SENSOR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Flattenable.h>
+
+#include <hardware/sensors.h>
+
+#include <android/sensor.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensor { };
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class Parcel;
+
+// ----------------------------------------------------------------------------
+
+class Sensor : public ASensor, public Flattenable
+{
+public:
+ enum {
+ TYPE_ACCELEROMETER = ASENSOR_TYPE_ACCELEROMETER,
+ TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
+ TYPE_GYROSCOPE = ASENSOR_TYPE_GYROSCOPE,
+ TYPE_LIGHT = ASENSOR_TYPE_LIGHT,
+ TYPE_PROXIMITY = ASENSOR_TYPE_PROXIMITY
+ };
+
+ Sensor();
+ Sensor(struct sensor_t const* hwSensor);
+ virtual ~Sensor();
+
+ const String8& getName() const;
+ const String8& getVendor() const;
+ int32_t getHandle() const;
+ int32_t getType() const;
+ float getMinValue() const;
+ float getMaxValue() const;
+ float getResolution() const;
+ float getPowerUsage() const;
+ int32_t getMinDelay() const;
+
+ // Flattenable interface
+ virtual size_t getFlattenedSize() const;
+ virtual size_t getFdCount() const;
+ virtual status_t flatten(void* buffer, size_t size,
+ int fds[], size_t count) const;
+ virtual status_t unflatten(void const* buffer, size_t size,
+ int fds[], size_t count);
+
+private:
+ String8 mName;
+ String8 mVendor;
+ int32_t mHandle;
+ int32_t mType;
+ float mMinValue;
+ float mMaxValue;
+ float mResolution;
+ float mPower;
+ int32_t mMinDelay;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_H
diff --git a/include/gui/SensorChannel.h b/include/gui/SensorChannel.h
new file mode 100644
index 0000000..bb54618
--- /dev/null
+++ b/include/gui/SensorChannel.h
@@ -0,0 +1,53 @@
+/*
+ * 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_SENSOR_CHANNEL_H
+#define ANDROID_GUI_SENSOR_CHANNEL_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+
+namespace android {
+// ----------------------------------------------------------------------------
+class Parcel;
+
+class SensorChannel : public RefBase
+{
+public:
+
+ SensorChannel();
+ SensorChannel(const Parcel& data);
+ virtual ~SensorChannel();
+
+ int getFd() const;
+ ssize_t write(void const* vaddr, size_t size);
+ ssize_t read(void* vaddr, size_t size);
+
+ status_t writeToParcel(Parcel* reply) const;
+
+private:
+ int mSendFd;
+ mutable int mReceiveFd;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_CHANNEL_H
diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h
new file mode 100644
index 0000000..6581ae3
--- /dev/null
+++ b/include/gui/SensorEventQueue.h
@@ -0,0 +1,82 @@
+/*
+ * 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_SENSOR_EVENT_QUEUE_H
+#define ANDROID_SENSOR_EVENT_QUEUE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <gui/SensorChannel.h>
+
+// ----------------------------------------------------------------------------
+
+struct ALooper;
+struct ASensorEvent;
+
+// Concrete types for the NDK
+struct ASensorEventQueue {
+ ALooper* looper;
+};
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorEventConnection;
+class Sensor;
+class PollLoop;
+
+// ----------------------------------------------------------------------------
+
+class SensorEventQueue : public ASensorEventQueue, public RefBase
+{
+public:
+ SensorEventQueue(const sp<ISensorEventConnection>& connection);
+ virtual ~SensorEventQueue();
+ virtual void onFirstRef();
+
+ int getFd() const;
+ ssize_t write(ASensorEvent const* events, size_t numEvents);
+ ssize_t read(ASensorEvent* events, size_t numEvents);
+
+ status_t waitForEvent() const;
+ status_t wake() const;
+
+ status_t enableSensor(Sensor const* sensor) const;
+ status_t disableSensor(Sensor const* sensor) const;
+ status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;
+
+ // these are here only to support SensorManager.java
+ status_t enableSensor(int32_t handle, int32_t us) const;
+ status_t disableSensor(int32_t handle) const;
+
+private:
+ sp<PollLoop> getPollLoop() const;
+ sp<ISensorEventConnection> mSensorEventConnection;
+ sp<SensorChannel> mSensorChannel;
+ mutable Mutex mLock;
+ mutable sp<PollLoop> mPollLoop;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SENSOR_EVENT_QUEUE_H
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
new file mode 100644
index 0000000..e1b1a7b
--- /dev/null
+++ b/include/gui/SensorManager.h
@@ -0,0 +1,63 @@
+/*
+ * 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_SENSOR_MANAGER_H
+#define ANDROID_GUI_SENSOR_MANAGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+#include <utils/Vector.h>
+
+#include <gui/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensorManager { };
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorServer;
+class Sensor;
+class SensorEventQueue;
+
+// ----------------------------------------------------------------------------
+
+class SensorManager : public ASensorManager, public Singleton<SensorManager>
+{
+public:
+ SensorManager();
+ ~SensorManager();
+
+ ssize_t getSensorList(Sensor const* const** list) const;
+ Sensor const* getDefaultSensor(int type);
+ sp<SensorEventQueue> createEventQueue();
+
+private:
+ sp<ISensorServer> mSensorServer;
+ Sensor const** mSensorList;
+ Vector<Sensor> mSensors;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_MANAGER_H
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
new file mode 100644
index 0000000..c967efb
--- /dev/null
+++ b/include/media/AudioEffect.h
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOEFFECT_H
+#define ANDROID_AUDIOEFFECT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
+#include <media/EffectApi.h>
+#include <media/AudioSystem.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class effect_param_cblk_t;
+
+// ----------------------------------------------------------------------------
+
+class AudioEffect : public RefBase
+{
+public:
+
+ /*
+ * Static methods for effect libraries management.
+ */
+
+ /*
+ * Loads the effect library which path is given as first argument.
+ * This must be the full path of a dynamic library (.so) implementing one or
+ * more effect engines and exposing the effect library interface described in
+ * EffectApi.h. The function returns a handle on the library for use by
+ * further call to unloadEffectLibrary() to unload the library.
+ *
+ * Parameters:
+ * libPath: full path of the dynamic library file in the file system.
+ * handle: address where to return the library handle
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface or
+ * application does not have permission to configure audio
+ * NO_INIT effect factory not initialized or
+ * library could not be loaded or
+ * library does not implement required functions
+ * BAD_VALUE invalid libPath string or handle
+ *
+ * Returned value:
+ * *handle updated with library handle
+ */
+ static status_t loadEffectLibrary(const char *libPath, int *handle);
+
+ /*
+ * Unloads the effect library which handle is given as argument.
+ *
+ * Parameters:
+ * handle: library handle
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface or
+ * application does not have permission to configure audio
+ * NO_INIT effect factory not initialized
+ * BAD_VALUE invalid handle
+ */
+ static status_t unloadEffectLibrary(int handle);
+
+ /*
+ * Static methods for effects enumeration.
+ */
+
+ /*
+ * Returns the number of effects available. This method together
+ * with queryEffect() is used to enumerate all effects:
+ * The enumeration sequence is:
+ * queryNumberEffects(&num_effects);
+ * for (i = 0; i < num_effects; i++)
+ * queryEffect(i,...);
+ *
+ * Parameters:
+ * numEffects: address where the number of effects should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid numEffects pointer
+ *
+ * Returned value
+ * *numEffects: updated with number of effects available
+ */
+ static status_t queryNumberEffects(uint32_t *numEffects);
+
+ /*
+ * Returns an effect descriptor during effect
+ * enumeration.
+ *
+ * Parameters:
+ * index: index of the queried effect.
+ * descriptor: address where the effect descriptor should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid descriptor pointer or index
+ * INVALID_OPERATION effect list has changed since last execution of queryNumberEffects()
+ *
+ * Returned value
+ * *descriptor: updated with effect descriptor
+ */
+ static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
+
+
+ /*
+ * Returns the descriptor for the specified effect uuid.
+ *
+ * Parameters:
+ * uuid: pointer to effect uuid.
+ * descriptor: address where the effect descriptor should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid uuid or descriptor pointers
+ * NAME_NOT_FOUND no effect with this uuid found
+ *
+ * Returned value
+ * *descriptor updated with effect descriptor
+ */
+ static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);
+
+
+ /*
+ * Events used by callback function (effect_callback_t).
+ */
+ enum event_type {
+ EVENT_CONTROL_STATUS_CHANGED = 0,
+ EVENT_ENABLE_STATUS_CHANGED = 1,
+ EVENT_PARAMETER_CHANGED = 2,
+ EVENT_ERROR = 3
+ };
+
+ /* Callback function notifying client application of a change in effect engine state or
+ * configuration.
+ * An effect engine can be shared by several applications but only one has the control
+ * of the engine activity and configuration at a time.
+ * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or
+ * retrieves the control of the effect engine. Loss of control happens
+ * if another application requests the use of the engine by creating an AudioEffect for
+ * the same effect type but with a higher priority. Control is returned when the
+ * application having the control deletes its AudioEffect object.
+ * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the
+ * control of the effect engine when the effect is enabled or disabled.
+ * The EVENT_PARAMETER_CHANGED event is received by all applications not having the
+ * control of the effect engine when an effect parameter is changed.
+ * The EVENT_ERROR event is received when the media server process dies.
+ *
+ * Parameters:
+ *
+ * event: type of event notified (see enum AudioEffect::event_type).
+ * user: Pointer to context for use by the callback receiver.
+ * info: Pointer to optional parameter according to event type:
+ * - EVENT_CONTROL_STATUS_CHANGED: boolean indicating if control is granted (true)
+ * or stolen (false).
+ * - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true)
+ * or disabled (false).
+ * - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure.
+ * - EVENT_ERROR: status_t indicating the error (DEAD_OBJECT when media server dies).
+ */
+
+ typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
+
+
+ /* Constructor.
+ * AudioEffect is the base class for creating and controlling an effect engine from
+ * the application process. Creating an AudioEffect object will create the effect engine
+ * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine
+ * will be used. The application creating the AudioEffect object (or a derived class like
+ * Reverb for instance) will either receive control of the effect engine or not, depending
+ * on the priority parameter. If priority is higher than the priority used by the current
+ * effect engine owner, the control will be transfered to the new application. Otherwise
+ * control will remain to the previous application. In this case, the new application will be
+ * notified of changes in effect engine state or control ownership by the effect callback.
+ * After creating the AudioEffect, the application must call the initCheck() method and
+ * check the creation status before trying to control the effect engine (see initCheck()).
+ * If the effect is to be applied to an AudioTrack or MediaPlayer only the application
+ * must specify the audio session ID corresponding to this player.
+ */
+
+ /* Simple Constructor.
+ */
+ AudioEffect();
+
+
+ /* Constructor.
+ *
+ * Parameters:
+ *
+ * type: type of effect created: can be null if uuid is specified. This corresponds to
+ * the OpenSL ES interface implemented by this effect.
+ * uuid: Uuid of effect created: can be null if type is specified. This uuid corresponds to
+ * a particular implementation of an effect type.
+ * priority: requested priority for effect control: the priority level corresponds to the
+ * value of priority parameter: negative values indicate lower priorities, positive values
+ * higher priorities, 0 being the normal priority.
+ * cbf: optional callback function (see effect_callback_t)
+ * user: pointer to context for use by the callback receiver.
+ * sessionID: audio session this effect is associated to. If 0, the effect will be global to
+ * the output mix. If not 0, the effect will be applied to all players
+ * (AudioTrack or MediaPLayer) within the same audio session.
+ * output: HAL audio output stream to which this effect must be attached. Leave at 0 for
+ * automatic output selection by AudioFlinger.
+ */
+
+ AudioEffect(const effect_uuid_t *type,
+ const effect_uuid_t *uuid = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = 0,
+ void* user = 0,
+ int sessionId = 0,
+ audio_io_handle_t output = 0
+ );
+
+ /* Constructor.
+ * Same as above but with type and uuid specified by character strings
+ */
+ AudioEffect(const char *typeStr,
+ const char *uuidStr = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = 0,
+ void* user = 0,
+ int sessionId = 0,
+ audio_io_handle_t output = 0
+ );
+
+ /* Terminates the AudioEffect and unregisters it from AudioFlinger.
+ * The effect engine is also destroyed if this AudioEffect was the last controlling
+ * the engine.
+ */
+ ~AudioEffect();
+
+ /* Initialize an uninitialized AudioEffect.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR or ALREADY_EXISTS: successful initialization
+ * - INVALID_OPERATION: AudioEffect is already initialized
+ * - BAD_VALUE: invalid parameter
+ * - NO_INIT: audio flinger or audio hardware not initialized
+ * */
+ status_t set(const effect_uuid_t *type,
+ const effect_uuid_t *uuid = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = 0,
+ void* user = 0,
+ int sessionId = 0,
+ audio_io_handle_t output = 0
+ );
+
+ /* Result of constructing the AudioEffect. This must be checked
+ * before using any AudioEffect API.
+ * initCheck() can return:
+ * - NO_ERROR: the effect engine is successfully created and the application has control.
+ * - ALREADY_EXISTS: the effect engine is successfully created but the application does not
+ * have control.
+ * - NO_INIT: the effect creation failed.
+ *
+ */
+ status_t initCheck() const;
+
+
+ /* Returns the unique effect Id for the controlled effect engine. This ID is unique
+ * system wide and is used for instance in the case of auxiliary effects to attach
+ * the effect to an AudioTrack or MediaPlayer.
+ *
+ */
+ int32_t id() const { return mId; }
+
+ /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h).
+ */
+ effect_descriptor_t descriptor() const;
+
+ /* Returns effect control priority of this AudioEffect object.
+ */
+ int32_t priority() const { return mPriority; }
+
+
+ /* Enables or disables the effect engine.
+ *
+ * Parameters:
+ * enabled: requested enable state.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the application does not have control of the effect engine or the
+ * effect is already in the requested state.
+ */
+ virtual status_t setEnabled(bool enabled);
+ bool getEnabled() const;
+
+ /* Sets a parameter value.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and its value (See EffectApi.h).
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the application does not have control of the effect engine.
+ * - BAD_VALUE: invalid parameter identifier or value.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t setParameter(effect_param_t *param);
+
+ /* Prepare a new parameter value that will be set by next call to
+ * setParameterCommit(). This method can be used to set multiple parameters
+ * in a synchronous manner or to avoid multiple binder calls for each
+ * parameter.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and its value (See EffectApi.h).
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the application does not have control of the effect engine.
+ * - NO_MEMORY: no more space available in shared memory used for deferred parameter
+ * setting.
+ */
+ virtual status_t setParameterDeferred(effect_param_t *param);
+
+ /* Commit all parameter values previously prepared by setParameterDeferred().
+ *
+ * Parameters:
+ * none
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: No new parameter values ready for commit.
+ * - BAD_VALUE: invalid parameter identifier or value: there is no indication
+ * as to which of the parameters caused this error.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t setParameterCommit();
+
+ /* Gets a parameter value.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and the returned value (See EffectApi.h).
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the AudioEffect was not successfully initialized.
+ * - BAD_VALUE: invalid parameter identifier.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t getParameter(effect_param_t *param);
+
+ /* Sends a command and receives a response to/from effect engine.
+ * See EffectApi.h for details on effect command() function, valid command codes
+ * and formats.
+ */
+ virtual status_t command(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *cmdData,
+ uint32_t *replySize,
+ void *replyData);
+
+
+ /*
+ * Utility functions.
+ */
+
+ /* Converts the string passed as first argument to the effect_uuid_t
+ * pointed to by second argument
+ */
+ static status_t stringToGuid(const char *str, effect_uuid_t *guid);
+ /* Converts the effect_uuid_t pointed to by first argument to the
+ * string passed as second argument
+ */
+ static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen);
+
+protected:
+ volatile int32_t mEnabled; // enable state
+ int32_t mSessionId; // audio session ID
+ int32_t mPriority; // priority for effect control
+ status_t mStatus; // effect status
+ effect_callback_t mCbf; // callback function for status, control and
+ // parameter changes notifications
+ void* mUserData; // client context for callback function
+ effect_descriptor_t mDescriptor; // effect descriptor
+ int32_t mId; // system wide unique effect engine instance ID
+
+private:
+
+ // Implements the IEffectClient interface
+ class EffectClient : public android::BnEffectClient, public android::IBinder::DeathRecipient
+ {
+ public:
+
+ EffectClient(AudioEffect *effect) : mEffect(effect){}
+
+ // IEffectClient
+ virtual void controlStatusChanged(bool controlGranted) {
+ mEffect->controlStatusChanged(controlGranted);
+ }
+ virtual void enableStatusChanged(bool enabled) {
+ mEffect->enableStatusChanged(enabled);
+ }
+ virtual void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData) {
+ mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ }
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();}
+
+ private:
+ AudioEffect *mEffect;
+ };
+
+
+ friend class EffectClient;
+
+ // IEffectClient
+ void controlStatusChanged(bool controlGranted);
+ void enableStatusChanged(bool enabled);
+ void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData);
+ void binderDied();
+
+
+ sp<IEffect> mIEffect; // IEffect binder interface
+ sp<EffectClient> mIEffectClient; // IEffectClient implementation
+ sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting
+ effect_param_cblk_t* mCblk; // control block for deferred parameter setting
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOEFFECT_H
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 92bc126..38e3d44 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -100,6 +100,19 @@ public:
typedef void (*callback_t)(int event, void* user, void *info);
+ /* Returns the minimum frame count required for the successful creation of
+ * an AudioRecord object.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - NO_INIT: audio server or audio hardware not initialized
+ * - BAD_VALUE: unsupported configuration
+ */
+
+ static status_t getMinFrameCount(int* frameCount,
+ uint32_t sampleRate,
+ int format,
+ int channelCount);
+
/* Constructs an uninitialized AudioRecord. No connection with
* AudioFlinger takes place.
*/
@@ -142,7 +155,8 @@ public:
uint32_t flags = 0,
callback_t cbf = 0,
void* user = 0,
- int notificationFrames = 0);
+ int notificationFrames = 0,
+ int sessionId = 0);
/* Terminates the AudioRecord and unregisters it from AudioFlinger.
@@ -168,7 +182,8 @@ public:
callback_t cbf = 0,
void* user = 0,
int notificationFrames = 0,
- bool threadCanCallJava = false);
+ bool threadCanCallJava = false,
+ int sessionId = 0);
/* Result of constructing the AudioRecord. This must be checked
@@ -270,6 +285,16 @@ public:
*/
audio_io_handle_t getInput();
+ /* returns the audio session ID associated to this AudioRecord.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * AudioRecord session ID.
+ */
+ int getSessionId();
+
/* obtains a buffer of "frameCount" frames. The buffer must be
* filled entirely. If the track is stopped, obtainBuffer() returns
* STOPPED instead of NO_ERROR as long as there are buffers availlable,
@@ -356,6 +381,7 @@ private:
uint32_t mFlags;
uint32_t mChannels;
audio_io_handle_t mInput;
+ int mSessionId;
};
}; // namespace android
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index d0ccc50..9fd905f 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -168,6 +168,15 @@ public:
TX_DISABLE = 0
};
+ // special audio session values
+ enum audio_sessions {
+ SESSION_OUTPUT_STAGE = -1, // session for effects attached to a particular output stream
+ // (value must be less than 0)
+ SESSION_OUTPUT_MIX = 0, // session for effects applied to output mix. These effects can
+ // be moved by audio policy manager to another output stream
+ // (value must be 0)
+ };
+
/* These are static methods to control the system-wide AudioFlinger
* only privileged processes can have access to them
*/
@@ -234,6 +243,8 @@ public:
static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = DEFAULT);
static unsigned int getInputFramesLost(audio_io_handle_t ioHandle);
+
+ static int newAudioSessionId();
//
// AudioPolicyService interface
//
@@ -351,8 +362,12 @@ public:
uint32_t format = FORMAT_DEFAULT,
uint32_t channels = CHANNEL_OUT_STEREO,
output_flags flags = OUTPUT_FLAG_INDIRECT);
- static status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
- static status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
+ static status_t startOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0);
+ static status_t stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0);
static void releaseOutput(audio_io_handle_t output);
static audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
@@ -368,6 +383,16 @@ public:
static status_t setStreamVolumeIndex(stream_type stream, int index);
static status_t getStreamVolumeIndex(stream_type stream, int *index);
+ static uint32_t getStrategyForStream(stream_type stream);
+
+ static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
+ static status_t registerEffect(effect_descriptor_t *desc,
+ audio_io_handle_t output,
+ uint32_t strategy,
+ int session,
+ int id);
+ static status_t unregisterEffect(int id);
+
static const sp<IAudioPolicyService>& get_audio_policy_service();
// ----------------------------------------------------------------------------
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 14b30ae..4475d4a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -102,6 +102,17 @@ public:
typedef void (*callback_t)(int event, void* user, void *info);
+ /* Returns the minimum frame count required for the successful creation of
+ * an AudioTrack object.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - NO_INIT: audio server or audio hardware not initialized
+ */
+
+ static status_t getMinFrameCount(int* frameCount,
+ int streamType =-1,
+ uint32_t sampleRate = 0);
+
/* Constructs an uninitialized AudioTrack. No connection with
* AudioFlinger takes place.
*/
@@ -138,7 +149,8 @@ public:
uint32_t flags = 0,
callback_t cbf = 0,
void* user = 0,
- int notificationFrames = 0);
+ int notificationFrames = 0,
+ int sessionId = 0);
/* Creates an audio track and registers it with AudioFlinger. With this constructor,
* The PCM data to be rendered by AudioTrack is passed in a shared memory buffer
@@ -157,7 +169,8 @@ public:
uint32_t flags = 0,
callback_t cbf = 0,
void* user = 0,
- int notificationFrames = 0);
+ int notificationFrames = 0,
+ int sessionId = 0);
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources assotiated with the AudioTrack.
@@ -182,7 +195,8 @@ public:
void* user = 0,
int notificationFrames = 0,
const sp<IMemory>& sharedBuffer = 0,
- bool threadCanCallJava = false);
+ bool threadCanCallJava = false,
+ int sessionId = 0);
/* Result of constructing the AudioTrack. This must be checked
@@ -239,10 +253,17 @@ public:
/* set volume for this track, mostly used for games' sound effects
+ * left and right volumes. Levels must be <= 1.0.
*/
- void setVolume(float left, float right);
+ status_t setVolume(float left, float right);
void getVolume(float* left, float* right);
+ /* set the send level for this track. An auxiliary effect should be attached
+ * to the track with attachEffect(). Level must be <= 1.0.
+ */
+ status_t setAuxEffectSendLevel(float level);
+ void getAuxEffectSendLevel(float* level);
+
/* set sample rate for this track, mostly used for games' sound effects
*/
status_t setSampleRate(int sampleRate);
@@ -340,6 +361,31 @@ public:
*/
audio_io_handle_t getOutput();
+ /* returns the unique ID associated to this track.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * AudioTrack ID.
+ */
+ int getSessionId();
+
+
+ /* Attach track auxiliary output to specified effect. Used effectId = 0
+ * to detach track from effect.
+ *
+ * Parameters:
+ *
+ * effectId: effectId obtained from AudioEffect::id().
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the effect is not an auxiliary effect.
+ * - BAD_VALUE: The specified effect ID is invalid
+ */
+ status_t attachAuxEffect(int effectId);
+
/* obtains a buffer of "frameCount" frames. The buffer must be
* filled entirely. If the track is stopped, obtainBuffer() returns
* STOPPED instead of NO_ERROR as long as there are buffers availlable,
@@ -398,13 +444,15 @@ private:
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
- audio_io_handle_t output);
+ audio_io_handle_t output,
+ bool enforceFrameCount);
sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
sp<AudioTrackThread> mAudioTrackThread;
float mVolume[2];
+ float mSendLevel;
uint32_t mFrameCount;
audio_track_cblk_t* mCblk;
@@ -420,7 +468,8 @@ private:
callback_t mCbf;
void* mUserData;
- uint32_t mNotificationFrames;
+ uint32_t mNotificationFramesReq; // requested number of frames between each notification callback
+ uint32_t mNotificationFramesAct; // actual number of frames between each notification callback
sp<IMemory> mSharedBuffer;
int mLoopCount;
uint32_t mRemainingFrames;
@@ -429,6 +478,8 @@ private:
uint32_t mNewPosition;
uint32_t mUpdatePeriod;
uint32_t mFlags;
+ int mSessionId;
+ int mAuxEffectId;
};
diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h
new file mode 100644
index 0000000..16fb43c
--- /dev/null
+++ b/include/media/EffectApi.h
@@ -0,0 +1,796 @@
+/*
+ * 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_EFFECTAPI_H_
+#define ANDROID_EFFECTAPI_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/////////////////////////////////////////////////
+// Effect control interface
+/////////////////////////////////////////////////
+
+// The effect control interface is exposed by each effect engine implementation. It consists of
+// a set of functions controlling the configuration, activation and process of the engine.
+// The functions are grouped in a structure of type effect_interface_s:
+// struct effect_interface_s {
+// effect_process_t process;
+// effect_command_t command;
+// };
+
+
+// effect_interface_t: Effect control interface handle.
+// The effect_interface_t serves two purposes regarding the implementation of the effect engine:
+// - 1 it is the address of a pointer to an effect_interface_s structure where the functions
+// of the effect control API for a particular effect are located.
+// - 2 it is the address of the context of a particular effect instance.
+// A typical implementation in the effect library would define a structure as follows:
+// struct effect_module_s {
+// const struct effect_interface_s *itfe;
+// effect_config_t config;
+// effect_context_t context;
+// }
+// The implementation of EffectCreate() function would then allocate a structure of this
+// type and return its address as effect_interface_t
+typedef struct effect_interface_s **effect_interface_t;
+
+
+// Effect API version 1.0
+#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version
+
+// Maximum length of character strings in structures defines by this API.
+#define EFFECT_STRING_LEN_MAX 64
+
+//
+//--- Effect descriptor structure effect_descriptor_t
+//
+
+// Unique effect ID (can be generated from the following site:
+// http://www.itu.int/ITU-T/asn1/uuid.html)
+// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
+// - When used for effect type and the engine is implementing and effect corresponding to a standard
+// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
+// - When used as uuid, it should be a unique UUID for this particular implementation.
+typedef struct effect_uuid_s {
+ uint32_t timeLow;
+ uint16_t timeMid;
+ uint16_t timeHiAndVersion;
+ uint16_t clockSeq;
+ uint8_t node[6];
+} effect_uuid_t;
+
+// NULL UUID definition (matches SL_IID_NULL_)
+#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
+ { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
+static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER;
+const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_;
+const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
+
+// The effect descriptor contains necessary information to facilitate the enumeration of the effect
+// engines present in a library.
+typedef struct effect_descriptor_s {
+ effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect
+ effect_uuid_t uuid; // UUID for this particular implementation
+ uint16_t apiVersion; // Version of the effect API implemented: matches EFFECT_API_VERSION
+ uint32_t flags; // effect engine capabilities/requirements flags (see below)
+ uint16_t cpuLoad; // CPU load indication (see below)
+ uint16_t memoryUsage; // Data Memory usage (see below)
+ char name[EFFECT_STRING_LEN_MAX]; // human readable effect name
+ char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name
+} effect_descriptor_t;
+
+// CPU load and memory usage indication: each effect implementation must provide an indication of
+// its CPU and memory usage for the audio effect framework to limit the number of effects
+// instantiated at a given time on a given platform.
+// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS.
+// The memory usage is expressed in KB and includes only dynamically allocated memory
+
+// Definitions for flags field of effect descriptor.
+// +---------------------------+-----------+-----------------------------------
+// | description | bits | values
+// +---------------------------+-----------+-----------------------------------
+// | connection mode | 0..1 | 0 insert: after track process
+// | | | 1 auxiliary: connect to track auxiliary
+// | | | output and use send level
+// | | | 2 replace: replaces track process function;
+// | | | must implement SRC, volume and mono to stereo.
+// | | | 3 reserved
+// +---------------------------+-----------+-----------------------------------
+// | insertion preference | 2..4 | 0 none
+// | | | 1 first of the chain
+// | | | 2 last of the chain
+// | | | 3 exclusive (only effect in the insert chain)
+// | | | 4..7 reserved
+// +---------------------------+-----------+-----------------------------------
+// | Volume management | 5..6 | 0 none
+// | | | 1 implements volume control
+// | | | 2 requires volume indication
+// | | | 3 reserved
+// +---------------------------+-----------+-----------------------------------
+// | Device indication | 7..8 | 0 none
+// | | | 1 requires device updates
+// | | | 2..3 reserved
+// +---------------------------+-----------+-----------------------------------
+// | Sample input mode | 9..10 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
+// | | | command must specify a buffer descriptor
+// | | | 1 provider: process() function uses the
+// | | | bufferProvider indicated by the
+// | | | EFFECT_CMD_CONFIGURE command to request input.
+// | | | buffers.
+// | | | 2 both: both input modes are supported
+// | | | 3 reserved
+// +---------------------------+-----------+-----------------------------------
+// | Sample output mode | 11..12 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
+// | | | command must specify a buffer descriptor
+// | | | 1 provider: process() function uses the
+// | | | bufferProvider indicated by the
+// | | | EFFECT_CMD_CONFIGURE command to request output
+// | | | buffers.
+// | | | 2 both: both output modes are supported
+// | | | 3 reserved
+// +---------------------------+-----------+-----------------------------------
+// | Hardware acceleration | 13..15 | 0 No hardware acceleration
+// | | | 1 non tunneled hw acceleration: the process() function
+// | | | reads the samples, send them to HW accelerated
+// | | | effect processor, reads back the processed samples
+// | | | and returns them to the output buffer.
+// | | | 2 tunneled hw acceleration: the process() function is
+// | | | transparent. The effect interface is only used to
+// | | | control the effect engine. This mode is relevant for
+// | | | global effects actually applied by the audio
+// | | | hardware on the output stream.
+// +---------------------------+-----------+-----------------------------------
+// | Audio Mode indication | 16..17 | 0 none
+// | | | 1 requires audio mode updates
+// | | | 2..3 reserved
+// +---------------------------+-----------+-----------------------------------
+
+// Insert mode
+#define EFFECT_FLAG_TYPE_MASK 0x00000003
+#define EFFECT_FLAG_TYPE_INSERT 0x00000000
+#define EFFECT_FLAG_TYPE_AUXILIARY 0x00000001
+#define EFFECT_FLAG_TYPE_REPLACE 0x00000002
+
+// Insert preference
+#define EFFECT_FLAG_INSERT_MASK 0x0000001C
+#define EFFECT_FLAG_INSERT_ANY 0x00000000
+#define EFFECT_FLAG_INSERT_FIRST 0x00000004
+#define EFFECT_FLAG_INSERT_LAST 0x00000008
+#define EFFECT_FLAG_INSERT_EXCLUSIVE 0x0000000C
+
+
+// Volume control
+#define EFFECT_FLAG_VOLUME_MASK 0x00000060
+#define EFFECT_FLAG_VOLUME_CTRL 0x00000020
+#define EFFECT_FLAG_VOLUME_IND 0x00000040
+#define EFFECT_FLAG_VOLUME_NONE 0x00000000
+
+// Device indication
+#define EFFECT_FLAG_DEVICE_MASK 0x00000180
+#define EFFECT_FLAG_DEVICE_IND 0x00000080
+#define EFFECT_FLAG_DEVICE_NONE 0x00000000
+
+// Sample input modes
+#define EFFECT_FLAG_INPUT_MASK 0x00000600
+#define EFFECT_FLAG_INPUT_DIRECT 0x00000000
+#define EFFECT_FLAG_INPUT_PROVIDER 0x00000200
+#define EFFECT_FLAG_INPUT_BOTH 0x00000400
+
+// Sample output modes
+#define EFFECT_FLAG_OUTPUT_MASK 0x00001800
+#define EFFECT_FLAG_OUTPUT_DIRECT 0x00000000
+#define EFFECT_FLAG_OUTPUT_PROVIDER 0x00000800
+#define EFFECT_FLAG_OUTPUT_BOTH 0x00001000
+
+// Hardware acceleration mode
+#define EFFECT_FLAG_HW_ACC_MASK 0x00006000
+#define EFFECT_FLAG_HW_ACC_SIMPLE 0x00002000
+#define EFFECT_FLAG_HW_ACC_TUNNEL 0x00004000
+
+// Audio mode indication
+#define EFFECT_FLAG_AUDIO_MODE_MASK 0x00018000
+#define EFFECT_FLAG_AUDIO_MODE_IND 0x00008000
+#define EFFECT_FLAG_AUDIO_MODE_NONE 0x00000000
+
+// Forward definition of type audio_buffer_t
+typedef struct audio_buffer_s audio_buffer_t;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: process
+//
+// Description: Effect process function. Takes input samples as specified
+// (count and location) in input buffer descriptor and output processed
+// samples as specified in output buffer descriptor. If the buffer descriptor
+// is not specified the function must use either the buffer or the
+// buffer provider function installed by the EFFECT_CMD_CONFIGURE command.
+// The effect framework will call the process() function after the EFFECT_CMD_ENABLE
+// command is received and until the EFFECT_CMD_DISABLE is received. When the engine
+// receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully
+// and when done indicate that it is OK to stop calling the process() function by
+// returning the -ENODATA status.
+//
+// NOTE: the process() function implementation should be "real-time safe" that is
+// it should not perform blocking calls: malloc/free, sleep, read/write/open/close,
+// pthread_cond_wait/pthread_mutex_lock...
+//
+// Input:
+// effect_interface_t: handle to the effect interface this function
+// is called on.
+// inBuffer: buffer descriptor indicating where to read samples to process.
+// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
+//
+// inBuffer: buffer descriptor indicating where to write processed samples.
+// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
+//
+// Output:
+// returned value: 0 successful operation
+// -ENODATA the engine has finished the disable phase and the framework
+// can stop calling process()
+// -EINVAL invalid interface handle or
+// invalid input/output buffer description
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_process_t)(effect_interface_t self,
+ audio_buffer_t *inBuffer,
+ audio_buffer_t *outBuffer);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: command
+//
+// Description: Send a command and receive a response to/from effect engine.
+//
+// Input:
+// effect_interface_t: handle to the effect interface this function
+// is called on.
+// cmdCode: command code: the command can be a standardized command defined in
+// effect_command_e (see below) or a proprietary command.
+// cmdSize: size of command in bytes
+// pCmdData: pointer to command data
+// pReplyData: pointer to reply data
+//
+// Input/Output:
+// replySize: maximum size of reply data as input
+// actual size of reply data as output
+//
+// Output:
+// returned value: 0 successful operation
+// -EINVAL invalid interface handle or
+// invalid command/reply size or format according to command code
+// The return code should be restricted to indicate problems related to the this
+// API specification. Status related to the execution of a particular command should be
+// indicated as part of the reply field.
+//
+// *pReplyData updated with command response
+//
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_command_t)(effect_interface_t self,
+ uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t *replySize,
+ void *pReplyData);
+
+
+// Effect control interface definition
+struct effect_interface_s {
+ effect_process_t process;
+ effect_command_t command;
+};
+
+
+//
+//--- Standardized command codes for command() function
+//
+enum effect_command_e {
+ EFFECT_CMD_INIT, // initialize effect engine
+ EFFECT_CMD_CONFIGURE, // configure effect engine (see effect_config_t)
+ EFFECT_CMD_RESET, // reset effect engine
+ EFFECT_CMD_ENABLE, // enable effect process
+ EFFECT_CMD_DISABLE, // disable effect process
+ EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t)
+ EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred
+ EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred
+ EFFECT_CMD_GET_PARAM, // get parameter
+ EFFECT_CMD_SET_DEVICE, // set audio device (see audio_device_e)
+ EFFECT_CMD_SET_VOLUME, // set volume
+ EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...)
+ EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
+};
+
+//==================================================================================================
+// command: EFFECT_CMD_INIT
+//--------------------------------------------------------------------------------------------------
+// description:
+// Initialize effect engine: All configurations return to default
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: 0
+// data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_CONFIGURE
+//--------------------------------------------------------------------------------------------------
+// description:
+// Apply new audio parameters configurations for input and output buffers
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(effect_config_t)
+// data: effect_config_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_RESET
+//--------------------------------------------------------------------------------------------------
+// description:
+// Reset the effect engine. Keep configuration but resets state and buffer content
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: 0
+// data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: 0
+// data: N/A
+//==================================================================================================
+// command: EFFECT_CMD_ENABLE
+//--------------------------------------------------------------------------------------------------
+// description:
+// Enable the process. Called by the framework before the first call to process()
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: 0
+// data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_DISABLE
+//--------------------------------------------------------------------------------------------------
+// description:
+// Disable the process. Called by the framework after the last call to process()
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: 0
+// data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_SET_PARAM
+//--------------------------------------------------------------------------------------------------
+// description:
+// Set a parameter and apply it immediately
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(effect_param_t) + size of param and value
+// data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_SET_PARAM_DEFERRED
+//--------------------------------------------------------------------------------------------------
+// description:
+// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(effect_param_t) + size of param and value
+// data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: 0
+// data: N/A
+//==================================================================================================
+// command: EFFECT_CMD_SET_PARAM_COMMIT
+//--------------------------------------------------------------------------------------------------
+// description:
+// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: 0
+// data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(int)
+// data: status
+//==================================================================================================
+// command: EFFECT_CMD_GET_PARAM
+//--------------------------------------------------------------------------------------------------
+// description:
+// Get a parameter value
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(effect_param_t) + size of param
+// data: effect_param_t + param
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: sizeof(effect_param_t) + size of param and value
+// data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//==================================================================================================
+// command: EFFECT_CMD_SET_DEVICE
+//--------------------------------------------------------------------------------------------------
+// description:
+// Set the rendering device the audio output path is connected to. See audio_device_e for device
+// values.
+// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
+// command when the device changes
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(uint32_t)
+// data: audio_device_e
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: 0
+// data: N/A
+//==================================================================================================
+// command: EFFECT_CMD_SET_VOLUME
+//--------------------------------------------------------------------------------------------------
+// description:
+// Set and get volume. Used by audio framework to delegate volume control to effect engine.
+// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in
+// its descriptor to receive this command before every call to process() function
+// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
+// the volume that should be applied before the effect is processed. The overall volume (the volume
+// actually applied by the effect engine multiplied by the returned value) should match the value
+// indicated in the command.
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: n * sizeof(uint32_t)
+// data: volume for each channel defined in effect_config_t for output buffer expressed in
+// 8.24 fixed point format
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: n * sizeof(uint32_t) / 0
+// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
+// volume for each channel defined in effect_config_t for output buffer expressed in
+// 8.24 fixed point format
+// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
+// N/A
+// It is legal to receive a null pointer as pReplyData in which case the effect framework has
+// delegated volume control to another effect
+//==================================================================================================
+// command: EFFECT_CMD_SET_AUDIO_MODE
+//--------------------------------------------------------------------------------------------------
+// description:
+// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its
+// descriptor to receive this command when the audio mode changes.
+//--------------------------------------------------------------------------------------------------
+// command format:
+// size: sizeof(uint32_t)
+// data: audio_mode_e
+//--------------------------------------------------------------------------------------------------
+// reply format:
+// size: 0
+// data: N/A
+//==================================================================================================
+// command: EFFECT_CMD_FIRST_PROPRIETARY
+//--------------------------------------------------------------------------------------------------
+// description:
+// All proprietary effect commands must use command codes above this value. The size and format of
+// command and response fields is free in this case
+//==================================================================================================
+
+
+// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
+// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
+// regard to the channel mask definition in audio_channels_e e.g :
+// Stereo: left, right
+// 5 point 1: front left, front right, front center, low frequency, back left, back right
+// The buffer size is expressed in frame count, a frame being composed of samples for all
+// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
+// definition
+struct audio_buffer_s {
+ size_t frameCount; // number of frames in buffer
+ union {
+ void* raw; // raw pointer to start of buffer
+ int32_t* s32; // pointer to signed 32 bit data at start of buffer
+ int16_t* s16; // pointer to signed 16 bit data at start of buffer
+ uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer
+ };
+};
+
+// The buffer_provider_s structure contains functions that can be used
+// by the effect engine process() function to query and release input
+// or output audio buffer.
+// The getBuffer() function is called to retrieve a buffer where data
+// should read from or written to by process() function.
+// The releaseBuffer() function MUST be called when the buffer retrieved
+// with getBuffer() is not needed anymore.
+// The process function should use the buffer provider mechanism to retrieve
+// input or output buffer if the inBuffer or outBuffer passed as argument is NULL
+// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE
+// command did not specify an audio buffer.
+
+typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer);
+
+typedef struct buffer_provider_s {
+ buffer_function_t getBuffer; // retrieve next buffer
+ buffer_function_t releaseBuffer; // release used buffer
+ void *cookie; // for use by client of buffer provider functions
+} buffer_provider_t;
+
+
+// The buffer_config_s structure specifies the input or output audio format
+// to be used by the effect engine. It is part of the effect_config_t
+// structure that defines both input and output buffer configurations and is
+// passed by the EFFECT_CMD_CONFIGURE command.
+typedef struct buffer_config_s {
+ audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly
+ uint32_t samplingRate; // sampling rate
+ uint32_t channels; // channel mask (see audio_channels_e)
+ buffer_provider_t bufferProvider; // buffer provider
+ uint8_t format; // Audio format (see audio_format_e)
+ uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e)
+ uint16_t mask; // indicates which of the above fields is valid
+} buffer_config_t;
+
+// Sample format
+enum audio_format_e {
+ SAMPLE_FORMAT_PCM_S15, // PCM signed 16 bits
+ SAMPLE_FORMAT_PCM_U8, // PCM unsigned 8 bits
+ SAMPLE_FORMAT_PCM_S7_24, // PCM signed 7.24 fixed point representation
+ SAMPLE_FORMAT_OTHER // other format (e.g. compressed)
+};
+
+// Channel mask
+enum audio_channels_e {
+ CHANNEL_FRONT_LEFT = 0x1, // front left channel
+ CHANNEL_FRONT_RIGHT = 0x2, // front right channel
+ CHANNEL_FRONT_CENTER = 0x4, // front center channel
+ CHANNEL_LOW_FREQUENCY = 0x8, // low frequency channel
+ CHANNEL_BACK_LEFT = 0x10, // back left channel
+ CHANNEL_BACK_RIGHT = 0x20, // back right channel
+ CHANNEL_FRONT_LEFT_OF_CENTER = 0x40, // front left of center channel
+ CHANNEL_FRONT_RIGHT_OF_CENTER = 0x80, // front right of center channel
+ CHANNEL_BACK_CENTER = 0x100, // back center channel
+ CHANNEL_MONO = CHANNEL_FRONT_LEFT,
+ CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT),
+ CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
+ CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
+ CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
+ CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER),
+ CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
+ CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
+ CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
+ CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
+ CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER),
+};
+
+// Render device
+enum audio_device_e {
+ DEVICE_EARPIECE = 0x1, // earpiece
+ DEVICE_SPEAKER = 0x2, // speaker
+ DEVICE_WIRED_HEADSET = 0x4, // wired headset, with microphone
+ DEVICE_WIRED_HEADPHONE = 0x8, // wired headphone, without microphone
+ DEVICE_BLUETOOTH_SCO = 0x10, // generic bluetooth SCO
+ DEVICE_BLUETOOTH_SCO_HEADSET = 0x20, // bluetooth SCO headset
+ DEVICE_BLUETOOTH_SCO_CARKIT = 0x40, // bluetooth SCO car kit
+ DEVICE_BLUETOOTH_A2DP = 0x80, // generic bluetooth A2DP
+ DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100, // bluetooth A2DP headphones
+ DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200, // bluetooth A2DP speakers
+ DEVICE_AUX_DIGITAL = 0x400, // digital output
+ DEVICE_EXTERNAL_SPEAKER = 0x800 // external speaker (stereo and High quality)
+};
+
+// Audio mode
+enum audio_mode_e {
+ AUDIO_MODE_NORMAL, // phone idle
+ AUDIO_MODE_RINGTONE, // phone ringing
+ AUDIO_MODE_IN_CALL // phone call connected
+};
+
+// Values for "accessMode" field of buffer_config_t:
+// overwrite, read only, accumulate (read/modify/write)
+enum effect_buffer_access_e {
+ EFFECT_BUFFER_ACCESS_WRITE,
+ EFFECT_BUFFER_ACCESS_READ,
+ EFFECT_BUFFER_ACCESS_ACCUMULATE
+
+};
+
+// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
+// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command
+#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account
+#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account
+#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account
+#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account
+#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account
+#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account
+#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \
+ EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \
+ EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER)
+
+
+// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE
+// command to configure audio parameters and buffers for effect engine input and output.
+typedef struct effect_config_s {
+ buffer_config_t inputCfg;
+ buffer_config_t outputCfg;;
+} effect_config_t;
+
+
+// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM
+// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command.
+// psize and vsize represent the actual size of parameter and value.
+//
+// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
+//
+// +-----------+
+// | status | sizeof(int)
+// +-----------+
+// | psize | sizeof(int)
+// +-----------+
+// | vsize | sizeof(int)
+// +-----------+
+// | | | |
+// ~ parameter ~ > psize |
+// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int)
+// +-----------+ |
+// | padding | |
+// +-----------+
+// | | |
+// ~ value ~ > vsize
+// | | |
+// +-----------+
+
+typedef struct effect_param_s {
+ int32_t status; // Transaction status (unused for command, used for reply)
+ uint32_t psize; // Parameter size
+ uint32_t vsize; // Value size
+ char data[]; // Start of Parameter + Value data
+} effect_param_t;
+
+
+/////////////////////////////////////////////////
+// Effect library interface
+/////////////////////////////////////////////////
+
+// An effect library is required to implement and expose the following functions
+// to enable effect enumeration and instantiation. The name of these functions must be as
+// specified here as the effect framework will get the function address with dlsym():
+//
+// - effect_QueryNumberEffects_t EffectQueryNumberEffects;
+// - effect_QueryEffect_t EffectQueryEffect;
+// - effect_CreateEffect_t EffectCreate;
+// - effect_ReleaseEffect_t EffectRelease;
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectQueryNumberEffects
+//
+// Description: Returns the number of different effects exposed by the
+// library. Each effect must have a unique effect uuid (see
+// effect_descriptor_t). This function together with EffectQueryEffect()
+// is used to enumerate all effects present in the library.
+//
+// Input/Output:
+// pNumEffects: address where the number of effects should be returned.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV library failed to initialize
+// -EINVAL invalid pNumEffects
+// *pNumEffects: updated with number of effects in library
+//
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectQueryEffect
+//
+// Description: Returns the descriptor of the effect engine which index is
+// given as first argument.
+// See effect_descriptor_t for details on effect descriptors.
+// This function together with EffectQueryNumberEffects() is used to enumerate all
+// effects present in the library. The enumeration sequence is:
+// EffectQueryNumberEffects(&num_effects);
+// for (i = 0; i < num_effects; i++)
+// EffectQueryEffect(i,...);
+//
+// Input/Output:
+// index: index of the effect
+// pDescriptor: address where to return the effect descriptor.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV library failed to initialize
+// -EINVAL invalid pDescriptor or index
+// -ENOSYS effect list has changed since last execution of
+// EffectQueryNumberEffects()
+// -ENOENT no more effect available
+// *pDescriptor: updated with the effect descriptor.
+//
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_QueryEffect_t)(uint32_t index,
+ effect_descriptor_t *pDescriptor);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectCreate
+//
+// Description: Creates an effect engine of the specified type and returns an
+// effect control interface on this engine. The function will allocate the
+// resources for an instance of the requested effect engine and return
+// a handle on the effect control interface.
+//
+// Input:
+// uuid: pointer to the effect uuid.
+// sessionId: audio session to which this effect instance will be attached. All effects
+// created with the same session ID are connected in series and process the same signal
+// stream. Knowing that two effects are part of the same effect chain can help the
+// library implement some kind of optimizations.
+// ioId: identifies the output or input stream this effect is directed to at audio HAL.
+// For future use especially with tunneled HW accelerated effects
+//
+// Input/Output:
+// pInterface: address where to return the effect interface.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV library failed to initialize
+// -EINVAL invalid pEffectUuid or pInterface
+// -ENOENT no effect with this uuid found
+// *pInterface: updated with the effect interface handle.
+//
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid,
+ int32_t sessionId,
+ int32_t ioId,
+ effect_interface_t *pInterface);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectRelease
+//
+// Description: Releases the effect engine whose handle is given as argument.
+// All resources allocated to this particular instance of the effect are
+// released.
+//
+// Input:
+// interface: handle on the effect interface to be released.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV library failed to initialize
+// -EINVAL invalid interface handle
+//
+////////////////////////////////////////////////////////////////////////////////
+typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface);
+
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTAPI_H_*/
diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h
new file mode 100644
index 0000000..75f8d78
--- /dev/null
+++ b/include/media/EffectBassBoostApi.h
@@ -0,0 +1,43 @@
+/*
+ * 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_EFFECTBASSBOOSTAPI_H_
+#define ANDROID_EFFECTBASSBOOSTAPI_H_
+
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
+#endif //OPENSL_ES_H_
+
+/* enumerated parameter settings for BassBoost effect */
+typedef enum
+{
+ BASSBOOST_PARAM_STRENGTH_SUPPORTED,
+ BASSBOOST_PARAM_STRENGTH
+} t_bassboost_params;
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTBASSBOOSTAPI_H_*/
diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h
new file mode 100644
index 0000000..2233e3f
--- /dev/null
+++ b/include/media/EffectEnvironmentalReverbApi.h
@@ -0,0 +1,69 @@
+/*
+ * 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_EFFECTENVIRONMENTALREVERBAPI_H_
+#define ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_
+
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } };
+const effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_;
+#endif //OPENSL_ES_H_
+
+/* enumerated parameter settings for environmental reverb effect */
+typedef enum
+{
+ // Parameters below are as defined in OpenSL ES specification for environmental reverb interface
+ REVERB_PARAM_ROOM_LEVEL, // in millibels, range -6000 to 0
+ REVERB_PARAM_ROOM_HF_LEVEL, // in millibels, range -4000 to 0
+ REVERB_PARAM_DECAY_TIME, // in milliseconds, range 100 to 20000
+ REVERB_PARAM_DECAY_HF_RATIO, // in permilles, range 100 to 1000
+ REVERB_PARAM_REFLECTIONS_LEVEL, // in millibels, range -6000 to 0
+ REVERB_PARAM_REFLECTIONS_DELAY, // in milliseconds, range 0 to 65
+ REVERB_PARAM_REVERB_LEVEL, // in millibels, range -6000 to 0
+ REVERB_PARAM_REVERB_DELAY, // in milliseconds, range 0 to 65
+ REVERB_PARAM_DIFFUSION, // in permilles, range 0 to 1000
+ REVERB_PARAM_DENSITY, // in permilles, range 0 to 1000
+ REVERB_PARAM_PROPERTIES,
+ REVERB_PARAM_BYPASS
+} t_env_reverb_params;
+
+//t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
+typedef struct s_reverb_settings {
+ int16_t roomLevel;
+ int16_t roomHFLevel;
+ int32_t decayTime;
+ int16_t decayHFRatio;
+ int16_t reflectionsLevel;
+ int32_t reflectionsDelay;
+ int16_t reverbLevel;
+ int32_t reverbDelay;
+ int16_t diffusion;
+ int16_t density;
+} __attribute__((packed)) t_reverb_settings;
+
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_*/
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
new file mode 100644
index 0000000..0492ea0
--- /dev/null
+++ b/include/media/EffectEqualizerApi.h
@@ -0,0 +1,58 @@
+/*
+ * 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_EFFECTEQUALIZERAPI_H_
+#define ANDROID_EFFECTEQUALIZERAPI_H_
+
+#include <media/EffectApi.h>
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
+#endif //OPENSL_ES_H_
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/* enumerated parameters for Equalizer effect */
+typedef enum
+{
+ EQ_PARAM_NUM_BANDS, // Gets the number of frequency bands that the equalizer supports.
+ EQ_PARAM_LEVEL_RANGE, // Returns the minimum and maximum band levels supported.
+ EQ_PARAM_BAND_LEVEL, // Gets/Sets the gain set for the given equalizer band.
+ EQ_PARAM_CENTER_FREQ, // Gets the center frequency of the given band.
+ EQ_PARAM_BAND_FREQ_RANGE, // Gets the frequency range of the given frequency band.
+ EQ_PARAM_GET_BAND, // Gets the band that has the most effect on the given frequency.
+ EQ_PARAM_CUR_PRESET, // Gets/Sets the current preset.
+ EQ_PARAM_GET_NUM_OF_PRESETS, // Gets the total number of presets the equalizer supports.
+ EQ_PARAM_GET_PRESET_NAME, // Gets the preset name based on the index.
+ EQ_PARAM_PROPERTIES // Gets/Sets all parameters at a time.
+} t_equalizer_params;
+
+//t_equalizer_settings groups all current equalizer setting for backup and restore.
+typedef struct s_equalizer_settings {
+ uint16_t curPreset;
+ uint16_t numBands;
+ uint16_t bandLevels[];
+} t_equalizer_settings;
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTEQUALIZERAPI_H_*/
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
new file mode 100644
index 0000000..53205bb
--- /dev/null
+++ b/include/media/EffectPresetReverbApi.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTPRESETREVERBAPI_H_
+#define ANDROID_EFFECTPRESETREVERBAPI_H_
+
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_;
+#endif //OPENSL_ES_H_
+
+/* enumerated parameter settings for preset reverb effect */
+typedef enum
+{
+ REVERB_PARAM_PRESET
+} t_preset_reverb_params;
+
+
+typedef enum
+{
+ REVERB_PRESET_NONE,
+ REVERB_PRESET_SMALLROOM,
+ REVERB_PRESET_MEDIUMROOM,
+ REVERB_PRESET_LARGEROOM,
+ REVERB_PRESET_MEDIUMHALL,
+ REVERB_PRESET_LARGEHALL,
+ REVERB_PRESET_PLATE
+} t_reverb_presets;
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTPRESETREVERBAPI_H_*/
diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h
new file mode 100644
index 0000000..c3d5131
--- /dev/null
+++ b/include/media/EffectVirtualizerApi.h
@@ -0,0 +1,43 @@
+/*
+ * 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_EFFECTVIRTUALIZERAPI_H_
+#define ANDROID_EFFECTVIRTUALIZERAPI_H_
+
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
+#endif //OPENSL_ES_H_
+
+/* enumerated parameter settings for virtualizer effect */
+typedef enum
+{
+ VIRTUALIZER_PARAM_STRENGTH_SUPPORTED,
+ VIRTUALIZER_PARAM_STRENGTH
+} t_virtualizer_params;
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTVIRTUALIZERAPI_H_*/
diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h
new file mode 100644
index 0000000..bef1a4f
--- /dev/null
+++ b/include/media/EffectVisualizerApi.h
@@ -0,0 +1,56 @@
+/*
+ * 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_EFFECTVISUALIZERAPI_H_
+#define ANDROID_EFFECTVISUALIZERAPI_H_
+
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_VISUALIZATION_ =
+ { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_;
+#endif //OPENSL_ES_H_
+
+#define VISUALIZER_CAPTURE_SIZE_MAX 1024 // maximum capture size in samples
+#define VISUALIZER_CAPTURE_SIZE_MIN 128 // minimum capture size in samples
+
+/* enumerated parameters for Visualizer effect */
+typedef enum
+{
+ VISU_PARAM_CAPTURE_SIZE, // Sets the number PCM samples in the capture.
+} t_visualizer_params;
+
+/* commands */
+typedef enum
+{
+ VISU_CMD_CAPTURE = EFFECT_CMD_FIRST_PROPRIETARY, // Gets the latest PCM capture.
+}t_visualizer_cmds;
+
+// VISU_CMD_CAPTURE retrieves the latest PCM snapshot captured by the visualizer engine.
+// It returns the number of samples specified by VISU_PARAM_CAPTURE_SIZE
+// in 8 bit unsigned format (0 = 0x80)
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTVISUALIZERAPI_H_*/
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
new file mode 100644
index 0000000..0ed1a14
--- /dev/null
+++ b/include/media/EffectsFactoryApi.h
@@ -0,0 +1,221 @@
+/*
+ * 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_EFFECTSFACTORYAPI_H_
+#define ANDROID_EFFECTSFACTORYAPI_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <media/EffectApi.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/////////////////////////////////////////////////
+// Effect factory interface
+/////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectQueryNumberEffects
+//
+// Description: Returns the number of different effects in all loaded libraries.
+// Each effect must have a different effect uuid (see
+// effect_descriptor_t). This function together with EffectQueryEffect()
+// is used to enumerate all effects present in all loaded libraries.
+// Each time EffectQueryNumberEffects() is called, the factory must
+// reset the index of the effect descriptor returned by next call to
+// EffectQueryEffect() to restart enumeration from the beginning.
+//
+// Input/Output:
+// pNumEffects: address where the number of effects should be returned.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pNumEffects
+// *pNumEffects: updated with number of effects in factory
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectQueryNumberEffects(uint32_t *pNumEffects);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectQueryEffect
+//
+// Description: Returns a descriptor of the next available effect.
+// See effect_descriptor_t for a details on effect descriptor.
+// This function together with EffectQueryNumberEffects() is used to enumerate all
+// effects present in all loaded libraries. The enumeration sequence is:
+// EffectQueryNumberEffects(&num_effects);
+// for (i = 0; i < num_effects; i++)
+// EffectQueryEffect(i,...);
+//
+// Input/Output:
+// pDescriptor: address where to return the effect descriptor.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENOENT no more effect available
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pDescriptor
+// -ENOSYS effect list has changed since last execution of EffectQueryNumberEffects()
+// *pDescriptor: updated with the effect descriptor.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectCreate
+//
+// Description: Creates an effect engine of the specified type and returns an
+// effect control interface on this engine. The function will allocate the
+// resources for an instance of the requested effect engine and return
+// a handler on the effect control interface.
+//
+// Input:
+// pEffectUuid: pointer to the effect uuid.
+// sessionId: audio session to which this effect instance will be attached. All effects created
+// with the same session ID are connected in series and process the same signal stream.
+// Knowing that two effects are part of the same effect chain can help the library implement
+// some kind of optimizations.
+// ioId: identifies the output or input stream this effect is directed to at audio HAL. For future
+// use especially with tunneled HW accelerated effects
+//
+// Input/Output:
+// pInterface: address where to return the effect interface.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pEffectUuid or pInterface
+// -ENOENT no effect with this uuid found
+// *pInterface: updated with the effect interface.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectRelease
+//
+// Description: Releases the effect engine whose handler is given as argument.
+// All resources allocated to this particular instance of the effect are
+// released.
+//
+// Input:
+// interface: handler on the effect interface to be released.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid interface handler
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectRelease(effect_interface_t interface);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectLoadLibrary
+//
+// Description: Loads the effect library which path is given as first argument.
+// This must be the full path of a dynamic library (.so) implementing one or
+// more effect engines and exposing the effect library interface described in
+// EffectApi.h. The function returns a handle on the library for used by
+// further call to EffectUnloadLibrary() to unload the library.
+//
+// Input:
+// libPath: full path of the dynamic library file in the file system.
+//
+// handle: address where to return the library handle
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV effect factory not initialized or
+// library could not be loaded or
+// library does not implement required functions
+// -EINVAL invalid libPath string or handle
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectLoadLibrary(const char *libPath, int *handle);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectUnloadLibrary
+//
+// Description: Unloads the effect library which handle is given as argument.
+//
+// Input:
+// handle: library handle
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV effect factory not initialized
+// -ENOENT invalid handle
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectUnloadLibrary(int handle);
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectGetDescriptor
+//
+// Description: Returns the descriptor of the effect which uuid is pointed
+// to by first argument.
+//
+// Input:
+// pEffectUuid: pointer to the effect uuid.
+//
+// Input/Output:
+// pDescriptor: address where to return the effect descriptor.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pEffectUuid or pDescriptor
+// -ENOENT no effect with this uuid found
+// *pDescriptor: updated with the effect descriptor.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectGetDescriptor(effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectIsNullUuid
+//
+// Description: Helper function to compare effect uuid to EFFECT_UUID_NULL
+//
+// Input:
+// pEffectUuid: pointer to effect uuid to compare to EFFECT_UUID_NULL.
+//
+// Output:
+// returned value: 0 if uuid is different from EFFECT_UUID_NULL.
+// 1 if uuid is equal to EFFECT_UUID_NULL.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectIsNullUuid(effect_uuid_t *pEffectUuid);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTSFACTORYAPI_H_*/
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index c147632..70e505e 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -27,6 +27,9 @@
#include <media/IAudioTrack.h>
#include <media/IAudioRecord.h>
#include <media/IAudioFlingerClient.h>
+#include <media/EffectApi.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
#include <utils/String8.h>
namespace android {
@@ -51,6 +54,7 @@ public:
uint32_t flags,
const sp<IMemory>& sharedBuffer,
int output,
+ int *sessionId,
status_t *status) = 0;
virtual sp<IAudioRecord> openRecord(
@@ -61,6 +65,7 @@ public:
int channelCount,
int frameCount,
uint32_t flags,
+ int *sessionId,
status_t *status) = 0;
/* query the audio hardware state. This state never changes,
@@ -134,6 +139,30 @@ public:
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0;
virtual unsigned int getInputFramesLost(int ioHandle) = 0;
+
+ virtual int newAudioSessionId() = 0;
+
+ virtual status_t loadEffectLibrary(const char *libPath, int *handle) = 0;
+
+ virtual status_t unloadEffectLibrary(int handle) = 0;
+
+ virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
+
+ virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
+
+ virtual status_t getEffectDescriptor(effect_uuid_t *pEffectUUID, effect_descriptor_t *pDescriptor) = 0;
+
+ virtual sp<IEffect> createEffect(pid_t pid,
+ effect_descriptor_t *pDesc,
+ const sp<IEffectClient>& client,
+ int32_t priority,
+ int output,
+ int sessionId,
+ status_t *status,
+ int *id,
+ int *enabled) = 0;
+
+ virtual status_t moveEffects(int session, int srcOutput, int dstOutput) = 0;
};
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 4804bbd..49eee59 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -53,8 +53,12 @@ public:
uint32_t format = AudioSystem::FORMAT_DEFAULT,
uint32_t channels = 0,
AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT) = 0;
- virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0;
- virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0;
+ virtual status_t startOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0) = 0;
+ virtual status_t stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0) = 0;
virtual void releaseOutput(audio_io_handle_t output) = 0;
virtual audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
@@ -69,6 +73,14 @@ public:
int indexMax) = 0;
virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) = 0;
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) = 0;
+ virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
+ virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0;
+ virtual status_t registerEffect(effect_descriptor_t *desc,
+ audio_io_handle_t output,
+ uint32_t strategy,
+ int session,
+ int id) = 0;
+ virtual status_t unregisterEffect(int id) = 0;
};
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index de6426a..47d530b 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -62,6 +62,11 @@ public:
*/
virtual void pause() = 0;
+ /* Attach track auxiliary output to specified effect. Use effectId = 0
+ * to detach track from effect.
+ */
+ virtual status_t attachAuxEffect(int effectId) = 0;
+
/* get this tracks control block */
virtual sp<IMemory> getCblk() const = 0;
};
diff --git a/include/media/IEffect.h b/include/media/IEffect.h
new file mode 100644
index 0000000..ff04869
--- /dev/null
+++ b/include/media/IEffect.h
@@ -0,0 +1,60 @@
+/*
+ * 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_IEFFECT_H
+#define ANDROID_IEFFECT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+
+namespace android {
+
+class IEffect: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(Effect);
+
+ virtual status_t enable() = 0;
+
+ virtual status_t disable() = 0;
+
+ virtual status_t command(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t *pReplySize,
+ void *pReplyData) = 0;
+
+ virtual void disconnect() = 0;
+
+ virtual sp<IMemory> getCblk() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnEffect: public BnInterface<IEffect>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IEFFECT_H
diff --git a/include/media/IEffectClient.h b/include/media/IEffectClient.h
new file mode 100644
index 0000000..2f78c98
--- /dev/null
+++ b/include/media/IEffectClient.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IEFFECTCLIENT_H
+#define ANDROID_IEFFECTCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+
+namespace android {
+
+class IEffectClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(EffectClient);
+
+ virtual void controlStatusChanged(bool controlGranted) = 0;
+ virtual void enableStatusChanged(bool enabled) = 0;
+ virtual void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnEffectClient: public BnInterface<IEffectClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IEFFECTCLIENT_H
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 2619691..af9a7ed 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -48,6 +48,8 @@ public:
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;
// Invoke a generic method on the player by using opaque parcels
// for the request and reply.
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 31c0991..9416ca1 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -40,15 +40,14 @@ public:
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
+ const char* url, const KeyedVector<String8, String8> *headers = NULL,
+ 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<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;
-
- // Take a peek at currently playing audio, for visualization purposes.
- // This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available.
- virtual sp<IMemory> snoop() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index 73bf2ee..54adca8 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -24,7 +24,7 @@ namespace android {
class ISurface;
class ICamera;
-class IMediaPlayerClient;
+class IMediaRecorderClient;
class IMediaRecorder: public IInterface
{
@@ -43,7 +43,7 @@ public:
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;
- virtual status_t setListener(const sp<IMediaPlayerClient>& listener) = 0;
+ virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
virtual status_t prepare() = 0;
virtual status_t getMaxAmplitude(int* max) = 0;
virtual status_t start() = 0;
diff --git a/include/media/IMediaRecorderClient.h b/include/media/IMediaRecorderClient.h
new file mode 100644
index 0000000..0058ef2
--- /dev/null
+++ b/include/media/IMediaRecorderClient.h
@@ -0,0 +1,48 @@
+/*
+ * 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_IMEDIARECORDERCLIENT_H
+#define ANDROID_IMEDIARECORDERCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMediaRecorderClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaRecorderClient);
+
+ virtual void notify(int msg, int ext1, int ext2) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaRecorderClient: public BnInterface<IMediaRecorderClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIARECORDERCLIENT_H
+
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 9e606d9..3662983 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -39,7 +39,6 @@ template<typename T> class SortedVector;
enum player_type {
PV_PLAYER = 1,
SONIVOX_PLAYER = 2,
- VORBIS_PLAYER = 3,
STAGEFRIGHT_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
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index a4eea2a..c3cd361 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -48,8 +48,8 @@ public:
static MediaProfiles* getInstance();
/**
- * Returns the value for the given param name at the given quality level,
- * or -1 if error.
+ * Returns the value for the given param name for the given camera at
+ * the given quality level, or -1 if error.
*
* Supported param name are:
* duration - the recording duration.
@@ -64,7 +64,8 @@ public:
* aud.hz - audio sample rate
* aud.ch - number of audio channels
*/
- int getCamcorderProfileParamByName(const char *name, camcorder_quality quality) const;
+ int getCamcorderProfileParamByName(const char *name, int cameraId,
+ camcorder_quality quality) const;
/**
* Returns the output file formats supported.
@@ -124,12 +125,7 @@ public:
/**
* Returns the number of image encoding quality levels supported.
*/
- Vector<int> getImageEncodingQualityLevels() const;
-
- /**
- * Returns the maximum amount of memory in bytes we can use for decoding a JPEG file.
- */
- int getImageDecodingMaxMemory() const;
+ Vector<int> getImageEncodingQualityLevels(int cameraId) const;
private:
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
@@ -171,7 +167,8 @@ private:
struct CamcorderProfile {
CamcorderProfile()
- : mFileFormat(OUTPUT_FORMAT_THREE_GPP),
+ : mCameraId(0),
+ mFileFormat(OUTPUT_FORMAT_THREE_GPP),
mQuality(CAMCORDER_QUALITY_HIGH),
mDuration(0),
mVideoCodec(0),
@@ -182,6 +179,7 @@ private:
delete mAudioCodec;
}
+ int mCameraId;
output_format mFileFormat;
camcorder_quality mQuality;
int mDuration;
@@ -249,6 +247,11 @@ private:
int tag;
};
+ struct ImageEncodingQualityLevels {
+ int mCameraId;
+ Vector<int> mLevels;
+ };
+
// Debug
static void logVideoCodec(const VideoCodec& codec);
static void logAudioCodec(const AudioCodec& codec);
@@ -267,9 +270,11 @@ private:
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
- static CamcorderProfile* createCamcorderProfile(const char **atts);
- static int getImageEncodingQualityLevel(const char **atts);
- static int getImageDecodingMaxMemory(const char **atts);
+ static CamcorderProfile* createCamcorderProfile(int cameraId, const char **atts);
+ static int getCameraId(const char **atts);
+
+ ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
+ void addImageEncodingQualityLevel(int cameraId, const char** atts);
// Customized element tag handler for parsing the xml configuration file.
static void startElementHandler(void *userData, const char *name, const char **atts);
@@ -303,6 +308,7 @@ private:
static bool sIsInitialized;
static MediaProfiles *sInstance;
static Mutex sLock;
+ int mCurrentCameraId;
Vector<CamcorderProfile*> mCamcorderProfiles;
Vector<AudioEncoderCap*> mAudioEncoders;
@@ -310,8 +316,7 @@ private:
Vector<AudioDecoderCap*> mAudioDecoders;
Vector<VideoDecoderCap*> mVideoDecoders;
Vector<output_format> mEncoderOutputFileFormats;
- Vector<int> mImageEncodingQualityLevels;
- int mImageDecodingMaxMemory;
+ Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
};
}; // namespace android
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index 5b787a7..5e9e368 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -41,13 +41,14 @@ struct MediaRecorderBase {
virtual status_t setOutputFile(const char *path) = 0;
virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
virtual status_t setParameters(const String8& params) = 0;
- virtual status_t setListener(const sp<IMediaPlayerClient>& listener) = 0;
+ virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
virtual status_t prepare() = 0;
virtual status_t start() = 0;
virtual status_t stop() = 0;
virtual status_t close() = 0;
virtual status_t reset() = 0;
virtual status_t getMaxAmplitude(int *max) = 0;
+ virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
private:
MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/PVMediaRecorder.h b/include/media/PVMediaRecorder.h
index 2a1298a..c091c39 100644
--- a/include/media/PVMediaRecorder.h
+++ b/include/media/PVMediaRecorder.h
@@ -18,7 +18,7 @@
#ifndef ANDROID_PVMEDIARECORDER_H
#define ANDROID_PVMEDIARECORDER_H
-#include <media/IMediaPlayerClient.h>
+#include <media/IMediaRecorderClient.h>
#include <media/MediaRecorderBase.h>
namespace android {
@@ -45,13 +45,14 @@ public:
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<IMediaPlayerClient>& listener);
+ 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();
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
new file mode 100644
index 0000000..5d51de8
--- /dev/null
+++ b/include/media/Visualizer.h
@@ -0,0 +1,160 @@
+/*
+ * 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_MEDIA_VISUALIZER_H
+#define ANDROID_MEDIA_VISUALIZER_H
+
+#include <media/AudioEffect.h>
+#include <media/EffectVisualizerApi.h>
+#include <string.h>
+
+/**
+ * The Visualizer class enables application to retrieve part of the currently playing audio for
+ * visualization purpose. It is not an audio recording interface and only returns partial and low
+ * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
+ * of the visualizer requires the permission android.permission.RECORD_AUDIO.
+ * The audio session ID passed to the constructor indicates which audio content should be
+ * visualized:
+ * - If the session is 0, the audio output mix is visualized
+ * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack
+ * using this audio session is visualized
+ * Two types of representation of audio content can be captured:
+ * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method
+ * - Frequency data: 8-bit magnitude FFT by using the getFft() method
+ *
+ * The length of the capture can be retrieved or specified by calling respectively
+ * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT
+ * is half of the specified capture size but both sides of the spectrum are returned yielding in a
+ * number of bytes equal to the capture size. The capture size must be a power of 2 in the range
+ * returned by getMinCaptureSize() and getMaxCaptureSize().
+ * In addition to the polling capture mode, a callback mode is also available by installing a
+ * callback function by use of the setCaptureCallBack() method. The rate at which the callback
+ * is called as well as the type of data returned is specified.
+ * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method.
+ * When data capture is not needed any more, the Visualizer should be disabled.
+ */
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class Visualizer: public AudioEffect {
+public:
+
+ enum callback_flags {
+ CAPTURE_WAVEFORM = 0x00000001, // capture callback returns a PCM wave form
+ CAPTURE_FFT = 0x00000002, // apture callback returns a frequency representation
+ CAPTURE_CALL_JAVA = 0x00000004 // the callback thread can call java
+ };
+
+
+ /* Constructor.
+ * See AudioEffect constructor for details on parameters.
+ */
+ Visualizer(int32_t priority = 0,
+ effect_callback_t cbf = 0,
+ void* user = 0,
+ int sessionId = 0);
+
+ ~Visualizer();
+
+ virtual status_t setEnabled(bool enabled);
+
+ // maximum capture size in samples
+ static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
+ // minimum capture size in samples
+ static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; }
+ // maximum capture rate in millihertz
+ static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; }
+
+ // callback used to return periodic PCM or FFT captures to the application. Either one or both
+ // types of data are returned (PCM and FFT) according to flags indicated when installing the
+ // callback. When a type of data is not present, the corresponding size (waveformSize or
+ // fftSize) is 0.
+ typedef void (*capture_cbk_t)(void* user,
+ uint32_t waveformSize,
+ uint8_t *waveform,
+ uint32_t fftSize,
+ uint8_t *fft,
+ uint32_t samplingrate);
+
+ // install a callback to receive periodic captures. The capture rate is specified in milliHertz
+ // and the capture format is according to flags (see callback_flags).
+ status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate);
+
+ // set the capture size capture size must be a power of two in the range
+ // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN]
+ // must be called when the visualizer is not enabled
+ status_t setCaptureSize(uint32_t size);
+ uint32_t getCaptureSize() { return mCaptureSize; }
+
+ // returns the capture rate indicated when installing the callback
+ uint32_t getCaptureRate() { return mCaptureRate; }
+
+ // returns the sampling rate of the audio being captured
+ uint32_t getSamplingRate() { return mSampleRate; }
+
+ // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
+ // getCaptureSize()
+ status_t getWaveForm(uint8_t *waveform);
+
+ // return a capture in FFT 8 bit signed format. The size of the capture is equal to
+ // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum
+ // are returned
+ status_t getFft(uint8_t *fft);
+
+private:
+
+ static const uint32_t CAPTURE_RATE_MAX = 20000;
+ static const uint32_t CAPTURE_RATE_DEF = 10000;
+ static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX;
+
+ /* internal class to handle the callback */
+ class CaptureThread : public Thread
+ {
+ public:
+ CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false);
+
+ private:
+ friend class Visualizer;
+ virtual bool threadLoop();
+ virtual status_t readyToRun();
+ virtual void onFirstRef();
+ Visualizer& mReceiver;
+ Mutex mLock;
+ uint32_t mSleepTimeUs;
+ };
+
+ status_t doFft(uint8_t *fft, uint8_t *waveform);
+ void periodicCapture();
+ uint32_t initCaptureSize();
+
+ Mutex mLock;
+ uint32_t mCaptureRate;
+ uint32_t mCaptureSize;
+ uint32_t mSampleRate;
+ capture_cbk_t mCaptureCallBack;
+ void *mCaptureCbkUser;
+ sp<CaptureThread> mCaptureThread;
+ uint32_t mCaptureFlags;
+ void *mFftTable;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_MEDIA_VISUALIZER_H
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 7fad1b7..207191d 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -93,6 +93,11 @@ enum media_info_type {
// The video is too complex for the decoder: it can't decode frames fast
// enough. Possibly only the audio plays fine at this stage.
MEDIA_INFO_VIDEO_TRACK_LAGGING = 700,
+ // MediaPlayer is temporarily pausing playback internally in order to
+ // buffer more data.
+ MEDIA_INFO_BUFFERING_START = 701,
+ // MediaPlayer is resuming playback after filling buffers.
+ MEDIA_INFO_BUFFERING_END = 702,
// 8xx
// Bad interleaving means that a media has been improperly interleaved or not
// interleaved at all, e.g has all the video samples first then all the audio
@@ -161,12 +166,15 @@ public:
void notify(int msg, int ext1, int ext2);
static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
- static int snoop(short *data, int len, int kind);
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);
+ status_t attachAuxEffect(int effectId);
private:
void clear_l();
status_t seekTo_l(int msec);
@@ -193,6 +201,8 @@ private:
float mRightVolume;
int mVideoWidth;
int mVideoHeight;
+ int mAudioSessionId;
+ float mSendLevel;
};
}; // namespace android
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 9ea6c7b..291b18a 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -22,7 +22,7 @@
#include <utils/threads.h>
#include <utils/List.h>
#include <utils/Errors.h>
-#include <media/IMediaPlayerClient.h>
+#include <media/IMediaRecorderClient.h>
#include <media/IMediaDeathNotifier.h>
namespace android {
@@ -73,6 +73,9 @@ enum output_format {
OUTPUT_FORMAT_AAC_ADIF = 5,
OUTPUT_FORMAT_AAC_ADTS = 6,
+ /* Stream over a socket, limited to a single stream */
+ OUTPUT_FORMAT_RTP_AVP = 7,
+
OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
};
@@ -135,7 +138,10 @@ enum media_recorder_error_type {
enum media_recorder_info_type {
MEDIA_RECORDER_INFO_UNKNOWN = 1,
MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800,
- MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801
+ MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801,
+ MEDIA_RECORDER_INFO_COMPLETION_STATUS = 802,
+ MEDIA_RECORDER_INFO_PROGRESS_FRAME_STATUS = 803,
+ MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS = 804,
};
// ----------------------------------------------------------------------------
@@ -146,7 +152,7 @@ public:
virtual void notify(int msg, int ext1, int ext2) = 0;
};
-class MediaRecorder : public BnMediaPlayerClient,
+class MediaRecorder : public BnMediaRecorderClient,
public virtual IMediaDeathNotifier
{
public:
diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h
index 372909a..813dd43 100644
--- a/include/media/stagefright/AMRWriter.h
+++ b/include/media/stagefright/AMRWriter.h
@@ -26,6 +26,7 @@
namespace android {
struct MediaSource;
+struct MetaData;
struct AMRWriter : public MediaWriter {
AMRWriter(const char *filename);
@@ -35,25 +36,30 @@ struct AMRWriter : public MediaWriter {
virtual status_t addSource(const sp<MediaSource> &source);
virtual bool reachedEOS();
- virtual status_t start();
+ virtual status_t start(MetaData *params = NULL);
virtual void stop();
+ virtual void pause();
protected:
virtual ~AMRWriter();
private:
- Mutex mLock;
-
FILE *mFile;
status_t mInitCheck;
sp<MediaSource> mSource;
bool mStarted;
+ volatile bool mPaused;
+ volatile bool mResumed;
volatile bool mDone;
- bool mReachedEOS;
+ volatile bool mReachedEOS;
pthread_t mThread;
+ int64_t mEstimatedSizeBytes;
+ int64_t mEstimatedDurationUs;
static void *ThreadWrapper(void *);
void threadFunc();
+ bool exceedsFileSizeLimit();
+ bool exceedsFileDurationLimit();
AMRWriter(const AMRWriter &);
AMRWriter &operator=(const AMRWriter &);
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index eb00140..2597e9e 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -39,6 +39,9 @@ struct AudioSource : public MediaSource {
virtual status_t stop();
virtual sp<MetaData> getFormat();
+ // Returns the maximum amplitude since last call.
+ int16_t getMaxAmplitude();
+
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
@@ -46,13 +49,24 @@ protected:
virtual ~AudioSource();
private:
- enum { kMaxBufferSize = 8192 };
+ enum { kMaxBufferSize = 2048 };
AudioRecord *mRecord;
status_t mInitCheck;
bool mStarted;
+
+ bool mCollectStats;
+ bool mTrackMaxAmplitude;
+ int64_t mStartTimeUs;
+ int16_t mMaxAmplitude;
+ int64_t mPrevSampleTimeUs;
+ int64_t mTotalLostFrames;
+ int64_t mPrevLostBytes;
+
MediaBufferGroup *mGroup;
+ void trackMaxAmplitude(int16_t *data, int nSamples);
+
AudioSource(const AudioSource &);
AudioSource &operator=(const AudioSource &);
};
diff --git a/include/media/stagefright/CachingDataSource.h b/include/media/stagefright/CachingDataSource.h
deleted file mode 100644
index 42d50e5..0000000
--- a/include/media/stagefright/CachingDataSource.h
+++ /dev/null
@@ -1,66 +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 CACHING_DATASOURCE_H_
-
-#define CACHING_DATASOURCE_H_
-
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class CachingDataSource : public DataSource {
-public:
- CachingDataSource(
- const sp<DataSource> &source, size_t pageSize, int numPages);
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off_t offset, void *data, size_t size);
-
- virtual status_t getSize(off_t *size);
-
- virtual uint32_t flags();
-
-protected:
- virtual ~CachingDataSource();
-
-private:
- struct Page {
- Page *mPrev, *mNext;
- off_t mOffset;
- size_t mLength;
- void *mData;
- };
-
- sp<DataSource> mSource;
- void *mData;
- size_t mPageSize;
- Page *mFirst, *mLast;
-
- Page *allocate_page();
-
- Mutex mLock;
-
- CachingDataSource(const CachingDataSource &);
- CachingDataSource &operator=(const CachingDataSource &);
-};
-
-} // namespace android
-
-#endif // CACHING_DATASOURCE_H_
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index ea435de..3192d03 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -28,18 +28,15 @@ namespace android {
class ICamera;
class IMemory;
-class ISurface;
class Camera;
-class CameraSource : public MediaSource {
+class CameraSource : public MediaSource, public MediaBufferObserver {
public:
static CameraSource *Create();
- static CameraSource *CreateFromICamera(const sp<ICamera> &icamera);
+ static CameraSource *CreateFromCamera(const sp<Camera> &camera);
virtual ~CameraSource();
- void setPreviewSurface(const sp<ISurface> &surface);
-
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
@@ -48,25 +45,39 @@ public:
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+
private:
friend class CameraSourceListener;
sp<Camera> mCamera;
- sp<ISurface> mPreviewSurface;
+ sp<MetaData> mMeta;
Mutex mLock;
Condition mFrameAvailableCondition;
- List<sp<IMemory> > mFrames;
+ Condition mFrameCompleteCondition;
+ List<sp<IMemory> > mFramesReceived;
+ List<sp<IMemory> > mFramesBeingEncoded;
List<int64_t> mFrameTimes;
- int mWidth, mHeight;
+ int64_t mStartTimeUs;
int64_t mFirstFrameTimeUs;
- int32_t mNumFrames;
+ 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 dataCallback(int32_t msgType, const sp<IMemory> &data);
+ void dataCallbackTimestamp(
+ int64_t timestampUs, int32_t msgType, const sp<IMemory> &data);
+
+ void releaseQueuedFrames();
+ void releaseOneRecordingFrame(const sp<IMemory>& frame);
CameraSource(const CameraSource &);
CameraSource &operator=(const CameraSource &);
diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h
index 1e341b9..bc3f464 100644
--- a/include/media/stagefright/ColorConverter.h
+++ b/include/media/stagefright/ColorConverter.h
@@ -58,6 +58,11 @@ private:
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);
+
ColorConverter(const ColorConverter &);
ColorConverter &operator=(const ColorConverter &);
};
diff --git a/include/media/stagefright/HTTPDataSource.h b/include/media/stagefright/HTTPDataSource.h
deleted file mode 100644
index 0400bea..0000000
--- a/include/media/stagefright/HTTPDataSource.h
+++ /dev/null
@@ -1,103 +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 HTTP_DATASOURCE_H_
-
-#define HTTP_DATASOURCE_H_
-
-#include <media/stagefright/DataSource.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class HTTPStream;
-
-class HTTPDataSource : public DataSource {
-public:
- HTTPDataSource(
- const char *host, int port, const char *path,
- const KeyedVector<String8, String8> *headers = NULL);
-
- HTTPDataSource(
- const char *uri,
- const KeyedVector<String8, String8> *headers = NULL);
-
- status_t connect();
- void disconnect();
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off_t offset, void *data, size_t size);
-
- virtual status_t getSize(off_t *size);
-
- virtual uint32_t flags();
-
-protected:
- virtual ~HTTPDataSource();
-
-private:
- enum {
- kBufferSize = 64 * 1024,
-
- // If we encounter a socket-read error we'll try reconnecting
- // and restarting the read for at most this many times.
- kMaxNumRetries = 3,
- };
-
- enum State {
- DISCONNECTED,
- CONNECTING,
- CONNECTED
- };
-
- State mState;
- mutable Mutex mStateLock;
-
- String8 mHeaders;
-
- String8 mStartingHost;
- String8 mStartingPath;
- int mStartingPort;
-
- HTTPStream *mHttp;
-
- void *mBuffer;
- size_t mBufferLength;
- off_t mBufferOffset;
-
- bool mContentLengthValid;
- unsigned long long mContentLength;
-
- int32_t mNumRetriesLeft;
-
- void init(const KeyedVector<String8, String8> *headers);
-
- ssize_t sendRangeRequest(size_t offset);
- void initHeaders(const KeyedVector<String8, String8> *overrides);
-
- status_t connectWithRedirectsAndRange(off_t rangeStart);
- void applyTimeoutResponse();
-
- HTTPDataSource(const HTTPDataSource &);
- HTTPDataSource &operator=(const HTTPDataSource &);
-};
-
-} // namespace android
-
-#endif // HTTP_DATASOURCE_H_
-
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 6b93f19..be96935 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -36,9 +36,10 @@ public:
MPEG4Writer(int fd);
virtual status_t addSource(const sp<MediaSource> &source);
- virtual status_t start();
+ virtual status_t start(MetaData *param = NULL);
virtual bool reachedEOS();
virtual void stop();
+ virtual void pause();
void beginBox(const char *fourcc);
void writeInt8(int8_t x);
@@ -49,6 +50,9 @@ public:
void writeFourcc(const char *fourcc);
void write(const void *data, size_t size);
void endBox();
+ uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
+ status_t setInterleaveDuration(uint32_t duration);
+ int32_t getTimeScale() const { return mTimeScale; }
protected:
virtual ~MPEG4Writer();
@@ -57,16 +61,90 @@ private:
class Track;
FILE *mFile;
+ bool mUse32BitOffset;
+ bool mPaused;
+ bool mStarted;
off_t mOffset;
off_t mMdatOffset;
+ uint8_t *mMoovBoxBuffer;
+ off_t mMoovBoxBufferOffset;
+ bool mWriteMoovBoxToMemory;
+ off_t mFreeBoxOffset;
+ bool mStreamableFile;
+ off_t mEstimatedMoovBoxSize;
+ uint32_t mInterleaveDurationUs;
+ int32_t mTimeScale;
+ int64_t mStartTimestampUs;
+
Mutex mLock;
List<Track *> mTracks;
List<off_t> mBoxes;
- off_t addSample(MediaBuffer *buffer);
- off_t addLengthPrefixedSample(MediaBuffer *buffer);
+ void setStartTimestampUs(int64_t timeUs);
+ int64_t getStartTimestampUs(); // Not const
+ status_t startTracks(MetaData *params);
+ size_t numTracks();
+ int64_t estimateMoovBoxSize(int32_t bitRate);
+
+ struct Chunk {
+ Track *mTrack; // Owner
+ int64_t mTimeStampUs; // Timestamp of the 1st sample
+ List<MediaBuffer *> mSamples; // Sample data
+
+ // Convenient constructor
+ Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples)
+ : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) {
+ }
+
+ };
+ struct ChunkInfo {
+ Track *mTrack; // Owner
+ List<Chunk> mChunks; // Remaining chunks to be written
+ };
+
+ bool mIsFirstChunk;
+ volatile bool mDone; // Writer thread is done?
+ pthread_t mThread; // Thread id for the writer
+ List<ChunkInfo> mChunkInfos; // Chunk infos
+ Condition mChunkReadyCondition; // Signal that chunks are available
+
+ // Writer thread handling
+ status_t startWriterThread();
+ void stopWriterThread();
+ static void *ThreadWrapper(void *me);
+ void threadFunc();
+
+ // Buffer a single chunk to be written out later.
+ void bufferChunk(const Chunk& chunk);
+
+ // Write all buffered chunks from all tracks
+ void writeChunks();
+
+ // Write a chunk if there is one
+ status_t writeOneChunk();
+
+ // Write the first chunk from the given ChunkInfo.
+ void writeFirstChunk(ChunkInfo* info);
+
+ // Adjust other track media clock (presumably wall clock)
+ // based on audio track media clock with the drift time.
+ int64_t mDriftTimeUs;
+ void addDriftTimeUs(int64_t driftTimeUs);
+ int64_t getDriftTimeUs();
+
+ void lock();
+ void unlock();
+
+ // Acquire lock before calling these methods
+ off_t addSample_l(MediaBuffer *buffer);
+ off_t addLengthPrefixedSample_l(MediaBuffer *buffer);
+
+ inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
+ bool exceedsFileSizeLimit();
+ bool exceedsFileDurationLimit();
+ void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
MPEG4Writer(const MPEG4Writer &);
MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 207195a..92ce068 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -22,6 +22,7 @@ namespace android {
extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
+extern const char *MEDIA_MIMETYPE_VIDEO_VPX;
extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
extern const char *MEDIA_MIMETYPE_VIDEO_H263;
@@ -33,11 +34,15 @@ extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS;
+extern const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW;
+extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
extern const char *MEDIA_MIMETYPE_CONTAINER_OGG;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS;
} // namespace android
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index 96d57e7..dafc621 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
+#include <media/stagefright/MediaErrors.h>
#include <utils/RefBase.h>
namespace android {
@@ -61,28 +62,56 @@ struct MediaSource : public RefBase {
// a) not request a seek
// b) not be late, i.e. lateness_us = 0
struct ReadOptions {
+ enum SeekMode {
+ SEEK_PREVIOUS_SYNC,
+ SEEK_NEXT_SYNC,
+ SEEK_CLOSEST_SYNC,
+ SEEK_CLOSEST,
+ };
+
ReadOptions();
// Reset everything back to defaults.
void reset();
- void setSeekTo(int64_t time_us);
+ void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
void clearSeekTo();
- bool getSeekTo(int64_t *time_us) const;
+ 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
+ // until a subsequent read-with-seek. Currently only supported by
+ // OMXCodec.
+ virtual status_t pause() {
+ return ERROR_UNSUPPORTED;
+ }
+
protected:
virtual ~MediaSource();
diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h
index b8232c6..8d3a9df 100644
--- a/include/media/stagefright/MediaWriter.h
+++ b/include/media/stagefright/MediaWriter.h
@@ -19,22 +19,41 @@
#define MEDIA_WRITER_H_
#include <utils/RefBase.h>
+#include <media/IMediaRecorderClient.h>
namespace android {
struct MediaSource;
+struct MetaData;
struct MediaWriter : public RefBase {
- MediaWriter() {}
+ MediaWriter()
+ : mMaxFileSizeLimitBytes(0),
+ mMaxFileDurationLimitUs(0) {
+ }
virtual status_t addSource(const sp<MediaSource> &source) = 0;
virtual bool reachedEOS() = 0;
- virtual status_t start() = 0;
+ virtual status_t start(MetaData *params = NULL) = 0;
virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
+ virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
+ virtual void setListener(const sp<IMediaRecorderClient>& listener) {
+ mListener = listener;
+ }
protected:
virtual ~MediaWriter() {}
+ int64_t mMaxFileSizeLimitBytes;
+ int64_t mMaxFileDurationLimitUs;
+ sp<IMediaRecorderClient> mListener;
+ void notify(int msg, int ext1, int ext2) {
+ if (mListener != NULL) {
+ mListener->notify(msg, ext1, ext2);
+ }
+ }
private:
MediaWriter(const MediaWriter &);
MediaWriter &operator=(const MediaWriter &);
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index dc2bd50..43354c2 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -30,10 +30,13 @@ namespace android {
// The following keys map to int32_t data unless indicated otherwise.
enum {
kKeyMIMEType = 'mime', // cstring
- kKeyWidth = 'widt',
- kKeyHeight = 'heig',
- kKeyChannelCount = '#chn',
- kKeySampleRate = 'srte',
+ kKeyWidth = 'widt', // int32_t
+ kKeyHeight = 'heig', // int32_t
+ kKeyIFramesInterval = 'ifiv', // int32_t
+ kKeyStride = 'strd', // int32_t
+ kKeySliceHeight = 'slht', // int32_t
+ kKeyChannelCount = '#chn', // int32_t
+ kKeySampleRate = 'srte', // int32_t (also video frame rate)
kKeyBitRate = 'brte', // int32_t (bps)
kKeyESDS = 'esds', // raw data
kKeyAVCC = 'avcc', // raw data
@@ -43,6 +46,8 @@ enum {
kKeyIsSyncFrame = 'sync', // int32_t (bool)
kKeyIsCodecConfig = 'conf', // int32_t (bool)
kKeyTime = 'time', // int64_t (usecs)
+ kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp)
+ kKeyTargetTime = 'tarT', // int64_t (usecs)
kKeyDuration = 'dura', // int64_t (usecs)
kKeyColorFormat = 'colf',
kKeyPlatformPrivate = 'priv', // pointer
@@ -65,6 +70,26 @@ enum {
kKeyDiscNumber = 'dnum', // cstring
kKeyDate = 'date', // cstring
kKeyWriter = 'writ', // cstring
+ kKeyTimeScale = 'tmsl', // int32_t
+
+ // video profile and level
+ kKeyVideoProfile = 'vprf', // int32_t
+ kKeyVideoLevel = 'vlev', // int32_t
+
+ // Set this key to enable authoring files in 64-bit offset
+ kKey64BitFileOffset = 'fobt', // int32_t (bool)
+
+ // Identify the file output format for authoring
+ // Please see <media/mediarecorder.h> for the supported
+ // file output formats.
+ kKeyFileType = 'ftyp', // int32_t
+
+ // Track authoring progress status
+ // kKeyTrackTimeStatus is used to track progress in elapsed time
+ kKeyTrackTimeStatus = 'tktm', // int64_t
+
+ kKeyNotRealTime = 'ntrt', // bool (int32_t)
+
};
enum {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 1d76a1a..010ded1 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -27,6 +27,7 @@ namespace android {
class MemoryDealer;
struct OMXCodecObserver;
+struct CodecProfileLevel;
struct OMXCodec : public MediaSource,
public MediaBufferObserver {
@@ -52,6 +53,8 @@ struct OMXCodec : public MediaSource,
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
+ virtual status_t pause();
+
void on_message(const omx_message &msg);
// from MediaBufferObserver
@@ -98,6 +101,7 @@ private:
kDecoderLiesAboutNumberOfChannels = 256,
kInputBufferSizesAreBogus = 512,
kSupportsMultipleFramesPerInputBuffer = 1024,
+ kAvoidMemcopyInputRecordingFrames = 2048,
};
struct BufferInfo {
@@ -137,12 +141,17 @@ private:
bool mNoMoreOutputData;
bool mOutputPortSettingsHaveChanged;
int64_t mSeekTimeUs;
+ ReadOptions::SeekMode mSeekMode;
+ int64_t mTargetTimeUs;
+ int64_t mSkipTimeUs;
MediaBuffer *mLeftOverBuffer;
Mutex mLock;
Condition mAsyncCompletion;
+ bool mPaused;
+
// A list of indices into mPortStatus[kPortIndexOutput] filled with data.
List<size_t> mFilledBuffers;
Condition mBufferFilled;
@@ -156,8 +165,8 @@ private:
void setComponentRole();
- void setAMRFormat(bool isWAMR);
- void setAACFormat(int32_t numChannels, int32_t sampleRate);
+ void setAMRFormat(bool isWAMR, int32_t bitRate);
+ void setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
status_t setVideoPortFormatType(
OMX_U32 portIndex,
@@ -165,10 +174,24 @@ private:
OMX_COLOR_FORMATTYPE colorFormat);
void setVideoInputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height);
-
- status_t setupMPEG4EncoderParameters();
- status_t setupAVCEncoderParameters();
+ const char *mime, const sp<MetaData>& meta);
+
+ status_t setupBitRate(int32_t bitRate);
+ status_t setupErrorCorrectionParameters();
+ status_t setupH263EncoderParameters(const sp<MetaData>& meta);
+ status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
+ status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
+ status_t findTargetColorFormat(
+ const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat);
+
+ status_t isColorFormatSupported(
+ OMX_COLOR_FORMATTYPE colorFormat, int portIndex);
+
+ // If profile/level is set in the meta data, its value in the meta
+ // data will be used; otherwise, the default value will be used.
+ status_t getVideoProfileLevel(const sp<MetaData>& meta,
+ const CodecProfileLevel& defaultProfileLevel,
+ CodecProfileLevel& profileLevel);
status_t setVideoOutputFormat(
const char *mime, OMX_U32 width, OMX_U32 height);
diff --git a/include/media/stagefright/foundation/AAtomizer.h b/include/media/stagefright/foundation/AAtomizer.h
new file mode 100644
index 0000000..5f3a678
--- /dev/null
+++ b/include/media/stagefright/foundation/AAtomizer.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_ATOMIZER_H_
+
+#define A_ATOMIZER_H_
+
+#include <stdint.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct AAtomizer {
+ static const char *Atomize(const char *name);
+
+private:
+ static AAtomizer gAtomizer;
+
+ Mutex mLock;
+ Vector<List<AString> > mAtoms;
+
+ AAtomizer();
+
+ const char *atomize(const char *name);
+
+ static uint32_t Hash(const char *s);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAtomizer);
+};
+
+} // namespace android
+
+#endif // A_ATOMIZER_H_
diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h
new file mode 100644
index 0000000..9eceea3
--- /dev/null
+++ b/include/media/stagefright/foundation/ABase.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_BASE_H_
+
+#define A_BASE_H_
+
+#define DISALLOW_EVIL_CONSTRUCTORS(name) \
+ name(const name &); \
+ name &operator=(const name &)
+
+#endif // A_BASE_H_
diff --git a/include/media/stagefright/foundation/ABuffer.h b/include/media/stagefright/foundation/ABuffer.h
new file mode 100644
index 0000000..28f0aed
--- /dev/null
+++ b/include/media/stagefright/foundation/ABuffer.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_BUFFER_H_
+
+#define A_BUFFER_H_
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+
+struct ABuffer : public RefBase {
+ ABuffer(size_t capacity);
+ ABuffer(void *data, size_t capacity);
+
+ void setFarewellMessage(const sp<AMessage> msg);
+
+ uint8_t *base() { return (uint8_t *)mData; }
+ uint8_t *data() { return (uint8_t *)mData + mRangeOffset; }
+ size_t capacity() const { return mCapacity; }
+ size_t size() const { return mRangeLength; }
+ size_t offset() const { return mRangeOffset; }
+
+ void setRange(size_t offset, size_t size);
+
+ void setInt32Data(int32_t data) { mInt32Data = data; }
+ int32_t int32Data() const { return mInt32Data; }
+
+ sp<AMessage> meta();
+
+protected:
+ virtual ~ABuffer();
+
+private:
+ sp<AMessage> mFarewell;
+ sp<AMessage> mMeta;
+
+ void *mData;
+ size_t mCapacity;
+ size_t mRangeOffset;
+ size_t mRangeLength;
+
+ int32_t mInt32Data;
+
+ bool mOwnsData;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ABuffer);
+};
+
+} // namespace android
+
+#endif // A_BUFFER_H_
diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h
new file mode 100644
index 0000000..0f986a0
--- /dev/null
+++ b/include/media/stagefright/foundation/ADebug.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_DEBUG_H_
+
+#define A_DEBUG_H_
+
+#include <string.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+enum LogType {
+ VERBOSE,
+ INFO,
+ WARNING,
+ ERROR,
+ FATAL,
+};
+
+struct Logger {
+ Logger(LogType type);
+ virtual ~Logger();
+
+ template<class T> Logger &operator<<(const T &x) {
+ mMessage.append(x);
+
+ return *this;
+ }
+
+private:
+ android::AString mMessage;
+ LogType mLogType;
+
+ DISALLOW_EVIL_CONSTRUCTORS(Logger);
+};
+
+const char *LeafName(const char *s);
+
+#undef LOG
+#define LOG(type) Logger(type) << LeafName(__FILE__) << ":" << __LINE__ << " "
+
+#define CHECK(condition) \
+ do { \
+ if (!(condition)) { \
+ LOG(FATAL) << "CHECK(" #condition ") failed."; \
+ } \
+ } while (false)
+
+#define MAKE_COMPARATOR(suffix,op) \
+ template<class A, class B> \
+ AString Compare_##suffix(const A &a, const B &b) { \
+ AString res; \
+ if (!(a op b)) { \
+ res.append(a); \
+ res.append(" vs. "); \
+ res.append(b); \
+ } \
+ return res; \
+ }
+
+MAKE_COMPARATOR(EQ,==)
+MAKE_COMPARATOR(NE,!=)
+MAKE_COMPARATOR(LE,<=)
+MAKE_COMPARATOR(GE,>=)
+MAKE_COMPARATOR(LT,<)
+MAKE_COMPARATOR(GT,>)
+
+#define CHECK_OP(x,y,suffix,op) \
+ do { \
+ AString ___res = Compare_##suffix(x, y); \
+ if (!___res.empty()) { \
+ LOG(FATAL) << "CHECK_" #suffix "(" #x "," #y ") failed: " \
+ << ___res; \
+ } \
+ } while (false)
+
+#define CHECK_EQ(x,y) CHECK_OP(x,y,EQ,==)
+#define CHECK_NE(x,y) CHECK_OP(x,y,NE,!=)
+#define CHECK_LE(x,y) CHECK_OP(x,y,LE,<=)
+#define CHECK_LT(x,y) CHECK_OP(x,y,LT,<)
+#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
+#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
+
+#define TRESPASS() LOG(FATAL) << "Should not be here."
+
+} // namespace android
+
+#endif // A_DEBUG_H_
+
diff --git a/include/media/stagefright/foundation/AHandler.h b/include/media/stagefright/foundation/AHandler.h
new file mode 100644
index 0000000..b008b54
--- /dev/null
+++ b/include/media/stagefright/foundation/AHandler.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_HANDLER_H_
+
+#define A_HANDLER_H_
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+
+struct AHandler : public RefBase {
+ AHandler()
+ : mID(0) {
+ }
+
+ ALooper::handler_id id() const {
+ return mID;
+ }
+
+ sp<ALooper> looper();
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
+
+private:
+ friend struct ALooperRoster;
+
+ ALooper::handler_id mID;
+
+ void setID(ALooper::handler_id id) {
+ mID = id;
+ }
+
+ DISALLOW_EVIL_CONSTRUCTORS(AHandler);
+};
+
+} // namespace android
+
+#endif // A_HANDLER_H_
diff --git a/include/media/stagefright/foundation/AHandlerReflector.h b/include/media/stagefright/foundation/AHandlerReflector.h
new file mode 100644
index 0000000..857866a
--- /dev/null
+++ b/include/media/stagefright/foundation/AHandlerReflector.h
@@ -0,0 +1,32 @@
+#ifndef A_HANDLER_REFLECTOR_H_
+
+#define A_HANDLER_REFLECTOR_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+template<class T>
+struct AHandlerReflector : public AHandler {
+ AHandlerReflector(T *target)
+ : mTarget(target) {
+ }
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg) {
+ sp<T> target = mTarget.promote();
+ if (target != NULL) {
+ target->onMessageReceived(msg);
+ }
+ }
+
+private:
+ wp<T> mTarget;
+
+ AHandlerReflector(const AHandlerReflector<T> &);
+ AHandlerReflector<T> &operator=(const AHandlerReflector<T> &);
+};
+
+} // namespace android
+
+#endif // A_HANDLER_REFLECTOR_H_
diff --git a/include/media/stagefright/foundation/ALooper.h b/include/media/stagefright/foundation/ALooper.h
new file mode 100644
index 0000000..153ead9
--- /dev/null
+++ b/include/media/stagefright/foundation/ALooper.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_LOOPER_H_
+
+#define A_LOOPER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct AHandler;
+struct AMessage;
+
+struct ALooper : public RefBase {
+ typedef int32_t event_id;
+ typedef int32_t handler_id;
+
+ ALooper();
+
+ handler_id registerHandler(const sp<AHandler> &handler);
+ void unregisterHandler(handler_id handlerID);
+
+ status_t start(
+ bool runOnCallingThread = false,
+ bool canCallJava = false,
+ int32_t priority = PRIORITY_DEFAULT
+ );
+
+ status_t stop();
+
+ static int64_t GetNowUs();
+
+protected:
+ virtual ~ALooper();
+
+private:
+ friend struct ALooperRoster;
+
+ struct Event {
+ int64_t mWhenUs;
+ sp<AMessage> mMessage;
+ };
+
+ Mutex mLock;
+ Condition mQueueChangedCondition;
+
+ List<Event> mEventQueue;
+
+ struct LooperThread;
+ sp<LooperThread> mThread;
+ bool mRunningLocally;
+
+ void post(const sp<AMessage> &msg, int64_t delayUs);
+ bool loop();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ALooper);
+};
+
+} // namespace android
+
+#endif // A_LOOPER_H_
diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h
new file mode 100644
index 0000000..c1bd4ed
--- /dev/null
+++ b/include/media/stagefright/foundation/ALooperRoster.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_LOOPER_ROSTER_H_
+
+#define A_LOOPER_ROSTER_H_
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+struct ALooperRoster {
+ ALooperRoster();
+
+ ALooper::handler_id registerHandler(
+ const sp<ALooper> looper, const sp<AHandler> &handler);
+
+ void unregisterHandler(ALooper::handler_id handlerID);
+
+ void postMessage(const sp<AMessage> &msg, int64_t delayUs = 0);
+ void deliverMessage(const sp<AMessage> &msg);
+
+ sp<ALooper> findLooper(ALooper::handler_id handlerID);
+
+private:
+ struct HandlerInfo {
+ wp<ALooper> mLooper;
+ wp<AHandler> mHandler;
+ };
+
+ Mutex mLock;
+ KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
+ ALooper::handler_id mNextHandlerID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
+};
+
+} // namespace android
+
+#endif // A_LOOPER_ROSTER_H_
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
new file mode 100644
index 0000000..c674cba
--- /dev/null
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_MESSAGE_H_
+
+#define A_MESSAGE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AString;
+
+struct AMessage : public RefBase {
+ AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
+
+ void setWhat(uint32_t what);
+ uint32_t what() const;
+
+ void setTarget(ALooper::handler_id target);
+ ALooper::handler_id target() const;
+
+ void setInt32(const char *name, int32_t value);
+ void setInt64(const char *name, int64_t value);
+ void setSize(const char *name, size_t value);
+ void setFloat(const char *name, float value);
+ void setDouble(const char *name, double value);
+ void setPointer(const char *name, void *value);
+ void setString(const char *name, const char *s, ssize_t len = -1);
+ void setObject(const char *name, const sp<RefBase> &obj);
+ void setMessage(const char *name, const sp<AMessage> &obj);
+
+ bool findInt32(const char *name, int32_t *value) const;
+ bool findInt64(const char *name, int64_t *value) const;
+ bool findSize(const char *name, size_t *value) const;
+ bool findFloat(const char *name, float *value) const;
+ bool findDouble(const char *name, double *value) const;
+ bool findPointer(const char *name, void **value) const;
+ bool findString(const char *name, AString *value) const;
+ bool findObject(const char *name, sp<RefBase> *obj) const;
+ bool findMessage(const char *name, sp<AMessage> *obj) const;
+
+ void post(int64_t delayUs = 0);
+
+ sp<AMessage> dup() const;
+
+ AString debugString(int32_t indent = 0) const;
+
+protected:
+ virtual ~AMessage();
+
+private:
+ enum Type {
+ kTypeInt32,
+ kTypeInt64,
+ kTypeSize,
+ kTypeFloat,
+ kTypeDouble,
+ kTypePointer,
+ kTypeString,
+ kTypeObject,
+ kTypeMessage,
+ };
+
+ uint32_t mWhat;
+ ALooper::handler_id mTarget;
+
+ struct Item {
+ union {
+ int32_t int32Value;
+ int64_t int64Value;
+ size_t sizeValue;
+ float floatValue;
+ double doubleValue;
+ void *ptrValue;
+ RefBase *refValue;
+ AString *stringValue;
+ } u;
+ const char *mName;
+ Type mType;
+ };
+
+ enum {
+ kMaxNumItems = 16
+ };
+ Item mItems[kMaxNumItems];
+ size_t mNumItems;
+
+ void clear();
+ Item *allocateItem(const char *name);
+ void freeItem(Item *item);
+ const Item *findItem(const char *name, Type type) const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AMessage);
+};
+
+} // namespace android
+
+#endif // A_MESSAGE_H_
diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h
new file mode 100644
index 0000000..55ade64
--- /dev/null
+++ b/include/media/stagefright/foundation/AString.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_STRING_H_
+
+#define A_STRING_H_
+
+#include <sys/types.h>
+
+namespace android {
+
+struct AString {
+ AString();
+ AString(const char *s);
+ AString(const char *s, size_t size);
+ AString(const AString &from);
+ AString(const AString &from, size_t offset, size_t n);
+ ~AString();
+
+ AString &operator=(const AString &from);
+ void setTo(const char *s);
+ void setTo(const char *s, size_t size);
+ void setTo(const AString &from, size_t offset, size_t n);
+
+ size_t size() const;
+ const char *c_str() const;
+
+ bool empty() const;
+
+ void clear();
+ void trim();
+ void erase(size_t start, size_t n);
+
+ void append(char c) { append(&c, 1); }
+ void append(const char *s);
+ void append(const char *s, size_t size);
+ void append(const AString &from);
+ void append(const AString &from, size_t offset, size_t n);
+ void append(int x);
+ void append(unsigned x);
+ void append(long x);
+ void append(unsigned long x);
+ void append(long long x);
+ void append(unsigned long long x);
+ void append(float x);
+ void append(double x);
+ void append(void *x);
+
+ void insert(const AString &from, size_t insertionPos);
+ void insert(const char *from, size_t size, size_t insertionPos);
+
+ ssize_t find(const char *substring, size_t start = 0) const;
+
+ size_t hash() const;
+
+ bool operator==(const AString &other) const;
+ bool operator<(const AString &other) const;
+ bool operator>(const AString &other) const;
+
+ int compare(const AString &other) const;
+
+ bool startsWith(const char *prefix) const;
+
+ void tolower();
+
+private:
+ static const char *kEmptyString;
+
+ char *mData;
+ size_t mSize;
+ size_t mAllocSize;
+
+ void makeMutable();
+};
+
+AString StringPrintf(const char *format, ...);
+
+} // namespace android
+
+#endif // A_STRING_H_
+
diff --git a/include/media/stagefright/foundation/base64.h b/include/media/stagefright/foundation/base64.h
new file mode 100644
index 0000000..e340b89
--- /dev/null
+++ b/include/media/stagefright/foundation/base64.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BASE_64_H_
+
+#define BASE_64_H_
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ABuffer;
+struct AString;
+
+sp<ABuffer> decodeBase64(const AString &s);
+void encodeBase64(const void *data, size_t size, AString *out);
+
+} // namespace android
+
+#endif // BASE_64_H_
diff --git a/include/media/stagefright/foundation/hexdump.h b/include/media/stagefright/foundation/hexdump.h
new file mode 100644
index 0000000..f6083a9
--- /dev/null
+++ b/include/media/stagefright/foundation/hexdump.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HEXDUMP_H_
+
+#define HEXDUMP_H_
+
+#include <sys/types.h>
+
+namespace android {
+
+void hexdump(const void *_data, size_t size);
+
+} // namespace android
+
+#endif // HEXDUMP_H_
diff --git a/include/private/README b/include/private/README
new file mode 100644
index 0000000..ee41492
--- /dev/null
+++ b/include/private/README
@@ -0,0 +1,4 @@
+This folder contains private include files.
+
+These include files are part of the private implementation details of
+various framework components. Use at your peril.
diff --git a/include/private/media/AudioEffectShared.h b/include/private/media/AudioEffectShared.h
new file mode 100644
index 0000000..a3a99a4
--- /dev/null
+++ b/include/private/media/AudioEffectShared.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTCBASESHARED_H
+#define ANDROID_EFFECTCBASESHARED_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+// Size of buffer used to exchange parameters between application and mediaserver processes.
+#define EFFECT_PARAM_BUFFER_SIZE 1024
+
+
+// Shared memory area used to exchange parameters between application and mediaserver
+// process.
+struct effect_param_cblk_t
+{
+ Mutex lock;
+ volatile uint32_t clientIndex; // Current read/write index for application
+ volatile uint32_t serverIndex; // Current read/write index for mediaserver
+ uint8_t* buffer; // start of parameter buffer
+
+ effect_param_cblk_t()
+ : lock(Mutex::SHARED), clientIndex(0), serverIndex(0) {}
+};
+
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_EFFECTCBASESHARED_H
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 8e2db20..1510f87 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -32,6 +32,18 @@ namespace android {
#define MAX_RUN_TIMEOUT_MS 1000
#define WAIT_PERIOD_MS 10
+#define CBLK_UNDERRUN_MSK 0x0001
+#define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication
+#define CBLK_UNDERRUN_OFF 0x0000 // no underrun
+#define CBLK_DIRECTION_MSK 0x0002
+#define CBLK_DIRECTION_OUT 0x0002 // this cblk is for an AudioTrack
+#define CBLK_DIRECTION_IN 0x0000 // this cblk is for an AudioRecord
+#define CBLK_FORCEREADY_MSK 0x0004
+#define CBLK_FORCEREADY_ON 0x0004 // track is considered ready immediately by AudioFlinger
+#define CBLK_FORCEREADY_OFF 0x0000 // track is ready when buffer full
+#define CBLK_INVALID_MSK 0x0008
+#define CBLK_INVALID_ON 0x0008 // track buffer is invalidated by AudioFlinger: must be re-created
+#define CBLK_INVALID_OFF 0x0000
struct audio_track_cblk_t
{
@@ -44,12 +56,12 @@ struct audio_track_cblk_t
volatile uint32_t server;
uint32_t userBase;
uint32_t serverBase;
- void* buffers;
- uint32_t frameCount;
- // Cache line boundary
- uint32_t loopStart;
- uint32_t loopEnd;
- int loopCount;
+ void* buffers;
+ uint32_t frameCount;
+ // Cache line boundary
+ uint32_t loopStart;
+ uint32_t loopEnd;
+ int loopCount;
volatile union {
uint16_t volume[2];
uint32_t volumeLR;
@@ -58,15 +70,17 @@ struct audio_track_cblk_t
// NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for
// 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of
// 16 bit because data is converted to 16 bit before being stored in buffer
- uint32_t frameSize;
- uint8_t channels;
- uint8_t flowControlFlag; // underrun (out) or overrrun (in) indication
- uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord
- uint8_t forceReady;
+
+ uint8_t frameSize;
+ uint8_t channelCount;
+ uint16_t flags;
+
uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
uint16_t waitTimeMs; // Cumulated wait time
- // Cache line boundary (32 bytes)
+ uint16_t sendLevel;
+ uint16_t reserved;
+ // Cache line boundary (32 bytes)
audio_track_cblk_t();
uint32_t stepUser(uint32_t frameCount);
bool stepServer(uint32_t frameCount);
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9b5a1e0..1eb178e 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -43,24 +43,9 @@ namespace android {
* unless they are in use by the server, which is only the case for the last
* dequeue-able buffer. When these various conditions are not met, the caller
* waits until the condition is met.
- *
- *
- * CAVEATS:
- *
- * In the current implementation there are several limitations:
- * - buffers must be locked in the same order they've been dequeued
- * - buffers must be enqueued in the same order they've been locked
- * - dequeue() is not reentrant
- * - no error checks are done on the condition above
*
*/
-// When changing these values, the COMPILE_TIME_ASSERT at the end of this
-// file need to be updated.
-const unsigned int NUM_LAYERS_MAX = 31;
-const unsigned int NUM_BUFFER_MAX = 4;
-const unsigned int NUM_DISPLAY_MAX = 4;
-
// ----------------------------------------------------------------------------
class Region;
@@ -69,7 +54,11 @@ class SharedClient;
// ----------------------------------------------------------------------------
-// should be 128 bytes (32 longs)
+// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX
+// 4 * (11 + 7 + (1 + 2*7)*16) * 31
+// 1032 * 31
+// = ~27 KiB (31992)
+
class SharedBufferStack
{
friend class SharedClient;
@@ -78,21 +67,38 @@ class SharedBufferStack
friend class SharedBufferServer;
public:
- struct FlatRegion { // 12 bytes
- static const unsigned int NUM_RECT_MAX = 1;
- uint32_t count;
- uint16_t rects[4*NUM_RECT_MAX];
- };
-
+ // When changing these values, the COMPILE_TIME_ASSERT at the end of this
+ // file need to be updated.
+ static const unsigned int NUM_LAYERS_MAX = 31;
+ static const unsigned int NUM_BUFFER_MAX = 16;
+ static const unsigned int NUM_BUFFER_MIN = 2;
+ static const unsigned int NUM_DISPLAY_MAX = 4;
+
struct Statistics { // 4 longs
typedef int32_t usecs_t;
usecs_t totalTime;
usecs_t reserved[3];
};
+
+ struct SmallRect {
+ uint16_t l, t, r, b;
+ };
+
+ struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
+ static const unsigned int NUM_RECT_MAX = 6;
+ uint32_t count;
+ SmallRect rects[NUM_RECT_MAX];
+ };
+
+ struct BufferData {
+ FlatRegion dirtyRegion;
+ SmallRect crop;
+ };
SharedBufferStack();
void init(int32_t identity);
status_t setDirtyRegion(int buffer, const Region& reg);
+ status_t setCrop(int buffer, const Rect& reg);
Region getDirtyRegion(int buffer) const;
// these attributes are part of the conditions/updates
@@ -104,24 +110,25 @@ public:
// not part of the conditions
volatile int32_t reallocMask;
+ volatile int8_t index[NUM_BUFFER_MAX];
int32_t identity; // surface's identity (const)
- int32_t reserved32[9];
+ int32_t token; // surface's token (for debugging)
+ int32_t reserved32[1];
Statistics stats;
- FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes
+ int32_t reserved;
+ BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes
};
// ----------------------------------------------------------------------------
-// 4 KB max
+// 32 KB max
class SharedClient
{
public:
SharedClient();
~SharedClient();
-
status_t validate(size_t token) const;
- uint32_t getIdentity(size_t token) const;
private:
friend class SharedBufferBase;
@@ -131,7 +138,7 @@ private:
// FIXME: this should be replaced by a lock-less primitive
Mutex lock;
Condition cv;
- SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+ SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
};
// ============================================================================
@@ -139,18 +146,17 @@ private:
class SharedBufferBase
{
public:
- SharedBufferBase(SharedClient* sharedClient, int surface, int num,
+ SharedBufferBase(SharedClient* sharedClient, int surface,
int32_t identity);
~SharedBufferBase();
- uint32_t getIdentity();
status_t getStatus() const;
+ int32_t getIdentity() const;
size_t getFrontBuffer() const;
String8 dump(char const* prefix) const;
protected:
SharedClient* const mSharedClient;
SharedBufferStack* const mSharedStack;
- const int mNumBuffers;
const int mIdentity;
friend struct Update;
@@ -160,61 +166,22 @@ protected:
SharedBufferStack& stack;
inline ConditionBase(SharedBufferBase* sbc)
: stack(*sbc->mSharedStack) { }
+ virtual ~ConditionBase() { };
+ virtual bool operator()() const = 0;
+ virtual const char* name() const = 0;
};
+ status_t waitForCondition(const ConditionBase& condition);
struct UpdateBase {
SharedBufferStack& stack;
inline UpdateBase(SharedBufferBase* sbb)
: stack(*sbb->mSharedStack) { }
};
-
- template <typename T>
- status_t waitForCondition(T condition);
-
template <typename T>
status_t updateCondition(T update);
};
template <typename T>
-status_t SharedBufferBase::waitForCondition(T condition)
-{
- const SharedBufferStack& stack( *mSharedStack );
- SharedClient& client( *mSharedClient );
- const nsecs_t TIMEOUT = s2ns(1);
- Mutex::Autolock _l(client.lock);
- while ((condition()==false) &&
- (stack.identity == mIdentity) &&
- (stack.status == NO_ERROR))
- {
- status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
-
- // handle errors and timeouts
- if (CC_UNLIKELY(err != NO_ERROR)) {
- if (err == TIMED_OUT) {
- if (condition()) {
- LOGE("waitForCondition(%s) timed out (identity=%d), "
- "but condition is true! We recovered but it "
- "shouldn't happen." , T::name(),
- stack.identity);
- break;
- } else {
- LOGW("waitForCondition(%s) timed out "
- "(identity=%d, status=%d). "
- "CPU may be pegged. trying again.", T::name(),
- stack.identity, stack.status);
- }
- } else {
- LOGE("waitForCondition(%s) error (%s) ",
- T::name(), strerror(-err));
- return err;
- }
- }
- }
- return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
-}
-
-
-template <typename T>
status_t SharedBufferBase::updateCondition(T update) {
SharedClient& client( *mSharedClient );
Mutex::Autolock _l(client.lock);
@@ -238,13 +205,21 @@ public:
status_t queue(int buf);
bool needNewBuffer(int buffer) const;
status_t setDirtyRegion(int buffer, const Region& reg);
+ status_t setCrop(int buffer, const Rect& reg);
+
+ class SetBufferCountCallback {
+ friend class SharedBufferClient;
+ virtual status_t operator()(int bufferCount) const = 0;
+ protected:
+ virtual ~SetBufferCountCallback() { }
+ };
+ status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
+
private:
friend struct Condition;
friend struct DequeueCondition;
friend struct LockCondition;
-
- int32_t computeTail() const;
struct QueueUpdate : public UpdateBase {
inline QueueUpdate(SharedBufferBase* sbb);
@@ -260,25 +235,34 @@ private:
struct DequeueCondition : public ConditionBase {
inline DequeueCondition(SharedBufferClient* sbc);
- inline bool operator()();
- static inline const char* name() { return "DequeueCondition"; }
+ inline bool operator()() const;
+ inline const char* name() const { return "DequeueCondition"; }
};
struct LockCondition : public ConditionBase {
int buf;
inline LockCondition(SharedBufferClient* sbc, int buf);
- inline bool operator()();
- static inline const char* name() { return "LockCondition"; }
+ inline bool operator()() const;
+ inline const char* name() const { return "LockCondition"; }
};
+ int32_t computeTail() const;
+
+ mutable RWLock mLock;
+ int mNumBuffers;
+
int32_t tail;
+ int32_t undoDequeueTail;
+ int32_t queued_head;
// statistics...
- nsecs_t mDequeueTime[NUM_BUFFER_MAX];
+ nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
};
// ----------------------------------------------------------------------------
-class SharedBufferServer : public SharedBufferBase
+class SharedBufferServer
+ : public SharedBufferBase,
+ public LightRefBase<SharedBufferServer>
{
public:
SharedBufferServer(SharedClient* sharedClient, int surface, int num,
@@ -287,16 +271,73 @@ public:
ssize_t retireAndLock();
status_t unlock(int buffer);
void setStatus(status_t status);
- status_t reallocate();
- status_t assertReallocate(int buffer);
+ status_t reallocateAll();
+ status_t reallocateAllExcept(int buffer);
int32_t getQueuedCount() const;
-
Region getDirtyRegion(int buffer) const;
+ status_t resize(int newNumBuffers);
+
SharedBufferStack::Statistics getStats() const;
private:
+ friend class LightRefBase<SharedBufferServer>;
+ ~SharedBufferServer();
+
+ /*
+ * BufferList is basically a fixed-capacity sorted-vector of
+ * unsigned 5-bits ints using a 32-bits int as storage.
+ * it has efficient iterators to find items in the list and not in the list.
+ */
+ class BufferList {
+ size_t mCapacity;
+ uint32_t mList;
+ public:
+ BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
+ : mCapacity(c), mList(0) { }
+ status_t add(int value);
+ status_t remove(int value);
+ uint32_t getMask() const { return mList; }
+
+ class const_iterator {
+ friend class BufferList;
+ uint32_t mask, curr;
+ const_iterator(uint32_t mask) :
+ mask(mask), curr(__builtin_clz(mask)) {
+ }
+ public:
+ inline bool operator == (const const_iterator& rhs) const {
+ return mask == rhs.mask;
+ }
+ inline bool operator != (const const_iterator& rhs) const {
+ return mask != rhs.mask;
+ }
+ inline int operator *() const { return curr; }
+ inline const const_iterator& operator ++() {
+ mask &= ~(1<<(31-curr));
+ curr = __builtin_clz(mask);
+ return *this;
+ }
+ };
+
+ inline const_iterator begin() const {
+ return const_iterator(mList);
+ }
+ inline const_iterator end() const {
+ return const_iterator(0);
+ }
+ inline const_iterator free_begin() const {
+ uint32_t mask = (1 << (32-mCapacity)) - 1;
+ return const_iterator( ~(mList | mask) );
+ }
+ };
+
+ // this protects mNumBuffers and mBufferList
+ mutable RWLock mLock;
+ int mNumBuffers;
+ BufferList mBufferList;
+
struct UnlockUpdate : public UpdateBase {
const int lockedBuffer;
inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
@@ -314,13 +355,6 @@ private:
inline StatusUpdate(SharedBufferBase* sbb, status_t status);
inline ssize_t operator()();
};
-
- struct ReallocateCondition : public ConditionBase {
- int buf;
- inline ReallocateCondition(SharedBufferBase* sbb, int buf);
- inline bool operator()();
- static inline const char* name() { return "ReallocateCondition"; }
- };
};
// ===========================================================================
@@ -344,13 +378,12 @@ struct surface_flinger_cblk_t // 4KB max
uint8_t connected;
uint8_t reserved[3];
uint32_t pad[7];
- display_cblk_t displays[NUM_DISPLAY_MAX];
+ display_cblk_t displays[SharedBufferStack::NUM_DISPLAY_MAX];
};
// ---------------------------------------------------------------------------
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
// ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 472f759..ddbe03d 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -47,13 +47,30 @@ protected:
POST_BUFFER, // one-way transaction
CREATE_OVERLAY,
REQUEST_BUFFER,
+ SET_BUFFER_COUNT,
};
public:
DECLARE_META_INTERFACE(Surface);
- virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0;
+ /*
+ * requests a new buffer for the given index. If w, h, or format are
+ * null the buffer is created with the parameters assigned to the
+ * surface it is bound to. Otherwise the buffer's parameters are
+ * set to those specified.
+ */
+ virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+ uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
+
+ /*
+ * sets the number of buffers dequeuable for this surface.
+ */
+ virtual status_t setBufferCount(int bufferCount) = 0;
+ // ------------------------------------------------------------------------
+ // Deprecated...
+ // ------------------------------------------------------------------------
+
class BufferHeap {
public:
enum {
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index d1e7785..dd44aa5 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -27,7 +27,7 @@
#include <ui/PixelFormat.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -85,8 +85,11 @@ public:
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
+ virtual sp<ISurfaceComposerClient> createConnection() = 0;
- virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+ /* create a client connection with surface flinger
+ */
+ virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
/* retrieve the control block */
virtual sp<IMemoryHeap> getCblk() const = 0;
@@ -123,6 +126,7 @@ public:
// Java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
+ CREATE_CLIENT_CONNECTION,
GET_CBLK,
OPEN_GLOBAL_TRANSACTION,
CLOSE_GLOBAL_TRANSACTION,
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
index d257645..a1e9e04 100644
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
#include <stdint.h>
#include <sys/types.h>
@@ -26,7 +26,7 @@
#include <binder/IInterface.h>
#include <ui/PixelFormat.h>
-
+
#include <surfaceflinger/ISurface.h>
namespace android {
@@ -42,10 +42,10 @@ typedef int32_t DisplayID;
class layer_state_t;
-class ISurfaceFlingerClient : public IInterface
+class ISurfaceComposerClient : public IInterface
{
-public:
- DECLARE_META_INTERFACE(SurfaceFlingerClient);
+public:
+ DECLARE_META_INTERFACE(SurfaceComposerClient);
struct surface_data_t {
int32_t token;
@@ -56,26 +56,36 @@ public:
status_t readFromParcel(const Parcel& parcel);
status_t writeToParcel(Parcel* parcel) const;
};
-
+
virtual sp<IMemoryHeap> getControlBlock() const = 0;
+ virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const = 0;
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual sp<ISurface> createSurface( surface_data_t* data,
- int pid,
+ int pid,
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags) = 0;
-
+
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual status_t destroySurface(SurfaceID sid) = 0;
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual status_t setState(int32_t count, const layer_state_t* states) = 0;
};
// ----------------------------------------------------------------------------
-class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient>
+class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient>
{
public:
virtual status_t onTransact( uint32_t code,
@@ -88,4 +98,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..294c867 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -28,12 +29,15 @@
#include <ui/egl/android_natives.h>
#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+
+#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
namespace android {
// ---------------------------------------------------------------------------
+class GraphicBuffer;
class GraphicBufferMapper;
class IOMX;
class Rect;
@@ -41,6 +45,7 @@ class Surface;
class SurfaceComposerClient;
class SharedClient;
class SharedBufferClient;
+class SurfaceClient;
// ---------------------------------------------------------------------------
@@ -56,7 +61,6 @@ public:
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- SurfaceID ID() const { return mToken; }
uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
@@ -104,7 +108,7 @@ private:
SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceFlingerClient::surface_data_t& data,
+ const ISurfaceComposerClient::surface_data_t& data,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
~SurfaceControl();
@@ -128,7 +132,7 @@ private:
// ---------------------------------------------------------------------------
class Surface
- : public EGLNativeBase<android_native_window_t, Surface, RefBase>
+ : public EGLNativeBase<ANativeWindow, Surface, RefBase>
{
public:
struct SurfaceInfo {
@@ -141,17 +145,16 @@ public:
uint32_t reserved[2];
};
- Surface(const Parcel& data);
+ static status_t writeToParcel(
+ const sp<Surface>& control, Parcel* parcel);
+
+ static sp<Surface> readFromParcel(const Parcel& data);
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
}
- static bool isSameSurface(
- const sp<Surface>& lhs, const sp<Surface>& rhs);
-
bool isValid();
- SurfaceID ID() const { return mToken; }
uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
@@ -163,44 +166,43 @@ public:
// setSwapRectangle() is intended to be used by GL ES clients
void setSwapRectangle(const Rect& r);
-private:
- // can't be copied
- Surface& operator = (Surface& rhs);
- Surface(const Surface& rhs);
-
- Surface(const sp<SurfaceControl>& control);
- void init();
- ~Surface();
-
- friend class SurfaceComposerClient;
- friend class SurfaceControl;
-
+private:
+ /*
+ * Android frameworks friends
+ * (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 MediaRecorder;
- // mediaplayer needs access to ISurface for display
+ // MediaPlayer needs access to ISurface for display
friend class MediaPlayer;
friend class IOMX;
// this is just to be able to write some unit tests
friend class Test;
- sp<SurfaceComposerClient> getClient() const;
- sp<ISurface> getISurface() const;
+private:
+ friend class SurfaceComposerClient;
+ friend class SurfaceControl;
- status_t getBufferLocked(int index, int usage);
-
- status_t validate() const;
+ // can't be copied
+ Surface& operator = (Surface& rhs);
+ Surface(const Surface& rhs);
- inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
- inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-
- static int setSwapInterval(android_native_window_t* window, int interval);
- static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
- static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
- static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
- static int query(android_native_window_t* window, int what, int* value);
- static int perform(android_native_window_t* window, int operation, ...);
+ Surface(const sp<SurfaceControl>& control);
+ Surface(const Parcel& data, const sp<IBinder>& ref);
+ ~Surface();
+
+
+ /*
+ * ANativeWindow hooks
+ */
+ static int setSwapInterval(ANativeWindow* window, int interval);
+ static int dequeueBuffer(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 dequeueBuffer(android_native_buffer_t** buffer);
int lockBuffer(android_native_buffer_t* buffer);
@@ -208,44 +210,88 @@ private:
int query(int what, int* value);
int perform(int operation, va_list args);
- status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
-
void dispatch_setUsage(va_list args);
int dispatch_connect(va_list args);
int dispatch_disconnect(va_list args);
+ int dispatch_crop(va_list args);
+ int dispatch_set_buffer_count(va_list args);
+ int dispatch_set_buffers_geometry(va_list args);
void setUsage(uint32_t reqUsage);
int connect(int api);
int disconnect(int api);
+ int crop(Rect const* rect);
+ int setBufferCount(int bufferCount);
+ int setBuffersGeometry(int w, int h, int format);
+
+ /*
+ * private stuff...
+ */
+ void init();
+ status_t validate() const;
+ sp<ISurface> getISurface() const;
+
+ inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+ inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+ status_t getBufferLocked(int index,
+ uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+ int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
- uint32_t getUsage() const;
- int getConnectedApi() const;
+ int getConnectedApi() const;
+ bool needNewBuffer(int bufIdx,
+ uint32_t *pWidth, uint32_t *pHeight,
+ uint32_t *pFormat, uint32_t *pUsage) const;
+
+ static void cleanCachedSurfaces();
+
+ class BufferInfo {
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mFormat;
+ uint32_t mUsage;
+ mutable uint32_t mDirty;
+ enum {
+ GEOMETRY = 0x01
+ };
+ public:
+ BufferInfo();
+ void set(uint32_t w, uint32_t h, uint32_t format);
+ void set(uint32_t usage);
+ void get(uint32_t *pWidth, uint32_t *pHeight,
+ uint32_t *pFormat, uint32_t *pUsage) const;
+ bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
+ };
+
// constants
- sp<SurfaceComposerClient> mClient;
+ GraphicBufferMapper& mBufferMapper;
+ SurfaceClient& mClient;
+ SharedBufferClient* mSharedBufferClient;
+ status_t mInitCheck;
sp<ISurface> mSurface;
- SurfaceID mToken;
uint32_t mIdentity;
PixelFormat mFormat;
uint32_t mFlags;
- GraphicBufferMapper& mBufferMapper;
- SharedBufferClient* mSharedBufferClient;
// protected by mSurfaceLock
Rect mSwapRectangle;
- uint32_t mUsage;
int mConnected;
+ Rect mNextBufferCrop;
+ BufferInfo mBufferInfo;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
- sp<GraphicBuffer> mBuffers[2];
mutable Region mDirtyRegion;
// must be used from the lock/unlock thread
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
mutable Region mOldDirtyRegion;
- bool mNeedFullUpdate;
+ bool mReserved;
+
+ // only used from dequeueBuffer()
+ Vector< sp<GraphicBuffer> > mBuffers;
// query() must be called from dequeueBuffer() thread
uint32_t mWidth;
@@ -254,6 +300,10 @@ private:
// Inherently thread-safe
mutable Mutex mSurfaceLock;
mutable Mutex mApiLock;
+
+ // A cache of Surface objects that have been deserialized into this process.
+ static Mutex sCachedSurfacesLock;
+ static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
};
}; // namespace android
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 9d0f0cb..8773d71 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -22,8 +22,9 @@
#include <binder/IBinder.h>
-#include <utils/SortedVector.h>
#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+#include <utils/SortedVector.h>
#include <utils/threads.h>
#include <ui/PixelFormat.h>
@@ -39,8 +40,26 @@ class Region;
class SharedClient;
class ISurfaceComposer;
class DisplayInfo;
+class surface_flinger_cblk_t;
+
+// ---------------------------------------------------------------------------
+
+class ComposerService : public Singleton<ComposerService>
+{
+ // these are constants
+ sp<ISurfaceComposer> mComposerService;
+ sp<IMemoryHeap> mServerCblkMemory;
+ surface_flinger_cblk_t volatile* mServerCblk;
+ ComposerService();
+ friend class Singleton<ComposerService>;
+public:
+ static sp<ISurfaceComposer> getComposerService();
+ static surface_flinger_cblk_t const volatile * getControlBlock();
+};
-class SurfaceComposerClient : virtual public RefBase
+// ---------------------------------------------------------------------------
+
+class SurfaceComposerClient : public RefBase
{
public:
SurfaceComposerClient();
@@ -52,10 +71,6 @@ public:
// Return the connection of this client
sp<IBinder> connection() const;
- // Retrieve a client for an existing connection.
- static sp<SurfaceComposerClient>
- clientForConnection(const sp<IBinder>& conn);
-
// Forcibly remove connection before all references have gone away.
void dispose();
@@ -123,13 +138,6 @@ public:
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0);
-private:
- friend class Surface;
- friend class SurfaceControl;
-
- SurfaceComposerClient(const sp<ISurfaceComposer>& sm,
- const sp<IBinder>& conn);
-
status_t hide(SurfaceID id);
status_t show(SurfaceID id, int32_t layer = -1);
status_t freeze(SurfaceID id);
@@ -142,32 +150,26 @@ private:
status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
status_t setPosition(SurfaceID id, int32_t x, int32_t y);
status_t setSize(SurfaceID id, uint32_t w, uint32_t h);
-
- void signalServer();
-
status_t destroySurface(SurfaceID sid);
- void _init(const sp<ISurfaceComposer>& sm,
- const sp<ISurfaceFlingerClient>& conn);
-
- inline layer_state_t* _get_state_l(SurfaceID id);
- layer_state_t* _lockLayerState(SurfaceID id);
- inline void _unlockLayerState();
+private:
+ virtual void onFirstRef();
+ inline layer_state_t* get_state_l(SurfaceID id);
+ layer_state_t* lockLayerState(SurfaceID id);
+ inline void unlockLayerState();
mutable Mutex mLock;
- layer_state_t* mPrebuiltLayerState;
SortedVector<layer_state_t> mStates;
int32_t mTransactionOpen;
+ layer_state_t* mPrebuiltLayerState;
// these don't need to be protected because they never change
// after assignment
status_t mStatus;
- SharedClient* mControl;
- sp<IMemoryHeap> mControlMemory;
- sp<ISurfaceFlingerClient> mClient;
- sp<ISurfaceComposer> mSignalServer;
+ sp<ISurfaceComposerClient> mClient;
};
+// ---------------------------------------------------------------------------
}; // namespace android
#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3b18c77..dab35b3 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -18,6 +18,7 @@
#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>
@@ -27,6 +28,31 @@
#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 {
@@ -34,73 +60,154 @@ namespace android {
class KeyLayoutMap;
/*
- * Grand Central Station for events. With a single call to waitEvent()
- * you can wait for:
- * - input events from the keypad of a real device
- * - input events and meta-events (e.g. "quit") from the simulator
- * - synthetic events from the runtime (e.g. "URL fetch completed")
- * - real or forged "vsync" events
+ * 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; }
+};
+
+/*
+ * 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. */
+ INPUT_DEVICE_CLASS_DPAD = 0x00000020,
+
+ /* The input device is a gamepad (implies keyboard). */
+ INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040,
+
+ /* The input device has switches. */
+ INPUT_DEVICE_CLASS_SWITCH = 0x00000080,
+};
+
+/*
+ * Grand Central Station for events.
*
- * Do not instantiate this class. Instead, call startUp().
+ * 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 EventHub : public RefBase
+class EventHubInterface : public virtual RefBase {
+protected:
+ EventHubInterface() { }
+ virtual ~EventHubInterface() { }
+
+public:
+ // Synthetic raw event type codes produced when devices are added or removed.
+ enum {
+ DEVICE_ADDED = 0x10000000,
+ DEVICE_REMOVED = 0x20000000
+ };
+
+ 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;
+};
+
+class EventHub : public EventHubInterface
{
public:
EventHub();
-
+
status_t errorCheck() const;
+
+ virtual uint32_t getDeviceClasses(int32_t deviceId) const;
- // bit fields for classes of devices.
- enum {
- CLASS_KEYBOARD = 0x00000001,
- CLASS_ALPHAKEY = 0x00000002,
- CLASS_TOUCHSCREEN = 0x00000004,
- CLASS_TRACKBALL = 0x00000008,
- CLASS_TOUCHSCREEN_MT= 0x00000010,
- CLASS_DPAD = 0x00000020
- };
- uint32_t getDeviceClasses(int32_t deviceId) const;
-
- String8 getDeviceName(int32_t deviceId) const;
-
- int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
- int* outMaxValue, int* outFlat, int* outFuzz) const;
-
- int getSwitchState(int sw) const;
- int getSwitchState(int32_t deviceId, int sw) const;
-
- int getScancodeState(int key) const;
- int getScancodeState(int32_t deviceId, int key) const;
-
- int getKeycodeState(int key) const;
- int getKeycodeState(int32_t deviceId, int key) const;
+ virtual String8 getDeviceName(int32_t deviceId) const;
- status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ 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;
- // exclude a particular device from opening
- // this can be used to ignore input devices for sensors
- void addExcludedDevice(const char* deviceName);
+ virtual void addExcludedDevice(const char* deviceName);
- // special type codes when devices are added/removed.
- enum {
- DEVICE_ADDED = 0x10000000,
- DEVICE_REMOVED = 0x20000000
- };
-
- // examine key input devices for specific framework keycode support
- bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
+ virtual 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 getEvent(int32_t* outDeviceId, int32_t* outType,
- int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
- int32_t* outValue, nsecs_t* outWhen);
+ virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags) const;
+
+ virtual bool getEvent(RawEvent* outEvent);
protected:
virtual ~EventHub();
private:
bool openPlatformInput(void);
- int32_t convertDeviceKey_TI_P2(int code);
int open_device(const char *device);
int close_device(const char *device);
@@ -126,6 +233,12 @@ private:
device_t* getDevice(int32_t deviceId) const;
bool hasKeycode(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;
@@ -151,7 +264,7 @@ private:
// device ids that report particular switches.
#ifdef EV_SW
- int32_t mSwitches[SW_MAX+1];
+ int32_t mSwitches[SW_MAX + 1];
#endif
};
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 8ea3ab9..0f4594f 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -43,7 +43,7 @@ class NativeBuffer;
class FramebufferNativeWindow
: public EGLNativeBase<
- android_native_window_t,
+ ANativeWindow,
FramebufferNativeWindow,
LightRefBase<FramebufferNativeWindow> >
{
@@ -59,12 +59,12 @@ public:
private:
friend class LightRefBase<FramebufferNativeWindow>;
~FramebufferNativeWindow(); // this class cannot be overloaded
- static int setSwapInterval(android_native_window_t* window, int interval);
- static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
- static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
- static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
- static int query(android_native_window_t* window, int what, int* value);
- static int perform(android_native_window_t* window, int operation, ...);
+ static int setSwapInterval(ANativeWindow* window, int interval);
+ static int dequeueBuffer(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, ...);
framebuffer_device_t* fbDev;
alloc_device_t* grDev;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index e72b6b3..a3e85a9 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -93,10 +93,8 @@ public:
void setIndex(int index);
int getIndex() const;
- void setVerticalStride(uint32_t vstride);
- uint32_t getVerticalStride() const;
-protected:
+private:
virtual ~GraphicBuffer();
enum {
@@ -105,8 +103,12 @@ protected:
ownData = 2,
};
- inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
- inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+ inline const GraphicBufferMapper& getBufferMapper() const {
+ return mBufferMapper;
+ }
+ inline GraphicBufferMapper& getBufferMapper() {
+ return mBufferMapper;
+ }
uint8_t mOwner;
private:
@@ -134,7 +136,6 @@ private:
GraphicBufferMapper& mBufferMapper;
ssize_t mInitCheck;
- uint32_t mVStride;
int mIndex;
};
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 741d763..54b8236 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -73,9 +73,9 @@ private:
struct alloc_rec_t {
uint32_t w;
uint32_t h;
+ uint32_t s;
PixelFormat format;
uint32_t usage;
- void* vaddr;
size_t size;
};
diff --git a/include/ui/Input.h b/include/ui/Input.h
new file mode 100644
index 0000000..2385973
--- /dev/null
+++ b/include/ui/Input.h
@@ -0,0 +1,491 @@
+/*
+ * 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_H
+#define _UI_INPUT_H
+
+/**
+ * Native input event structures.
+ */
+
+#include <android/input.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+/*
+ * Additional private constants not defined in ndk/ui/input.h.
+ */
+enum {
+ /*
+ * Private control to determine when an app is tracking a key sequence.
+ */
+ AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
+};
+
+/*
+ * Maximum number of pointers supported per motion event.
+ */
+#define MAX_POINTERS 10
+
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct AInputEvent {
+ virtual ~AInputEvent() { }
+};
+
+/*
+ * Declare a concrete type for the NDK's input device forward declaration.
+ */
+struct AInputDevice {
+ virtual ~AInputDevice() { }
+};
+
+
+namespace android {
+
+/*
+ * Flags that flow alongside events in the input dispatch system to help with certain
+ * policy decisions such as waking from device sleep.
+ */
+enum {
+ /* These flags originate in RawEvents and are generally set in the key map. */
+
+ POLICY_FLAG_WAKE = 0x00000001,
+ POLICY_FLAG_WAKE_DROPPED = 0x00000002,
+ POLICY_FLAG_SHIFT = 0x00000004,
+ POLICY_FLAG_CAPS_LOCK = 0x00000008,
+ POLICY_FLAG_ALT = 0x00000010,
+ POLICY_FLAG_ALT_GR = 0x00000020,
+ POLICY_FLAG_MENU = 0x00000040,
+ POLICY_FLAG_LAUNCHER = 0x00000080,
+
+ POLICY_FLAG_RAW_MASK = 0x0000ffff,
+
+ /* These flags are set by the input reader policy as it intercepts each event. */
+
+ // Indicates that the screen was off when the event was received and the event
+ // should wake the device.
+ POLICY_FLAG_WOKE_HERE = 0x10000000,
+
+ // Indicates that the screen was dim when the event was received and the event
+ // should brighten the device.
+ POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+};
+
+/*
+ * Describes the basic configuration of input devices that are present.
+ */
+struct InputConfiguration {
+ enum {
+ TOUCHSCREEN_UNDEFINED = 0,
+ TOUCHSCREEN_NOTOUCH = 1,
+ TOUCHSCREEN_STYLUS = 2,
+ TOUCHSCREEN_FINGER = 3
+ };
+
+ enum {
+ KEYBOARD_UNDEFINED = 0,
+ KEYBOARD_NOKEYS = 1,
+ KEYBOARD_QWERTY = 2,
+ KEYBOARD_12KEY = 3
+ };
+
+ enum {
+ NAVIGATION_UNDEFINED = 0,
+ NAVIGATION_NONAV = 1,
+ NAVIGATION_DPAD = 2,
+ NAVIGATION_TRACKBALL = 3,
+ NAVIGATION_WHEEL = 4
+ };
+
+ int32_t touchScreen;
+ int32_t keyboard;
+ int32_t navigation;
+};
+
+/*
+ * Pointer coordinate data.
+ */
+struct PointerCoords {
+ float x;
+ float y;
+ float pressure;
+ float size;
+ float touchMajor;
+ float touchMinor;
+ float toolMajor;
+ float toolMinor;
+ float orientation;
+};
+
+/*
+ * Input events.
+ */
+class InputEvent : public AInputEvent {
+public:
+ virtual ~InputEvent() { }
+
+ virtual int32_t getType() const = 0;
+
+ inline int32_t getDeviceId() const { return mDeviceId; }
+
+ inline int32_t getSource() const { return mSource; }
+
+protected:
+ void initialize(int32_t deviceId, int32_t source);
+ void initialize(const InputEvent& from);
+
+private:
+ int32_t mDeviceId;
+ int32_t mSource;
+};
+
+/*
+ * Key events.
+ */
+class KeyEvent : public InputEvent {
+public:
+ virtual ~KeyEvent() { }
+
+ virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
+
+ inline int32_t getAction() const { return mAction; }
+
+ inline int32_t getFlags() const { return mFlags; }
+
+ inline int32_t getKeyCode() const { return mKeyCode; }
+
+ inline int32_t getScanCode() const { return mScanCode; }
+
+ inline int32_t getMetaState() const { return mMetaState; }
+
+ inline int32_t getRepeatCount() const { return mRepeatCount; }
+
+ inline nsecs_t getDownTime() const { return mDownTime; }
+
+ inline nsecs_t getEventTime() const { return mEventTime; }
+
+ // Return true if this event may have a default action implementation.
+ static bool hasDefaultAction(int32_t keyCode);
+ bool hasDefaultAction() const;
+
+ // Return true if this event represents a system key.
+ static bool isSystemKey(int32_t keyCode);
+ bool isSystemKey() const;
+
+ void initialize(
+ 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,
+ nsecs_t eventTime);
+ void initialize(const KeyEvent& from);
+
+private:
+ int32_t mAction;
+ int32_t mFlags;
+ int32_t mKeyCode;
+ int32_t mScanCode;
+ int32_t mMetaState;
+ int32_t mRepeatCount;
+ nsecs_t mDownTime;
+ nsecs_t mEventTime;
+};
+
+/*
+ * Motion events.
+ */
+class MotionEvent : public InputEvent {
+public:
+ virtual ~MotionEvent() { }
+
+ virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
+
+ inline int32_t getAction() const { return mAction; }
+
+ inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+
+ inline int32_t getMetaState() const { return mMetaState; }
+
+ inline float getXOffset() const { return mXOffset; }
+
+ inline float getYOffset() const { return mYOffset; }
+
+ inline float getXPrecision() const { return mXPrecision; }
+
+ inline float getYPrecision() const { return mYPrecision; }
+
+ inline nsecs_t getDownTime() const { return mDownTime; }
+
+ inline size_t getPointerCount() const { return mPointerIds.size(); }
+
+ inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; }
+
+ inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+
+ inline float getRawX(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).x;
+ }
+
+ inline float getRawY(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).y;
+ }
+
+ inline float getX(size_t pointerIndex) const {
+ return getRawX(pointerIndex) + mXOffset;
+ }
+
+ inline float getY(size_t pointerIndex) const {
+ return getRawY(pointerIndex) + mYOffset;
+ }
+
+ inline float getPressure(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).pressure;
+ }
+
+ inline float getSize(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).size;
+ }
+
+ inline float getTouchMajor(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).touchMajor;
+ }
+
+ inline float getTouchMinor(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).touchMinor;
+ }
+
+ inline float getToolMajor(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).toolMajor;
+ }
+
+ inline float getToolMinor(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).toolMinor;
+ }
+
+ inline float getOrientation(size_t pointerIndex) const {
+ return getCurrentPointerCoords(pointerIndex).orientation;
+ }
+
+ inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
+
+ inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
+ return mSampleEventTimes[historicalIndex];
+ }
+
+ inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+ }
+
+ inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+ }
+
+ inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
+ }
+
+ inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
+ }
+
+ inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+ }
+
+ inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+ }
+
+ inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
+ }
+
+ inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
+ }
+
+ inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
+ }
+
+ inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
+ }
+
+ inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
+ return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
+ }
+
+ void initialize(
+ int32_t deviceId,
+ int32_t source,
+ int32_t action,
+ int32_t edgeFlags,
+ int32_t metaState,
+ float xOffset,
+ float yOffset,
+ float xPrecision,
+ float yPrecision,
+ nsecs_t downTime,
+ nsecs_t eventTime,
+ size_t pointerCount,
+ const int32_t* pointerIds,
+ const PointerCoords* pointerCoords);
+
+ void addSample(
+ nsecs_t eventTime,
+ const PointerCoords* pointerCoords);
+
+ void offsetLocation(float xOffset, float yOffset);
+
+ // Low-level accessors.
+ inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
+ inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
+ inline const PointerCoords* getSamplePointerCoords() const {
+ return mSamplePointerCoords.array();
+ }
+
+private:
+ int32_t mAction;
+ int32_t mEdgeFlags;
+ int32_t mMetaState;
+ float mXOffset;
+ float mYOffset;
+ float mXPrecision;
+ float mYPrecision;
+ nsecs_t mDownTime;
+ Vector<int32_t> mPointerIds;
+ Vector<nsecs_t> mSampleEventTimes;
+ Vector<PointerCoords> mSamplePointerCoords;
+
+ inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
+ return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+ }
+
+ inline const PointerCoords& getHistoricalPointerCoords(
+ size_t pointerIndex, size_t historicalIndex) const {
+ return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+ }
+};
+
+/*
+ * Input event factory.
+ */
+class InputEventFactoryInterface {
+protected:
+ virtual ~InputEventFactoryInterface() { }
+
+public:
+ InputEventFactoryInterface() { }
+
+ virtual KeyEvent* createKeyEvent() = 0;
+ virtual MotionEvent* createMotionEvent() = 0;
+};
+
+/*
+ * A simple input event factory implementation that uses a single preallocated instance
+ * of each type of input event that are reused for each request.
+ */
+class PreallocatedInputEventFactory : public InputEventFactoryInterface {
+public:
+ PreallocatedInputEventFactory() { }
+ virtual ~PreallocatedInputEventFactory() { }
+
+ virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
+ virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
+
+private:
+ KeyEvent mKeyEvent;
+ MotionEvent mMotionEvent;
+};
+
+/*
+ * Describes the characteristics and capabilities of an input device.
+ */
+class InputDeviceInfo {
+public:
+ InputDeviceInfo();
+ InputDeviceInfo(const InputDeviceInfo& other);
+ ~InputDeviceInfo();
+
+ struct MotionRange {
+ float min;
+ float max;
+ float flat;
+ float fuzz;
+ };
+
+ void initialize(int32_t id, const String8& name);
+
+ inline int32_t getId() const { return mId; }
+ inline const String8 getName() const { return mName; }
+ inline uint32_t getSources() const { return mSources; }
+
+ const MotionRange* getMotionRange(int32_t rangeType) const;
+
+ void addSource(uint32_t source);
+ void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
+ void addMotionRange(int32_t rangeType, const MotionRange& range);
+
+ inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+ inline int32_t getKeyboardType() const { return mKeyboardType; }
+
+private:
+ int32_t mId;
+ String8 mName;
+ uint32_t mSources;
+ int32_t mKeyboardType;
+
+ KeyedVector<int32_t, MotionRange> mMotionRanges;
+};
+
+/*
+ * Provides remote access to information about an input device.
+ *
+ * Note: This is essentially a wrapper for Binder calls into the Window Manager Service.
+ */
+class InputDeviceProxy : public RefBase, public AInputDevice {
+protected:
+ InputDeviceProxy();
+ virtual ~InputDeviceProxy();
+
+public:
+ static void getDeviceIds(Vector<int32_t>& outIds);
+
+ static sp<InputDeviceProxy> getDevice(int32_t id);
+
+ inline const InputDeviceInfo* getInfo() { return & mInfo; }
+
+ // TODO add hasKeys, keymap, etc...
+
+private:
+ InputDeviceInfo mInfo;
+};
+
+
+} // namespace android
+
+#endif // _UI_INPUT_H
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
new file mode 100644
index 0000000..d3495fe
--- /dev/null
+++ b/include/ui/InputDispatcher.h
@@ -0,0 +1,669 @@
+/*
+ * 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/PollLoop.h>
+#include <utils/Pool.h>
+
+#include <stddef.h>
+#include <unistd.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 subsequent event delivery should be held until the
+ * current event is delivered to this target or a timeout occurs. */
+ FLAG_SYNC = 0x01,
+
+ /* This flag indicates that a MotionEvent with ACTION_DOWN falls outside of the area of
+ * this target and so should instead be delivered as an ACTION_OUTSIDE to this target. */
+ FLAG_OUTSIDE = 0x02,
+
+ /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
+ * In the case of a key event, it should be delivered with KeyEvent.FLAG_CANCELED set.
+ * In the case of a motion event, it should be delivered as MotionEvent.ACTION_CANCEL. */
+ FLAG_CANCEL = 0x04
+ };
+
+ // The input channel to be targeted.
+ sp<InputChannel> inputChannel;
+
+ // Flags for the input target.
+ int32_t flags;
+
+ // The timeout for event delivery to this target in nanoseconds. Or -1 if none.
+ nsecs_t timeout;
+
+ // The x and y offset to add to a MotionEvent as it is delivered.
+ // (ignored for KeyEvents)
+ float xOffset, yOffset;
+};
+
+
+/*
+ * 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 input channel is unrecoverably broken. */
+ virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
+
+ /* Notifies the system that an input channel is not responding.
+ * Returns true and a new timeout value if the dispatcher should keep waiting.
+ * Otherwise returns false. */
+ virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
+ nsecs_t& outNewTimeout) = 0;
+
+ /* Notifies the system that an input channel recovered from ANR. */
+ virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
+
+ /* Gets the key repeat timeout or -1 if automatic key repeating is disabled. */
+ virtual nsecs_t getKeyRepeatTimeout() = 0;
+
+ /* Waits for key event input targets to become available.
+ * If the event is being injected, injectorPid and injectorUid should specify the
+ * process id and used id of the injecting application, otherwise they should both
+ * be -1.
+ * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
+ virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
+ int32_t injectorPid, int32_t injectorUid,
+ Vector<InputTarget>& outTargets) = 0;
+
+ /* Waits for motion event targets to become available.
+ * If the event is being injected, injectorPid and injectorUid should specify the
+ * process id and used id of the injecting application, otherwise they should both
+ * be -1.
+ * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
+ virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+ int32_t injectorPid, int32_t injectorUid,
+ Vector<InputTarget>& outTargets) = 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:
+ /* 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 notifyAppSwitchComing(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 metaState, int32_t edgeFlags,
+ uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime) = 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;
+
+ /* Preempts input dispatch in progress by making pending synchronous
+ * dispatches asynchronous instead. This method is generally called during a focus
+ * transition from one application to the next so as to enable the new application
+ * to start receiving input as soon as possible without having to wait for the
+ * old application to finish up.
+ *
+ * This method may be called on any thread (usually by the input manager).
+ */
+ virtual void preemptInputDispatch() = 0;
+
+ /* Registers or unregister input channels that may be used as targets for input events.
+ *
+ * These methods may be called on any thread (usually by the input manager).
+ */
+ virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 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 dispatchOnce();
+
+ virtual void notifyConfigurationChanged(nsecs_t eventTime);
+ virtual void notifyAppSwitchComing(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 metaState, int32_t edgeFlags,
+ uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime);
+
+ virtual int32_t injectInputEvent(const InputEvent* event,
+ int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
+
+ virtual void preemptInputDispatch();
+
+ virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+ virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+private:
+ template <typename T>
+ struct Link {
+ T* next;
+ T* prev;
+ };
+
+ struct EventEntry : Link<EventEntry> {
+ enum {
+ TYPE_SENTINEL,
+ TYPE_CONFIGURATION_CHANGED,
+ TYPE_KEY,
+ TYPE_MOTION
+ };
+
+ int32_t refCount;
+ int32_t type;
+ nsecs_t eventTime;
+
+ int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
+ bool injectionIsAsync; // set to true if injection is not waiting for the result
+ int32_t injectorPid; // -1 if not injected
+ int32_t injectorUid; // -1 if not injected
+
+ bool dispatchInProgress; // initially false, set to true while dispatching
+ int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
+
+ inline bool isInjected() { return injectorPid >= 0; }
+ };
+
+ struct ConfigurationChangedEntry : EventEntry {
+ };
+
+ struct KeyEntry : EventEntry {
+ 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;
+ };
+
+ struct MotionSample {
+ MotionSample* next;
+
+ nsecs_t eventTime;
+ PointerCoords pointerCoords[MAX_POINTERS];
+ };
+
+ struct MotionEntry : EventEntry {
+ int32_t deviceId;
+ int32_t source;
+ uint32_t policyFlags;
+ int32_t action;
+ 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;
+ };
+
+ // 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;
+ nsecs_t timeout;
+
+ // 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 isSyncTarget() {
+ return targetFlags & InputTarget::FLAG_SYNC;
+ }
+ };
+
+ // 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;
+ };
+
+ // Generic queue implementation.
+ template <typename T>
+ struct Queue {
+ T head;
+ T tail;
+
+ inline Queue() {
+ head.prev = NULL;
+ head.next = & tail;
+ tail.prev = & head;
+ tail.next = NULL;
+ }
+
+ inline bool isEmpty() {
+ return head.next == & tail;
+ }
+
+ inline void enqueueAtTail(T* entry) {
+ T* last = tail.prev;
+ last->next = entry;
+ entry->prev = last;
+ entry->next = & tail;
+ tail.prev = entry;
+ }
+
+ inline void enqueueAtHead(T* entry) {
+ T* first = head.next;
+ head.next = entry;
+ entry->prev = & head;
+ 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 = head.next;
+ dequeue(first);
+ return first;
+ }
+ };
+
+ /* Allocates queue entries and performs reference counting as needed. */
+ class Allocator {
+ public:
+ Allocator();
+
+ 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 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);
+ CommandEntry* obtainCommandEntry(Command command);
+
+ 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 appendMotionSample(MotionEntry* motionEntry,
+ nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+ private:
+ 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);
+ };
+
+ /* 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 client is not responding.
+ STATUS_NOT_RESPONDING,
+ // The input channel has been unregistered.
+ STATUS_ZOMBIE
+ };
+
+ Status status;
+ sp<InputChannel> inputChannel;
+ InputPublisher inputPublisher;
+ Queue<DispatchEntry> outboundQueue;
+ nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
+
+ nsecs_t lastEventTime; // the time when the event was originally captured
+ nsecs_t lastDispatchTime; // the time when the last event was dispatched
+ nsecs_t lastANRTime; // the time when the last ANR was recorded
+
+ 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;
+
+ // Determine whether this connection has a pending synchronous dispatch target.
+ // Since there can only ever be at most one such target at a time, if there is one,
+ // it must be at the tail because nothing else can be enqueued after it.
+ inline bool hasPendingSyncTarget() {
+ return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
+ }
+
+ // Gets the time since the current event was originally obtained from the input driver.
+ inline double getEventLatencyMillis(nsecs_t currentTime) {
+ return (currentTime - lastEventTime) / 1000000.0;
+ }
+
+ // Gets the time since the current event entered the outbound dispatch queue.
+ inline double getDispatchLatencyMillis(nsecs_t currentTime) {
+ return (currentTime - lastDispatchTime) / 1000000.0;
+ }
+
+ // Gets the time since the current event ANR was declared, if applicable.
+ inline double getANRLatencyMillis(nsecs_t currentTime) {
+ return (currentTime - lastANRTime) / 1000000.0;
+ }
+
+ status_t initialize();
+
+ void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
+ };
+
+ sp<InputDispatcherPolicyInterface> mPolicy;
+
+ Mutex mLock;
+
+ Allocator mAllocator;
+ sp<PollLoop> mPollLoop;
+
+ Queue<EventEntry> mInboundQueue;
+ Queue<CommandEntry> mCommandQueue;
+
+ // All registered connections mapped by receive pipe file descriptor.
+ KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
+
+ // 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;
+
+ // List of connections that have timed out. Only used by dispatchOnce()
+ // We don't use a ref-counted pointer here because it is not possible for a connection
+ // to be unregistered while processing timed out connections since we hold the lock for
+ // the duration.
+ Vector<Connection*> mTimedOutConnections;
+
+ // Preallocated key and motion event objects used only to ask the input dispatcher policy
+ // for the targets of an event that is to be dispatched.
+ KeyEvent mReusableKeyEvent;
+ MotionEvent mReusableMotionEvent;
+
+ // The input targets that were most recently identified for dispatch.
+ // If there is a synchronous event dispatch in progress, the current input targets will
+ // remain unchanged until the dispatch has completed or been aborted.
+ Vector<InputTarget> mCurrentInputTargets;
+ bool mCurrentInputTargetsValid; // false while targets are being recomputed
+
+ // Event injection and synchronization.
+ Condition mInjectionResultAvailableCondition;
+ EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
+ void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
+
+ Condition mInjectionSyncFinishedCondition;
+ void decrementPendingSyncDispatchesLocked(EventEntry* entry);
+
+ // Key repeat tracking.
+ // XXX Move this up to the input reader instead.
+ struct KeyRepeatState {
+ KeyEntry* lastKeyEntry; // or null if no repeat
+ nsecs_t nextRepeatTime;
+ } mKeyRepeatState;
+
+ void resetKeyRepeatLocked();
+
+ // Deferred command processing.
+ bool runCommandsLockedInterruptible();
+ CommandEntry* postCommandLocked(Command command);
+
+ // Process events that have just been dequeued from the head of the input queue.
+ void processConfigurationChangedLockedInterruptible(
+ nsecs_t currentTime, ConfigurationChangedEntry* entry);
+ void processKeyLockedInterruptible(
+ nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
+ void processKeyRepeatLockedInterruptible(
+ nsecs_t currentTime, nsecs_t keyRepeatTimeout);
+ void processMotionLockedInterruptible(
+ nsecs_t currentTime, MotionEntry* entry);
+
+ // Identify input targets for an event and dispatch to them.
+ void identifyInputTargetsAndDispatchKeyLockedInterruptible(
+ nsecs_t currentTime, KeyEntry* entry);
+ void identifyInputTargetsAndDispatchMotionLockedInterruptible(
+ nsecs_t currentTime, MotionEntry* entry);
+ void dispatchEventToCurrentInputTargetsLocked(
+ nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
+
+ // 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 timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+ void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
+ const sp<Connection>& connection, nsecs_t newTimeout);
+ void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+ bool broken);
+ static bool handleReceiveCallback(int receiveFd, int events, void* data);
+
+ // 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, bool recoveredFromANR);
+ void onDispatchCycleANRLocked(
+ nsecs_t currentTime, const sp<Connection>& connection);
+ void onDispatchCycleBrokenLocked(
+ nsecs_t currentTime, const sp<Connection>& connection);
+
+ // Outbound policy interactions.
+ void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
+ void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
+ void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
+};
+
+/* 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_PRIV_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
new file mode 100644
index 0000000..4012c69
--- /dev/null
+++ b/include/ui/InputManager.h
@@ -0,0 +1,172 @@
+/*
+ * 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;
+
+ /* Registers an input channel prior to using it as the target of an event. */
+ virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
+
+ /* Unregisters an input channel. */
+ virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 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.
+ */
+ virtual int32_t injectInputEvent(const InputEvent* event,
+ int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
+
+ /* Preempts input dispatch in progress by making pending synchronous
+ * dispatches asynchronous instead. This method is generally called during a focus
+ * transition from one application to the next so as to enable the new application
+ * to start receiving input as soon as possible without having to wait for the
+ * old application to finish up.
+ */
+ virtual void preemptInputDispatch() = 0;
+
+ /* Gets input device configuration. */
+ 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.
+ */
+ 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;
+
+ /* Queries 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;
+
+ /* Determines 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;
+};
+
+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 status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+ virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+ virtual int32_t injectInputEvent(const InputEvent* event,
+ int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
+
+ virtual void preemptInputDispatch();
+
+ 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);
+
+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
new file mode 100644
index 0000000..71c6c51
--- /dev/null
+++ b/include/ui/InputReader.h
@@ -0,0 +1,845 @@
+/*
+ * 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;
+
+
+/*
+ * 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
+ };
+
+ /* Actions returned by interceptXXX methods. */
+ enum {
+ // The input dispatcher should do nothing and discard the input unless other
+ // flags are set.
+ ACTION_NONE = 0,
+
+ // The input dispatcher should dispatch the input to the application.
+ ACTION_DISPATCH = 0x00000001,
+
+ // The input dispatcher should perform special filtering in preparation for
+ // a pending app switch.
+ ACTION_APP_SWITCH_COMING = 0x00000002,
+ };
+
+ /* 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;
+ };
+
+ /* 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;
+
+ /* Provides feedback for a virtual key down.
+ */
+ virtual void virtualKeyDownFeedback() = 0;
+
+ /* Intercepts a key event.
+ * The policy can use this method as an opportunity to perform power management functions
+ * and early event preprocessing such as updating policy flags.
+ *
+ * Returns a policy action constant such as ACTION_DISPATCH.
+ */
+ virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
+ bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;
+
+ /* Intercepts a switch event.
+ * The policy can use this method as an opportunity to perform power management functions
+ * and early event preprocessing such as updating policy flags.
+ *
+ * Switches are not dispatched to applications so this method should
+ * usually return ACTION_NONE.
+ */
+ virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+ uint32_t& policyFlags) = 0;
+
+ /* Intercepts a generic touch, trackball or other event.
+ * The policy can use this method as an opportunity to perform power management functions
+ * and early event preprocessing such as updating policy flags.
+ *
+ * Returns a policy action constant such as ACTION_DISPATCH.
+ */
+ virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 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 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:
+ /* 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 {
+protected:
+ InputReaderContext() { }
+ virtual ~InputReaderContext() { }
+
+public:
+ 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, private InputReaderContext {
+public:
+ InputReader(const sp<EventHubInterface>& eventHub,
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputDispatcherInterface>& dispatcher);
+ virtual ~InputReader();
+
+ 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);
+
+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(nsecs_t when, int32_t deviceId);
+ void removeDevice(nsecs_t when, int32_t deviceId);
+ InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
+ 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 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();
+
+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);
+};
+
+
+/* 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 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;
+
+ bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
+};
+
+
+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 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);
+ void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
+ bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);
+
+ 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 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;
+ }
+
+ inline bool isDirty() {
+ return 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);
+ void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+ PointerCoords* pointerCoords, nsecs_t downTime);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+ TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ virtual ~TouchInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ 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:
+ /* Maximum pointer id value supported.
+ * (This is limited by our use of BitSet32 to track pointer assignments.) */
+ static const uint32_t MAX_POINTER_ID = 31;
+
+ 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;
+ }
+ };
+
+ struct PointerData {
+ uint32_t id;
+ int32_t x;
+ int32_t y;
+ int32_t pressure;
+ int32_t size;
+ int32_t touchMajor;
+ int32_t touchMinor;
+ int32_t toolMajor;
+ int32_t toolMinor;
+ int32_t orientation;
+ };
+
+ 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;
+
+ // Raw axis information.
+ struct Axes {
+ RawAbsoluteAxisInfo x;
+ RawAbsoluteAxisInfo y;
+ RawAbsoluteAxisInfo pressure;
+ RawAbsoluteAxisInfo size;
+ RawAbsoluteAxisInfo touchMajor;
+ RawAbsoluteAxisInfo touchMinor;
+ RawAbsoluteAxisInfo toolMajor;
+ RawAbsoluteAxisInfo toolMinor;
+ RawAbsoluteAxisInfo orientation;
+ } mAxes;
+
+ // 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;
+
+ int32_t pressureOrigin;
+ float pressureScale;
+
+ int32_t sizeOrigin;
+ float sizeScale;
+
+ float orientationScale;
+
+ // Oriented motion ranges for input device info.
+ struct OrientedRanges {
+ InputDeviceInfo::MotionRange x;
+ InputDeviceInfo::MotionRange y;
+ InputDeviceInfo::MotionRange pressure;
+ InputDeviceInfo::MotionRange size;
+ InputDeviceInfo::MotionRange touchMajor;
+ InputDeviceInfo::MotionRange touchMinor;
+ InputDeviceInfo::MotionRange toolMajor;
+ InputDeviceInfo::MotionRange toolMinor;
+ 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 configureAxes();
+ virtual bool configureSurfaceLocked();
+ virtual void configureVirtualKeysLocked();
+
+ 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 JumpTouchFilterState {
+ 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, int32_t motionEventAction);
+
+ void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags,
+ int32_t keyCode, int32_t scanCode, nsecs_t downTime);
+
+ 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 configureAxes();
+
+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;
+ }
+
+ inline bool isDirty() {
+ return fields != 0;
+ }
+ } mAccumulator;
+
+ bool mDown;
+ int32_t mX;
+ int32_t mY;
+ int32_t mPressure;
+ int32_t mSize;
+
+ 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 configureAxes();
+
+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
+ };
+
+ 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;
+
+ 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();
+ }
+
+ inline bool isDirty() {
+ return pointerCount != 0;
+ }
+ } 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
new file mode 100644
index 0000000..31ec701
--- /dev/null
+++ b/include/ui/InputTransport.h
@@ -0,0 +1,334 @@
+/*
+ * 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_TRANSPORT_H
+#define _UI_INPUT_TRANSPORT_H
+
+/**
+ * Native input transport.
+ *
+ * Uses anonymous shared memory as a whiteboard for sending input events from an
+ * InputPublisher to an InputConsumer and ensuring appropriate synchronization.
+ * One interesting feature is that published events can be updated in place as long as they
+ * have not yet been consumed.
+ *
+ * The InputPublisher and InputConsumer only take care of transferring event data
+ * over an InputChannel and sending synchronization signals. The InputDispatcher and InputQueue
+ * build on these abstractions to add multiplexing and queueing.
+ */
+
+#include <semaphore.h>
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/PollLoop.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * An input channel consists of a shared memory buffer and a pair of pipes
+ * used to send input messages from an InputPublisher to an InputConsumer
+ * across processes. Each channel has a descriptive name for debugging purposes.
+ *
+ * Each endpoint has its own InputChannel object that specifies its own file descriptors.
+ *
+ * The input channel is closed when all references to it are released.
+ */
+class InputChannel : public RefBase {
+protected:
+ virtual ~InputChannel();
+
+public:
+ InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd,
+ int32_t sendPipeFd);
+
+ /* Creates a pair of input channels and their underlying shared memory buffers
+ * and pipes.
+ *
+ * Returns OK on success.
+ */
+ static status_t openInputChannelPair(const String8& name,
+ sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
+
+ inline String8 getName() const { return mName; }
+ inline int32_t getAshmemFd() const { return mAshmemFd; }
+ inline int32_t getReceivePipeFd() const { return mReceivePipeFd; }
+ inline int32_t getSendPipeFd() const { return mSendPipeFd; }
+
+ /* Sends a signal to the other endpoint.
+ *
+ * Returns OK on success.
+ * Returns DEAD_OBJECT if the channel's peer has been closed.
+ * Other errors probably indicate that the channel is broken.
+ */
+ status_t sendSignal(char signal);
+
+ /* Receives a signal send by the other endpoint.
+ * (Should only call this after poll() indicates that the receivePipeFd has available input.)
+ *
+ * Returns OK on success.
+ * Returns WOULD_BLOCK if there is no signal present.
+ * Returns DEAD_OBJECT if the channel's peer has been closed.
+ * Other errors probably indicate that the channel is broken.
+ */
+ status_t receiveSignal(char* outSignal);
+
+private:
+ String8 mName;
+ int32_t mAshmemFd;
+ int32_t mReceivePipeFd;
+ int32_t mSendPipeFd;
+};
+
+/*
+ * Private intermediate representation of input events as messages written into an
+ * ashmem buffer.
+ */
+struct InputMessage {
+ /* Semaphore count is set to 1 when the message is published.
+ * It becomes 0 transiently while the publisher updates the message.
+ * It becomes 0 permanently when the consumer consumes the message.
+ */
+ sem_t semaphore;
+
+ /* Initialized to false by the publisher.
+ * Set to true by the consumer when it consumes the message.
+ */
+ bool consumed;
+
+ int32_t type;
+
+ struct SampleData {
+ nsecs_t eventTime;
+ PointerCoords coords[0]; // variable length
+ };
+
+ int32_t deviceId;
+ int32_t source;
+
+ union {
+ struct {
+ int32_t action;
+ int32_t flags;
+ int32_t keyCode;
+ int32_t scanCode;
+ int32_t metaState;
+ int32_t repeatCount;
+ nsecs_t downTime;
+ nsecs_t eventTime;
+ } key;
+
+ struct {
+ int32_t action;
+ int32_t metaState;
+ int32_t edgeFlags;
+ nsecs_t downTime;
+ float xOffset;
+ float yOffset;
+ float xPrecision;
+ float yPrecision;
+ size_t pointerCount;
+ int32_t pointerIds[MAX_POINTERS];
+ size_t sampleCount;
+ SampleData sampleData[0]; // variable length
+ } motion;
+ };
+
+ /* Gets the number of bytes to add to step to the next SampleData object in a motion
+ * event message for a given number of pointers.
+ */
+ static inline size_t sampleDataStride(size_t pointerCount) {
+ return sizeof(InputMessage::SampleData) + pointerCount * sizeof(PointerCoords);
+ }
+
+ /* Adds the SampleData stride to the given pointer. */
+ static inline SampleData* sampleDataPtrIncrement(SampleData* ptr, size_t stride) {
+ return reinterpret_cast<InputMessage::SampleData*>(reinterpret_cast<char*>(ptr) + stride);
+ }
+};
+
+/*
+ * Publishes input events to an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent consumer.
+ */
+class InputPublisher {
+public:
+ /* Creates a publisher associated with an input channel. */
+ explicit InputPublisher(const sp<InputChannel>& channel);
+
+ /* Destroys the publisher and releases its input channel. */
+ ~InputPublisher();
+
+ /* Gets the underlying input channel. */
+ inline sp<InputChannel> getChannel() { return mChannel; }
+
+ /* Prepares the publisher for use. Must be called before it is used.
+ * Returns OK on success.
+ *
+ * This method implicitly calls reset(). */
+ status_t initialize();
+
+ /* Resets the publisher to its initial state and unpins its ashmem buffer.
+ * Returns OK on success.
+ *
+ * Should be called after an event has been consumed to release resources used by the
+ * publisher until the next event is ready to be published.
+ */
+ status_t reset();
+
+ /* Publishes a key event to the ashmem buffer.
+ *
+ * Returns OK on success.
+ * Returns INVALID_OPERATION if the publisher has not been reset.
+ */
+ status_t publishKeyEvent(
+ 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,
+ nsecs_t eventTime);
+
+ /* Publishes a motion event to the ashmem buffer.
+ *
+ * Returns OK on success.
+ * Returns INVALID_OPERATION if the publisher has not been reset.
+ * Returns BAD_VALUE if pointerCount is less than 1 or greater than MAX_POINTERS.
+ */
+ status_t publishMotionEvent(
+ int32_t deviceId,
+ int32_t source,
+ int32_t action,
+ int32_t edgeFlags,
+ int32_t metaState,
+ float xOffset,
+ float yOffset,
+ float xPrecision,
+ float yPrecision,
+ nsecs_t downTime,
+ nsecs_t eventTime,
+ size_t pointerCount,
+ const int32_t* pointerIds,
+ const PointerCoords* pointerCoords);
+
+ /* Appends a motion sample to a motion event unless already consumed.
+ *
+ * Returns OK on success.
+ * Returns INVALID_OPERATION if the current event is not a AMOTION_EVENT_ACTION_MOVE event.
+ * Returns FAILED_TRANSACTION if the current event has already been consumed.
+ * Returns NO_MEMORY if the buffer is full and no additional samples can be added.
+ */
+ status_t appendMotionSample(
+ nsecs_t eventTime,
+ const PointerCoords* pointerCoords);
+
+ /* Sends a dispatch signal to the consumer to inform it that a new message is available.
+ *
+ * Returns OK on success.
+ * Errors probably indicate that the channel is broken.
+ */
+ status_t sendDispatchSignal();
+
+ /* Receives the finished signal from the consumer in reply to the original dispatch signal.
+ *
+ * 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();
+
+private:
+ sp<InputChannel> mChannel;
+
+ size_t mAshmemSize;
+ InputMessage* mSharedMessage;
+ bool mPinned;
+ bool mSemaphoreInitialized;
+ bool mWasDispatched;
+
+ size_t mMotionEventPointerCount;
+ InputMessage::SampleData* mMotionEventSampleDataTail;
+ size_t mMotionEventSampleDataStride;
+
+ status_t publishInputEvent(
+ int32_t type,
+ int32_t deviceId,
+ int32_t source);
+};
+
+/*
+ * Consumes input events from an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent publisher.
+ */
+class InputConsumer {
+public:
+ /* Creates a consumer associated with an input channel. */
+ explicit InputConsumer(const sp<InputChannel>& channel);
+
+ /* Destroys the consumer and releases its input channel. */
+ ~InputConsumer();
+
+ /* Gets the underlying input channel. */
+ inline sp<InputChannel> getChannel() { return mChannel; }
+
+ /* Prepares the consumer for use. Must be called before it is used. */
+ status_t initialize();
+
+ /* Consumes the input event in the buffer and copies its contents into
+ * an InputEvent object created using the specified factory.
+ * This operation will block if the publisher is updating the event.
+ *
+ * Returns OK on success.
+ * Returns INVALID_OPERATION if there is no currently published event.
+ * Returns NO_MEMORY if the event could not be created.
+ */
+ status_t consume(InputEventFactoryInterface* factory, InputEvent** outEvent);
+
+ /* Sends a finished signal to the publisher to inform it that the current message is
+ * finished processing.
+ *
+ * Returns OK on success.
+ * Errors probably indicate that the channel is broken.
+ */
+ status_t sendFinishedSignal();
+
+ /* Receives the dispatched signal from the publisher.
+ *
+ * Returns OK on success.
+ * Returns WOULD_BLOCK if there is no signal present.
+ * Other errors probably indicate that the channel is broken.
+ */
+ status_t receiveDispatchSignal();
+
+private:
+ sp<InputChannel> mChannel;
+
+ size_t mAshmemSize;
+ InputMessage* mSharedMessage;
+
+ void populateKeyEvent(KeyEvent* keyEvent) const;
+ void populateMotionEvent(MotionEvent* motionEvent) const;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_TRANSPORT_H
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index 571e47b..c8d6ffc 100644..100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -17,6 +17,8 @@
#ifndef _UI_KEYCODE_LABELS_H
#define _UI_KEYCODE_LABELS_H
+#include <android/keycodes.h>
+
struct KeycodeLabel {
const char *literal;
int value;
@@ -114,113 +116,32 @@ static const KeycodeLabel KEYCODES[] = {
{ "MEDIA_REWIND", 89 },
{ "MEDIA_FAST_FORWARD", 90 },
{ "MUTE", 91 },
+ { "PAGE_UP", 92 },
+ { "PAGE_DOWN", 93 },
+ { "PICTSYMBOLS", 94 },
+ { "SWITCH_CHARSET", 95 },
+ { "BUTTON_A", 96 },
+ { "BUTTON_B", 97 },
+ { "BUTTON_C", 98 },
+ { "BUTTON_X", 99 },
+ { "BUTTON_Y", 100 },
+ { "BUTTON_Z", 101 },
+ { "BUTTON_L1", 102 },
+ { "BUTTON_R1", 103 },
+ { "BUTTON_L2", 104 },
+ { "BUTTON_R2", 105 },
+ { "BUTTON_THUMBL", 106 },
+ { "BUTTON_THUMBR", 107 },
+ { "BUTTON_START", 108 },
+ { "BUTTON_SELECT", 109 },
+ { "BUTTON_MODE", 110 },
- // NOTE: If you add a new keycode here you must also add it to:
- // (enum KeyCode, in this file)
- // frameworks/base/core/java/android/view/KeyEvent.java
- // tools/puppet_master/PuppetMaster.nav_keys.py
- // frameworks/base/core/res/res/values/attrs.xml
+ // 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.
{ NULL, 0 }
};
-// These constants need to match the above mappings.
-typedef enum KeyCode {
- kKeyCodeUnknown = 0,
-
- kKeyCodeSoftLeft = 1,
- kKeyCodeSoftRight = 2,
- kKeyCodeHome = 3,
- kKeyCodeBack = 4,
- kKeyCodeCall = 5,
- kKeyCodeEndCall = 6,
- kKeyCode0 = 7,
- kKeyCode1 = 8,
- kKeyCode2 = 9,
- kKeyCode3 = 10,
- kKeyCode4 = 11,
- kKeyCode5 = 12,
- kKeyCode6 = 13,
- kKeyCode7 = 14,
- kKeyCode8 = 15,
- kKeyCode9 = 16,
- kKeyCodeStar = 17,
- kKeyCodePound = 18,
- kKeyCodeDpadUp = 19,
- kKeyCodeDpadDown = 20,
- kKeyCodeDpadLeft = 21,
- kKeyCodeDpadRight = 22,
- kKeyCodeDpadCenter = 23,
- kKeyCodeVolumeUp = 24,
- kKeyCodeVolumeDown = 25,
- kKeyCodePower = 26,
- kKeyCodeCamera = 27,
- kKeyCodeClear = 28,
- kKeyCodeA = 29,
- kKeyCodeB = 30,
- kKeyCodeC = 31,
- kKeyCodeD = 32,
- kKeyCodeE = 33,
- kKeyCodeF = 34,
- kKeyCodeG = 35,
- kKeyCodeH = 36,
- kKeyCodeI = 37,
- kKeyCodeJ = 38,
- kKeyCodeK = 39,
- kKeyCodeL = 40,
- kKeyCodeM = 41,
- kKeyCodeN = 42,
- kKeyCodeO = 43,
- kKeyCodeP = 44,
- kKeyCodeQ = 45,
- kKeyCodeR = 46,
- kKeyCodeS = 47,
- kKeyCodeT = 48,
- kKeyCodeU = 49,
- kKeyCodeV = 50,
- kKeyCodeW = 51,
- kKeyCodeX = 52,
- kKeyCodeY = 53,
- kKeyCodeZ = 54,
- kKeyCodeComma = 55,
- kKeyCodePeriod = 56,
- kKeyCodeAltLeft = 57,
- kKeyCodeAltRight = 58,
- kKeyCodeShiftLeft = 59,
- kKeyCodeShiftRight = 60,
- kKeyCodeTab = 61,
- kKeyCodeSpace = 62,
- kKeyCodeSym = 63,
- kKeyCodeExplorer = 64,
- kKeyCodeEnvelope = 65,
- kKeyCodeNewline = 66,
- kKeyCodeDel = 67,
- kKeyCodeGrave = 68,
- kKeyCodeMinus = 69,
- kKeyCodeEquals = 70,
- kKeyCodeLeftBracket = 71,
- kKeyCodeRightBracket = 72,
- kKeyCodeBackslash = 73,
- kKeyCodeSemicolon = 74,
- kKeyCodeApostrophe = 75,
- kKeyCodeSlash = 76,
- kKeyCodeAt = 77,
- kKeyCodeNum = 78,
- kKeyCodeHeadSetHook = 79,
- kKeyCodeFocus = 80,
- kKeyCodePlus = 81,
- kKeyCodeMenu = 82,
- kKeyCodeNotification = 83,
- kKeyCodeSearch = 84,
- kKeyCodePlayPause = 85,
- kKeyCodeStop = 86,
- kKeyCodeNextSong = 87,
- kKeyCodePreviousSong = 88,
- kKeyCodeRewind = 89,
- kKeyCodeForward = 90,
- kKeyCodeMute = 91
-} KeyCode;
-
static const KeycodeLabel FLAGS[] = {
{ "WAKE", 0x00000001 },
{ "WAKE_DROPPED", 0x00000002 },
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index a213c09..4e65a2d 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -20,31 +20,28 @@
#include <utils/TypeHelpers.h>
#include <ui/Point.h>
+#include <android/rect.h>
+
namespace android {
-class Rect
+class Rect : public ARect
{
public:
- int left;
- int top;
- int right;
- int bottom;
-
- typedef int value_type;
+ typedef int32_t value_type;
// we don't provide copy-ctor and operator= on purpose
// because we want the compiler generated versions
inline Rect() {
}
- inline Rect(int w, int h)
- : left(0), top(0), right(w), bottom(h) {
+ inline Rect(int32_t w, int32_t h) {
+ left = top = 0; right = w; bottom = h;
}
- inline Rect(int l, int t, int r, int b)
- : left(l), top(t), right(r), bottom(b) {
+ inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {
+ left = l; top = t; right = r; bottom = b;
}
- inline Rect(const Point& lt, const Point& rb)
- : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) {
+ inline Rect(const Point& lt, const Point& rb) {
+ left = lt.x; top = lt.y; right = rb.x; bottom = rb.y;
}
void makeInvalid();
@@ -68,12 +65,12 @@ public:
}
// rectangle's width
- inline int width() const {
+ inline int32_t width() const {
return right-left;
}
// rectangle's height
- inline int height() const {
+ inline int32_t height() const {
return bottom-top;
}
@@ -136,12 +133,12 @@ public:
const Rect operator + (const Point& rhs) const;
const Rect operator - (const Point& rhs) const;
- void translate(int dx, int dy) { // legacy, don't use.
+ void translate(int32_t dx, int32_t dy) { // legacy, don't use.
offsetBy(dx, dy);
}
- Rect& offsetTo(int x, int y);
- Rect& offsetBy(int x, int y);
+ Rect& offsetTo(int32_t x, int32_t y);
+ Rect& offsetBy(int32_t x, int32_t y);
bool intersect(const Rect& with, Rect* result) const;
};
diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h
index 9c92af8..402843e 100644
--- a/include/ui/android_native_buffer.h
+++ b/include/ui/android_native_buffer.h
@@ -33,6 +33,15 @@ typedef struct android_native_buffer_t
common.version = sizeof(android_native_buffer_t);
memset(common.reserved, 0, sizeof(common.reserved));
}
+
+ // Implement the methods that sp<android_native_buffer_t> expects so that it
+ // can be used to automatically refcount android_native_buffer_t's.
+ void incStrong(const void* id) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* id) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
#endif
struct android_native_base_t common;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 773fd93..ca89b06 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -22,6 +22,8 @@
#include <hardware/gralloc.h>
+#include <android/native_window.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,6 +43,14 @@ extern "C" {
struct android_native_buffer_t;
+typedef struct android_native_rect_t
+{
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} android_native_rect_t;
+
// ---------------------------------------------------------------------------
typedef struct android_native_base_t
@@ -63,15 +73,18 @@ typedef struct android_native_base_t
/* attributes queriable with query() */
enum {
NATIVE_WINDOW_WIDTH = 0,
- NATIVE_WINDOW_HEIGHT = 1,
- NATIVE_WINDOW_FORMAT = 2,
+ NATIVE_WINDOW_HEIGHT,
+ NATIVE_WINDOW_FORMAT,
};
/* valid operations for the (*perform)() hook */
enum {
NATIVE_WINDOW_SET_USAGE = 0,
- NATIVE_WINDOW_CONNECT = 1,
- NATIVE_WINDOW_DISCONNECT = 2
+ NATIVE_WINDOW_CONNECT,
+ NATIVE_WINDOW_DISCONNECT,
+ NATIVE_WINDOW_SET_CROP,
+ NATIVE_WINDOW_SET_BUFFER_COUNT,
+ NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
};
/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -79,16 +92,25 @@ enum {
NATIVE_WINDOW_API_EGL = 1
};
-typedef struct android_native_window_t
+struct ANativeWindow
{
#ifdef __cplusplus
- android_native_window_t()
+ ANativeWindow()
: flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
{
common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
- common.version = sizeof(android_native_window_t);
+ common.version = sizeof(ANativeWindow);
memset(common.reserved, 0, sizeof(common.reserved));
}
+
+ // Implement the methods that sp<ANativeWindow> expects so that it
+ // can be used to automatically refcount ANativeWindow's.
+ void incStrong(const void* id) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* id) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
#endif
struct android_native_base_t common;
@@ -115,7 +137,7 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*setSwapInterval)(struct android_native_window_t* window,
+ int (*setSwapInterval)(struct ANativeWindow* window,
int interval);
/*
@@ -125,7 +147,7 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*dequeueBuffer)(struct android_native_window_t* window,
+ int (*dequeueBuffer)(struct ANativeWindow* window,
struct android_native_buffer_t** buffer);
/*
@@ -135,7 +157,7 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*lockBuffer)(struct android_native_window_t* window,
+ int (*lockBuffer)(struct ANativeWindow* window,
struct android_native_buffer_t* buffer);
/*
* hook called by EGL when modifications to the render buffer are done.
@@ -145,7 +167,7 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*queueBuffer)(struct android_native_window_t* window,
+ int (*queueBuffer)(struct ANativeWindow* window,
struct android_native_buffer_t* buffer);
/*
@@ -153,13 +175,13 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*query)(struct android_native_window_t* window,
+ int (*query)(struct ANativeWindow* window,
int what, int* value);
/*
* hook used to perform various operations on the surface.
* (*perform)() is a generic mechanism to add functionality to
- * android_native_window_t while keeping backward binary compatibility.
+ * ANativeWindow while keeping backward binary compatibility.
*
* This hook should not be called directly, instead use the helper functions
* defined below.
@@ -171,19 +193,25 @@ typedef struct android_native_window_t
* NATIVE_WINDOW_SET_USAGE
* NATIVE_WINDOW_CONNECT
* NATIVE_WINDOW_DISCONNECT
+ * NATIVE_WINDOW_SET_CROP
+ * NATIVE_WINDOW_SET_BUFFER_COUNT
+ * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
*
*/
- int (*perform)(struct android_native_window_t* window,
+ int (*perform)(struct ANativeWindow* window,
int operation, ... );
void* reserved_proc[3];
-} android_native_window_t;
+};
+// Backwards compatibility... please switch to ANativeWindow.
+typedef struct ANativeWindow android_native_window_t;
/*
- * native_window_set_usage() sets the intended usage flags for the next
- * buffers acquired with (*lockBuffer)() and on.
+ * native_window_set_usage(..., usage)
+ * Sets the intended usage flags for the next buffers
+ * acquired with (*lockBuffer)() and on.
* By default (if this function is never called), a usage of
* GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
* is assumed.
@@ -192,35 +220,83 @@ typedef struct android_native_window_t
*/
static inline int native_window_set_usage(
- android_native_window_t* window, int usage)
+ ANativeWindow* window, int usage)
{
return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
}
/*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made current.
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made current.
* Returns -EINVAL if for some reason the window cannot be connected, which
* can happen if it's connected to some other API.
*/
static inline int native_window_connect(
- android_native_window_t* window, int api)
+ ANativeWindow* window, int api)
{
return window->perform(window, NATIVE_WINDOW_CONNECT, api);
}
/*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made not current.
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made not current.
* An error is returned if for instance the window wasn't connected in the
* first place.
*/
static inline int native_window_disconnect(
- android_native_window_t* window, int api)
+ ANativeWindow* window, int api)
{
return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
}
+/*
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * A buffer's crop region is scaled to match the surface's size.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * if 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid,
+ * out of the buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+ ANativeWindow* window,
+ android_native_rect_t const * crop)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
+
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+ ANativeWindow* window,
+ size_t bufferCount)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the geometry specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon composition.
+ *
+ * If all parameters are 0, the normal behavior is restored. That is,
+ * dequeued buffers following this call will be sized to the window's size.
+ *
+ */
+static inline int native_window_set_buffers_geometry(
+ ANativeWindow* window,
+ int w, int h, int format)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+ w, h, format);
+}
// ---------------------------------------------------------------------------
@@ -263,6 +339,15 @@ namespace android {
template <typename NATIVE_TYPE, typename TYPE, typename REF>
class EGLNativeBase : public NATIVE_TYPE, public REF
{
+public:
+ // Disambiguate between the incStrong in REF and NATIVE_TYPE
+ void incStrong(const void* id) const {
+ REF::incStrong(id);
+ }
+ void decStrong(const void* id) const {
+ REF::decStrong(id);
+ }
+
protected:
typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
EGLNativeBase() : NATIVE_TYPE(), REF() {
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
index 5908bcc..2a09095 100644
--- a/include/utils/Asset.h
+++ b/include/utils/Asset.h
@@ -61,15 +61,6 @@ public:
ACCESS_BUFFER,
} AccessMode;
- enum {
- /* data larger than this does not get uncompressed into a buffer */
-#ifdef HAVE_ANDROID_OS
- UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
-#else
- UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024
-#endif
- };
-
/*
* Read data from the current offset. Returns the actual number of
* bytes read, 0 on EOF, or -1 on error.
@@ -317,6 +308,8 @@ private:
FileMap* mMap; // for memory-mapped input
int mFd; // for file input
+ class StreamingZipInflater* mZipInflater; // for streaming large compressed assets
+
unsigned char* mBuf; // for getBuffer()
};
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
index d8994e0..9e2bf37 100644
--- a/include/utils/AssetManager.h
+++ b/include/utils/AssetManager.h
@@ -29,6 +29,24 @@
#include <utils/ZipFileRO.h>
#include <utils/threads.h>
+/*
+ * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAssetManager { };
+
+#ifdef __cplusplus
+};
+#endif
+
+
+/*
+ * Now the proper C++ android-namespace definitions
+ */
+
namespace android {
class Asset; // fwd decl for things that include Asset.h first
@@ -48,7 +66,7 @@ struct ResTable_config;
* The asset hierarchy may be examined like a filesystem, using
* AssetDir objects to peruse a single directory.
*/
-class AssetManager {
+class AssetManager : public AAssetManager {
public:
typedef enum CacheMode {
CACHE_UNKNOWN = 0,
@@ -111,6 +129,8 @@ public:
*/
void setConfiguration(const ResTable_config& config, const char* locale = NULL);
+ void getConfiguration(ResTable_config* outConfig) const;
+
typedef Asset::AccessMode AccessMode; // typing shortcut
/*
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
new file mode 100644
index 0000000..19c8bf0
--- /dev/null
+++ b/include/utils/BitSet.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_BITSET_H
+#define UTILS_BITSET_H
+
+#include <stdint.h>
+
+/*
+ * Contains some bit manipulation helpers.
+ */
+
+namespace android {
+
+// A simple set of 32 bits that can be individually marked or cleared.
+struct BitSet32 {
+ uint32_t value;
+
+ inline BitSet32() : value(0) { }
+ explicit inline BitSet32(uint32_t value) : value(value) { }
+
+ // Gets the value associated with a particular bit index.
+ static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; }
+
+ // Clears the bit set.
+ inline void clear() { value = 0; }
+
+ // Returns true if the bit set does not contain any marked bits.
+ inline bool isEmpty() const { return ! value; }
+
+ // Returns true if the specified bit is marked.
+ inline bool hasBit(uint32_t n) const { return value & valueForBit(n); }
+
+ // Marks the specified bit.
+ inline void markBit(uint32_t n) { value |= valueForBit(n); }
+
+ // Clears the specified bit.
+ inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); }
+
+ // Finds the first marked bit in the set.
+ // Result is undefined if all bits are unmarked.
+ inline uint32_t firstMarkedBit() const { return __builtin_clz(value); }
+
+ // Finds the first unmarked bit in the set.
+ // Result is undefined if all bits are marked.
+ inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); }
+
+ inline bool operator== (const BitSet32& other) const { return value == other.value; }
+ inline bool operator!= (const BitSet32& other) const { return value != other.value; }
+};
+
+} // namespace android
+
+#endif // UTILS_BITSET_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
deleted file mode 100644
index 8e22b0f..0000000
--- a/include/utils/Buffer.h
+++ /dev/null
@@ -1,107 +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 __UTILS_BUFFER_H__
-#define __UTILS_BUFFER_H__ 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-class Buffer
-{
-private:
- char *buf;
- int bufsiz;
- int used;
- void ensureCapacity(int len);
-
- void
- makeRoomFor(int len)
- {
- if (len + used >= bufsiz) {
- bufsiz = (len + used) * 3/2 + 2;
- char *blah = new char[bufsiz];
-
- memcpy(blah, buf, used);
- delete[] buf;
- buf = blah;
- }
- }
-
-public:
- Buffer()
- {
- bufsiz = 16;
- buf = new char[bufsiz];
- clear();
- }
-
- ~Buffer()
- {
- delete[] buf;
- }
-
- void
- clear()
- {
- buf[0] = '\0';
- used = 0;
- }
-
- int
- length()
- {
- return used;
- }
-
- void
- append(const char c)
- {
- makeRoomFor(1);
- buf[used] = c;
- used++;
- buf[used] = '\0';
- }
-
- void
- append(const char *s, int len)
- {
- makeRoomFor(len);
-
- memcpy(buf + used, s, len);
- used += len;
- buf[used] = '\0';
- }
-
- void
- append(const char *s)
- {
- append(s, strlen(s));
- }
-
- char *
- getBytes()
- {
- return buf;
- }
-};
-
-}; // namespace android
-
-#endif
diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h
new file mode 100644
index 0000000..d2ca82e
--- /dev/null
+++ b/include/utils/ObbFile.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 OBBFILE_H_
+#define OBBFILE_H_
+
+#include <stdint.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class ObbFile : public RefBase {
+protected:
+ virtual ~ObbFile();
+
+public:
+ ObbFile();
+
+ bool readFrom(const char* filename);
+ bool readFrom(int fd);
+ bool writeTo(const char* filename);
+ bool writeTo(int fd);
+ bool removeFrom(const char* filename);
+ bool removeFrom(int fd);
+
+ const char* getFileName() const {
+ return mFileName;
+ }
+
+ const String8 getPackageName() const {
+ return mPackageName;
+ }
+
+ int32_t getVersion() const {
+ return mVersion;
+ }
+
+ void setPackageName(String8 packageName) {
+ mPackageName = packageName;
+ }
+
+ void setVersion(int32_t version) {
+ mVersion = version;
+ }
+
+ static inline uint32_t get4LE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ }
+
+ static inline void put4LE(unsigned char* buf, uint32_t val) {
+ buf[0] = val & 0xFF;
+ buf[1] = (val >> 8) & 0xFF;
+ buf[2] = (val >> 16) & 0xFF;
+ buf[3] = (val >> 24) & 0xFF;
+ }
+
+private:
+ /* Package name this ObbFile is associated with */
+ String8 mPackageName;
+
+ /* Package version this ObbFile is associated with */
+ int32_t mVersion;
+
+ const char* mFileName;
+
+ size_t mFileSize;
+
+ size_t mFooterStart;
+
+ unsigned char* mReadBuf;
+
+ bool parseObbFile(int fd);
+};
+
+}
+#endif /* OBBFILE_H_ */
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
new file mode 100644
index 0000000..81230e8
--- /dev/null
+++ b/include/utils/PollLoop.h
@@ -0,0 +1,197 @@
+/*
+ * 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_POLL_LOOP_H
+#define UTILS_POLL_LOOP_H
+
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+#include <sys/poll.h>
+
+#include <android/looper.h>
+
+struct ALooper : public android::RefBase {
+protected:
+ virtual ~ALooper() { }
+
+public:
+ ALooper() { }
+};
+
+namespace android {
+
+/**
+ * A basic file descriptor polling loop based on poll() with callbacks.
+ */
+class PollLoop : public ALooper {
+protected:
+ virtual ~PollLoop();
+
+public:
+ PollLoop(bool allowNonCallbacks);
+
+ /**
+ * A callback that it to be invoked when an event occurs on a file descriptor.
+ * Specifies the events that were triggered and the user data provided when the
+ * callback was set.
+ *
+ * Returns true if the callback should be kept, false if it should be removed automatically
+ * after the callback returns.
+ */
+ typedef bool (*Callback)(int fd, int events, void* data);
+
+ enum {
+ POLL_CALLBACK = ALOOPER_POLL_CALLBACK,
+ POLL_TIMEOUT = ALOOPER_POLL_TIMEOUT,
+ POLL_ERROR = ALOOPER_POLL_ERROR,
+ };
+
+ /**
+ * Performs a single call to poll() with optional timeout in milliseconds.
+ * Invokes callbacks for all file descriptors on which an event occurred.
+ *
+ * If the timeout is zero, returns immediately without blocking.
+ * If the timeout is negative, waits indefinitely until awoken.
+ *
+ * Returns ALOOPER_POLL_CALLBACK if a callback was invoked.
+ *
+ * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
+ * timeout expired.
+ *
+ * Returns ALOPER_POLL_ERROR if an error occurred.
+ *
+ * Returns a value >= 0 containing a file descriptor if it has data
+ * and it has no callback function (requiring the caller here to handle it).
+ * In this (and only this) case outEvents and outData will contain the poll
+ * events and data associated with the fd.
+ *
+ * This method must only be called on the thread owning the PollLoop.
+ * This method blocks until either a file descriptor is signalled, a timeout occurs,
+ * or wake() is called.
+ * This method does not return until it has finished invoking the appropriate callbacks
+ * for all file descriptors that were signalled.
+ */
+ int32_t pollOnce(int timeoutMillis, int* outEvents = NULL, void** outData = NULL);
+
+ /**
+ * Wakes the loop asynchronously.
+ *
+ * This method can be called on any thread.
+ * This method returns immediately.
+ */
+ void wake();
+
+ /**
+ * Control whether this PollLoop instance allows using IDs instead
+ * of callbacks.
+ */
+ bool getAllowNonCallbacks() const;
+
+ /**
+ * Sets the callback for a file descriptor, replacing the existing one, if any.
+ * It is an error to call this method with events == 0 or callback == NULL.
+ *
+ * Note that a callback can be invoked with the POLLERR, POLLHUP or POLLNVAL events
+ * even if it is not explicitly requested when registered.
+ *
+ * This method can be called on any thread.
+ * This method may block briefly if it needs to wake the poll loop.
+ */
+ void setCallback(int fd, int events, Callback callback, void* data = NULL);
+
+ /**
+ * Like setCallback(), but for the NDK callback function.
+ */
+ void setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+ void* data);
+
+ /**
+ * Removes the callback for a file descriptor, if one exists.
+ *
+ * When this method returns, it is safe to close the file descriptor since the poll loop
+ * will no longer have a reference to it. However, it is possible for the callback to
+ * already be running or for it to run one last time if the file descriptor was already
+ * signalled. Calling code is responsible for ensuring that this case is safely handled.
+ * For example, if the callback takes care of removing itself during its own execution either
+ * by returning false or calling this method, then it can be guaranteed to not be invoked
+ * again at any later time unless registered anew.
+ *
+ * This method can be called on any thread.
+ * This method may block briefly if it needs to wake the poll loop.
+ *
+ * Returns true if a callback was actually removed, false if none was registered.
+ */
+ bool removeCallback(int fd);
+
+ /**
+ * Set the given PollLoop to be associated with the
+ * calling thread. There must be a 1:1 relationship between
+ * PollLoop and thread.
+ */
+ static void setForThread(const sp<PollLoop>& pollLoop);
+
+ /**
+ * Return the PollLoop associated with the calling thread.
+ */
+ static sp<PollLoop> getForThread();
+
+private:
+ struct RequestedCallback {
+ Callback callback;
+ ALooper_callbackFunc* looperCallback;
+ void* data;
+ };
+
+ struct PendingCallback {
+ int fd;
+ int events;
+ Callback callback;
+ ALooper_callbackFunc* looperCallback;
+ void* data;
+ };
+
+ const bool mAllowNonCallbacks;
+
+ Mutex mLock;
+ bool mPolling;
+ uint32_t mWaiters;
+ Condition mAwake;
+ Condition mResume;
+
+ int mWakeReadPipeFd;
+ int mWakeWritePipeFd;
+
+ Vector<struct pollfd> mRequestedFds;
+ Vector<RequestedCallback> mRequestedCallbacks;
+
+ Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
+ Vector<PendingCallback> mPendingFds; // used privately by pollOnce
+ size_t mPendingFdsPos;
+
+ void openWakePipe();
+ void closeWakePipe();
+
+ void setCallbackCommon(int fd, int events, Callback callback,
+ ALooper_callbackFunc* looperCallback, void* data);
+ ssize_t getRequestIndexLocked(int fd);
+ void wakeAndLock();
+ static void threadDestructor(void *st);
+};
+
+} // namespace android
+
+#endif // UTILS_POLL_LOOP_H
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
new file mode 100644
index 0000000..2ee768e
--- /dev/null
+++ b/include/utils/Pool.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_POOL_H
+#define UTILS_POOL_H
+
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+class PoolImpl {
+public:
+ PoolImpl(size_t objSize);
+ ~PoolImpl();
+
+ void* allocImpl();
+ void freeImpl(void* obj);
+
+private:
+ size_t mObjSize;
+};
+
+/*
+ * A homogeneous typed memory pool for fixed size objects.
+ * Not intended to be thread-safe.
+ */
+template<typename T>
+class Pool : private PoolImpl {
+public:
+ /* Creates an initially empty pool. */
+ Pool() : PoolImpl(sizeof(T)) { }
+
+ /* Destroys the pool.
+ * Assumes that the pool is empty. */
+ ~Pool() { }
+
+ /* Allocates an object from the pool, growing the pool if needed. */
+ inline T* alloc() {
+ void* mem = allocImpl();
+ if (! traits<T>::has_trivial_ctor) {
+ return new (mem) T();
+ } else {
+ return static_cast<T*>(mem);
+ }
+ }
+
+ /* Frees an object from the pool. */
+ inline void free(T* obj) {
+ if (! traits<T>::has_trivial_dtor) {
+ obj->~T();
+ }
+ freeImpl(obj);
+ }
+};
+
+} // namespace android
+
+#endif // UTILS_POOL_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index bd7f28c..9c64ac0 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -333,9 +333,10 @@ sp<T>::~sp()
template<typename T>
sp<T>& sp<T>::operator = (const sp<T>& other) {
- if (other.m_ptr) other.m_ptr->incStrong(this);
+ T* otherPtr(other.m_ptr);
+ if (otherPtr) otherPtr->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
- m_ptr = other.m_ptr;
+ m_ptr = otherPtr;
return *this;
}
@@ -351,9 +352,10 @@ sp<T>& sp<T>::operator = (T* other)
template<typename T> template<typename U>
sp<T>& sp<T>::operator = (const sp<U>& other)
{
- if (other.m_ptr) other.m_ptr->incStrong(this);
+ U* otherPtr(other.m_ptr);
+ if (otherPtr) otherPtr->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
- m_ptr = other.m_ptr;
+ m_ptr = otherPtr;
return *this;
}
@@ -466,10 +468,12 @@ wp<T>& wp<T>::operator = (T* other)
template<typename T>
wp<T>& wp<T>::operator = (const wp<T>& other)
{
- if (other.m_ptr) other.m_refs->incWeak(this);
+ weakref_type* otherRefs(other.m_refs);
+ T* otherPtr(other.m_ptr);
+ if (otherPtr) otherRefs->incWeak(this);
if (m_ptr) m_refs->decWeak(this);
- m_ptr = other.m_ptr;
- m_refs = other.m_refs;
+ m_ptr = otherPtr;
+ m_refs = otherRefs;
return *this;
}
@@ -478,8 +482,9 @@ wp<T>& wp<T>::operator = (const sp<T>& other)
{
weakref_type* newRefs =
other != NULL ? other->createWeak(this) : 0;
+ T* otherPtr(other.m_ptr);
if (m_ptr) m_refs->decWeak(this);
- m_ptr = other.get();
+ m_ptr = otherPtr;
m_refs = newRefs;
return *this;
}
@@ -498,10 +503,12 @@ wp<T>& wp<T>::operator = (U* other)
template<typename T> template<typename U>
wp<T>& wp<T>::operator = (const wp<U>& other)
{
- if (other.m_ptr) other.m_refs->incWeak(this);
+ weakref_type* otherRefs(other.m_refs);
+ U* otherPtr(other.m_ptr);
+ if (otherPtr) otherRefs->incWeak(this);
if (m_ptr) m_refs->decWeak(this);
- m_ptr = other.m_ptr;
- m_refs = other.m_refs;
+ m_ptr = otherPtr;
+ m_refs = otherRefs;
return *this;
}
@@ -510,8 +517,9 @@ wp<T>& wp<T>::operator = (const sp<U>& other)
{
weakref_type* newRefs =
other != NULL ? other->createWeak(this) : 0;
+ U* otherPtr(other.m_ptr);
if (m_ptr) m_refs->decWeak(this);
- m_ptr = other.get();
+ m_ptr = otherPtr;
m_refs = newRefs;
return *this;
}
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b701ce7..da86da4 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -31,6 +31,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <android/configuration.h>
+
namespace android {
/** ********************************************************************
@@ -822,25 +824,25 @@ struct ResTable_config
};
enum {
- ORIENTATION_ANY = 0x0000,
- ORIENTATION_PORT = 0x0001,
- ORIENTATION_LAND = 0x0002,
- ORIENTATION_SQUARE = 0x0003,
+ ORIENTATION_ANY = ACONFIGURATION_ORIENTATION_ANY,
+ ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
+ ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
+ ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
};
enum {
- TOUCHSCREEN_ANY = 0x0000,
- TOUCHSCREEN_NOTOUCH = 0x0001,
- TOUCHSCREEN_STYLUS = 0x0002,
- TOUCHSCREEN_FINGER = 0x0003,
+ TOUCHSCREEN_ANY = ACONFIGURATION_TOUCHSCREEN_ANY,
+ TOUCHSCREEN_NOTOUCH = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
+ TOUCHSCREEN_STYLUS = ACONFIGURATION_TOUCHSCREEN_STYLUS,
+ TOUCHSCREEN_FINGER = ACONFIGURATION_TOUCHSCREEN_FINGER,
};
enum {
- DENSITY_DEFAULT = 0,
- DENSITY_LOW = 120,
- DENSITY_MEDIUM = 160,
- DENSITY_HIGH = 240,
- DENSITY_NONE = 0xffff
+ DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
+ DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
+ DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
+ DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+ DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
};
union {
@@ -853,33 +855,34 @@ struct ResTable_config
};
enum {
- KEYBOARD_ANY = 0x0000,
- KEYBOARD_NOKEYS = 0x0001,
- KEYBOARD_QWERTY = 0x0002,
- KEYBOARD_12KEY = 0x0003,
+ KEYBOARD_ANY = ACONFIGURATION_KEYBOARD_ANY,
+ KEYBOARD_NOKEYS = ACONFIGURATION_KEYBOARD_NOKEYS,
+ KEYBOARD_QWERTY = ACONFIGURATION_KEYBOARD_QWERTY,
+ KEYBOARD_12KEY = ACONFIGURATION_KEYBOARD_12KEY,
};
enum {
- NAVIGATION_ANY = 0x0000,
- NAVIGATION_NONAV = 0x0001,
- NAVIGATION_DPAD = 0x0002,
- NAVIGATION_TRACKBALL = 0x0003,
- NAVIGATION_WHEEL = 0x0004,
+ NAVIGATION_ANY = ACONFIGURATION_NAVIGATION_ANY,
+ NAVIGATION_NONAV = ACONFIGURATION_NAVIGATION_NONAV,
+ NAVIGATION_DPAD = ACONFIGURATION_NAVIGATION_DPAD,
+ NAVIGATION_TRACKBALL = ACONFIGURATION_NAVIGATION_TRACKBALL,
+ NAVIGATION_WHEEL = ACONFIGURATION_NAVIGATION_WHEEL,
};
enum {
MASK_KEYSHIDDEN = 0x0003,
- KEYSHIDDEN_ANY = 0x0000,
- KEYSHIDDEN_NO = 0x0001,
- KEYSHIDDEN_YES = 0x0002,
- KEYSHIDDEN_SOFT = 0x0003,
+ KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
+ KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
+ KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
+ KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
};
enum {
MASK_NAVHIDDEN = 0x000c,
- NAVHIDDEN_ANY = 0x0000,
- NAVHIDDEN_NO = 0x0004,
- NAVHIDDEN_YES = 0x0008,
+ SHIFT_NAVHIDDEN = 2,
+ NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
+ NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
+ NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
};
union {
@@ -929,31 +932,34 @@ struct ResTable_config
enum {
// screenLayout bits for screen size class.
MASK_SCREENSIZE = 0x0f,
- SCREENSIZE_ANY = 0x00,
- SCREENSIZE_SMALL = 0x01,
- SCREENSIZE_NORMAL = 0x02,
- SCREENSIZE_LARGE = 0x03,
+ SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
+ SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
+ SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
+ SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
+ SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
// screenLayout bits for wide/long screen variation.
MASK_SCREENLONG = 0x30,
- SCREENLONG_ANY = 0x00,
- SCREENLONG_NO = 0x10,
- SCREENLONG_YES = 0x20,
+ SHIFT_SCREENLONG = 4,
+ SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
+ SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
+ SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
};
enum {
// uiMode bits for the mode type.
MASK_UI_MODE_TYPE = 0x0f,
- UI_MODE_TYPE_ANY = 0x00,
- UI_MODE_TYPE_NORMAL = 0x01,
- UI_MODE_TYPE_DESK = 0x02,
- UI_MODE_TYPE_CAR = 0x03,
+ UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
+ UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
+ UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
+ UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
// uiMode bits for the night switch.
MASK_UI_MODE_NIGHT = 0x30,
- UI_MODE_NIGHT_ANY = 0x00,
- UI_MODE_NIGHT_NO = 0x10,
- UI_MODE_NIGHT_YES = 0x20,
+ SHIFT_UI_MODE_NIGHT = 4,
+ UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
+ UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
+ UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
};
union {
@@ -1022,19 +1028,19 @@ struct ResTable_config
// match the corresponding ones in android.content.pm.ActivityInfo and
// attrs_manifest.xml.
enum {
- CONFIG_MCC = 0x0001,
- CONFIG_MNC = 0x0002,
- CONFIG_LOCALE = 0x0004,
- CONFIG_TOUCHSCREEN = 0x0008,
- CONFIG_KEYBOARD = 0x0010,
- CONFIG_KEYBOARD_HIDDEN = 0x0020,
- CONFIG_NAVIGATION = 0x0040,
- CONFIG_ORIENTATION = 0x0080,
- CONFIG_DENSITY = 0x0100,
- CONFIG_SCREEN_SIZE = 0x0200,
- CONFIG_VERSION = 0x0400,
- CONFIG_SCREEN_LAYOUT = 0x0800,
- CONFIG_UI_MODE = 0x1000
+ CONFIG_MCC = ACONFIGURATION_MCC,
+ CONFIG_MNC = ACONFIGURATION_MCC,
+ CONFIG_LOCALE = ACONFIGURATION_LOCALE,
+ CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
+ CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
+ CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
+ CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
+ CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
+ CONFIG_DENSITY = ACONFIGURATION_DENSITY,
+ CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+ CONFIG_VERSION = ACONFIGURATION_VERSION,
+ CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
+ CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
};
// Compare two configuration, returning CONFIG_* flags set for each value
@@ -1208,7 +1214,28 @@ struct ResTable_config
if (screenLayout || o.screenLayout) {
if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
&& (requested->screenLayout & MASK_SCREENSIZE)) {
- return (screenLayout & MASK_SCREENSIZE);
+ // A little backwards compatibility here: undefined is
+ // considered equivalent to normal. But only if the
+ // requested size is at least normal; otherwise, small
+ // is better than the default.
+ int mySL = (screenLayout & MASK_SCREENSIZE);
+ int oSL = (o.screenLayout & MASK_SCREENSIZE);
+ int fixedMySL = mySL;
+ int fixedOSL = oSL;
+ if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+ if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+ if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+ }
+ // For screen size, the best match is the one that is
+ // closest to the requested screen size, but not over
+ // (the not over part is dealt with in match() below).
+ if (fixedMySL == fixedOSL) {
+ // If the two are the same, but 'this' is actually
+ // undefined, then the other is really a better match.
+ if (mySL == 0) return false;
+ return true;
+ }
+ return fixedMySL >= fixedOSL;
}
if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
&& (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1370,8 +1397,11 @@ struct ResTable_config
if (screenConfig != 0) {
const int screenSize = screenLayout&MASK_SCREENSIZE;
const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
- if (setScreenSize != 0 && screenSize != 0
- && screenSize != setScreenSize) {
+ // Any screen sizes for larger screens than the setting do not
+ // match.
+ if ((setScreenSize != 0 && screenSize != 0
+ && screenSize > setScreenSize) ||
+ (setScreenSize == 0 && screenSize != 0)) {
return false;
}
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index bc7626a8..3b975b4 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -54,11 +54,13 @@ private:
* (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
* and avoid to have a copy of them in each compilation units Singleton<TYPE>
* is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
*/
-#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
- template class Singleton< TYPE >; \
- template< class TYPE > Mutex Singleton< TYPE >::sLock; \
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
+ template class Singleton< TYPE >; \
+ template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE); \
template<> TYPE* Singleton< TYPE >::sInstance(0);
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
index cc0bebc..693dd3c 100644
--- a/include/utils/StopWatch.h
+++ b/include/utils/StopWatch.h
@@ -37,6 +37,8 @@ public:
const char* name() const;
nsecs_t lap();
nsecs_t elapsedTime() const;
+
+ void reset();
private:
const char* mName;
diff --git a/include/utils/StreamingZipInflater.h b/include/utils/StreamingZipInflater.h
new file mode 100644
index 0000000..16867d8
--- /dev/null
+++ b/include/utils/StreamingZipInflater.h
@@ -0,0 +1,82 @@
+/*
+ * 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 __LIBS_STREAMINGZIPINFLATER_H
+#define __LIBS_STREAMINGZIPINFLATER_H
+
+#include <unistd.h>
+#include <inttypes.h>
+#include <zlib.h>
+
+namespace android {
+
+class StreamingZipInflater {
+public:
+ static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
+ 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);
+
+ // Flavor that gets the compressed data from an in-memory buffer
+ StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
+
+ ~StreamingZipInflater();
+
+ // read 'count' bytes of uncompressed data from the current position. outBuf may
+ // be NULL, in which case the data is consumed and discarded.
+ ssize_t read(void* outBuf, size_t count);
+
+ // 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);
+
+private:
+ void initInflateState();
+ int readNextChunk();
+
+ // where to find the uncompressed data
+ int mFd;
+ off_t mInFileStart; // where the compressed data lives in the file
+ class FileMap* mDataMap;
+
+ z_stream mInflateState;
+ bool mStreamNeedsInit;
+
+ // output invariants for this asset
+ uint8_t* mOutBuf; // output buf for decompressed bytes
+ size_t mOutBufSize; // allocated size of mOutBuf
+ size_t mOutTotalSize; // total uncompressed size of the blob
+
+ // current output state bookkeeping
+ off_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
+
+ // input invariants
+ uint8_t* mInBuf;
+ size_t mInBufSize; // allocated size of mInBuf;
+ size_t mInTotalSize; // total size of compressed data for this blob
+
+ // input state bookkeeping
+ size_t mInNextChunkOffset; // offset from start of blob at which the next input chunk lies
+ // the z_stream contains state about input block consumption
+};
+
+}
+
+#endif
diff --git a/include/utils/String8.h b/include/utils/String8.h
index c4b18a4..ef0b51a 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -171,6 +171,9 @@ public:
status_t append(const char* other);
status_t append(const char* other, size_t numChars);
+ status_t appendFormat(const char* fmt, ...)
+ __attribute__((format (printf, 2, 3)));
+
// Note that this function takes O(N) time to calculate the value.
// No cache value is stored.
size_t getUtf32Length() const;
@@ -372,7 +375,7 @@ inline String8& String8::operator+=(const String8& other)
inline String8 String8::operator+(const String8& other) const
{
- String8 tmp;
+ String8 tmp(*this);
tmp += other;
return tmp;
}
@@ -385,7 +388,7 @@ inline String8& String8::operator+=(const char* other)
inline String8 String8::operator+(const char* other) const
{
- String8 tmp;
+ String8 tmp(*this);
tmp += other;
return tmp;
}
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ad59fd6..ec851bd 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -114,13 +114,19 @@ public:
ssize_t appendVector(const Vector<TYPE>& vector);
+ //! insert an array at a given index
+ ssize_t insertArrayAt(const TYPE* array, size_t index, size_t length);
+
+ //! append an array at the end of this vector
+ ssize_t appendArray(const TYPE* array, size_t length);
+
/*!
* add/insert/replace items
*/
//! insert one or several items initialized with their default constructor
inline ssize_t insertAt(size_t index, size_t numItems = 1);
- //! insert on onr several items initialized from a prototype item
+ //! insert one or several items initialized from a prototype item
ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
//! pop the top of the stack (removes the last element). No-op if the stack's empty
inline void pop();
@@ -259,6 +265,16 @@ ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
}
template<class TYPE> inline
+ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {
+ return VectorImpl::insertArrayAt(array, index, length);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {
+ return VectorImpl::appendArray(array, length);
+}
+
+template<class TYPE> inline
ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
return VectorImpl::insertAt(&item, index, numItems);
}
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index 49b03f1..c4ec2ff 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -65,9 +65,11 @@ public:
size_t capacity() const;
ssize_t setCapacity(size_t size);
- /*! append/insert another vector */
+ /*! append/insert another vector or array */
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
ssize_t appendVector(const VectorImpl& vector);
+ ssize_t insertArrayAt(const void* array, size_t index, size_t length);
+ ssize_t appendArray(const void* array, size_t length);
/*! add/insert/replace items */
ssize_t insertAt(size_t where, size_t numItems = 1);
@@ -184,6 +186,8 @@ private:
void push(const void* item);
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
ssize_t appendVector(const VectorImpl& vector);
+ ssize_t insertArrayAt(const void* array, size_t index, size_t length);
+ ssize_t appendArray(const void* array, size_t length);
ssize_t insertAt(size_t where, size_t numItems = 1);
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
ssize_t replaceAt(size_t index);
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index 30e0036..e38bf66 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -47,8 +47,8 @@ extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
const char* fileName);
extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
- int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+ int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_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 51c4f2f..97d31f4 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -58,14 +58,19 @@ typedef void* ZipEntryRO;
class ZipFileRO {
public:
ZipFileRO()
- : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+ : mFd(-1), mFileName(NULL), mFileLength(-1),
+ mDirectoryMap(NULL),
+ mNumEntries(-1), mDirectoryOffset(-1),
+ mHashTableSize(-1), mHashTable(NULL)
{}
~ZipFileRO() {
free(mHashTable);
- if (mFileMap)
- mFileMap->release();
+ if (mDirectoryMap)
+ mDirectoryMap->release();
if (mFd >= 0)
close(mFd);
+ if (mFileName)
+ free(mFileName);
}
/*
@@ -118,8 +123,8 @@ public:
* Returns "false" if "entry" is bogus or if the data in the Zip file
* appears to be bad.
*/
- bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+ bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
/*
* Create a new FileMap object that maps a subset of the archive. For
@@ -155,13 +160,13 @@ public:
* Utility function: uncompress deflated data, buffer to buffer.
*/
static bool inflateBuffer(void* outBuf, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Utility function: uncompress deflated data, buffer to fd.
*/
static bool inflateBuffer(int fd, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Some basic functions for raw data manipulation. "LE" means
@@ -179,6 +184,9 @@ private:
ZipFileRO(const ZipFileRO& src);
ZipFileRO& operator=(const ZipFileRO& src);
+ /* locate and parse the central directory */
+ bool mapCentralDirectory(void);
+
/* parse the archive, prepping internal structures */
bool parseZipArchive(void);
@@ -203,12 +211,21 @@ private:
/* open Zip archive */
int mFd;
+ /* zip file name */
+ char* mFileName;
+
+ /* length of file */
+ size_t mFileLength;
+
/* mapped file */
- FileMap* mFileMap;
+ FileMap* mDirectoryMap;
/* number of entries in the Zip archive */
int mNumEntries;
+ /* CD directory offset in the Zip archive */
+ off_t mDirectoryOffset;
+
/*
* We know how many entries are in the Zip archive, so we have a
* fixed-size hash table. We probe for an empty slot.
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 5ac0c5e..1bcfaed 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -295,6 +295,96 @@ typedef Mutex::Autolock AutoMutex;
/*****************************************************************************/
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ RWLock();
+ RWLock(const char* name);
+ RWLock(int type, const char* name = NULL);
+ ~RWLock();
+
+ status_t readLock();
+ status_t tryReadLock();
+ status_t writeLock();
+ status_t tryWriteLock();
+ void unlock();
+
+ class AutoRLock {
+ public:
+ inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
+ inline ~AutoRLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+ class AutoWLock {
+ public:
+ inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
+ inline ~AutoWLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+private:
+ // A RWLock cannot be copied
+ RWLock(const RWLock&);
+ RWLock& operator = (const RWLock&);
+
+ pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+ if (type == SHARED) {
+ pthread_rwlockattr_t attr;
+ pthread_rwlockattr_init(&attr);
+ pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_rwlock_init(&mRWLock, &attr);
+ pthread_rwlockattr_destroy(&attr);
+ } else {
+ pthread_rwlock_init(&mRWLock, NULL);
+ }
+}
+inline RWLock::~RWLock() {
+ pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+ return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+ return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+ return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+ return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+ pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+/*****************************************************************************/
+
/*
* Condition variable class. The implementation is system-dependent.
*