Merge "BufferQueue: Hook up IProducerListener"
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 8f4da65..671d031 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -1022,7 +1022,13 @@
// Make the profile directory write-only for group and other. Owner can rwx it.
if (chmod(profile_dir, 0711) < 0) {
ALOGE("cannot chown profile dir '%s': %s\n", profile_dir, strerror(errno));
- unlink(profile_dir);
+ rmdir(profile_dir);
+ return -1;
+ }
+
+ if (selinux_android_restorecon(profile_dir, 0) < 0) {
+ ALOGE("cannot restorecon profile dir '%s': %s\n", profile_dir, strerror(errno));
+ rmdir(profile_dir);
return -1;
}
}
diff --git a/data/etc/android.software.managedprofiles.xml b/data/etc/android.software.managedprofiles.xml
new file mode 100644
index 0000000..233a78d
--- /dev/null
+++ b/data/etc/android.software.managedprofiles.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is the standard feature indicating that the device supports managed profiles. -->
+<permissions>
+ <feature name="android.software.managedprofiles" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 4d81fb6..0bdadef 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -4,9 +4,9 @@
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.
@@ -44,9 +44,12 @@
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
+ <!-- Feature to specify if the device support managed profiles. -->
+ <feature name="android.software.managedprofiles" />
+
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
- android.hardware.camera.autofocus.xml or
+ android.hardware.camera.autofocus.xml or
android.hardware.camera.autofocus-flash.xml -->
<!-- devices with a front facing camera must include
android.hardware.camera.front.xml -->
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 2a74b0f..4f7465f 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -4,9 +4,9 @@
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.
@@ -45,10 +45,13 @@
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
+ <!-- Feature to specify if the device support managed profiles. -->
+ <feature name="android.software.managedprofiles" />
+
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with a rear-facing camera must include one of these as appropriate:
- android.hardware.camera.xml or
- android.hardware.camera.autofocus.xml or
+ android.hardware.camera.xml or
+ android.hardware.camera.autofocus.xml or
android.hardware.camera.autofocus-flash.xml -->
<!-- devices with a front facing camera must include
android.hardware.camera.front.xml -->
diff --git a/include/android/configuration.h b/include/android/configuration.h
index 6d8784d..97d4c42 100644
--- a/include/android/configuration.h
+++ b/include/android/configuration.h
@@ -83,6 +83,7 @@
ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03,
ACONFIGURATION_UI_MODE_TYPE_TELEVISION = 0x04,
ACONFIGURATION_UI_MODE_TYPE_APPLIANCE = 0x05,
+ ACONFIGURATION_UI_MODE_TYPE_WATCH = 0x06,
ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00,
ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1,
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 129ea3e..b4e7ebe 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -281,6 +281,28 @@
*/
int ASensor_getMinDelay(ASensor const* sensor);
+/*
+ * Returns the maximum size of batches for this sensor. Batches will often be
+ * smaller, as the hardware fifo might be used for other sensors.
+ */
+int ASensor_getFifoMaxEventCount(ASensor const* sensor);
+
+/*
+ * Returns the hardware batch fifo size reserved to this sensor.
+ */
+int ASensor_getFifoReservedEventCount(ASensor const* sensor);
+
+/*
+ * Returns this sensor's string type.
+ */
+const char* ASensor_getStringType(ASensor const* sensor);
+
+/*
+ * Returns the permission required to see or access this sensor, or the
+ * empty string if none is required.
+ */
+const char* ASensor_getRequiredPermission(ASensor const* sensor);
+
#ifdef __cplusplus
};
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index e63a0d0..3bc978d 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -27,11 +27,6 @@
// ---------------------------------------------------------------------------
namespace android {
-// Global variables
-extern int mArgC;
-extern const char* const* mArgV;
-extern int mArgLen;
-
class IPCThreadState;
class ProcessState : public virtual RefBase
@@ -62,12 +57,6 @@
wp<IBinder> getWeakProxyForHandle(int32_t handle);
void expungeHandle(int32_t handle, IBinder* binder);
- void setArgs(int argc, const char* const argv[]);
- int getArgC() const;
- const char* const* getArgV() const;
-
- void setArgV0(const char* txt);
-
void spawnPooledThread(bool isMain);
status_t setThreadPoolMaxThreadCount(size_t maxThreads);
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 85bf5a9..da876ec 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -112,10 +112,6 @@
// needed gralloc buffers.
BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL);
- static void createBufferQueue(sp<BnGraphicBufferProducer>* outProducer,
- sp<BnGraphicBufferConsumer>* outConsumer,
- const sp<IGraphicBufferAlloc>& allocator = NULL);
-
static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator = NULL);
diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h
index f8267bf..a4718b9 100644
--- a/include/gui/DisplayEventReceiver.h
+++ b/include/gui/DisplayEventReceiver.h
@@ -49,7 +49,7 @@
struct Header {
uint32_t type;
uint32_t id;
- nsecs_t timestamp;
+ nsecs_t timestamp __attribute__((aligned(8)));
};
struct VSync {
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 35dcd4e..efde5db 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -22,9 +22,12 @@
#include <utils/RefBase.h>
#include <utils/Errors.h>
+#include <utils/Timers.h>
+#include <utils/Vector.h>
#include <binder/IInterface.h>
+#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
#include <gui/IGraphicBufferAlloc.h>
@@ -122,6 +125,19 @@
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform) = 0;
+
+
+ /* Clears the frame statistics for animations.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ virtual status_t clearAnimationFrameStats() = 0;
+
+ /* Gets the frame statistics for animations.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0;
};
// ----------------------------------------------------------------------------
@@ -145,6 +161,8 @@
GET_DISPLAY_INFO,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
+ CLEAR_ANIMATION_FRAME_STATS,
+ GET_ANIMATION_FRAME_STATS
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index cb9816f..58c1f6a 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -25,6 +25,7 @@
#include <binder/IInterface.h>
+#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
namespace android {
@@ -65,6 +66,16 @@
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual status_t destroySurface(const sp<IBinder>& handle) = 0;
+
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0;
+
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 0c81426..033b262 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -69,6 +69,8 @@
int32_t getVersion() const;
int32_t getFifoReservedEventCount() const;
int32_t getFifoMaxEventCount() const;
+ const String8& getStringType() const;
+ const String8& getRequiredPermission() const;
// LightFlattenable protocol
inline bool isFixedSize() const { return false; }
@@ -89,6 +91,10 @@
int32_t mVersion;
int32_t mFifoReservedEventCount;
int32_t mFifoMaxEventCount;
+ String8 mStringType;
+ String8 mRequiredPermission;
+ static void flattenString8(void*& buffer, size_t& size, const String8& string8);
+ static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index ac53f02..6a53ccb 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -28,6 +28,7 @@
#include <utils/SortedVector.h>
#include <utils/threads.h>
+#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
#include <gui/CpuConsumer.h>
@@ -125,6 +126,12 @@
status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack);
status_t destroySurface(const sp<IBinder>& id);
+ status_t clearLayerFrameStats(const sp<IBinder>& token) const;
+ status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
+
+ static status_t clearAnimationFrameStats();
+ static status_t getAnimationFrameStats(FrameStats* outStats);
+
static void setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);
static void setDisplayLayerStack(const sp<IBinder>& token,
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index f27754c..84fb9f9 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -24,6 +24,7 @@
#include <utils/RefBase.h>
#include <utils/threads.h>
+#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
@@ -52,10 +53,10 @@
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
-
+
// release surface data from java
void clear();
-
+
status_t setLayerStack(int32_t layerStack);
status_t setLayer(int32_t layer);
status_t setPosition(float x, float y);
@@ -73,6 +74,9 @@
sp<Surface> getSurface() const;
+ status_t clearLayerFrameStats() const;
+ status_t getLayerFrameStats(FrameStats* outStats) const;
+
private:
// can't be copied
SurfaceControl& operator = (SurfaceControl& rhs);
@@ -90,7 +94,7 @@
status_t validate() const;
void destroy();
-
+
sp<SurfaceComposerClient> mClient;
sp<IBinder> mHandle;
sp<IGraphicBufferProducer> mGraphicBufferProducer;
diff --git a/include/input/Input.h b/include/input/Input.h
index bb5ceaf..077a03b 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -178,13 +178,9 @@
/* These flags are set by the input reader policy as it intercepts each event. */
- // Indicates that the screen was off when the event was received and the event
- // should wake the device.
- POLICY_FLAG_WOKE_HERE = 0x10000000,
-
- // Indicates that the screen was dim when the event was received and the event
- // should brighten the device.
- POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+ // Indicates that the device was in an interactive state when the
+ // event was intercepted.
+ POLICY_FLAG_INTERACTIVE = 0x20000000,
// Indicates that the event should be dispatched to applications.
// The input event should still be sent to the InputDispatcher so that it can see all
diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h
index 95bdf77..fc6b49c 100644
--- a/include/media/drm/DrmAPI.h
+++ b/include/media/drm/DrmAPI.h
@@ -178,12 +178,16 @@
// provisioning server.
//
// If successful, the opaque provision request blob is returned to the caller.
- virtual status_t getProvisionRequest(Vector<uint8_t> &request,
+ virtual status_t getProvisionRequest(String8 const &cert_type,
+ String8 const &cert_authority,
+ Vector<uint8_t> &request,
String8 &defaultUrl) = 0;
// After a provision response is received by the app, it is provided to the
// Drm plugin using provideProvisionResponse.
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) = 0;
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrapped_key) = 0;
// A means of enforcing the contractual requirement for a concurrent stream
// limit per subscriber across devices is provided via SecureStop. SecureStop
@@ -290,6 +294,15 @@
bool &match) = 0;
+ // Compute an RSA signature on the provided message using the algorithm
+ // specified by algorithm.
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrapped_key,
+ Vector<uint8_t> &signature) = 0;
+
+
status_t setListener(const sp<DrmPluginListener>& listener) {
Mutex::Autolock lock(mEventLock);
mListener = listener;
diff --git a/include/media/openmax/OMX_Types.h b/include/media/openmax/OMX_Types.h
index 03fd4bc..9dec372 100644
--- a/include/media/openmax/OMX_Types.h
+++ b/include/media/openmax/OMX_Types.h
@@ -48,6 +48,8 @@
#ifndef OMX_Types_h
#define OMX_Types_h
+#include <stdint.h>
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -160,10 +162,10 @@
typedef signed short OMX_S16;
/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
-typedef unsigned long OMX_U32;
+typedef uint32_t OMX_U32;
/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
-typedef signed long OMX_S32;
+typedef int32_t OMX_S32;
/* Users with compilers that cannot accept the "long long" designation should
diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h
index d85003f..511797a 100644
--- a/include/powermanager/IPowerManager.h
+++ b/include/powermanager/IPowerManager.h
@@ -19,6 +19,7 @@
#include <utils/Errors.h>
#include <binder/IInterface.h>
+#include <hardware/power.h>
namespace android {
@@ -36,6 +37,7 @@
const String16& packageName, int uid) = 0;
virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags) = 0;
virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids) = 0;
+ virtual status_t powerHint(int hintId, int data) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/ui/FrameStats.h b/include/ui/FrameStats.h
new file mode 100644
index 0000000..5fdf94d
--- /dev/null
+++ b/include/ui/FrameStats.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_FRAME_STATS_H
+#define ANDROID_UI_FRAME_STATS_H
+
+#include <utils/Flattenable.h>
+#include <utils/Timers.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class FrameStats : public LightFlattenable<FrameStats> {
+public:
+
+ /*
+ * Approximate refresh time, in nanoseconds.
+ */
+ nsecs_t refreshPeriodNano;
+
+ /*
+ * The times in nanoseconds for when the frame contents were posted by the producer (e.g.
+ * the application). They are either explicitly set or defaulted to the time when
+ * Surface::queueBuffer() was called.
+ */
+ Vector<nsecs_t> desiredPresentTimesNano;
+
+ /*
+ * The times in milliseconds for when the frame contents were presented on the screen.
+ */
+ Vector<nsecs_t> actualPresentTimesNano;
+
+ /*
+ * The times in nanoseconds for when the frame contents were ready to be presented. Note that
+ * a frame can be posted and still it contents being rendered asynchronously in GL. In such a
+ * case these are the times when the frame contents were completely rendered (i.e. their fences
+ * signaled).
+ */
+ Vector<nsecs_t> frameReadyTimesNano;
+
+ // LightFlattenable
+ bool isFixedSize() const;
+ size_t getFlattenedSize() const;
+ status_t flatten(void* buffer, size_t size) const;
+ status_t unflatten(void const* buffer, size_t size);
+};
+
+}; // namespace android
+
+#endif // ANDROID_UI_FRAME_STATS_H
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 19ed047..303d6cf 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -48,11 +48,6 @@
namespace android {
-// Global variables
-int mArgC;
-const char* const* mArgV;
-int mArgLen;
-
class PoolThread : public Thread
{
public:
@@ -280,36 +275,6 @@
if (e && e->binder == binder) e->binder = NULL;
}
-void ProcessState::setArgs(int argc, const char* const argv[])
-{
- mArgC = argc;
- mArgV = (const char **)argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
-}
-
-int ProcessState::getArgC() const
-{
- return mArgC;
-}
-
-const char* const* ProcessState::getArgV() const
-{
- return mArgV;
-}
-
-void ProcessState::setArgV0(const char* txt)
-{
- if (mArgV != NULL) {
- strncpy((char*)mArgV[0], txt, mArgLen);
- set_process_name(txt);
- }
-}
-
String8 ProcessState::makeBinderThreadName() {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
String8 name;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 6d2cb25..d04b67d 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -43,19 +43,6 @@
}
}
-void BufferQueue::createBufferQueue(sp<BnGraphicBufferProducer>* outProducer,
- sp<BnGraphicBufferConsumer>* outConsumer,
- const sp<IGraphicBufferAlloc>& allocator) {
- LOG_ALWAYS_FATAL_IF(outProducer == NULL,
- "BufferQueue: outProducer must not be NULL");
- LOG_ALWAYS_FATAL_IF(outConsumer == NULL,
- "BufferQueue: outConsumer must not be NULL");
-
- sp<BufferQueueCore> core(new BufferQueueCore(allocator));
- *outProducer = new BufferQueueProducer(core);
- *outConsumer = new BufferQueueConsumer(core);
-}
-
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
@@ -65,8 +52,19 @@
"BufferQueue: outConsumer must not be NULL");
sp<BufferQueueCore> core(new BufferQueueCore(allocator));
- *outProducer = new BufferQueueProducer(core);
- *outConsumer = new BufferQueueConsumer(core);
+ LOG_ALWAYS_FATAL_IF(core == NULL,
+ "BufferQueue: failed to create BufferQueueCore");
+
+ sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
+ LOG_ALWAYS_FATAL_IF(producer == NULL,
+ "BufferQueue: failed to create BufferQueueProducer");
+
+ sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
+ LOG_ALWAYS_FATAL_IF(consumer == NULL,
+ "BufferQueue: failed to create BufferQueueConsumer");
+
+ *outProducer = producer;
+ *outConsumer = consumer;
}
BufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) :
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 28bbb1b..71ba4e7 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -20,6 +20,8 @@
#define EGL_EGLEXT_PROTOTYPES
+#include <inttypes.h>
+
#include <gui/BufferItem.h>
#include <gui/BufferQueueCore.h>
#include <gui/IConsumerListener.h>
@@ -82,7 +84,7 @@
Fifo::const_iterator current(mQueue.begin());
while (current != mQueue.end()) {
fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], "
- "xform=0x%02x, time=%#llx, scale=%s\n",
+ "xform=0x%02x, time=%#" PRIx64 ", scale=%s\n",
current->mSlot, current->mGraphicBuffer.get(),
current->mCrop.left, current->mCrop.top, current->mCrop.right,
current->mCrop.bottom, current->mTransform, current->mTimestamp,
@@ -92,7 +94,7 @@
result.appendFormat("%s-BufferQueue mMaxAcquiredBufferCount=%d, "
"mDequeueBufferCannotBlock=%d, default-size=[%dx%d], "
- "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
+ "default-format=%d, transform-hint=%02x, FIFO(%zu)={%s}\n",
prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock,
mDefaultWidth, mDefaultHeight, mDefaultBufferFormat, mTransformHint,
mQueue.size(), fifo.string());
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 82d931e..ea37309 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -795,8 +795,16 @@
}
status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
- Mutex::Autolock _l(mCore->mMutex);
- mCore->mSidebandStream = stream;
+ sp<IConsumerListener> listener;
+ { // Autolock scope
+ Mutex::Autolock _l(mCore->mMutex);
+ mCore->mSidebandStream = stream;
+ listener = mCore->mConsumerListener;
+ } // Autolock scope
+
+ if (listener != NULL) {
+ listener->onSidebandStreamChanged();
+ }
return NO_ERROR;
}
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 7ee3081..3215b2f 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -350,20 +350,24 @@
{
status_t err = NO_ERROR;
+ int buf = item.mBuf;
+
if (!mAttached) {
ST_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL "
"ES context");
+ releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+ mEglDisplay, EGL_NO_SYNC_KHR);
return INVALID_OPERATION;
}
// Confirm state.
err = checkAndUpdateEglStateLocked();
if (err != NO_ERROR) {
+ releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+ mEglDisplay, EGL_NO_SYNC_KHR);
return err;
}
- int buf = item.mBuf;
-
// If the mEglSlot entry is empty, create an EGLImage for the gralloc
// buffer currently in the slot in ConsumerBase.
//
@@ -377,6 +381,12 @@
if (image == EGL_NO_IMAGE_KHR) {
ST_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d",
mEglDisplay, buf);
+ const sp<GraphicBuffer>& gb = mSlots[buf].mGraphicBuffer;
+ ST_LOGW("buffer size=%ux%u st=%u usage=0x%x fmt=%d",
+ gb->getWidth(), gb->getHeight(), gb->getStride(),
+ gb->getUsage(), gb->getPixelFormat());
+ releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+ mEglDisplay, EGL_NO_SYNC_KHR);
return UNKNOWN_ERROR;
}
mEglSlots[buf].mEglImage = image;
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index cdd06f3..1b19626 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -402,7 +402,7 @@
}
sp<NativeHandle> stream;
if (reply.readInt32()) {
- stream = NativeHandle::create(reply.readNativeHandle());
+ stream = NativeHandle::create(reply.readNativeHandle(), true);
}
return stream;
}
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 50490af..c0b08c1 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -338,7 +338,7 @@
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<NativeHandle> stream;
if (data.readInt32()) {
- stream = NativeHandle::create(data.readNativeHandle());
+ stream = NativeHandle::create(data.readNativeHandle(), true);
}
status_t result = setSidebandStream(stream);
reply->writeInt32(result);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index e96cc54..c067244 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -229,6 +229,21 @@
memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo));
return reply.readInt32();
}
+
+ virtual status_t clearAnimationFrameStats() {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ remote()->transact(BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t getAnimationFrameStats(FrameStats* outStats) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply);
+ reply.read(*outStats);
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -351,6 +366,20 @@
reply->writeInt32(result);
return NO_ERROR;
}
+ case CLEAR_ANIMATION_FRAME_STATS: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ status_t result = clearAnimationFrameStats();
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
+ case GET_ANIMATION_FRAME_STATS: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ FrameStats stats;
+ status_t result = getAnimationFrameStats(&stats);
+ reply->write(stats);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 1adc134..3da6423 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -39,7 +39,9 @@
enum {
CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
- DESTROY_SURFACE
+ DESTROY_SURFACE,
+ CLEAR_LAYER_FRAME_STATS,
+ GET_LAYER_FRAME_STATS
};
class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
@@ -73,6 +75,23 @@
remote()->transact(DESTROY_SURFACE, data, &reply);
return reply.readInt32();
}
+
+ virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeStrongBinder(handle);
+ remote()->transact(CLEAR_LAYER_FRAME_STATS, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeStrongBinder(handle);
+ remote()->transact(GET_LAYER_FRAME_STATS, data, &reply);
+ reply.read(*outStats);
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
@@ -101,7 +120,23 @@
} break;
case DESTROY_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- reply->writeInt32( destroySurface( data.readStrongBinder() ) );
+ reply->writeInt32(destroySurface( data.readStrongBinder() ) );
+ return NO_ERROR;
+ } break;
+ case CLEAR_LAYER_FRAME_STATS: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ sp<IBinder> handle = data.readStrongBinder();
+ status_t result = clearLayerFrameStats(handle);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ } break;
+ case GET_LAYER_FRAME_STATS: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ sp<IBinder> handle = data.readStrongBinder();
+ FrameStats stats;
+ status_t result = getLayerFrameStats(handle, &stats);
+ reply->write(stats);
+ reply->writeInt32(result);
return NO_ERROR;
} break;
default:
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index da6b0f9..6f1a3f2 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -48,14 +48,90 @@
mResolution = hwSensor->resolution;
mPower = hwSensor->power;
mMinDelay = hwSensor->minDelay;
+
// Set fifo event count zero for older devices which do not support batching. Fused
// sensors also have their fifo counts set to zero.
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
mFifoReservedEventCount = hwSensor->fifoReservedEventCount;
mFifoMaxEventCount = hwSensor->fifoMaxEventCount;
- } else {
- mFifoReservedEventCount = 0;
- mFifoMaxEventCount = 0;
+ }
+
+ // Ensure existing sensors have correct string type and required
+ // permissions.
+ switch (mType) {
+ case SENSOR_TYPE_ACCELEROMETER:
+ mStringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+ break;
+ case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+ mStringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+ break;
+ case SENSOR_TYPE_GAME_ROTATION_VECTOR:
+ mStringType = SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR;
+ break;
+ case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+ mStringType = SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
+ break;
+ case SENSOR_TYPE_GRAVITY:
+ mStringType = SENSOR_STRING_TYPE_GRAVITY;
+ break;
+ case SENSOR_TYPE_GYROSCOPE:
+ mStringType = SENSOR_STRING_TYPE_GYROSCOPE;
+ break;
+ case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+ mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
+ break;
+ case SENSOR_TYPE_HEART_RATE:
+ mStringType = SENSOR_STRING_TYPE_HEART_RATE;
+ mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
+ break;
+ case SENSOR_TYPE_LIGHT:
+ mStringType = SENSOR_STRING_TYPE_LIGHT;
+ break;
+ case SENSOR_TYPE_LINEAR_ACCELERATION:
+ mStringType = SENSOR_STRING_TYPE_LINEAR_ACCELERATION;
+ break;
+ case SENSOR_TYPE_MAGNETIC_FIELD:
+ mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+ break;
+ case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+ mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+ break;
+ case SENSOR_TYPE_ORIENTATION:
+ mStringType = SENSOR_STRING_TYPE_ORIENTATION;
+ break;
+ case SENSOR_TYPE_PRESSURE:
+ mStringType = SENSOR_STRING_TYPE_PRESSURE;
+ break;
+ case SENSOR_TYPE_PROXIMITY:
+ mStringType = SENSOR_STRING_TYPE_PROXIMITY;
+ break;
+ case SENSOR_TYPE_RELATIVE_HUMIDITY:
+ mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
+ break;
+ case SENSOR_TYPE_ROTATION_VECTOR:
+ mStringType = SENSOR_STRING_TYPE_ROTATION_VECTOR;
+ break;
+ case SENSOR_TYPE_SIGNIFICANT_MOTION:
+ mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION;
+ break;
+ case SENSOR_TYPE_STEP_COUNTER:
+ mStringType = SENSOR_STRING_TYPE_STEP_COUNTER;
+ break;
+ case SENSOR_TYPE_STEP_DETECTOR:
+ mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR;
+ break;
+ case SENSOR_TYPE_TEMPERATURE:
+ mStringType = SENSOR_STRING_TYPE_TEMPERATURE;
+ break;
+ default:
+ // Only pipe the stringType and requiredPermission for custom sensors.
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->stringType) {
+ mStringType = hwSensor->stringType;
+ }
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->requiredPermission) {
+ mRequiredPermission = hwSensor->requiredPermission;
+ }
+ break;
}
}
@@ -115,6 +191,14 @@
return mFifoMaxEventCount;
}
+const String8& Sensor::getStringType() const {
+ return mStringType;
+}
+
+const String8& Sensor::getRequiredPermission() const {
+ return mRequiredPermission;
+}
+
size_t Sensor::getFlattenedSize() const
{
size_t fixedSize =
@@ -123,8 +207,10 @@
sizeof(int32_t) * 3;
size_t variableSize =
- sizeof(int32_t) + FlattenableUtils::align<4>(mName.length()) +
- sizeof(int32_t) + FlattenableUtils::align<4>(mVendor.length());
+ sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
+ sizeof(uint32_t) + FlattenableUtils::align<4>(mVendor.length()) +
+ sizeof(uint32_t) + FlattenableUtils::align<4>(mStringType.length()) +
+ sizeof(uint32_t) + FlattenableUtils::align<4>(mRequiredPermission.length());
return fixedSize + variableSize;
}
@@ -134,14 +220,8 @@
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, mName.length());
- memcpy(static_cast<char*>(buffer), mName.string(), mName.length());
- FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mName.length()));
-
- FlattenableUtils::write(buffer, size, mVendor.length());
- memcpy(static_cast<char*>(buffer), mVendor.string(), mVendor.length());
- FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mVendor.length()));
-
+ flattenString8(buffer, size, mName);
+ flattenString8(buffer, size, mVendor);
FlattenableUtils::write(buffer, size, mVersion);
FlattenableUtils::write(buffer, size, mHandle);
FlattenableUtils::write(buffer, size, mType);
@@ -152,38 +232,23 @@
FlattenableUtils::write(buffer, size, mMinDelay);
FlattenableUtils::write(buffer, size, mFifoReservedEventCount);
FlattenableUtils::write(buffer, size, mFifoMaxEventCount);
+ flattenString8(buffer, size, mStringType);
+ flattenString8(buffer, size, mRequiredPermission);
return NO_ERROR;
}
status_t Sensor::unflatten(void const* buffer, size_t size) {
- size_t len;
-
- if (size < sizeof(size_t)) {
+ if (!unflattenString8(buffer, size, mName)) {
return NO_MEMORY;
}
- FlattenableUtils::read(buffer, size, len);
- if (size < len) {
+ if (!unflattenString8(buffer, size, mVendor)) {
return NO_MEMORY;
}
- mName.setTo(static_cast<char const*>(buffer), len);
- FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
-
-
- if (size < sizeof(size_t)) {
- return NO_MEMORY;
- }
- FlattenableUtils::read(buffer, size, len);
- if (size < len) {
- return NO_MEMORY;
- }
- mVendor.setTo(static_cast<char const*>(buffer), len);
- FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
size_t fixedSize =
sizeof(int32_t) * 3 +
sizeof(float) * 4 +
sizeof(int32_t) * 3;
-
if (size < fixedSize) {
return NO_MEMORY;
}
@@ -198,8 +263,37 @@
FlattenableUtils::read(buffer, size, mMinDelay);
FlattenableUtils::read(buffer, size, mFifoReservedEventCount);
FlattenableUtils::read(buffer, size, mFifoMaxEventCount);
+
+ if (!unflattenString8(buffer, size, mStringType)) {
+ return NO_MEMORY;
+ }
+ if (!unflattenString8(buffer, size, mRequiredPermission)) {
+ return NO_MEMORY;
+ }
return NO_ERROR;
}
+void Sensor::flattenString8(void*& buffer, size_t& size,
+ const String8& string8) {
+ uint32_t len = string8.length();
+ FlattenableUtils::write(buffer, size, len);
+ memcpy(static_cast<char*>(buffer), string8.string(), len);
+ FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
+}
+
+bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& outputString8) {
+ uint32_t len;
+ if (size < sizeof(len)) {
+ return false;
+ }
+ FlattenableUtils::read(buffer, size, len);
+ if (size < len) {
+ return false;
+ }
+ outputString8.setTo(static_cast<char const*>(buffer), len);
+ FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
+ return true;
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6b20eaf..b7af415 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -515,6 +515,21 @@
return err;
}
+status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const {
+ if (mStatus != NO_ERROR) {
+ return mStatus;
+ }
+ return mClient->clearLayerFrameStats(token);
+}
+
+status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token,
+ FrameStats* outStats) const {
+ if (mStatus != NO_ERROR) {
+ return mStatus;
+ }
+ return mClient->getLayerFrameStats(token, outStats);
+}
+
inline Composer& SurfaceComposerClient::getComposer() {
return mComposer;
}
@@ -622,6 +637,14 @@
ComposerService::getComposerService()->unblank(token);
}
+status_t SurfaceComposerClient::clearAnimationFrameStats() {
+ return ComposerService::getComposerService()->clearAnimationFrameStats();
+}
+
+status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) {
+ return ComposerService::getComposerService()->getAnimationFrameStats(outStats);
+}
+
// ----------------------------------------------------------------------------
status_t ScreenshotClient::capture(
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index de182ee..7c6dfb8 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -156,6 +156,20 @@
return client->setCrop(mHandle, crop);
}
+status_t SurfaceControl::clearLayerFrameStats() const {
+ status_t err = validate();
+ if (err < 0) return err;
+ const sp<SurfaceComposerClient>& client(mClient);
+ return client->clearLayerFrameStats(mHandle);
+}
+
+status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const {
+ status_t err = validate();
+ if (err < 0) return err;
+ const sp<SurfaceComposerClient>& client(mClient);
+ return client->getLayerFrameStats(mHandle, outStats);
+}
+
status_t SurfaceControl::validate() const
{
if (mHandle==0 || mClient==0) {
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index e578eef..fe8f8b1 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -83,12 +83,12 @@
if (forkPid == 0) {
// Child process
- sp<BnGraphicBufferProducer> producer;
- sp<BnGraphicBufferConsumer> consumer;
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
sp<IServiceManager> serviceManager = defaultServiceManager();
- serviceManager->addService(PRODUCER_NAME, producer.get());
- serviceManager->addService(CONSUMER_NAME, consumer.get());
+ serviceManager->addService(PRODUCER_NAME, producer->asBinder());
+ serviceManager->addService(CONSUMER_NAME, consumer->asBinder());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOG_ALWAYS_FATAL("Shouldn't be here");
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index 9f61a09..abd3724 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -64,11 +64,13 @@
test_info->name(),
params.width, params.height,
params.maxLockedBuffers, params.format);
- sp<BufferQueue> bq = new BufferQueue();
- mCC = new CpuConsumer(bq, params.maxLockedBuffers);
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ mCC = new CpuConsumer(consumer, params.maxLockedBuffers);
String8 name("CpuConsumer_Under_Test");
mCC->setName(name);
- mSTC = new Surface(bq);
+ mSTC = new Surface(producer);
mANW = mSTC;
}
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 70a89cd..aadfe61 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -81,11 +81,9 @@
ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
- mBQ = new BufferQueue();
mDC = new DummyConsumer;
- mProducer = mBQ;
- mConsumer = mBQ;
+ BufferQueue::createBufferQueue(&mProducer, &mConsumer);
// Test check: Can't connect producer if no consumer yet
ASSERT_EQ(NO_INIT, TryConnectProducer());
@@ -202,7 +200,6 @@
}
private: // hide from test body
- sp<BufferQueue> mBQ;
sp<DummyConsumer> mDC;
protected: // accessible from test body
diff --git a/libs/gui/tests/MultiTextureConsumer_test.cpp b/libs/gui/tests/MultiTextureConsumer_test.cpp
index 853c25c..1eb6ef6 100644
--- a/libs/gui/tests/MultiTextureConsumer_test.cpp
+++ b/libs/gui/tests/MultiTextureConsumer_test.cpp
@@ -34,9 +34,11 @@
virtual void SetUp() {
GLTest::SetUp();
- sp<BufferQueue> bq = new BufferQueue();
- mGlConsumer = new GLConsumer(bq, TEX_ID);
- mSurface = new Surface(bq);
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ mGlConsumer = new GLConsumer(consumer, TEX_ID);
+ mSurface = new Surface(producer);
mANW = mSurface.get();
}
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
index 1077c9d..2d5b8aa 100644
--- a/libs/gui/tests/SRGB_test.cpp
+++ b/libs/gui/tests/SRGB_test.cpp
@@ -68,13 +68,15 @@
}
virtual void SetUp() {
- mBufferQueue = new BufferQueue();
- ASSERT_EQ(NO_ERROR, mBufferQueue->setDefaultBufferSize(
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ ASSERT_EQ(NO_ERROR, consumer->setDefaultBufferSize(
DISPLAY_WIDTH, DISPLAY_HEIGHT));
- mCpuConsumer = new CpuConsumer(mBufferQueue, 1);
+ mCpuConsumer = new CpuConsumer(consumer, 1);
String8 name("CpuConsumer_for_SRGBTest");
mCpuConsumer->setName(name);
- mInputSurface = new Surface(mBufferQueue);
+ mInputSurface = new Surface(producer);
ASSERT_NO_FATAL_FAILURE(createEGLSurface(mInputSurface.get()));
ASSERT_NO_FATAL_FAILURE(createDebugSurface());
@@ -222,7 +224,6 @@
}
// Primary producer and consumer
- sp<BufferQueue> mBufferQueue;
sp<Surface> mInputSurface;
sp<CpuConsumer> mCpuConsumer;
CpuConsumer::LockedBuffer mLockedBuffer;
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 989fcef..7f9fcc4 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -43,9 +43,11 @@
ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
- sp<BufferQueue> bq = new BufferQueue();
- mST = new GLConsumer(bq, 123);
- mSTC = new Surface(bq);
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ mST = new GLConsumer(consumer, 123);
+ mSTC = new Surface(producer);
mANW = mSTC;
// We need a valid GL context so we can test updateTexImage()
@@ -711,9 +713,11 @@
ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
- sp<BufferQueue> bq = new BufferQueue();
- sp<GLConsumer> st(new GLConsumer(bq, i));
- sp<Surface> stc(new Surface(bq));
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<GLConsumer> st(new GLConsumer(consumer, i));
+ sp<Surface> stc(new Surface(producer));
mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
static_cast<ANativeWindow*>(stc.get()), NULL);
ASSERT_EQ(EGL_SUCCESS, eglGetError());
diff --git a/libs/gui/tests/SurfaceTextureGL.h b/libs/gui/tests/SurfaceTextureGL.h
index ac112c4..3bff192 100644
--- a/libs/gui/tests/SurfaceTextureGL.h
+++ b/libs/gui/tests/SurfaceTextureGL.h
@@ -37,10 +37,10 @@
void SetUp() {
GLTest::SetUp();
- sp<BufferQueue> bq = new BufferQueue();
- mBQ = bq;
- mST = new GLConsumer(bq, TEX_ID);
- mSTC = new Surface(bq);
+ sp<IGraphicBufferProducer> producer;
+ BufferQueue::createBufferQueue(&producer, &mConsumer);
+ mST = new GLConsumer(mConsumer, TEX_ID);
+ mSTC = new Surface(producer);
mANW = mSTC;
mTextureRenderer = new TextureRenderer(TEX_ID, mST);
ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
@@ -60,7 +60,7 @@
mTextureRenderer->drawTexture();
}
- sp<BufferQueue> mBQ;
+ sp<IGraphicBufferConsumer> mConsumer;
sp<GLConsumer> mST;
sp<Surface> mSTC;
sp<ANativeWindow> mANW;
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index 25b2319..fa1e1b7 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -451,7 +451,7 @@
};
sp<DisconnectWaiter> dw(new DisconnectWaiter());
- mBQ->consumerConnect(dw, false);
+ mConsumer->consumerConnect(dw, false);
sp<Thread> pt(new ProducerThread(mANW));
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 4b6e603..bf87fad 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -88,11 +88,13 @@
sp<ANativeWindow> anw(mSurface);
// Verify the screenshot works with no protected buffers.
- sp<BufferQueue> bq = new BufferQueue();
- sp<CpuConsumer> consumer = new CpuConsumer(bq, 1);
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- ASSERT_EQ(NO_ERROR, sf->captureScreen(display, bq,
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer,
64, 64, 0, 0x7fffffff, false));
// Set the PROTECTED usage bit and verify that the screenshot fails. Note
@@ -121,7 +123,7 @@
&buf));
ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
}
- ASSERT_EQ(NO_ERROR, sf->captureScreen(display, bq,
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer,
64, 64, 0, 0x7fffffff, false));
}
@@ -136,10 +138,12 @@
TEST_F(SurfaceTest, QueryConsumerUsage) {
const int TEST_USAGE_FLAGS =
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
- sp<BufferQueue> bq = new BufferQueue();
- sp<BufferItemConsumer> c = new BufferItemConsumer(bq,
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<BufferItemConsumer> c = new BufferItemConsumer(consumer,
TEST_USAGE_FLAGS);
- sp<Surface> s = new Surface(bq);
+ sp<Surface> s = new Surface(producer);
sp<ANativeWindow> anw(s);
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 008446b..eec97be 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -18,6 +18,7 @@
LOCAL_SRC_FILES:= \
Fence.cpp \
FramebufferNativeWindow.cpp \
+ FrameStats.cpp \
GraphicBuffer.cpp \
GraphicBufferAllocator.cpp \
GraphicBufferMapper.cpp \
diff --git a/libs/ui/FrameStats.cpp b/libs/ui/FrameStats.cpp
new file mode 100644
index 0000000..acbe27e
--- /dev/null
+++ b/libs/ui/FrameStats.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014 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 <ui/FrameStats.h>
+
+namespace android {
+
+bool FrameStats::isFixedSize() const {
+ return false;
+}
+
+size_t FrameStats::getFlattenedSize() const {
+ const size_t timestampSize = sizeof(nsecs_t);
+
+ size_t size = timestampSize;
+ size += 3 * desiredPresentTimesNano.size() * timestampSize;
+
+ return size;
+}
+
+status_t FrameStats::flatten(void* buffer, size_t size) const {
+ if (size < getFlattenedSize()) {
+ return NO_MEMORY;
+ }
+
+ nsecs_t* timestamps = reinterpret_cast<nsecs_t*>(buffer);
+ const size_t timestampSize = sizeof(nsecs_t);
+ size_t frameCount = desiredPresentTimesNano.size();
+
+ memcpy(timestamps, &refreshPeriodNano, timestampSize);
+ timestamps += 1;
+
+ memcpy(timestamps, desiredPresentTimesNano.array(), frameCount * timestampSize);
+ timestamps += frameCount;
+
+ memcpy(timestamps, actualPresentTimesNano.array(), frameCount * timestampSize);
+ timestamps += frameCount;
+
+ memcpy(timestamps, frameReadyTimesNano.array(), frameCount * timestampSize);
+
+ return NO_ERROR;
+}
+
+status_t FrameStats::unflatten(void const* buffer, size_t size) {
+ const size_t timestampSize = sizeof(nsecs_t);
+
+ if (size < timestampSize) {
+ return NO_MEMORY;
+ }
+
+ nsecs_t const* timestamps = reinterpret_cast<nsecs_t const*>(buffer);
+ size_t frameCount = (size - timestampSize) / (3 * timestampSize);
+
+ memcpy(&refreshPeriodNano, timestamps, timestampSize);
+ timestamps += 1;
+
+ desiredPresentTimesNano.resize(frameCount);
+ memcpy(desiredPresentTimesNano.editArray(), timestamps, frameCount * timestampSize);
+ timestamps += frameCount;
+
+ actualPresentTimesNano.resize(frameCount);
+ memcpy(actualPresentTimesNano.editArray(), timestamps, frameCount * timestampSize);
+ timestamps += frameCount;
+
+ frameReadyTimesNano.resize(frameCount);
+ memcpy(frameReadyTimesNano.editArray(), timestamps, frameCount * timestampSize);
+
+ return NO_ERROR;
+}
+
+} // namespace android
diff --git a/opengl/libagl/fixed_asm.S b/opengl/libagl/fixed_asm.S
index 05044f2..5e08856 100644
--- a/opengl/libagl/fixed_asm.S
+++ b/opengl/libagl/fixed_asm.S
@@ -17,7 +17,7 @@
.text
- .align
+ .align 2
.global gglFloatToFixed
.type gglFloatToFixed, %function
diff --git a/opengl/libagl/iterators.S b/opengl/libagl/iterators.S
index 8c86482..8fe9039 100644
--- a/opengl/libagl/iterators.S
+++ b/opengl/libagl/iterators.S
@@ -17,7 +17,7 @@
.text
- .align
+ .align 2
.arm
.global iterators0032
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 67fbae5..44b5560 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -222,7 +222,7 @@
}
char value[PROPERTY_VALUE_MAX];
property_get("debug.egl.callstack", value, "0");
- if (atoi(value)) {
+ if (true || atoi(value)) {
CallStack stack(LOG_TAG);
}
}
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index fea52f3..a4364c6 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -107,9 +107,11 @@
};
// Create a EGLSurface
- sp<BufferQueue> bq = new BufferQueue();
- bq->consumerConnect(new DummyConsumer, false);
- sp<Surface> mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( bq));
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ consumer->consumerConnect(new DummyConsumer, false);
+ sp<Surface> mSTC = new Surface(producer);
sp<ANativeWindow> mANW = mSTC;
EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index b70ea76..ac73c1f 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1045,10 +1045,6 @@
AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE,
- AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4,
- AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8,
- AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12,
- AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16,
};
status_t EventHub::openDeviceLocked(const char *devicePath) {
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index dbfc957..f219f95 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -251,10 +251,10 @@
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
nsecs_t currentTime = now();
- // Reset the key repeat timer whenever we disallow key events, even if the next event
- // is not a key. This is to ensure that we abort a key repeat if the device is just coming
- // out of sleep.
- if (!mPolicy->isKeyRepeatEnabled()) {
+ // Reset the key repeat timer whenever normal dispatch is suspended while the
+ // device is in a non-interactive state. This is to ensure that we abort a key
+ // repeat if the device is just coming out of sleep.
+ if (!mDispatchEnabled) {
resetKeyRepeatLocked();
}
@@ -1138,30 +1138,6 @@
// For security reasons, we defer updating the touch state until we are sure that
// event injection will be allowed.
- //
- // FIXME In the original code, screenWasOff could never be set to true.
- // The reason is that the POLICY_FLAG_WOKE_HERE
- // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
- // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
- // actually enqueued using the policyFlags that appeared in the final EV_SYN
- // events upon which no preprocessing took place. So policyFlags was always 0.
- // In the new native input dispatcher we're a bit more careful about event
- // preprocessing so the touches we receive can actually have non-zero policyFlags.
- // Unfortunately we obtain undesirable behavior.
- //
- // Here's what happens:
- //
- // When the device dims in anticipation of going to sleep, touches
- // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
- // the device to brighten and reset the user activity timer.
- // Touches on other windows (such as the launcher window)
- // are dropped. Then after a moment, the device goes to sleep. Oops.
- //
- // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
- // instead of POLICY_FLAG_WOKE_HERE...
- //
- bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
-
int32_t displayId = entry->displayId;
int32_t action = entry->action;
int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
@@ -1246,10 +1222,7 @@
isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
| InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
- if (! screenWasOff
- || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
- newTouchedWindowHandle = windowHandle;
- }
+ newTouchedWindowHandle = windowHandle;
break; // found touched window, exit window loop
}
}
@@ -2412,10 +2385,6 @@
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
- if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- flags |= AKEY_EVENT_FLAG_WOKE_HERE;
- }
-
bool needWake;
{ // acquire lock
mLock.lock();
@@ -2595,10 +2564,6 @@
mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
}
- if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- flags |= AKEY_EVENT_FLAG_WOKE_HERE;
- }
-
mLock.lock();
firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
keyEvent->getDeviceId(), keyEvent->getSource(),
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 29854b2..9439124 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -211,9 +211,6 @@
/* Gets the input dispatcher configuration. */
virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
- /* Returns true if automatic key repeating is enabled. */
- virtual bool isKeyRepeatEnabled() = 0;
-
/* Filters an input event.
* Return true to dispatch the event unmodified, false to consume the event.
* A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index fc89a9b..7aac6ed 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -65,10 +65,6 @@
*outConfig = mConfig;
}
- virtual bool isKeyRepeatEnabled() {
- return true;
- }
-
virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
return true;
}
diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp
index 5ecd299..ee730d6 100644
--- a/services/powermanager/IPowerManager.cpp
+++ b/services/powermanager/IPowerManager.cpp
@@ -33,6 +33,7 @@
ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1,
RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2,
UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3,
+ POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4,
};
class BpPowerManager : public BpInterface<IPowerManager>
@@ -54,6 +55,7 @@
data.writeString16(tag);
data.writeString16(packageName);
data.writeInt32(0); // no WorkSource
+ data.writeString16(NULL, 0); // no history tag
return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply);
}
@@ -89,6 +91,15 @@
// but it should return ASAP
return remote()->transact(UPDATE_WAKE_LOCK_UIDS, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ virtual status_t powerHint(int hintId, int param)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());
+ data.writeInt32(hintId);
+ data.writeInt32(param);
+ return remote()->transact(POWER_HINT, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
IMPLEMENT_META_INTERFACE(PowerManager, "android.os.IPowerManager");
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index f0bfe2c..8837a4d 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -206,7 +206,7 @@
String8 result;
if (!PermissionCache::checkCallingPermission(sDump)) {
result.appendFormat("Permission Denial: "
- "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
+ "can't dump SensorService from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
} else {
@@ -216,21 +216,24 @@
const Sensor& s(mSensorList[i]);
const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
result.appendFormat(
- "%-48s| %-32s | 0x%08x | ",
+ "%-48s| %-32s| %-48s| 0x%08x | \"%s\"\n\t",
s.getName().string(),
s.getVendor().string(),
- s.getHandle());
+ s.getStringType().string(),
+ s.getHandle(),
+ s.getRequiredPermission().string());
if (s.getMinDelay() > 0) {
result.appendFormat(
- "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
+ "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
} else {
result.append(s.getMinDelay() == 0
? "on-demand | "
: "one-shot | ");
}
if (s.getFifoMaxEventCount() > 0) {
- result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
+ result.appendFormat("FifoMax=%d events | ",
+ s.getFifoMaxEventCount());
} else {
result.append("no batching support | ");
}
@@ -491,10 +494,23 @@
{
char value[PROPERTY_VALUE_MAX];
property_get("debug.sensors", value, "0");
- if (atoi(value)) {
- return mUserSensorListDebug;
+ const Vector<Sensor>& initialSensorList = (atoi(value)) ?
+ mUserSensorListDebug : mUserSensorList;
+ Vector<Sensor> accessibleSensorList;
+ for (size_t i = 0; i < initialSensorList.size(); i++) {
+ Sensor sensor = initialSensorList[i];
+ if (canAccessSensor(sensor)) {
+ accessibleSensorList.add(sensor);
+ } else {
+ String8 infoMessage;
+ infoMessage.appendFormat(
+ "Skipped sensor %s because it requires permission %s",
+ sensor.getName().string(),
+ sensor.getRequiredPermission().string());
+ ALOGI(infoMessage.string());
+ }
}
- return mUserSensorList;
+ return accessibleSensorList;
}
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
@@ -540,6 +556,10 @@
BatteryService::cleanup(c->getUid());
}
+Sensor SensorService::getSensorFromHandle(int handle) const {
+ return mSensorMap.valueFor(handle)->getSensor();
+}
+
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
@@ -550,6 +570,11 @@
if (sensor == NULL) {
return BAD_VALUE;
}
+
+ if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) {
+ return BAD_VALUE;
+ }
+
Mutex::Autolock _l(mLock);
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
@@ -671,6 +696,10 @@
if (!sensor)
return BAD_VALUE;
+ if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) {
+ return BAD_VALUE;
+ }
+
if (ns < 0)
return BAD_VALUE;
@@ -684,17 +713,44 @@
status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
int handle) {
- if (mInitCheck != NO_ERROR) return mInitCheck;
- SensorInterface* sensor = mSensorMap.valueFor(handle);
- if (sensor == NULL) {
- return BAD_VALUE;
- }
- if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
- ALOGE("flush called on Significant Motion sensor");
- return INVALID_OPERATION;
- }
- return sensor->flush(connection.get(), handle);
+ if (mInitCheck != NO_ERROR) return mInitCheck;
+ SensorInterface* sensor = mSensorMap.valueFor(handle);
+ if (sensor == NULL) {
+ return BAD_VALUE;
+ }
+
+ if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) {
+ return BAD_VALUE;
+ }
+
+ if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+ ALOGE("flush called on Significant Motion sensor");
+ return INVALID_OPERATION;
+ }
+ return sensor->flush(connection.get(), handle);
}
+
+
+bool SensorService::canAccessSensor(const Sensor& sensor) {
+ String16 permissionString(sensor.getRequiredPermission());
+ return permissionString.size() == 0 ||
+ PermissionCache::checkCallingPermission(permissionString);
+}
+
+bool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) {
+ if (canAccessSensor(sensor)) {
+ return true;
+ } else {
+ String8 errorMessage;
+ errorMessage.appendFormat(
+ "%s a sensor (%s) without holding its required permission: %s",
+ operation,
+ sensor.getName().string(),
+ sensor.getRequiredPermission().string());
+ return false;
+ }
+}
+
// ---------------------------------------------------------------------------
SensorService::SensorRecord::SensorRecord(
@@ -763,6 +819,9 @@
bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
Mutex::Autolock _l(mConnectionLock);
+ if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) {
+ return false;
+ }
if (mSensorInfo.indexOfKey(handle) < 0) {
mSensorInfo.add(handle, FlushInfo());
return true;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 1dc2dd3..e88ffc8 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -131,6 +131,7 @@
String8 getSensorName(int handle) const;
bool isVirtualSensor(int handle) const;
+ Sensor getSensorFromHandle(int handle) const;
void recordLastValue(const sensors_event_t* buffer, size_t count);
static void sortEventBuffer(sensors_event_t* buffer, size_t count);
Sensor registerSensor(SensorInterface* sensor);
@@ -141,7 +142,8 @@
const sp<SensorEventConnection>& connection, int handle);
void cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
sensors_event_t const* buffer, const int count);
-
+ static bool canAccessSensor(const Sensor& sensor);
+ static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation);
// constants
Vector<Sensor> mSensorList;
Vector<Sensor> mUserSensorListDebug;
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 975631c..f7d32d0 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -155,5 +155,23 @@
return mFlinger->onLayerRemoved(this, handle);
}
+status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
+ sp<Layer> layer = getLayerUser(handle);
+ if (layer == NULL) {
+ return NAME_NOT_FOUND;
+ }
+ layer->clearFrameStats();
+ return NO_ERROR;
+}
+
+status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
+ sp<Layer> layer = getLayerUser(handle);
+ if (layer == NULL) {
+ return NAME_NOT_FOUND;
+ }
+ layer->getFrameStats(outStats);
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 84e649f..b6d7381 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -60,6 +60,10 @@
virtual status_t destroySurface(const sp<IBinder>& handle);
+ virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
+
+ virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
+
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/services/surfaceflinger/FrameTracker.cpp b/services/surfaceflinger/FrameTracker.cpp
index 2fb665e..c09bbe4 100644
--- a/services/surfaceflinger/FrameTracker.cpp
+++ b/services/surfaceflinger/FrameTracker.cpp
@@ -22,6 +22,7 @@
#include <cutils/log.h>
#include <ui/Fence.h>
+#include <ui/FrameStats.h>
#include <utils/String8.h>
@@ -100,7 +101,7 @@
processFencesLocked();
}
-void FrameTracker::clear() {
+void FrameTracker::clearStats() {
Mutex::Autolock lock(mMutex);
for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
mFrameRecords[i].desiredPresentTime = 0;
@@ -115,6 +116,32 @@
mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
}
+void FrameTracker::getStats(FrameStats* outStats) const {
+ Mutex::Autolock lock(mMutex);
+ processFencesLocked();
+
+ outStats->refreshPeriodNano = mDisplayPeriod;
+
+ const size_t offset = mOffset;
+ for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {
+ const size_t index = (offset + i) % NUM_FRAME_RECORDS;
+
+ // Skip frame records with no data (if buffer not yet full).
+ if (mFrameRecords[index].desiredPresentTime == 0) {
+ continue;
+ }
+
+ nsecs_t desiredPresentTimeNano = mFrameRecords[index].desiredPresentTime;
+ outStats->desiredPresentTimesNano.push_back(desiredPresentTimeNano);
+
+ nsecs_t actualPresentTimeNano = mFrameRecords[index].actualPresentTime;
+ outStats->actualPresentTimesNano.push_back(actualPresentTimeNano);
+
+ nsecs_t frameReadyTimeNano = mFrameRecords[index].frameReadyTime;
+ outStats->frameReadyTimesNano.push_back(frameReadyTimeNano);
+ }
+}
+
void FrameTracker::logAndResetStats(const String8& name) {
Mutex::Autolock lock(mMutex);
logStatsLocked(name);
@@ -206,7 +233,7 @@
mFrameRecords[idx].actualPresentTime < INT64_MAX;
}
-void FrameTracker::dump(String8& result) const {
+void FrameTracker::dumpStats(String8& result) const {
Mutex::Autolock lock(mMutex);
processFencesLocked();
diff --git a/services/surfaceflinger/FrameTracker.h b/services/surfaceflinger/FrameTracker.h
index 9233247..cd5e3f3 100644
--- a/services/surfaceflinger/FrameTracker.h
+++ b/services/surfaceflinger/FrameTracker.h
@@ -78,15 +78,18 @@
// advanceFrame advances the frame tracker to the next frame.
void advanceFrame();
- // clear resets all the tracked frame data to zero.
- void clear();
+ // clearStats clears the tracked frame stats.
+ void clearStats();
+
+ // getStats gets the tracked frame stats.
+ void getStats(FrameStats* outStats) const;
// logAndResetStats dumps the current statistics to the binary event log
// and then resets the accumulated statistics to their initial values.
void logAndResetStats(const String8& name);
- // dump appends the current frame display time history to the result string.
- void dump(String8& result) const;
+ // dumpStats dump appends the current frame display time history to the result string.
+ void dumpStats(String8& result) const;
private:
struct FrameRecord {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7f2ee2a..1b86204 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -117,8 +117,8 @@
void Layer::onFirstRef() {
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
- sp<BnGraphicBufferProducer> producer;
- sp<BnGraphicBufferConsumer> consumer;
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
@@ -959,7 +959,7 @@
bool Layer::isVisible() const {
const Layer::State& s(mDrawingState);
return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
- && (mActiveBuffer != NULL);
+ && (mActiveBuffer != NULL || mSidebandStream != NULL);
}
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
@@ -1244,18 +1244,22 @@
}
}
-void Layer::dumpStats(String8& result) const {
- mFrameTracker.dump(result);
+void Layer::dumpFrameStats(String8& result) const {
+ mFrameTracker.dumpStats(result);
}
-void Layer::clearStats() {
- mFrameTracker.clear();
+void Layer::clearFrameStats() {
+ mFrameTracker.clearStats();
}
void Layer::logFrameStats() {
mFrameTracker.logAndResetStats(mName);
}
+void Layer::getFrameStats(FrameStats* outStats) const {
+ mFrameTracker.getStats(outStats);
+}
+
// ---------------------------------------------------------------------------
Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8f8989e..62970c3 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -27,6 +27,7 @@
#include <utils/String8.h>
#include <utils/Timers.h>
+#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
@@ -288,9 +289,10 @@
/* always call base class first */
void dump(String8& result, Colorizer& colorizer) const;
- void dumpStats(String8& result) const;
- void clearStats();
+ void dumpFrameStats(String8& result) const;
+ void clearFrameStats();
void logFrameStats();
+ void getFrameStats(FrameStats* outStats) const;
protected:
// constant
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index f6010b7..1a2b7e5 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -20,7 +20,7 @@
namespace android {
-MonitoredProducer::MonitoredProducer(const sp<BnGraphicBufferProducer>& producer,
+MonitoredProducer::MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
const sp<SurfaceFlinger>& flinger) :
mProducer(producer),
mFlinger(flinger) {}
@@ -49,8 +49,7 @@
wp<IBinder> mProducer;
};
- mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger,
- static_cast<BnGraphicBufferProducer*>(this)));
+ mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder()));
}
status_t MonitoredProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
@@ -101,5 +100,9 @@
return mProducer->setSidebandStream(stream);
}
+IBinder* MonitoredProducer::onAsBinder() {
+ return mProducer->asBinder().get();
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index fdb63e6..1e6431e 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -27,9 +27,9 @@
// MonitoredProducer wraps an IGraphicBufferProducer so that SurfaceFlinger will
// be notified upon its destruction
-class MonitoredProducer : public BnGraphicBufferProducer {
+class MonitoredProducer : public IGraphicBufferProducer {
public:
- MonitoredProducer(const sp<BnGraphicBufferProducer>& producer,
+ MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
const sp<SurfaceFlinger>& flinger);
virtual ~MonitoredProducer();
@@ -49,9 +49,10 @@
bool producerControlledByApp, QueueBufferOutput* output);
virtual status_t disconnect(int api);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
+ virtual IBinder* onAsBinder();
private:
- sp<BnGraphicBufferProducer> mProducer;
+ sp<IGraphicBufferProducer> mProducer;
sp<SurfaceFlinger> mFlinger;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d084bf5..a346520 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -574,6 +574,18 @@
return NO_ERROR;
}
+status_t SurfaceFlinger::clearAnimationFrameStats() {
+ Mutex::Autolock _l(mStateLock);
+ mAnimFrameTracker.clearStats();
+ return NO_ERROR;
+}
+
+status_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
+ Mutex::Autolock _l(mStateLock);
+ mAnimFrameTracker.getStats(outStats);
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
@@ -2255,14 +2267,14 @@
result.appendFormat("%" PRId64 "\n", period);
if (name.isEmpty()) {
- mAnimFrameTracker.dump(result);
+ mAnimFrameTracker.dumpStats(result);
} else {
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
if (name == layer->getName()) {
- layer->dumpStats(result);
+ layer->dumpFrameStats(result);
}
}
}
@@ -2282,11 +2294,11 @@
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
if (name.isEmpty() || (name == layer->getName())) {
- layer->clearStats();
+ layer->clearFrameStats();
}
}
- mAnimFrameTracker.clear();
+ mAnimFrameTracker.clearStats();
}
// This should only be called from the main thread. Otherwise it would need
@@ -2500,6 +2512,8 @@
case BOOT_FINISHED:
case BLANK:
case UNBLANK:
+ case CLEAR_ANIMATION_FRAME_STATS:
+ case GET_ANIMATION_FRAME_STATS:
{
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 630f4b7..717ee66 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -210,6 +210,8 @@
// called when screen is turning back on
virtual void unblank(const sp<IBinder>& display);
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
+ virtual status_t clearAnimationFrameStats();
+ virtual status_t getAnimationFrameStats(FrameStats* outStats) const;
/* ------------------------------------------------------------------------
* DeathRecipient interface