am 2d4cf62a: am 8d9f899a: am 031fec0b: Merge "ServiceManager: Print kernel/userspace binder version"
* commit '2d4cf62a2cdfbfbbca5757eb7dd1498d118bf7c9':
ServiceManager: Print kernel/userspace binder version
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index f69a72d..8922d54 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -245,8 +245,6 @@
run_command("LAST LOGCAT", 10, "logcat", "-L", "-v", "threadtime",
"-b", "all", "-d", "*:v", NULL);
- for_each_userid(do_dump_settings, NULL);
-
/* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
run_command("NETWORK INTERFACES", 10, "ip", "link", NULL);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index d17a677..8335e26 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -26,7 +26,6 @@
typedef void (for_each_pid_func)(int, const char *);
typedef void (for_each_tid_func)(int, int, const char *);
-typedef void (for_each_userid_func)(int);
/* prints the contents of a file */
int dump_file(const char *title, const char *path);
@@ -57,9 +56,6 @@
/* for each thread in the system, run the specified function */
void for_each_tid(for_each_tid_func func, const char *header);
-/* for each user id in the system, run the specified function */
-void for_each_userid(for_each_userid_func func, const char *header);
-
/* Displays a blocked processes in-kernel wait channel */
void show_wchan(int pid, int tid, const char *name);
@@ -69,9 +65,6 @@
/* Gets the dmesg output for the kernel */
void do_dmesg();
-/* Dumps settings for a given user id */
-void do_dump_settings(int userid);
-
/* Prints the contents of all the routing tables, both IPv4 and IPv6. */
void dump_route_tables();
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index cf14c8b..3d9a2b5 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -206,22 +206,6 @@
return;
}
-void do_dump_settings(int userid) {
- char title[255];
- char dbpath[255];
- char sql[255];
- sprintf(title, "SYSTEM SETTINGS (user %d)", userid);
- if (userid == 0) {
- strcpy(dbpath, "/data/data/com.android.providers.settings/databases/settings.db");
- strcpy(sql, "pragma user_version; select * from system; select * from secure; select * from global;");
- } else {
- sprintf(dbpath, "/data/system/users/%d/settings.db", userid);
- strcpy(sql, "pragma user_version; select * from system; select * from secure;");
- }
- run_command(title, 20, SU_PATH, "root", "sqlite3", dbpath, sql, NULL);
- return;
-}
-
void do_dmesg() {
printf("------ KERNEL LOG (dmesg) ------\n");
/* Get size of kernel buffer */
diff --git a/data/etc/android.software.midi.xml b/data/etc/android.software.midi.xml
new file mode 100644
index 0000000..a03cd55
--- /dev/null
+++ b/data/etc/android.software.midi.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<permissions>
+ <feature name="android.software.midi" />
+</permissions>
diff --git a/include/binder/IProcessInfoService.h b/include/binder/IProcessInfoService.h
new file mode 100644
index 0000000..dc62f45
--- /dev/null
+++ b/include/binder/IProcessInfoService.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 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_I_PROCESS_INFO_SERVICE_H
+#define ANDROID_I_PROCESS_INFO_SERVICE_H
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IProcessInfoService : public IInterface {
+public:
+ DECLARE_META_INTERFACE(ProcessInfoService);
+
+ virtual status_t getProcessStatesFromPids( size_t length,
+ /*in*/ int32_t* pids,
+ /*out*/ int32_t* states) = 0;
+
+ enum {
+ GET_PROCESS_STATES_FROM_PIDS = IBinder::FIRST_CALL_TRANSACTION,
+ };
+};
+
+// ----------------------------------------------------------------------
+
+class BnProcessInfoService : public BnInterface<IProcessInfoService> {
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_I_PROCESS_INFO_SERVICE_H
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index a52e044..0ba3abe 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -96,6 +96,7 @@
status_t writeInt32(int32_t val);
status_t writeUint32(uint32_t val);
status_t writeInt64(int64_t val);
+ status_t writeUint64(uint64_t val);
status_t writeFloat(float val);
status_t writeDouble(double val);
status_t writeCString(const char* str);
@@ -157,6 +158,8 @@
status_t readUint32(uint32_t *pArg) const;
int64_t readInt64() const;
status_t readInt64(int64_t *pArg) const;
+ uint64_t readUint64() const;
+ status_t readUint64(uint64_t *pArg) const;
float readFloat() const;
status_t readFloat(float *pArg) const;
double readDouble() const;
diff --git a/include/binder/ProcessInfoService.h b/include/binder/ProcessInfoService.h
new file mode 100644
index 0000000..c5ead20
--- /dev/null
+++ b/include/binder/ProcessInfoService.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PROCESS_INFO_SERVICE_H
+#define ANDROID_PROCESS_INFO_SERVICE_H
+
+#include <binder/IProcessInfoService.h>
+#include <utils/Errors.h>
+#include <utils/Singleton.h>
+#include <sys/types.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class ProcessInfoService : public Singleton<ProcessInfoService> {
+
+ friend class Singleton<ProcessInfoService>;
+ sp<IProcessInfoService> mProcessInfoService;
+ Mutex mProcessInfoLock;
+
+ ProcessInfoService();
+
+ status_t getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, /*out*/ int32_t* states);
+ void updateBinderLocked();
+
+ static const int BINDER_ATTEMPT_LIMIT = 5;
+
+public:
+
+ /**
+ * For each PID in the given "pids" input array, write the current process state
+ * for that process into the "states" output array, or
+ * ActivityManager.PROCESS_STATE_NONEXISTENT * to indicate that no process with the given PID
+ * exists.
+ *
+ * Returns NO_ERROR if this operation was successful, or a negative error code otherwise.
+ */
+ static status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids,
+ /*out*/ int32_t* states) {
+ return ProcessInfoService::getInstance().getProcessStatesImpl(length, /*in*/ pids,
+ /*out*/ states);
+ }
+
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_PROCESS_INFO_SERVICE_H
+
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 01b6ff4..cc41bae 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -20,10 +20,10 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <gui/IGraphicBufferConsumer.h>
-
#include <ui/Rect.h>
+#include <system/graphics.h>
+
#include <utils/Flattenable.h>
#include <utils/StrongPointer.h>
@@ -45,7 +45,6 @@
enum { INVALID_BUFFER_SLOT = -1 };
BufferItem();
~BufferItem();
- operator IGraphicBufferConsumer::BufferItem() const;
static const char* scalingModeName(uint32_t scalingMode);
@@ -78,11 +77,21 @@
// automatically when the buffer was queued.
bool mIsAutoTimestamp;
+ // mDataSpace is the current dataSpace value for this buffer slot. This gets
+ // set by queueBuffer each time this slot is queued. The meaning of the
+ // dataSpace is format-dependent.
+ android_dataspace mDataSpace;
+
// mFrameNumber is the number of the queued frame for this slot.
uint64_t mFrameNumber;
- // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
- int mSlot;
+ union {
+ // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
+ int mSlot;
+
+ // mBuf is the former name for mSlot
+ int mBuf;
+ };
// mIsDroppable whether this buffer was queued with the
// property that it can be replaced by a new buffer for the purpose of
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index 869b470..930fabf 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -42,8 +42,6 @@
public:
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
- typedef BufferQueue::BufferItem BufferItem;
-
enum { DEFAULT_MAX_BUFFERS = -1 };
enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
@@ -76,8 +74,8 @@
//
// If waitForFence is true, and the acquired BufferItem has a valid fence object,
// acquireBuffer will wait on the fence with no timeout before returning.
- status_t acquireBuffer(BufferItem *item, nsecs_t presentWhen,
- bool waitForFence = true);
+ status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen,
+ bool waitForFence = true);
// Returns an acquired buffer to the queue, allowing it to be reused. Since
// only a fixed number of buffers may be acquired at a time, old buffers
@@ -96,6 +94,13 @@
// GraphicBuffers of a defaultFormat if no format is specified
// in dequeueBuffer
status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+
+ // setDefaultBufferDataSpace allows the BufferQueue to create
+ // GraphicBuffers of a defaultDataSpace if no data space is specified
+ // in queueBuffer.
+ // The initial default is HAL_DATASPACE_UNKNOWN
+ status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
+
};
} // namespace android
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 1188837..721b218 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_GUI_BUFFERQUEUE_H
#define ANDROID_GUI_BUFFERQUEUE_H
+#include <gui/BufferItem.h>
#include <gui/BufferQueueDefs.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
@@ -34,7 +35,7 @@
// Attempts at runtime to increase the number of buffers past this will fail.
enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
// Used as a placeholder slot# when the value isn't pointing to an existing buffer.
- enum { INVALID_BUFFER_SLOT = IGraphicBufferConsumer::BufferItem::INVALID_BUFFER_SLOT };
+ enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };
// Alias to <IGraphicBufferConsumer.h> -- please scope from there in future code!
enum {
NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
@@ -47,7 +48,6 @@
// for backward source compatibility
typedef ::android::ConsumerListener ConsumerListener;
- typedef IGraphicBufferConsumer::BufferItem BufferItem;
// ProxyConsumerListener is a ConsumerListener implementation that keeps a weak
// reference to the actual consumer object. It forwards all calls to that
@@ -62,7 +62,7 @@
public:
ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
virtual ~ProxyConsumerListener();
- virtual void onFrameAvailable(const android::BufferItem& item);
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void onBuffersReleased();
virtual void onSidebandStreamChanged();
private:
diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h
index 898c451..9c91fc7 100644
--- a/include/gui/BufferQueueConsumer.h
+++ b/include/gui/BufferQueueConsumer.h
@@ -128,6 +128,13 @@
// in dequeueBuffer. The initial default is HAL_PIXEL_FORMAT_RGBA_8888.
virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+ // setDefaultBufferDataSpace allows the BufferQueue to create
+ // GraphicBuffers of a defaultDataSpace if no data space is specified
+ // in queueBuffer.
+ // The initial default is HAL_DATASPACE_UNKNOWN
+ virtual status_t setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace);
+
// setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
// These are merged with the bits passed to dequeueBuffer. The values are
// enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index b23cb08..40026bd 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_GUI_BUFFERQUEUECORE_H
#define ANDROID_GUI_BUFFERQUEUECORE_H
+#include <gui/BufferItem.h>
#include <gui/BufferQueueDefs.h>
#include <gui/BufferSlot.h>
@@ -45,7 +46,6 @@
namespace android {
-class BufferItem;
class IConsumerListener;
class IGraphicBufferAlloc;
class IProducerListener;
@@ -58,7 +58,7 @@
public:
// Used as a placeholder slot number when the value isn't pointing to an
// existing buffer.
- enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem
+ enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT };
// We reserve two slots in order to guarantee that the producer and
// consumer can run asynchronously.
@@ -209,6 +209,11 @@
// in dequeueBuffer if a width and height of 0 are specified.
uint32_t mDefaultHeight;
+ // mDefaultBufferDataSpace holds the default dataSpace of queued buffers.
+ // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN)
+ // is specified.
+ android_dataspace mDefaultBufferDataSpace;
+
// mDefaultMaxBufferCount is the default limit on the number of buffers that
// will be allocated at one time. This default limit is set by the consumer.
// The limit (as opposed to the default limit) may be overriden by the
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
index f7ab5ac..ef0feab 100644
--- a/include/gui/ConsumerBase.h
+++ b/include/gui/ConsumerBase.h
@@ -153,8 +153,7 @@
// initialization that must take place the first time a buffer is assigned
// to a slot. If it is overridden the derived class's implementation must
// call ConsumerBase::acquireBufferLocked.
- virtual status_t acquireBufferLocked(IGraphicBufferConsumer::BufferItem *item,
- nsecs_t presentWhen);
+ virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
// releaseBufferLocked relinquishes control over a buffer, returning that
// control to the BufferQueue.
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index faf6852..c99ab29 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -53,6 +53,7 @@
uint32_t transform;
uint32_t scalingMode;
int64_t timestamp;
+ android_dataspace dataSpace;
uint64_t frameNumber;
// this is the same as format, except for formats that are compatible with
// a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter
@@ -90,6 +91,12 @@
// The initial default is PIXEL_FORMAT_RGBA_8888.
status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+ // setDefaultBufferDataSpace allows the BufferQueue to create
+ // GraphicBuffers of a defaultDataSpace if no data space is specified
+ // in queueBuffer.
+ // The initial default is HAL_DATASPACE_UNKNOWN
+ status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
+
// Gets the next graphics buffer from the producer and locks it for CPU use,
// filling out the passed-in locked buffer structure with the native pointer
// and metadata. Returns BAD_VALUE if no new buffer is available, and
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index 053d1ed..4912580 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -198,6 +198,7 @@
// These functions call the corresponding BufferQueue implementation
// so the refactoring can proceed smoothly
status_t setDefaultBufferFormat(PixelFormat defaultFormat);
+ status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
status_t setConsumerUsageBits(uint32_t usage);
status_t setTransformHint(uint32_t hint);
@@ -240,8 +241,7 @@
// acquireBufferLocked overrides the ConsumerBase method to update the
// mEglSlots array in addition to the ConsumerBase behavior.
- virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item,
- nsecs_t presentWhen);
+ virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
// releaseBufferLocked overrides the ConsumerBase method to update the
// mEglSlots array in addition to the ConsumerBase.
@@ -259,7 +259,7 @@
// This releases the buffer in the slot referenced by mCurrentTexture,
// then updates state to refer to the BufferItem, which must be a
// newly-acquired buffer.
- status_t updateAndReleaseLocked(const BufferQueue::BufferItem& item);
+ status_t updateAndReleaseLocked(const BufferItem& item);
// Binds mTexName and the current buffer to mTexTarget. Uses
// mCurrentTexture if it's set, mCurrentTextureImage if not. If the
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 9ac23c2..8f31b55 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -34,6 +34,7 @@
namespace android {
// ----------------------------------------------------------------------------
+class BufferItem;
class Fence;
class GraphicBuffer;
class IConsumerListener;
@@ -42,71 +43,6 @@
class IGraphicBufferConsumer : public IInterface {
public:
-
- // public facing structure for BufferSlot
- class BufferItem : public Flattenable<BufferItem> {
- friend class Flattenable<BufferItem>;
- size_t getPodSize() const;
- size_t getFlattenedSize() const;
- size_t getFdCount() const;
- status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
- status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
-
- public:
- // The default value of mBuf, used to indicate this doesn't correspond to a slot.
- enum { INVALID_BUFFER_SLOT = -1 };
- BufferItem();
-
- // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
- // if the buffer in this slot has been acquired in the past (see
- // BufferSlot.mAcquireCalled).
- sp<GraphicBuffer> mGraphicBuffer;
-
- // mFence is a fence that will signal when the buffer is idle.
- sp<Fence> mFence;
-
- // mCrop is the current crop rectangle for this buffer slot.
- Rect mCrop;
-
- // mTransform is the current transform flags for this buffer slot.
- // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>
- uint32_t mTransform;
-
- // mScalingMode is the current scaling mode for this buffer slot.
- // refer to NATIVE_WINDOW_SCALING_* in <window.h>
- uint32_t mScalingMode;
-
- // mTimestamp is the current timestamp for this buffer slot. This gets
- // to set by queueBuffer each time this slot is queued. This value
- // is guaranteed to be monotonically increasing for each newly
- // acquired buffer.
- int64_t mTimestamp;
-
- // mIsAutoTimestamp indicates whether mTimestamp was generated
- // automatically when the buffer was queued.
- bool mIsAutoTimestamp;
-
- // mFrameNumber is the number of the queued frame for this slot.
- uint64_t mFrameNumber;
-
- // mBuf is the slot index of this buffer (default INVALID_BUFFER_SLOT).
- int mBuf;
-
- // mIsDroppable whether this buffer was queued with the
- // property that it can be replaced by a new buffer for the purpose of
- // making sure dequeueBuffer() won't block.
- // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer
- // was queued.
- bool mIsDroppable;
-
- // Indicates whether this buffer has been seen by a consumer yet
- bool mAcquireCalled;
-
- // Indicates this buffer must be transformed by the inverse transform of the screen
- // it is displayed onto. This is applied after mTransform.
- bool mTransformToDisplayInverse;
- };
-
enum {
// Returned by releaseBuffer, after which the consumer must
// free any references to the just-released buffer that it might have.
@@ -287,6 +223,14 @@
// Return of a value other than NO_ERROR means an unknown error has occurred.
virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) = 0;
+ // setDefaultBufferDataSpace is a request to the producer to provide buffers
+ // of the indicated dataSpace. The producer may ignore this request.
+ // The initial default is HAL_DATASPACE_UNKNOWN.
+ //
+ // Return of a value other than NO_ERROR means an unknown error has occurred.
+ virtual status_t setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) = 0;
+
// setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
// These are merged with the bits passed to dequeueBuffer. The values are
// enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 4d3cd9a..374245a 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -265,6 +265,7 @@
inline QueueBufferInput(const Parcel& parcel);
// timestamp - a monotonically increasing value in nanoseconds
// isAutoTimestamp - if the timestamp was synthesized at queue time
+ // dataSpace - description of the contents, interpretation depends on format
// crop - a crop rectangle that's used as a hint to the consumer
// scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in <window.h>
// transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h>
@@ -274,17 +275,21 @@
// sticky - the sticky transform set in Surface (only used by the LEGACY
// camera mode).
inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,
- const Rect& crop, int scalingMode, uint32_t transform, bool async,
- const sp<Fence>& fence, uint32_t sticky = 0)
- : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop),
- scalingMode(scalingMode), transform(transform), stickyTransform(sticky),
- async(async), fence(fence) { }
+ android_dataspace dataSpace, const Rect& crop, int scalingMode,
+ uint32_t transform, bool async, const sp<Fence>& fence,
+ uint32_t sticky = 0)
+ : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp),
+ dataSpace(dataSpace), crop(crop), scalingMode(scalingMode),
+ transform(transform), stickyTransform(sticky),
+ async(async), fence(fence) { }
inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,
- Rect* outCrop, int* outScalingMode, uint32_t* outTransform,
- bool* outAsync, sp<Fence>* outFence,
+ android_dataspace* outDataSpace,
+ Rect* outCrop, int* outScalingMode,
+ uint32_t* outTransform, bool* outAsync, sp<Fence>* outFence,
uint32_t* outStickyTransform = NULL) const {
*outTimestamp = timestamp;
*outIsAutoTimestamp = bool(isAutoTimestamp);
+ *outDataSpace = dataSpace;
*outCrop = crop;
*outScalingMode = scalingMode;
*outTransform = transform;
@@ -304,6 +309,7 @@
private:
int64_t timestamp;
int isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
index 9c8afc5..9a29cb5 100644
--- a/include/gui/ISensorServer.h
+++ b/include/gui/ISensorServer.h
@@ -30,6 +30,7 @@
class Sensor;
class ISensorEventConnection;
+class String8;
class ISensorServer : public IInterface
{
@@ -37,7 +38,7 @@
DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0;
- virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
+ virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index 3176462..1afff68 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -26,6 +26,7 @@
#include <utils/RefBase.h>
#include <utils/Singleton.h>
#include <utils/Vector.h>
+#include <utils/String8.h>
#include <gui/SensorEventQueue.h>
@@ -40,7 +41,6 @@
class ISensorServer;
class Sensor;
class SensorEventQueue;
-
// ----------------------------------------------------------------------------
class SensorManager :
@@ -53,7 +53,7 @@
ssize_t getSensorList(Sensor const* const** list) const;
Sensor const* getDefaultSensor(int type);
- sp<SensorEventQueue> createEventQueue();
+ sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""));
private:
// DeathRecipient interface
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 863f22b..e973483 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -146,6 +146,7 @@
int dispatchLock(va_list args);
int dispatchUnlockAndPost(va_list args);
int dispatchSetSidebandStream(va_list args);
+ int dispatchSetBuffersDataSpace(va_list args);
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
@@ -157,7 +158,6 @@
virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);
- virtual int connect(int api, const sp<IProducerListener>& listener);
virtual int connect(int api);
virtual int disconnect(int api);
virtual int setBufferCount(int bufferCount);
@@ -168,6 +168,7 @@
virtual int setBuffersTransform(uint32_t transform);
virtual int setBuffersStickyTransform(uint32_t transform);
virtual int setBuffersTimestamp(int64_t timestamp);
+ virtual int setBuffersDataSpace(android_dataspace dataSpace);
virtual int setCrop(Rect const* rect);
virtual int setUsage(uint32_t reqUsage);
@@ -175,6 +176,11 @@
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
virtual int unlockAndPost();
+ virtual int connect(int api, const sp<IProducerListener>& listener);
+ virtual int detachNextBuffer(ANativeWindowBuffer** outBuffer,
+ sp<Fence>* outFence);
+ virtual int attachBuffer(ANativeWindowBuffer*);
+
protected:
enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
@@ -223,6 +229,11 @@
// a timestamp is auto-generated when queueBuffer is called.
int64_t mTimestamp;
+ // mDataSpace is the buffer dataSpace that will be used for the next buffer
+ // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which
+ // means that the buffer contains some type of color data.
+ android_dataspace mDataSpace;
+
// mCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mCrop;
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
new file mode 100644
index 0000000..629310f
--- /dev/null
+++ b/include/input/IInputFlinger.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 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 _LIBINPUT_IINPUT_FLINGER_H
+#define _LIBINPUT_IINPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+/*
+ * This class defines the Binder IPC interface for accessing various
+ * InputFlinger features.
+ */
+class IInputFlinger : public IInterface {
+public:
+ DECLARE_META_INTERFACE(InputFlinger);
+};
+
+
+/**
+ * Binder implementation.
+ */
+class BnInputFlinger : public BnInterface<IInputFlinger> {
+public:
+ enum {
+ DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+ };
+
+ virtual status_t onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_IINPUT_FLINGER_H
diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h
index 49939fd..b01476a 100644
--- a/include/media/drm/DrmAPI.h
+++ b/include/media/drm/DrmAPI.h
@@ -80,7 +80,8 @@
kDrmPluginEventProvisionRequired = 1,
kDrmPluginEventKeyNeeded,
kDrmPluginEventKeyExpired,
- kDrmPluginEventVendorDefined
+ kDrmPluginEventVendorDefined,
+ kDrmPluginEventSessionReclaimed
};
// Drm keys can be for offline content or for online streaming.
@@ -93,6 +94,15 @@
kKeyType_Release
};
+ // Enumerate KeyRequestTypes to allow an app to determine the
+ // type of a key request returned from getKeyRequest.
+ enum KeyRequestType {
+ kKeyRequestType_Unknown,
+ kKeyRequestType_Initial,
+ kKeyRequestType_Renewal,
+ kKeyRequestType_Release
+ };
+
DrmPlugin() {}
virtual ~DrmPlugin() {}
@@ -135,7 +145,8 @@
Vector<uint8_t> const &initData,
String8 const &mimeType, KeyType keyType,
KeyedVector<String8, String8> const &optionalParameters,
- Vector<uint8_t> &request, String8 &defaultUrl) = 0;
+ Vector<uint8_t> &request, String8 &defaultUrl,
+ KeyRequestType *keyRequestType) = 0;
//
// After a key response is received by the app, it is provided to the
diff --git a/include/media/openmax/OMX_AsString.h b/include/media/openmax/OMX_AsString.h
index 0f177a1..dbcecf5 100644
--- a/include/media/openmax/OMX_AsString.h
+++ b/include/media/openmax/OMX_AsString.h
@@ -521,6 +521,7 @@
case OMX_IndexParamVideoHevc: return "ParamVideoHevc";
// case OMX_IndexParamSliceSegments: return "ParamSliceSegments";
case OMX_IndexConfigAutoFramerateConversion: return "ConfigAutoFramerateConversion";
+ case OMX_IndexConfigPriority: return "ConfigPriority";
default: return asString((OMX_INDEXTYPE)i, def);
}
}
diff --git a/include/media/openmax/OMX_IVCommon.h b/include/media/openmax/OMX_IVCommon.h
index a5b9d18..f9b6f4b 100644
--- a/include/media/openmax/OMX_IVCommon.h
+++ b/include/media/openmax/OMX_IVCommon.h
@@ -157,6 +157,7 @@
* an acceptable range once that is done.
* */
OMX_COLOR_FormatAndroidOpaque = 0x7F000789,
+ OMX_COLOR_Format32BitRGBA8888 = 0x7F00A000,
/** Flexible 8-bit YUV format. Codec should report this format
* as being supported if it supports any YUV420 packed planar
* or semiplanar formats. When port is set to use this format,
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index ea3d0da..0122a27 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -83,6 +83,7 @@
/* Other configurations */
OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
OMX_IndexConfigAutoFramerateConversion, /**< reference: OMX_CONFIG_BOOLEANTYPE */
+ OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */
/* Time configurations */
OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index e7e8ffc..f26fecb 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -60,8 +60,6 @@
PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB
PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB
- PIXEL_FORMAT_sRGB_A_8888 = HAL_PIXEL_FORMAT_sRGB_A_8888, // 4x8-bit sRGB + A
- PIXEL_FORMAT_sRGB_X_8888 = HAL_PIXEL_FORMAT_sRGB_X_8888, // 4x8-bit sRGB, no A
};
typedef int32_t PixelFormat;
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 79decfe..d5860ef 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -26,6 +26,8 @@
IMemory.cpp \
IPCThreadState.cpp \
IPermissionController.cpp \
+ IProcessInfoService.cpp \
+ ProcessInfoService.cpp \
IServiceManager.cpp \
MemoryDealer.cpp \
MemoryBase.cpp \
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
index 8c60dc4..2fcd3d9 100644
--- a/libs/binder/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "IInterface"
+#include <utils/Log.h>
#include <binder/IInterface.h>
namespace android {
@@ -41,6 +43,25 @@
return iface->onAsBinder();
}
+
// ---------------------------------------------------------------------------
}; // namespace android
+
+extern "C" {
+
+void _ZN7android10IInterface8asBinderEv(void *retval, void* self) {
+ ALOGW("deprecated asBinder call, please update your code");
+ //ALOGI("self: %p, retval: %p", self, retval);
+ android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>;
+ *ret = android::IInterface::asBinder((android::IInterface*)self);
+}
+
+void _ZNK7android10IInterface8asBinderEv(void *retval, void *self) {
+ ALOGW("deprecated asBinder call, please update your code");
+ //ALOGI("self: %p, retval: %p", self, retval);
+ android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>;
+ *ret = android::IInterface::asBinder((android::IInterface*)self);
+}
+
+} // extern "C"
diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp
new file mode 100644
index 0000000..d86eb27
--- /dev/null
+++ b/libs/binder/IProcessInfoService.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IProcessInfoService.h>
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+#include <sys/types.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpProcessInfoService : public BpInterface<IProcessInfoService> {
+public:
+ BpProcessInfoService(const sp<IBinder>& impl)
+ : BpInterface<IProcessInfoService>(impl) {}
+
+ virtual status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids,
+ /*out*/ int32_t* states)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IProcessInfoService::getInterfaceDescriptor());
+ data.writeInt32Array(length, pids);
+ data.writeInt32(length); // write length of output array, used by java AIDL stubs
+ status_t err = remote()->transact(GET_PROCESS_STATES_FROM_PIDS, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ return err;
+ }
+ int32_t replyLen = reply.readInt32();
+ if (static_cast<size_t>(replyLen) != length) {
+ return NOT_ENOUGH_DATA;
+ }
+ if (replyLen > 0 && (err = reply.read(states, length * sizeof(*states))) != NO_ERROR) {
+ return err;
+ }
+ return reply.readInt32();
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(ProcessInfoService, "android.os.IProcessInfoService");
+
+// ----------------------------------------------------------------------
+
+status_t BnProcessInfoService::onTransact( uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags) {
+ switch(code) {
+ case GET_PROCESS_STATES_FROM_PIDS: {
+ CHECK_INTERFACE(IProcessInfoService, data, reply);
+ int32_t arrayLen = data.readInt32();
+ if (arrayLen <= 0) {
+ reply->writeNoException();
+ reply->writeInt32(0);
+ reply->writeInt32(NOT_ENOUGH_DATA);
+ return NO_ERROR;
+ }
+
+ size_t len = static_cast<size_t>(arrayLen);
+ int32_t pids[len];
+ status_t res = data.read(pids, len * sizeof(*pids));
+
+ // Ignore output array length returned in the parcel here, as the states array must
+ // always be the same length as the input PIDs array.
+ int32_t states[len];
+ for (size_t i = 0; i < len; i++) states[i] = -1;
+ if (res == NO_ERROR) {
+ res = getProcessStatesFromPids(len, /*in*/ pids, /*out*/ states);
+ }
+ reply->writeNoException();
+ reply->writeInt32Array(len, states);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 2c566f9..d4dd8c7 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -54,7 +54,17 @@
// ---------------------------------------------------------------------------
-#define PAD_SIZE(s) (((s)+3)&~3)
+// This macro should never be used at runtime, as a too large value
+// of s could cause an integer overflow. Instead, you should always
+// use the wrapper function pad_size()
+#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
+
+static size_t pad_size(size_t s) {
+ if (s > (SIZE_T_MAX - 3)) {
+ abort();
+ }
+ return PAD_SIZE_UNSAFE(s);
+}
// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
@@ -355,6 +365,12 @@
status_t Parcel::setDataSize(size_t size)
{
+ if (size > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
status_t err;
err = continueWrite(size);
if (err == NO_ERROR) {
@@ -366,18 +382,36 @@
void Parcel::setDataPosition(size_t pos) const
{
+ if (pos > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ abort();
+ }
+
mDataPos = pos;
mNextObjectHint = 0;
}
status_t Parcel::setDataCapacity(size_t size)
{
+ if (size > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
if (size > mDataCapacity) return continueWrite(size);
return NO_ERROR;
}
status_t Parcel::setData(const uint8_t* buffer, size_t len)
{
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
status_t err = restartWrite(len);
if (err == NO_ERROR) {
memcpy(const_cast<uint8_t*>(data()), buffer, len);
@@ -401,6 +435,12 @@
return NO_ERROR;
}
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
// range checks against the source parcel size
if ((offset > parcel->mDataSize)
|| (len > parcel->mDataSize)
@@ -561,6 +601,12 @@
status_t Parcel::finishWrite(size_t len)
{
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
//printf("Finish write of %d\n", len);
mDataPos += len;
ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
@@ -574,6 +620,12 @@
status_t Parcel::writeUnpadded(const void* data, size_t len)
{
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
size_t end = mDataPos + len;
if (end < mDataPos) {
// integer overflow
@@ -593,6 +645,12 @@
status_t Parcel::write(const void* data, size_t len)
{
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
void* const d = writeInplace(len);
if (d) {
memcpy(d, data, len);
@@ -603,7 +661,13 @@
void* Parcel::writeInplace(size_t len)
{
- const size_t padded = PAD_SIZE(len);
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return NULL;
+ }
+
+ const size_t padded = pad_size(len);
// sanity check for integer overflow
if (mDataPos+padded < mDataPos) {
@@ -652,6 +716,12 @@
}
status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
if (!val) {
return writeAligned(-1);
}
@@ -662,6 +732,12 @@
return ret;
}
status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
if (!val) {
return writeAligned(-1);
}
@@ -677,6 +753,11 @@
return writeAligned(val);
}
+status_t Parcel::writeUint64(uint64_t val)
+{
+ return writeAligned(val);
+}
+
status_t Parcel::writePointer(uintptr_t val)
{
return writeAligned<binder_uintptr_t>(val);
@@ -835,6 +916,12 @@
{
status_t status;
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
ALOGV("writeBlob: write in place");
status = writeInt32(0);
@@ -887,6 +974,12 @@
const size_t len = val.getFlattenedSize();
const size_t fd_count = val.getFdCount();
+ if ((len > INT32_MAX) || (fd_count > INT32_MAX)) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
err = this->writeInt32(len);
if (err) return err;
@@ -894,7 +987,7 @@
if (err) return err;
// payload
- void* const buf = this->writeInplace(PAD_SIZE(len));
+ void* const buf = this->writeInplace(pad_size(len));
if (buf == NULL)
return BAD_VALUE;
@@ -968,10 +1061,16 @@
status_t Parcel::read(void* outData, size_t len) const
{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
- && len <= PAD_SIZE(len)) {
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
+ if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
+ && len <= pad_size(len)) {
memcpy(outData, mData+mDataPos, len);
- mDataPos += PAD_SIZE(len);
+ mDataPos += pad_size(len);
ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
return NO_ERROR;
}
@@ -980,10 +1079,16 @@
const void* Parcel::readInplace(size_t len) const
{
- if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
- && len <= PAD_SIZE(len)) {
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return NULL;
+ }
+
+ if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
+ && len <= pad_size(len)) {
const void* data = mData+mDataPos;
- mDataPos += PAD_SIZE(len);
+ mDataPos += pad_size(len);
ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
return data;
}
@@ -992,7 +1097,7 @@
template<class T>
status_t Parcel::readAligned(T *pArg) const {
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(T)) <= mDataSize) {
const void* data = mData+mDataPos;
@@ -1016,7 +1121,7 @@
template<class T>
status_t Parcel::writeAligned(T val) {
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
@@ -1060,6 +1165,16 @@
return readAligned<int64_t>();
}
+status_t Parcel::readUint64(uint64_t *pArg) const
+{
+ return readAligned(pArg);
+}
+
+uint64_t Parcel::readUint64() const
+{
+ return readAligned<uint64_t>();
+}
+
status_t Parcel::readPointer(uintptr_t *pArg) const
{
status_t ret;
@@ -1147,7 +1262,7 @@
const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
if (eos) {
const size_t len = eos - str;
- mDataPos += PAD_SIZE(len+1);
+ mDataPos += pad_size(len+1);
ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
return str;
}
@@ -1306,8 +1421,14 @@
const size_t len = this->readInt32();
const size_t fd_count = this->readInt32();
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
// payload
- void const* const buf = this->readInplace(PAD_SIZE(len));
+ void const* const buf = this->readInplace(pad_size(len));
if (buf == NULL)
return BAD_VALUE;
@@ -1546,6 +1667,12 @@
status_t Parcel::growData(size_t len)
{
+ if (len > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
size_t newSize = ((mDataSize+len)*3)/2;
return (newSize <= mDataSize)
? (status_t) NO_MEMORY
@@ -1554,6 +1681,12 @@
status_t Parcel::restartWrite(size_t desired)
{
+ if (desired > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
if (mOwner) {
freeData();
return continueWrite(desired);
@@ -1594,6 +1727,12 @@
status_t Parcel::continueWrite(size_t desired)
{
+ if (desired > INT32_MAX) {
+ // don't accept size_t values which may have come from an
+ // inadvertent conversion from a negative int.
+ return BAD_VALUE;
+ }
+
// If shrinking, first adjust for any objects that appear
// after the new data size.
size_t objectsSize = mObjectsSize;
diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp
new file mode 100644
index 0000000..fb28643
--- /dev/null
+++ b/libs/binder/ProcessInfoService.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/ProcessInfoService.h>
+#include <binder/IServiceManager.h>
+
+#include <utils/Log.h>
+#include <utils/String16.h>
+
+namespace android {
+
+ProcessInfoService::ProcessInfoService() {
+ updateBinderLocked();
+}
+
+status_t ProcessInfoService::getProcessStatesImpl(size_t length, /*in*/ int32_t* pids,
+ /*out*/ int32_t* states) {
+ status_t err = NO_ERROR;
+ sp<IProcessInfoService> pis;
+ mProcessInfoLock.lock();
+ pis = mProcessInfoService;
+ mProcessInfoLock.unlock();
+
+ for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
+
+ if (pis != NULL) {
+ err = pis->getProcessStatesFromPids(length, /*in*/ pids, /*out*/ states);
+ if (err == NO_ERROR) return NO_ERROR; // success
+ if (IInterface::asBinder(pis)->isBinderAlive()) return err;
+ }
+ sleep(1);
+
+ mProcessInfoLock.lock();
+ if (pis == mProcessInfoService) {
+ updateBinderLocked();
+ }
+ pis = mProcessInfoService;
+ mProcessInfoLock.unlock();
+ }
+
+ ALOGW("%s: Could not retrieve process states from ProcessInfoService after %d retries.",
+ __FUNCTION__, BINDER_ATTEMPT_LIMIT);
+
+ return TIMED_OUT;
+}
+
+void ProcessInfoService::updateBinderLocked() {
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != NULL) {
+ const String16 name("processinfo");
+ mProcessInfoService = interface_cast<IProcessInfoService>(sm->checkService(name));
+ }
+}
+
+ANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService);
+
+}; // namespace android
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index e6fc791..312fb3b 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -28,6 +28,7 @@
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mTimestamp(0),
mIsAutoTimestamp(false),
+ mDataSpace(HAL_DATASPACE_UNKNOWN),
mFrameNumber(0),
mSlot(INVALID_BUFFER_SLOT),
mIsDroppable(false),
@@ -38,29 +39,13 @@
BufferItem::~BufferItem() {}
-BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
- IGraphicBufferConsumer::BufferItem bufferItem;
- bufferItem.mGraphicBuffer = mGraphicBuffer;
- bufferItem.mFence = mFence;
- bufferItem.mCrop = mCrop;
- bufferItem.mTransform = mTransform;
- bufferItem.mScalingMode = mScalingMode;
- bufferItem.mTimestamp = mTimestamp;
- bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
- bufferItem.mFrameNumber = mFrameNumber;
- bufferItem.mBuf = mSlot;
- bufferItem.mIsDroppable = mIsDroppable;
- bufferItem.mAcquireCalled = mAcquireCalled;
- bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
- return bufferItem;
-}
-
size_t BufferItem::getPodSize() const {
size_t c = sizeof(mCrop) +
sizeof(mTransform) +
sizeof(mScalingMode) +
sizeof(mTimestamp) +
sizeof(mIsAutoTimestamp) +
+ sizeof(mDataSpace) +
sizeof(mFrameNumber) +
sizeof(mSlot) +
sizeof(mIsDroppable) +
@@ -131,6 +116,7 @@
FlattenableUtils::write(buffer, size, mScalingMode);
FlattenableUtils::write(buffer, size, mTimestamp);
FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
+ FlattenableUtils::write(buffer, size, mDataSpace);
FlattenableUtils::write(buffer, size, mFrameNumber);
FlattenableUtils::write(buffer, size, mSlot);
FlattenableUtils::write(buffer, size, mIsDroppable);
@@ -173,6 +159,7 @@
FlattenableUtils::read(buffer, size, mScalingMode);
FlattenableUtils::read(buffer, size, mTimestamp);
FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
+ FlattenableUtils::read(buffer, size, mDataSpace);
FlattenableUtils::read(buffer, size, mFrameNumber);
FlattenableUtils::read(buffer, size, mSlot);
FlattenableUtils::read(buffer, size, mIsDroppable);
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 61de69a..194121f 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -19,6 +19,7 @@
//#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Log.h>
+#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
//#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -109,4 +110,10 @@
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t BufferItemConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
} // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 61fd8c4..2fcbaf2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -32,7 +32,7 @@
BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
- const android::BufferItem& item) {
+ const BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if (listener != NULL) {
listener->onFrameAvailable(item);
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index a798b18..526c3b7 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -496,6 +496,15 @@
return NO_ERROR;
}
+status_t BufferQueueConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ ATRACE_CALL();
+ BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
+ Mutex::Autolock lock(mCore->mMutex);
+ mCore->mDefaultBufferDataSpace = defaultDataSpace;
+ return NO_ERROR;
+}
+
status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
ATRACE_CALL();
BQ_LOGV("setConsumerUsageBits: %#x", usage);
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index ec1e631..edebc45 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -60,6 +60,7 @@
mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
mDefaultWidth(1),
mDefaultHeight(1),
+ mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
mDefaultMaxBufferCount(2),
mMaxAcquiredBufferCount(1),
mBufferHasBeenQueued(false),
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 13b864d..4c22ba3 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -516,14 +516,15 @@
int64_t timestamp;
bool isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
uint32_t stickyTransform;
bool async;
sp<Fence> fence;
- input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
- &async, &fence, &stickyTransform);
+ input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
+ &transform, &async, &fence, &stickyTransform);
if (fence == NULL) {
BQ_LOGE("queueBuffer: fence is NULL");
@@ -579,9 +580,9 @@
return BAD_VALUE;
}
- BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
+ BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
" crop=[%d,%d,%d,%d] transform=%#x scale=%s",
- slot, mCore->mFrameCounter + 1, timestamp,
+ slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
crop.left, crop.top, crop.right, crop.bottom, transform,
BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
@@ -595,6 +596,11 @@
return BAD_VALUE;
}
+ // Override UNKNOWN dataspace with consumer default
+ if (dataSpace == HAL_DATASPACE_UNKNOWN) {
+ dataSpace = mCore->mDefaultBufferDataSpace;
+ }
+
mSlots[slot].mFence = fence;
mSlots[slot].mBufferState = BufferSlot::QUEUED;
++mCore->mFrameCounter;
@@ -610,6 +616,7 @@
item.mScalingMode = static_cast<uint32_t>(scalingMode);
item.mTimestamp = timestamp;
item.mIsAutoTimestamp = isAutoTimestamp;
+ item.mDataSpace = dataSpace;
item.mFrameNumber = mCore->mFrameCounter;
item.mSlot = slot;
item.mFence = fence;
@@ -758,6 +765,9 @@
case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
value = static_cast<int32_t>(mCore->mConsumerUsageBits);
break;
+ case NATIVE_WINDOW_DEFAULT_DATASPACE:
+ value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
+ break;
default:
return BAD_VALUE;
}
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 5fc83ee..b874e3a 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -27,6 +27,7 @@
#include <hardware/hardware.h>
+#include <gui/BufferItem.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
@@ -179,7 +180,7 @@
}
}
-status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
nsecs_t presentWhen) {
status_t err = mConsumer->acquireBuffer(item, presentWhen);
if (err != NO_ERROR) {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index 73d34eb..eb39469 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -20,6 +20,7 @@
#include <cutils/compiler.h>
#include <utils/Log.h>
+#include <gui/BufferItem.h>
#include <gui/CpuConsumer.h>
#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
@@ -67,6 +68,13 @@
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t CpuConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace)
+{
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
static bool isPossiblyYUV(PixelFormat format) {
switch (static_cast<int>(format)) {
case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -74,11 +82,9 @@
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_sRGB_A_8888:
- case HAL_PIXEL_FORMAT_sRGB_X_8888:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_Y16:
- case HAL_PIXEL_FORMAT_RAW16: // same as HAL_PIXEL_FORMAT_RAW_SENSOR
+ case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
case HAL_PIXEL_FORMAT_BLOB:
@@ -105,7 +111,7 @@
return NOT_ENOUGH_DATA;
}
- BufferQueue::BufferItem b;
+ BufferItem b;
Mutex::Autolock _l(mMutex);
@@ -200,6 +206,7 @@
nativeBuffer->transform = b.mTransform;
nativeBuffer->scalingMode = b.mScalingMode;
nativeBuffer->timestamp = b.mTimestamp;
+ nativeBuffer->dataSpace = b.mDataSpace;
nativeBuffer->frameNumber = b.mFrameNumber;
nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index a0f68b4..96c0841 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -29,6 +29,7 @@
#include <hardware/hardware.h>
+#include <gui/BufferItem.h>
#include <gui/GLConsumer.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceComposer.h>
@@ -210,7 +211,7 @@
return err;
}
- BufferQueue::BufferItem item;
+ BufferItem item;
// Acquire the next buffer.
// In asynchronous mode the list is guaranteed to be one buffer
@@ -342,7 +343,7 @@
return sReleasedTexImageBuffer;
}
-status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t GLConsumer::acquireBufferLocked(BufferItem *item,
nsecs_t presentWhen) {
status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen);
if (err != NO_ERROR) {
@@ -373,7 +374,7 @@
return err;
}
-status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
+status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
{
status_t err = NO_ERROR;
@@ -1023,6 +1024,12 @@
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t GLConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Mutex::Autolock lock(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
Mutex::Autolock lock(mMutex);
usage |= DEFAULT_USAGE_FLAGS;
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index 2602884..3f23c2f 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <binder/IInterface.h>
+#include <gui/BufferItem.h>
#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
@@ -32,159 +33,6 @@
#include <system/window.h>
namespace android {
-// ---------------------------------------------------------------------------
-
-IGraphicBufferConsumer::BufferItem::BufferItem() :
- mTransform(0),
- mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
- mTimestamp(0),
- mIsAutoTimestamp(false),
- mFrameNumber(0),
- mBuf(INVALID_BUFFER_SLOT),
- mIsDroppable(false),
- mAcquireCalled(false),
- mTransformToDisplayInverse(false) {
- mCrop.makeInvalid();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
- size_t c = sizeof(mCrop) +
- sizeof(mTransform) +
- sizeof(mScalingMode) +
- sizeof(mTimestamp) +
- sizeof(mIsAutoTimestamp) +
- sizeof(mFrameNumber) +
- sizeof(mBuf) +
- sizeof(mIsDroppable) +
- sizeof(mAcquireCalled) +
- sizeof(mTransformToDisplayInverse);
- return c;
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
- size_t c = 0;
- if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFlattenedSize();
- c = FlattenableUtils::align<4>(c);
- }
- if (mFence != 0) {
- c += mFence->getFlattenedSize();
- c = FlattenableUtils::align<4>(c);
- }
- return sizeof(int32_t) + c + getPodSize();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
- size_t c = 0;
- if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFdCount();
- }
- if (mFence != 0) {
- c += mFence->getFdCount();
- }
- return c;
-}
-
-static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
- FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
-}
-
-static bool readBoolFromInt(void const*& buffer, size_t& size) {
- int32_t i;
- FlattenableUtils::read(buffer, size, i);
- return static_cast<bool>(i);
-}
-
-status_t IGraphicBufferConsumer::BufferItem::flatten(
- void*& buffer, size_t& size, int*& fds, size_t& count) const {
-
- // make sure we have enough space
- if (size < BufferItem::getFlattenedSize()) {
- return NO_MEMORY;
- }
-
- // content flags are stored first
- uint32_t& flags = *static_cast<uint32_t*>(buffer);
-
- // advance the pointer
- FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
-
- flags = 0;
- if (mGraphicBuffer != 0) {
- status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- flags |= 1;
- }
- if (mFence != 0) {
- status_t err = mFence->flatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- flags |= 2;
- }
-
- // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
- if (size < getPodSize()) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::write(buffer, size, mCrop);
- FlattenableUtils::write(buffer, size, mTransform);
- FlattenableUtils::write(buffer, size, mScalingMode);
- FlattenableUtils::write(buffer, size, mTimestamp);
- writeBoolAsInt(buffer, size, mIsAutoTimestamp);
- FlattenableUtils::write(buffer, size, mFrameNumber);
- FlattenableUtils::write(buffer, size, mBuf);
- writeBoolAsInt(buffer, size, mIsDroppable);
- writeBoolAsInt(buffer, size, mAcquireCalled);
- writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
-
- return NO_ERROR;
-}
-
-status_t IGraphicBufferConsumer::BufferItem::unflatten(
- void const*& buffer, size_t& size, int const*& fds, size_t& count) {
-
- if (size < sizeof(uint32_t))
- return NO_MEMORY;
-
- uint32_t flags = 0;
- FlattenableUtils::read(buffer, size, flags);
-
- if (flags & 1) {
- mGraphicBuffer = new GraphicBuffer();
- status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- }
-
- if (flags & 2) {
- mFence = new Fence();
- status_t err = mFence->unflatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- }
-
- // check we have enough space
- if (size < getPodSize()) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::read(buffer, size, mCrop);
- FlattenableUtils::read(buffer, size, mTransform);
- FlattenableUtils::read(buffer, size, mScalingMode);
- FlattenableUtils::read(buffer, size, mTimestamp);
- mIsAutoTimestamp = readBoolFromInt(buffer, size);
- FlattenableUtils::read(buffer, size, mFrameNumber);
- FlattenableUtils::read(buffer, size, mBuf);
- mIsDroppable = readBoolFromInt(buffer, size);
- mAcquireCalled = readBoolFromInt(buffer, size);
- mTransformToDisplayInverse = readBoolFromInt(buffer, size);
-
- return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
enum {
ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
@@ -200,6 +48,7 @@
SET_MAX_ACQUIRED_BUFFER_COUNT,
SET_CONSUMER_NAME,
SET_DEFAULT_BUFFER_FORMAT,
+ SET_DEFAULT_BUFFER_DATA_SPACE,
SET_CONSUMER_USAGE_BITS,
SET_TRANSFORM_HINT,
GET_SIDEBAND_STREAM,
@@ -371,6 +220,19 @@
return reply.readInt32();
}
+ virtual status_t setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(defaultDataSpace));
+ status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
+ data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return reply.readInt32();
+ }
+
virtual status_t setConsumerUsageBits(uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
@@ -530,6 +392,14 @@
reply->writeInt32(result);
return NO_ERROR;
}
+ case SET_DEFAULT_BUFFER_DATA_SPACE: {
+ CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+ android_dataspace defaultDataSpace =
+ static_cast<android_dataspace>(data.readInt32());
+ status_t result = setDefaultBufferDataSpace(defaultDataSpace);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
case SET_CONSUMER_USAGE_BITS: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
uint32_t usage = data.readUint32();
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 63d881e..a3e6fb2 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -440,6 +440,7 @@
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
return sizeof(timestamp)
+ sizeof(isAutoTimestamp)
+ + sizeof(dataSpace)
+ sizeof(crop)
+ sizeof(scalingMode)
+ sizeof(transform)
@@ -460,6 +461,7 @@
}
FlattenableUtils::write(buffer, size, timestamp);
FlattenableUtils::write(buffer, size, isAutoTimestamp);
+ FlattenableUtils::write(buffer, size, dataSpace);
FlattenableUtils::write(buffer, size, crop);
FlattenableUtils::write(buffer, size, scalingMode);
FlattenableUtils::write(buffer, size, transform);
@@ -474,6 +476,7 @@
size_t minNeeded =
sizeof(timestamp)
+ sizeof(isAutoTimestamp)
+ + sizeof(dataSpace)
+ sizeof(crop)
+ sizeof(scalingMode)
+ sizeof(transform)
@@ -486,6 +489,7 @@
FlattenableUtils::read(buffer, size, timestamp);
FlattenableUtils::read(buffer, size, isAutoTimestamp);
+ FlattenableUtils::read(buffer, size, dataSpace);
FlattenableUtils::read(buffer, size, crop);
FlattenableUtils::read(buffer, size, scalingMode);
FlattenableUtils::read(buffer, size, transform);
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 8e09e7c..3c85ec0 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -63,10 +63,11 @@
return v;
}
- virtual sp<ISensorEventConnection> createSensorEventConnection()
+ virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
{
Parcel data, reply;
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+ data.writeString8(packageName);
remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
}
@@ -96,7 +97,8 @@
}
case CREATE_SENSOR_EVENT_CONNECTION: {
CHECK_INTERFACE(ISensorServer, data, reply);
- sp<ISensorEventConnection> connection(createSensorEventConnection());
+ String8 packageName = data.readString8();
+ sp<ISensorEventConnection> connection(createSensorEventConnection(packageName));
reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
}
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index d6df404..142c6ec 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -139,14 +139,14 @@
return NULL;
}
-sp<SensorEventQueue> SensorManager::createEventQueue()
+sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
{
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
- mSensorServer->createSensorEventConnection();
+ mSensorServer->createSensorEventConnection(packageName);
if (connection == NULL) {
// SensorService just died.
ALOGE("createEventQueue: connection is NULL. SensorService died.");
diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp
index 8146869..43f9214 100644
--- a/libs/gui/StreamSplitter.cpp
+++ b/libs/gui/StreamSplitter.cpp
@@ -20,6 +20,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/StreamSplitter.h>
@@ -123,7 +124,7 @@
++mOutstandingBuffers;
// Acquire and detach the buffer from the input
- IGraphicBufferConsumer::BufferItem bufferItem;
+ BufferItem bufferItem;
status_t status = mInput->acquireBuffer(&bufferItem, /* presentWhen */ 0);
LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
"acquiring buffer from input failed (%d)", status);
@@ -141,7 +142,8 @@
IGraphicBufferProducer::QueueBufferInput queueInput(
bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp,
- bufferItem.mCrop, static_cast<int32_t>(bufferItem.mScalingMode),
+ bufferItem.mDataSpace, bufferItem.mCrop,
+ static_cast<int32_t>(bufferItem.mScalingMode),
bufferItem.mTransform, bufferItem.mIsDroppable,
bufferItem.mFence);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 98489b1..b80890f 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -64,6 +64,7 @@
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
+ mDataSpace = HAL_DATASPACE_UNKNOWN;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
@@ -317,8 +318,8 @@
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
IGraphicBufferProducer::QueueBufferOutput output;
IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
- crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,
- fence, mStickyTransform);
+ mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
+ mSwapIntervalZero, fence, mStickyTransform);
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
@@ -449,6 +450,9 @@
case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
res = dispatchSetSidebandStream(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
+ res = dispatchSetBuffersDataSpace(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -546,6 +550,12 @@
return OK;
}
+int Surface::dispatchSetBuffersDataSpace(va_list args) {
+ android_dataspace dataspace =
+ static_cast<android_dataspace>(va_arg(args, int));
+ return setBuffersDataSpace(dataspace);
+}
+
int Surface::connect(int api) {
static sp<IProducerListener> listener = new DummyProducerListener();
return connect(api, listener);
@@ -600,6 +610,55 @@
return err;
}
+int Surface::detachNextBuffer(ANativeWindowBuffer** outBuffer,
+ sp<Fence>* outFence) {
+ ATRACE_CALL();
+ ALOGV("Surface::detachNextBuffer");
+
+ if (outBuffer == NULL || outFence == NULL) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+
+ sp<GraphicBuffer> buffer(NULL);
+ sp<Fence> fence(NULL);
+ status_t result = mGraphicBufferProducer->detachNextBuffer(
+ &buffer, &fence);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ *outBuffer = buffer.get();
+ if (fence != NULL && fence->isValid()) {
+ *outFence = fence;
+ } else {
+ *outFence = Fence::NO_FENCE;
+ }
+
+ return NO_ERROR;
+}
+
+int Surface::attachBuffer(ANativeWindowBuffer* buffer)
+{
+ ATRACE_CALL();
+ ALOGV("Surface::attachBuffer");
+
+ Mutex::Autolock lock(mMutex);
+
+ sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
+ int32_t attachedSlot = -1;
+ status_t result = mGraphicBufferProducer->attachBuffer(
+ &attachedSlot, graphicBuffer);
+ if (result != NO_ERROR) {
+ ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
+ return result;
+ }
+ mSlots[attachedSlot].buffer = graphicBuffer;
+
+ return NO_ERROR;
+}
+
int Surface::setUsage(uint32_t reqUsage)
{
ALOGV("Surface::setUsage");
@@ -727,6 +786,14 @@
return NO_ERROR;
}
+int Surface::setBuffersDataSpace(android_dataspace dataSpace)
+{
+ ALOGV("Surface::setBuffersDataSpace");
+ Mutex::Autolock lock(mMutex);
+ mDataSpace = dataSpace;
+ return NO_ERROR;
+}
+
void Surface::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].buffer = 0;
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 838ad90..c38c797 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "BufferQueue_test"
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
@@ -124,11 +125,12 @@
*dataIn = 0x12345678;
ASSERT_EQ(OK, buffer->unlock());
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
uint32_t* dataOut;
@@ -150,9 +152,10 @@
int slot;
sp<Fence> fence;
sp<GraphicBuffer> buf;
- IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput qbi(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
- BufferQueue::BufferItem item;
+ BufferItem item;
for (int i = 0; i < 2; i++) {
ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
@@ -244,11 +247,12 @@
ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
uint32_t* dataOut;
@@ -273,7 +277,8 @@
mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
GRALLOC_USAGE_SW_WRITE_OFTEN));
ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
@@ -282,7 +287,7 @@
BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
@@ -338,11 +343,12 @@
*dataIn = 0x12345678;
ASSERT_EQ(OK, buffer->unlock());
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index abd3724..0beca92 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -166,7 +166,7 @@
uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) {
// Ignores components that don't exist for given pixel
switch(buf.format) {
- case HAL_PIXEL_FORMAT_RAW_SENSOR: {
+ case HAL_PIXEL_FORMAT_RAW16: {
String8 msg;
uint16_t *bPtr = (uint16_t*)buf.data;
bPtr += y * buf.stride + x;
@@ -429,7 +429,7 @@
void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) {
switch (format) {
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ case HAL_PIXEL_FORMAT_RAW16:
checkBayerRawBuffer(buf);
break;
case HAL_PIXEL_FORMAT_Y8:
@@ -505,7 +505,7 @@
case HAL_PIXEL_FORMAT_YV12:
fillYV12Buffer(img, params.width, params.height, *stride);
break;
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ case HAL_PIXEL_FORMAT_RAW16:
fillBayerRawBuffer(img, params.width, params.height, buf->getStride());
break;
case HAL_PIXEL_FORMAT_Y8:
@@ -537,7 +537,7 @@
ASSERT_NO_ERROR(err, "queueBuffer error:");
};
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuSingle) {
status_t err;
@@ -571,7 +571,7 @@
mCC->unlockBuffer(b);
}
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
status_t err;
@@ -614,7 +614,7 @@
}
}
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuLockMax) {
status_t err;
@@ -710,12 +710,12 @@
};
CpuConsumerTestParams rawTestSets[] = {
- { 512, 512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 512, 512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 100, 100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 100, 100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
+ { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16},
+ { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16},
+ { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16},
};
CpuConsumerTestParams rgba8888TestSets[] = {
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 8d5fd8f..c904a6b 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -57,6 +57,7 @@
// Parameters for a generic "valid" input for queueBuffer.
const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
+const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
@@ -126,6 +127,7 @@
QueueBufferInputBuilder() {
timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
+ dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
crop = QUEUE_BUFFER_INPUT_RECT;
scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
transform = QUEUE_BUFFER_INPUT_TRANSFORM;
@@ -137,6 +139,7 @@
return IGraphicBufferProducer::QueueBufferInput(
timestamp,
isAutoTimestamp,
+ dataSpace,
crop,
scalingMode,
transform,
@@ -154,6 +157,11 @@
return *this;
}
+ QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
+ this->dataSpace = dataSpace;
+ return *this;
+ }
+
QueueBufferInputBuilder& setCrop(Rect crop) {
this->crop = crop;
return *this;
@@ -182,6 +190,7 @@
private:
int64_t timestamp;
bool isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
index da2add7..e5907e7 100644
--- a/libs/gui/tests/SRGB_test.cpp
+++ b/libs/gui/tests/SRGB_test.cpp
@@ -214,10 +214,11 @@
ASSERT_EQ(GL_NO_ERROR, glGetError());
}
- void checkLockedBuffer(PixelFormat format) {
+ void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) {
ASSERT_EQ(mLockedBuffer.format, format);
ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH);
ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT);
+ ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace);
}
static bool withinTolerance(int a, int b) {
@@ -335,7 +336,8 @@
if (mLockedBuffer.format == outBuffer.format) {
memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize);
} else {
- ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888);
+ ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888);
+ ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB);
ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888);
uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
for (int y = 0; y < outBuffer.height; ++y) {
@@ -380,7 +382,8 @@
// Lock
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
// Compare a pixel in the middle of each texture
int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride *
@@ -411,7 +414,8 @@
// Lock
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
// Save the values of the middle pixel for later comparison against SRGB
uint8_t values[PIXEL_SIZE] = {};
@@ -460,7 +464,8 @@
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
// Make sure we actually got the SRGB buffer on the consumer side
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB));
// Verify that the stored value is the same, accounting for RGB/SRGB
for (int c = 0; c < PIXEL_SIZE; ++c) {
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 4e63a6f..767c7c6 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "StreamSplitter_test"
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/IConsumerListener.h>
#include <gui/ISurfaceComposer.h>
@@ -111,11 +112,12 @@
ASSERT_EQ(OK, buffer->unlock());
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0));
uint32_t* dataOut;
@@ -177,12 +179,13 @@
ASSERT_EQ(OK, buffer->unlock());
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
for (int output = 0; output < NUM_OUTPUTS; ++output) {
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0));
uint32_t* dataOut;
@@ -234,6 +237,7 @@
outputConsumer->consumerDisconnect();
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5e6aeef..4f87824 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -155,4 +155,26 @@
ASSERT_EQ(TEST_USAGE_FLAGS, flags);
}
+TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) {
+ const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB;
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
+
+ cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE);
+
+ sp<Surface> s = new Surface(producer);
+
+ sp<ANativeWindow> anw(s);
+
+ android_dataspace dataSpace;
+
+ int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE,
+ reinterpret_cast<int*>(&dataSpace));
+
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(TEST_DATASPACE, dataSpace);
+}
+
}
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index f1921a4..944ac7f 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -27,6 +27,7 @@
deviceSources := \
$(commonSources) \
+ IInputFlinger.cpp \
InputTransport.cpp \
VelocityControl.cpp \
VelocityTracker.cpp
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
new file mode 100644
index 0000000..e009731
--- /dev/null
+++ b/libs/input/IInputFlinger.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <input/IInputFlinger.h>
+
+
+namespace android {
+
+class BpInputFlinger : public BpInterface<IInputFlinger> {
+public:
+ BpInputFlinger(const sp<IBinder>& impl) :
+ BpInterface<IInputFlinger>(impl) { }
+
+ virtual status_t doSomething() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
+ remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply);
+ return reply.readInt32();
+ }
+};
+
+IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger");
+
+
+status_t BnInputFlinger::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ switch(code) {
+ case DO_SOMETHING_TRANSACTION: {
+ CHECK_INTERFACE(IInputFlinger, data, reply);
+ reply->writeInt32(0);
+ break;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+ return NO_ERROR;
+}
+
+};
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 99ed6f7..cab1dde 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -25,8 +25,6 @@
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_BGRA_8888:
- case PIXEL_FORMAT_sRGB_A_8888:
- case PIXEL_FORMAT_sRGB_X_8888:
return 4;
case PIXEL_FORMAT_RGB_888:
return 3;
@@ -57,4 +55,3 @@
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
-
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index ff08a6b..11a13c3 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -381,20 +381,15 @@
// Turn linear formats into corresponding sRGB formats when colorspace is
// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
-// the modification isn't possible, the original format is returned.
-static int modifyFormatColorspace(int fmt, EGLint colorspace) {
+// the modification isn't possible, the original dataSpace is returned.
+static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
+ EGLint colorspace) {
if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
- switch (fmt) {
- case HAL_PIXEL_FORMAT_sRGB_A_8888: return HAL_PIXEL_FORMAT_RGBA_8888;
- case HAL_PIXEL_FORMAT_sRGB_X_8888: return HAL_PIXEL_FORMAT_RGBX_8888;
- }
+ return HAL_DATASPACE_SRGB_LINEAR;
} else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
- switch (fmt) {
- case HAL_PIXEL_FORMAT_RGBA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
- case HAL_PIXEL_FORMAT_RGBX_8888: return HAL_PIXEL_FORMAT_sRGB_X_8888;
- }
+ return HAL_DATASPACE_SRGB;
}
- return fmt;
+ return dataSpace;
}
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
@@ -424,6 +419,7 @@
// by default, just pick RGBA_8888
EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
+ android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
EGLint a = 0;
cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
@@ -449,7 +445,7 @@
for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
if (*attr == EGL_GL_COLORSPACE_KHR) {
if (ENABLE_EGL_KHR_GL_COLORSPACE) {
- format = modifyFormatColorspace(format, *(attr+1));
+ dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
} else {
// Normally we'd pass through unhandled attributes to
// the driver. But in case the driver implements this
@@ -473,6 +469,16 @@
}
}
+ if (dataSpace != 0) {
+ int err = native_window_set_buffers_data_space(window, dataSpace);
+ if (err != 0) {
+ ALOGE("error setting native window pixel dataSpace: %s (%d)",
+ strerror(-err), err);
+ native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+ }
+
// the EGL spec requires that a new EGLSurface default to swap interval
// 1, so explicitly set that on the window here.
ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
index 1af59a3..ed867d8 100644
--- a/services/inputflinger/Android.mk
+++ b/services/inputflinger/Android.mk
@@ -45,3 +45,5 @@
LOCAL_MODULE := libinputflinger
include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 93ce010..3135692 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1293,7 +1293,10 @@
// Register with epoll.
struct epoll_event eventItem;
memset(&eventItem, 0, sizeof(eventItem));
- eventItem.events = mUsingEpollWakeup ? EPOLLIN : EPOLLIN | EPOLLWAKEUP;
+ eventItem.events = EPOLLIN;
+ if (mUsingEpollWakeup) {
+ eventItem.events |= EPOLLWAKEUP;
+ }
eventItem.data.u32 = deviceId;
if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
ALOGE("Could not add device fd to epoll instance. errno=%d", errno);
diff --git a/services/inputflinger/host/Android.mk b/services/inputflinger/host/Android.mk
new file mode 100644
index 0000000..b828175
--- /dev/null
+++ b/services/inputflinger/host/Android.mk
@@ -0,0 +1,62 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CLANG := true
+
+LOCAL_SRC_FILES:= \
+ InputFlinger.cpp \
+ InputDriver.cpp \
+ InputHost.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libcrypto \
+ libcutils \
+ libinput \
+ liblog \
+ libutils \
+ libhardware
+
+
+# TODO: Move inputflinger to its own process and mark it hidden
+#LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_CFLAGS += -Wno-unused-parameter
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+LOCAL_MODULE := libinputflingerhost
+
+include $(BUILD_SHARED_LIBRARY)
+
+########################################################################
+# build input flinger executable
+include $(CLEAR_VARS)
+
+LOCAL_CLANG := true
+
+LOCAL_SRC_FILES:= \
+ main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libinputflingerhost \
+ libutils
+
+LOCAL_MODULE := inputflinger
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp
new file mode 100644
index 0000000..3beb5ae
--- /dev/null
+++ b/services/inputflinger/host/InputDriver.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define LOG_TAG "InputDriver"
+
+#define LOG_NDEBUG 0
+
+#include "InputDriver.h"
+#include "InputHost.h"
+
+#include <hardware/input.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#define INDENT2 " "
+
+namespace android {
+
+static input_host_callbacks_t kCallbacks = {
+ .create_device_identifier = create_device_identifier,
+ .create_device_definition = create_device_definition,
+ .create_input_report_definition = create_input_report_definition,
+ .create_output_report_definition = create_output_report_definition,
+ .input_device_definition_add_report = input_device_definition_add_report,
+ .input_report_definition_add_collection = input_report_definition_add_collection,
+ .input_report_definition_declare_usage_int = input_report_definition_declare_usage_int,
+ .input_report_definition_declare_usages_bool = input_report_definition_declare_usages_bool,
+ .register_device = register_device,
+ .input_allocate_report = input_allocate_report,
+ .input_report_set_usage_int = input_report_set_usage_int,
+ .input_report_set_usage_bool = input_report_set_usage_bool,
+ .report_event = report_event,
+};
+
+InputDriver::InputDriver(const char* name) : mName(String8(name)) {
+ const hw_module_t* module;
+ int err = input_open(&module, name);
+ LOG_ALWAYS_FATAL_IF(err != 0, "Input module %s not found", name);
+ mHal = reinterpret_cast<const input_module_t*>(module);
+}
+
+void InputDriver::init(InputHostInterface* host) {
+ mHal->init(mHal, static_cast<input_host_t*>(host), kCallbacks);
+}
+
+void InputDriver::dump(String8& result) {
+ result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.string());
+}
+
+
+// HAL wrapper functions
+
+input_device_identifier_t* create_device_identifier(input_host_t* host,
+ const char* name, int32_t product_id, int32_t vendor_id,
+ input_bus_t bus, const char* unique_id) {
+ return nullptr;
+}
+
+input_device_definition_t* create_device_definition(input_host_t* host) {
+ return nullptr;
+}
+
+input_report_definition_t* create_input_report_definition(input_host_t* host) {
+ return nullptr;
+}
+
+input_report_definition_t* create_output_report_definition(input_host_t* host) {
+ return nullptr;
+}
+
+void input_device_definition_add_report(input_host_t* host,
+ input_device_definition_t* d, input_report_definition_t* r) { }
+
+void input_report_definition_add_collection(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id, int32_t arity) { }
+
+void input_report_definition_declare_usage_int(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id,
+ input_usage_t usage, int32_t min, int32_t max, float resolution) { }
+
+void input_report_definition_declare_usages_bool(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id,
+ input_usage_t* usage, size_t usage_count) { }
+
+
+input_device_handle_t* register_device(input_host_t* host,
+ input_device_identifier_t* id, input_device_definition_t* d) {
+ return nullptr;
+}
+
+input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r) {
+ return nullptr;
+}
+void input_report_set_usage_int(input_host_t* host, input_report_t* r,
+ input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index) { }
+
+void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
+ input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index) { }
+
+void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) { }
+
+
+} // namespace android
diff --git a/services/inputflinger/host/InputDriver.h b/services/inputflinger/host/InputDriver.h
new file mode 100644
index 0000000..7810173
--- /dev/null
+++ b/services/inputflinger/host/InputDriver.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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_INPUT_DRIVER_H
+#define ANDROID_INPUT_DRIVER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "InputHost.h"
+
+#include <hardware/input.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class InputHostInterface;
+
+class InputDriverInterface : public virtual RefBase {
+protected:
+ InputDriverInterface() = default;
+ virtual ~InputDriverInterface() = default;
+
+public:
+ virtual void init(InputHostInterface* host) = 0;
+
+ virtual void dump(String8& result) = 0;
+};
+
+class InputDriver : public InputDriverInterface {
+public:
+ InputDriver(const char* name);
+ virtual ~InputDriver() = default;
+
+ virtual void init(InputHostInterface* host) override;
+
+ virtual void dump(String8& result) override;
+
+private:
+ String8 mName;
+ const input_module_t* mHal;
+};
+
+
+extern "C" {
+
+input_device_identifier_t* create_device_identifier(input_host_t* host,
+ const char* name, int32_t product_id, int32_t vendor_id,
+ input_bus_t bus, const char* unique_id);
+
+input_device_definition_t* create_device_definition(input_host_t* host);
+
+input_report_definition_t* create_input_report_definition(input_host_t* host);
+
+input_report_definition_t* create_output_report_definition(input_host_t* host);
+
+void input_device_definition_add_report(input_host_t* host,
+ input_device_definition_t* d, input_report_definition_t* r);
+
+void input_report_definition_add_collection(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id, int32_t arity);
+
+void input_report_definition_declare_usage_int(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id,
+ input_usage_t usage, int32_t min, int32_t max, float resolution);
+
+void input_report_definition_declare_usages_bool(input_host_t* host,
+ input_report_definition_t* report, input_collection_id_t id,
+ input_usage_t* usage, size_t usage_count);
+
+
+input_device_handle_t* register_device(input_host_t* host,
+ input_device_identifier_t* id, input_device_definition_t* d);
+
+void unregister_device(input_host_t* host, input_device_handle_t* handle);
+
+input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r);
+
+void input_report_set_usage_int(input_host_t* host, input_report_t* r,
+ input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index);
+
+void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
+ input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index);
+
+void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report);
+
+}
+
+} // namespace android
+#endif // ANDROID_INPUT_DRIVER_H
diff --git a/services/inputflinger/host/InputFlinger.cpp b/services/inputflinger/host/InputFlinger.cpp
new file mode 100644
index 0000000..859c3b8
--- /dev/null
+++ b/services/inputflinger/host/InputFlinger.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#define LOG_TAG "InputFlinger"
+
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include "InputFlinger.h"
+#include "InputDriver.h"
+
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <hardware/input.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+
+namespace android {
+
+const String16 sAccessInputFlingerPermission("android.permission.ACCESS_INPUT_FLINGER");
+const String16 sDumpPermission("android.permission.DUMP");
+
+
+InputFlinger::InputFlinger() :
+ BnInputFlinger() {
+ ALOGI("InputFlinger is starting");
+ mHost = new InputHost();
+ mHost->registerInputDriver(new InputDriver(INPUT_INSTANCE_EVDEV));
+}
+
+InputFlinger::~InputFlinger() {
+}
+
+status_t InputFlinger::dump(int fd, const Vector<String16>& args) {
+ String8 result;
+ const IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
+ if ((uid != AID_SHELL)
+ && !PermissionCache::checkPermission(sDumpPermission, pid, uid)) {
+ result.appendFormat("Permission Denial: "
+ "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
+ } else {
+ dumpInternal(result);
+ }
+ write(fd, result.string(), result.size());
+ return OK;
+}
+
+void InputFlinger::dumpInternal(String8& result) {
+ result.append("INPUT FLINGER (dumpsys inputflinger)\n");
+ mHost->dump(result);
+}
+
+}; // namespace android
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
new file mode 100644
index 0000000..39e69e5
--- /dev/null
+++ b/services/inputflinger/host/InputFlinger.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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_INPUT_FLINGER_H
+#define ANDROID_INPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "InputHost.h"
+
+#include <cutils/compiler.h>
+#include <input/IInputFlinger.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class InputFlinger : public BnInputFlinger {
+public:
+ static char const* getServiceName() ANDROID_API {
+ return "inputflinger";
+ }
+
+ InputFlinger() ANDROID_API;
+
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+private:
+ virtual ~InputFlinger();
+
+ void dumpInternal(String8& result);
+
+ sp<InputHostInterface> mHost;
+};
+
+} // namespace android
+
+#endif // ANDROID_INPUT_FLINGER_H
diff --git a/services/inputflinger/host/InputHost.cpp b/services/inputflinger/host/InputHost.cpp
new file mode 100644
index 0000000..51d3e6b
--- /dev/null
+++ b/services/inputflinger/host/InputHost.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vector>
+
+#include "InputDriver.h"
+#include "InputHost.h"
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#define INDENT " "
+
+namespace android {
+
+void InputHost::registerInputDriver(InputDriverInterface* driver) {
+ LOG_ALWAYS_FATAL_IF(driver == nullptr, "Cannot register a nullptr as an InputDriver!");
+ driver->init(this);
+ mDrivers.push_back(driver);
+}
+
+void InputHost::dump(String8& result) {
+ result.append(INDENT "Input Drivers:\n");
+ for (size_t i = 0; i < mDrivers.size(); i++) {
+ mDrivers[i]->dump(result);
+ }
+}
+
+} // namespace android
diff --git a/services/inputflinger/host/InputHost.h b/services/inputflinger/host/InputHost.h
new file mode 100644
index 0000000..42a66e0
--- /dev/null
+++ b/services/inputflinger/host/InputHost.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 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_INPUT_HOST_H
+#define ANDROID_INPUT_HOST_H
+
+#include <vector>
+
+#include <hardware/input.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/StrongPointer.h>
+
+#include "InputDriver.h"
+
+// Declare a concrete type for the HAL
+struct input_host {
+};
+
+namespace android {
+
+class InputDriverInterface;
+
+class InputHostInterface : public input_host_t, public virtual RefBase {
+protected:
+ InputHostInterface() = default;
+ virtual ~InputHostInterface() = default;
+
+public:
+
+ virtual void registerInputDriver(InputDriverInterface* driver) = 0;
+
+ virtual void dump(String8& result) = 0;
+};
+
+class InputHost : public InputHostInterface {
+public:
+ InputHost() = default;
+
+ virtual void registerInputDriver(InputDriverInterface* driver) override;
+
+ virtual void dump(String8& result) override;
+
+private:
+ std::vector<sp<InputDriverInterface>> mDrivers;
+};
+
+} // namespace android
+#endif // ANDRIOD_INPUT_HOST_H
diff --git a/services/inputflinger/host/main.cpp b/services/inputflinger/host/main.cpp
new file mode 100644
index 0000000..0a517cc
--- /dev/null
+++ b/services/inputflinger/host/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/BinderService.h>
+#include "InputFlinger.h"
+
+using namespace android;
+
+int main(int, char**) {
+ ProcessState::self()->setThreadPoolMaxThreadCount(4);
+ BinderService<InputFlinger>::publishAndJoinThreadPool(true);
+ return 0;
+}
diff --git a/services/inputflinger/tests/Android.mk b/services/inputflinger/tests/Android.mk
index 0742a08..4c43392 100644
--- a/services/inputflinger/tests/Android.mk
+++ b/services/inputflinger/tests/Android.mk
@@ -10,7 +10,6 @@
shared_libraries := \
libcutils \
liblog \
- libandroidfw \
libutils \
libhardware \
libhardware_legacy \
@@ -24,7 +23,7 @@
external/skia/include/core
-module_tags := eng tests
+module_tags := tests
$(foreach file,$(test_src_files), \
$(eval include $(CLEAR_VARS)) \
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 80845a2..30a244b 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -85,6 +85,7 @@
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i<size_t(count) ; i++) {
const Info& info = mActivationCount.valueFor(list[i].handle);
+ if (info.batchParams.isEmpty()) continue;
result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
info.batchParams.size());
for (size_t j = 0; j < info.batchParams.size(); j++) {
@@ -147,8 +148,12 @@
if (enabled) {
ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
+ if (isClientDisabledLocked(ident)) {
+ return INVALID_OPERATION;
+ }
+
if (info.batchParams.indexOfKey(ident) >= 0) {
- if (info.batchParams.size() == 1) {
+ if (info.numActiveClients() == 1) {
// This is the first connection, we need to activate the underlying h/w sensor.
actuateHardware = true;
}
@@ -160,7 +165,7 @@
ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
if (info.removeBatchParamsForIdent(ident) >= 0) {
- if (info.batchParams.size() == 0) {
+ if (info.numActiveClients() == 0) {
// This is the last connection, we need to de-activate the underlying h/w sensor.
actuateHardware = true;
} else {
@@ -181,10 +186,15 @@
} else {
// sensor wasn't enabled for this ident
}
+
+ if (isClientDisabledLocked(ident)) {
+ return NO_ERROR;
+ }
}
if (actuateHardware) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
+ enabled);
err = mSensorDevice->activate(
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
@@ -197,7 +207,7 @@
}
// On older devices which do not support batch, call setDelay().
- if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
+ if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
info.bestBatchParams.batchDelay);
mSensorDevice->setDelay(
@@ -279,6 +289,7 @@
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
}
Mutex::Autolock _l(mLock);
+ if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
Info& info( mActivationCount.editValueFor(handle) );
// If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
// Calling setDelay() in batch mode is an invalid operation.
@@ -298,7 +309,6 @@
int SensorDevice::getHalDeviceVersion() const {
if (!mSensorDevice) return -1;
-
return mSensorDevice->common.version;
}
@@ -306,12 +316,89 @@
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
return INVALID_OPERATION;
}
+ if (isClientDisabled(ident)) return INVALID_OPERATION;
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
return mSensorDevice->flush(mSensorDevice, handle);
}
+bool SensorDevice::isClientDisabled(void* ident) {
+ Mutex::Autolock _l(mLock);
+ return isClientDisabledLocked(ident);
+}
+
+bool SensorDevice::isClientDisabledLocked(void* ident) {
+ return mDisabledClients.indexOf(ident) >= 0;
+}
+
+void SensorDevice::enableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ mDisabledClients.clear();
+ const int halVersion = getHalDeviceVersion();
+ for (size_t i = 0; i< mActivationCount.size(); ++i) {
+ Info& info = mActivationCount.editValueAt(i);
+ if (info.batchParams.isEmpty()) continue;
+ info.selectBatchParams();
+ const int sensor_handle = mActivationCount.keyAt(i);
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
+ sensor_handle);
+ status_t err(NO_ERROR);
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
+ err = mSensorDevice->batch(mSensorDevice, sensor_handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
+ }
+
+ if (err == NO_ERROR) {
+ err = mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ sensor_handle, 1);
+ ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
+ }
+
+ if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
+ err = mSensorDevice->setDelay(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ sensor_handle, info.bestBatchParams.batchDelay);
+ ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
+ }
+ }
+}
+
+void SensorDevice::disableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ for (size_t i = 0; i< mActivationCount.size(); ++i) {
+ const Info& info = mActivationCount.valueAt(i);
+ // Check if this sensor has been activated previously and disable it.
+ if (info.batchParams.size() > 0) {
+ const int sensor_handle = mActivationCount.keyAt(i);
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
+ sensor_handle);
+ mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
+ sensor_handle, 0);
+ // Add all the connections that were registered for this sensor to the disabled
+ // clients list.
+ for (int j = 0; j < info.batchParams.size(); ++j) {
+ mDisabledClients.add(info.batchParams.keyAt(j));
+ }
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
+int SensorDevice::Info::numActiveClients() {
+ SensorDevice& device(SensorDevice::getInstance());
+ int num = 0;
+ for (size_t i = 0; i < batchParams.size(); ++i) {
+ if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
+ ++num;
+ }
+ }
+ return num;
+}
+
status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
int64_t samplingPeriodNs,
int64_t maxBatchReportLatencyNs) {
@@ -329,19 +416,16 @@
}
void SensorDevice::Info::selectBatchParams() {
- BatchParams bestParams(-1, -1, -1);
+ BatchParams bestParams(0, -1, -1);
+ SensorDevice& device(SensorDevice::getInstance());
- if (batchParams.size() > 0) {
- BatchParams params = batchParams.valueAt(0);
- bestParams = params;
- }
-
- for (size_t i = 1; i < batchParams.size(); ++i) {
+ for (size_t i = 0; i < batchParams.size(); ++i) {
+ if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
BatchParams params = batchParams.valueAt(i);
- if (params.batchDelay < bestParams.batchDelay) {
+ if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
bestParams.batchDelay = params.batchDelay;
}
- if (params.batchTimeout < bestParams.batchTimeout) {
+ if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
bestParams.batchTimeout = params.batchTimeout;
}
}
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 761b48c..cf33a59 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -42,6 +42,7 @@
// Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
// batch call. For continous mode clients, maxBatchReportLatency is set to zero.
struct BatchParams {
+ // TODO: Get rid of flags parameter everywhere.
int flags;
nsecs_t batchDelay, batchTimeout;
BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
@@ -65,7 +66,7 @@
// requested by the client.
KeyedVector<void*, BatchParams> batchParams;
- Info() : bestBatchParams(-1, -1, -1) {}
+ Info() : bestBatchParams(0, -1, -1) {}
// Sets batch parameters for this ident. Returns error if this ident is not already present
// in the KeyedVector above.
status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
@@ -75,10 +76,17 @@
// Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
// the removed ident. If index >=0, ident is present and successfully removed.
ssize_t removeBatchParamsForIdent(void* ident);
+
+ int numActiveClients();
};
DefaultKeyedVector<int, Info> mActivationCount;
+ // Use this vector to determine which client is activated or deactivated.
+ SortedVector<void *> mDisabledClients;
SensorDevice();
+
+ bool isClientDisabled(void* ident);
+ bool isClientDisabledLocked(void* ident);
public:
ssize_t getSensorList(sensor_t const** list);
status_t initCheck() const;
@@ -90,6 +98,8 @@
// Call batch with timeout zero instead of calling setDelay() for newer devices.
status_t setDelay(void* ident, int handle, int64_t ns);
status_t flush(void* ident, int handle);
+ void disableAllSensors();
+ void enableAllSensors();
void autoDisable(void *ident, int handle);
void dump(String8& result);
};
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index a857366..2336d88 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -190,6 +190,7 @@
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
+ mMode = NORMAL;
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
@@ -230,7 +231,7 @@
static const String16 sDump("android.permission.DUMP");
-status_t SensorService::dump(int fd, const Vector<String16>& /*args*/)
+status_t SensorService::dump(int fd, const Vector<String16>& args)
{
String8 result;
if (!PermissionCache::checkCallingPermission(sDump)) {
@@ -238,6 +239,26 @@
"can't dump SensorService from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
+ } else if (args.size() > 0) {
+ if (args.size() > 1) {
+ return INVALID_OPERATION;
+ }
+ Mutex::Autolock _l(mLock);
+ SensorDevice& dev(SensorDevice::getInstance());
+ if (args[0] == String16("restrict") && mMode == NORMAL) {
+ mMode = RESTRICTED;
+ dev.disableAllSensors();
+ // Clear all pending flush connections for all active sensors. If one of the active
+ // connections has called flush() and the underlying sensor has been disabled before a
+ // flush complete event is returned, we need to remove the connection from this queue.
+ for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
+ mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
+ }
+ } else if (args[0] == String16("enable") && mMode == RESTRICTED) {
+ mMode = NORMAL;
+ dev.enableAllSensors();
+ }
+ return status_t(NO_ERROR);
} else {
Mutex::Autolock _l(mLock);
result.append("Sensor List:\n");
@@ -341,6 +362,17 @@
result.appendFormat("Socket Buffer size = %d events\n",
mSocketBufferSize/sizeof(sensors_event_t));
result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
+ result.appendFormat("Mode :");
+ switch(mMode) {
+ case NORMAL:
+ result.appendFormat(" NORMAL\n");
+ break;
+ case RESTRICTED:
+ result.appendFormat(" RESTRICTED\n");
+ break;
+ case DATA_INJECTION:
+ result.appendFormat(" DATA_INJECTION\n");
+ }
result.appendFormat("%zd active connections\n", mActiveConnections.size());
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
@@ -554,7 +586,6 @@
}
}
-
bool SensorService::isWakeLockAcquired() {
Mutex::Autolock _l(mLock);
return mWakeLockAcquired;
@@ -630,7 +661,6 @@
return sensor != NULL && sensor->getSensor().isWakeUpSensor();
}
-
SensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
return mActiveSensors.valueFor(handle);
}
@@ -655,10 +685,10 @@
return accessibleSensorList;
}
-sp<ISensorEventConnection> SensorService::createSensorEventConnection()
+sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName)
{
uid_t uid = IPCThreadState::self()->getCallingUid();
- sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
+ sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName));
return result;
}
@@ -708,7 +738,7 @@
}
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
- int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
+ int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
if (mInitCheck != NO_ERROR)
return mInitCheck;
@@ -723,6 +753,10 @@
}
Mutex::Autolock _l(mLock);
+ if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
+ return INVALID_OPERATION;
+ }
+
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
rec = new SensorRecord(connection);
@@ -773,7 +807,7 @@
"rate=%" PRId64 " timeout== %" PRId64"",
handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
- status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
+ status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
maxBatchReportLatencyNs);
// Call flush() before calling activate() on the sensor. Wait for a first flush complete
@@ -969,6 +1003,11 @@
}
}
+bool SensorService::isWhiteListedPackage(const String8& packageName) {
+ // TODO: Come up with a list of packages.
+ return (packageName.find(".cts.") != -1);
+}
+
// ---------------------------------------------------------------------------
SensorService::SensorRecord::SensorRecord(
const sp<SensorEventConnection>& connection)
@@ -1025,12 +1064,16 @@
return NULL;
}
+void SensorService::SensorRecord::clearAllPendingFlushConnections() {
+ mPendingFlushConnections.clear();
+}
+
// ---------------------------------------------------------------------------
SensorService::SensorEventConnection::SensorEventConnection(
- const sp<SensorService>& service, uid_t uid)
+ const sp<SensorService>& service, uid_t uid, String8 packageName)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
- mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0) {
+ mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -1062,8 +1105,8 @@
void SensorService::SensorEventConnection::dump(String8& result) {
Mutex::Autolock _l(mConnectionLock);
- result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
- mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
+ result.appendFormat("\t%s | WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
+ mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
@@ -1126,6 +1169,10 @@
return false;
}
+String8 SensorService::SensorEventConnection::getPackageName() const {
+ return mPackageName;
+}
+
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
bool value) {
Mutex::Autolock _l(mConnectionLock);
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index e9ca3a5..b31eaf3 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -27,6 +27,7 @@
#include <utils/AndroidThreads.h>
#include <utils/RefBase.h>
#include <utils/Looper.h>
+#include <utils/String8.h>
#include <binder/BinderService.h>
@@ -65,6 +66,27 @@
{
friend class BinderService<SensorService>;
+ enum Mode {
+ // The regular operating mode where any application can register/unregister/call flush on
+ // sensors.
+ NORMAL = 0,
+ // This mode is used only for testing sensors. Each sensor can be tested in isolation with
+ // the required sampling_rate and maxReportLatency parameters without having to think about
+ // the data rates requested by other applications. End user devices are always expected to be
+ // in NORMAL mode. When this mode is first activated, all active sensors from all connections
+ // are disabled. Calling flush() will return an error. In this mode, only the requests from
+ // selected apps whose package names are whitelisted are allowed (typically CTS apps). Only
+ // these apps can register/unregister/call flush() on sensors. If SensorService switches to
+ // NORMAL mode again, all sensors that were previously registered to are activated with the
+ // corresponding paramaters if the application hasn't unregistered for sensors in the mean
+ // time.
+ // NOTE: Non whitelisted app whose sensors were previously deactivated may still receive
+ // events if a whitelisted app requests data from the same sensor.
+ RESTRICTED,
+ // TODO: This mode hasn't been implemented yet.
+ DATA_INJECTION
+ };
+
static const char* WAKE_LOCK_NAME;
static char const* getServiceName() ANDROID_API { return "sensorservice"; }
@@ -78,7 +100,7 @@
// ISensorServer interface
virtual Vector<Sensor> getSensorList();
- virtual sp<ISensorEventConnection> createSensorEventConnection();
+ virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName);
virtual status_t dump(int fd, const Vector<String16>& args);
class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
@@ -133,7 +155,6 @@
// connection FD may be added to the Looper. The flags to set are determined by the internal
// state of the connection. FDs are added to the looper when wake-up sensors are registered
// (to poll for acknowledgements) and when write fails on the socket when there are too many
- // events (to poll when the FD is available for writing). FDs are removed when there is an
// error and the other end hangs up or when this client unregisters for this connection.
void updateLooperRegistration(const sp<Looper>& looper);
void updateLooperRegistrationLocked(const sp<Looper>& looper);
@@ -169,6 +190,7 @@
KeyedVector<int, FlushInfo> mSensorInfo;
sensors_event_t *mEventCache;
int mCacheSize, mMaxCacheSize;
+ String8 mPackageName;
#if DEBUG_CONNECTIONS
int mEventsReceived, mEventsSent, mEventsSentFromCache;
@@ -176,7 +198,7 @@
#endif
public:
- SensorEventConnection(const sp<SensorService>& service, uid_t uid);
+ SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName);
status_t sendEvents(sensors_event_t const* buffer, size_t count,
sensors_event_t* scratch,
@@ -190,6 +212,7 @@
void dump(String8& result);
bool needsWakeLock();
void resetWakeLockRefCount();
+ String8 getPackageName() const;
uid_t getUid() const { return mUid; }
};
@@ -208,6 +231,7 @@
void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
void removeFirstPendingFlushConnection();
SensorEventConnection * getFirstPendingFlushConnection();
+ void clearAllPendingFlushConnections();
};
class SensorEventAckReceiver : public Thread {
@@ -261,6 +285,11 @@
// to the output vector.
void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
+ // If SensorService is operating in RESTRICTED mode, only select whitelisted packages are
+ // allowed to register for or call flush on sensors. Typically only cts test packages are
+ // allowed.
+ bool isWhiteListedPackage(const String8& packageName);
+
// constants
Vector<Sensor> mSensorList;
Vector<Sensor> mUserSensorListDebug;
@@ -282,6 +311,7 @@
bool mWakeLockAcquired;
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
SensorEventConnection const **mMapFlushEventsToConnections;
+ Mode mMode;
// The size of this vector is constant, only the items are mutable
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
diff --git a/services/surfaceflinger/DdmConnection.cpp b/services/surfaceflinger/DdmConnection.cpp
index a000a84..659c2c8 100644
--- a/services/surfaceflinger/DdmConnection.cpp
+++ b/services/surfaceflinger/DdmConnection.cpp
@@ -66,7 +66,7 @@
jint (*registerNatives)(JNIEnv* env, jclass clazz);
registerNatives = reinterpret_cast<decltype(registerNatives)>(
dlsym(libandroid_runtime_dso,
- "Java_com_android_internal_util_WithFramework_registerNatives"));
+ "Java_com_android_internal_util_WithFramework_registerNatives"));
ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror());
if (!JNI_CreateJavaVM || !registerNatives) {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 4885c5f..6ef3295 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -29,8 +29,9 @@
#include <EGL/egl.h>
#include <hardware/hardware.h>
-#include <gui/Surface.h>
+#include <gui/BufferItem.h>
#include <gui/GraphicBufferAlloc.h>
+#include <gui/Surface.h>
#include <ui/GraphicBuffer.h>
#include "FramebufferSurface.h"
@@ -86,7 +87,7 @@
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Mutex::Autolock lock(mMutex);
- BufferQueue::BufferItem item;
+ BufferItem item;
status_t err = acquireBufferLocked(&item, 0);
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
outBuffer = mCurrentBuffer;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index edfed49..77a9a19 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -1105,8 +1105,6 @@
case PIXEL_FORMAT_RGB_888: return String8("RGB_888");
case PIXEL_FORMAT_RGB_565: return String8("RGB_565");
case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888");
- case PIXEL_FORMAT_sRGB_A_8888: return String8("sRGB_A_8888");
- case PIXEL_FORMAT_sRGB_X_8888: return String8("sRGB_x_8888");
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
return String8("ImplDef");
default:
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ef10fa7..0e94f0d 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -18,6 +18,8 @@
#include "VirtualDisplaySurface.h"
#include "HWComposer.h"
+#include <gui/BufferItem.h>
+
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
@@ -234,6 +236,7 @@
status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
QueueBufferInput(
systemTime(), false /* isAutoTimestamp */,
+ HAL_DATASPACE_UNKNOWN,
Rect(mSinkBufferWidth, mSinkBufferHeight),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
true /* async*/,
@@ -435,7 +438,7 @@
// Now acquire the buffer from the scratch pool -- should be the same
// slot and fence as we just queued.
Mutex::Autolock lock(mMutex);
- BufferQueue::BufferItem item;
+ BufferItem item;
result = acquireBufferLocked(&item, 0);
if (result != NO_ERROR)
return result;
@@ -453,12 +456,13 @@
// Extract the GLES release fence for HWC to acquire
int64_t timestamp;
bool isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
bool async;
- input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode,
- &transform, &async, &mFbFence);
+ input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop,
+ &scalingMode, &transform, &async, &mFbFence);
mFbProducerSlot = pslot;
mOutputFence = mFbFence;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9da1efd..2ac4765 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -764,7 +764,6 @@
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_sRGB_A_8888:
return false;
}
// in all other case, we have no blending (also for unknown formats)
@@ -1131,7 +1130,7 @@
}
virtual bool reject(const sp<GraphicBuffer>& buf,
- const IGraphicBufferConsumer::BufferItem& item) {
+ const BufferItem& item) {
if (buf == NULL) {
return false;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9dc140e..c931155 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -148,7 +148,11 @@
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
- mHasColorMatrix(false)
+ mHasColorMatrix(false),
+ mHasPoweredOff(false),
+ mFrameBuckets(),
+ mTotalTime(0),
+ mLastSwapTime(0)
{
ALOGI("SurfaceFlinger is starting");
@@ -953,8 +957,8 @@
}
}
+ const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
if (kIgnorePresentFences) {
- const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
if (hw->isDisplayOn()) {
enableHardwareVsync();
}
@@ -973,6 +977,26 @@
}
mAnimFrameTracker.advanceFrame();
}
+
+ if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
+ return;
+ }
+
+ nsecs_t currentTime = systemTime();
+ if (mHasPoweredOff) {
+ mHasPoweredOff = false;
+ } else {
+ nsecs_t period = mPrimaryDispSync.getPeriod();
+ nsecs_t elapsedTime = currentTime - mLastSwapTime;
+ size_t numPeriods = static_cast<size_t>(elapsedTime / period);
+ if (numPeriods < NUM_BUCKETS - 1) {
+ mFrameBuckets[numPeriods] += elapsedTime;
+ } else {
+ mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
+ }
+ mTotalTime += elapsedTime;
+ }
+ mLastSwapTime = currentTime;
}
void SurfaceFlinger::rebuildLayerStacks() {
@@ -2349,6 +2373,7 @@
}
mVisibleRegionsDirty = true;
+ mHasPoweredOff = true;
repaintEverything();
} else if (mode == HWC_POWER_MODE_OFF) {
if (type == DisplayDevice::DISPLAY_PRIMARY) {
@@ -2449,6 +2474,13 @@
mPrimaryDispSync.dump(result);
dumpAll = false;
}
+
+ if ((index < numArgs) &&
+ (args[index] == String16("--static-screen"))) {
+ index++;
+ dumpStaticScreenStats(result);
+ dumpAll = false;
+ }
}
if (dumpAll) {
@@ -2552,6 +2584,23 @@
result.append(config);
}
+void SurfaceFlinger::dumpStaticScreenStats(String8& result) const
+{
+ result.appendFormat("Static screen stats:\n");
+ for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
+ float bucketTimeSec = mFrameBuckets[b] / 1e9;
+ float percent = 100.0f *
+ static_cast<float>(mFrameBuckets[b]) / mTotalTime;
+ result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n",
+ b + 1, bucketTimeSec, percent);
+ }
+ float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
+ float percent = 100.0f *
+ static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
+ result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n",
+ NUM_BUCKETS - 1, bucketTimeSec, percent);
+}
+
void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
String8& result) const
{
@@ -2598,6 +2647,11 @@
mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
result.append("\n");
+ // Dump static screen stats
+ result.append("\n");
+ dumpStaticScreenStats(result);
+ result.append("\n");
+
/*
* Dump the visible layer list
*/
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4deb815..34f0aaa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -416,6 +416,8 @@
void logFrameStats();
+ void dumpStaticScreenStats(String8& result) const;
+
/* ------------------------------------------------------------------------
* Attributes
*/
@@ -493,6 +495,13 @@
mat4 mColorMatrix;
bool mHasColorMatrix;
+
+ // Static screen stats
+ bool mHasPoweredOff;
+ static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
+ nsecs_t mFrameBuckets[NUM_BUCKETS];
+ nsecs_t mTotalTime;
+ nsecs_t mLastSwapTime;
};
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 7de6ac4..abf3993 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -21,6 +21,8 @@
#include <private/gui/SyncFeatures.h>
+#include <gui/BufferItem.h>
+
#include <utils/Errors.h>
#include <utils/NativeHandle.h>
#include <utils/Trace.h>
@@ -47,7 +49,7 @@
return err;
}
- BufferQueue::BufferItem item;
+ BufferItem item;
// Acquire the next buffer.
// In asynchronous mode the list is guaranteed to be one buffer
@@ -101,8 +103,8 @@
return bindTextureImageLocked();
}
-status_t SurfaceFlingerConsumer::acquireBufferLocked(
- BufferQueue::BufferItem *item, nsecs_t presentWhen) {
+status_t SurfaceFlingerConsumer::acquireBufferLocked(BufferItem* item,
+ nsecs_t presentWhen) {
status_t result = GLConsumer::acquireBufferLocked(item, presentWhen);
if (result == NO_ERROR) {
mTransformToDisplayInverse = item->mTransformToDisplayInverse;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 28f2f6a..d1cf9b9 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -41,13 +41,13 @@
class BufferRejecter {
friend class SurfaceFlingerConsumer;
virtual bool reject(const sp<GraphicBuffer>& buf,
- const IGraphicBufferConsumer::BufferItem& item) = 0;
+ const BufferItem& item) = 0;
protected:
virtual ~BufferRejecter() { }
};
- virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item, nsecs_t presentWhen);
+ virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen);
// This version of updateTexImage() takes a functor that may be used to
// reject the newly acquired buffer. Unlike the GLConsumer version,