Merge "SurfaceTexture: fix transform matrix computation." into honeycomb-mr1
diff --git a/include/ui/Input.h b/include/ui/Input.h
index e92d7f5..d9d77c4 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -144,6 +144,14 @@
};
/*
+ * Button state.
+ */
+enum {
+ // Primary button pressed (left mouse button).
+ BUTTON_STATE_PRIMARY = 1 << 0,
+};
+
+/*
* Describes the basic configuration of input devices that are present.
*/
struct InputConfiguration {
@@ -544,6 +552,8 @@
~InputDeviceInfo();
struct MotionRange {
+ int32_t axis;
+ uint32_t source;
float min;
float max;
float flat;
@@ -556,16 +566,17 @@
inline const String8 getName() const { return mName; }
inline uint32_t getSources() const { return mSources; }
- const MotionRange* getMotionRange(int32_t axis) const;
+ const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
void addSource(uint32_t source);
- void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
- void addMotionRange(int32_t axis, const MotionRange& range);
+ void addMotionRange(int32_t axis, uint32_t source,
+ float min, float max, float flat, float fuzz);
+ void addMotionRange(const MotionRange& range);
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
inline int32_t getKeyboardType() const { return mKeyboardType; }
- inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+ inline const Vector<MotionRange>& getMotionRanges() const {
return mMotionRanges;
}
@@ -575,7 +586,7 @@
uint32_t mSources;
int32_t mKeyboardType;
- KeyedVector<int32_t, MotionRange> mMotionRanges;
+ Vector<MotionRange> mMotionRanges;
};
/*
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/surfaceflinger_client/tests/Surface_test.cpp
index b39631c..74ebf4e 100644
--- a/libs/surfaceflinger_client/tests/Surface_test.cpp
+++ b/libs/surfaceflinger_client/tests/Surface_test.cpp
@@ -15,22 +15,19 @@
*/
#include <gtest/gtest.h>
+
+#include <binder/IMemory.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/Surface.h>
#include <surfaceflinger/SurfaceComposerClient.h>
-
#include <utils/String8.h>
namespace android {
class SurfaceTest : public ::testing::Test {
protected:
- virtual sp<SurfaceComposerClient> getSurfaceComposerClient() {
- return sp<SurfaceComposerClient>(new SurfaceComposerClient);
- }
-
virtual void SetUp() {
- mComposerClient = getSurfaceComposerClient();
+ mComposerClient = new SurfaceComposerClient;
ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
mSurfaceControl = mComposerClient->createSurface(getpid(),
@@ -77,4 +74,60 @@
EXPECT_EQ(1, result);
}
+// This test probably doesn't belong here.
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
+ sp<ANativeWindow> anw(mSurface);
+
+ // Verify the screenshot works with no protected buffers.
+ sp<IMemoryHeap> heap;
+ uint32_t w=0, h=0;
+ PixelFormat fmt=0;
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+ 40000));
+ ASSERT_TRUE(heap != NULL);
+
+ // Set the PROTECTED usage bit and verify that the screenshot fails. Note
+ // that we need to dequeue a buffer in order for it to actually get
+ // allocated in SurfaceFlinger.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
+ GRALLOC_USAGE_PROTECTED));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+ android_native_buffer_t* buf = 0;
+ for (int i = 0; i < 4; i++) {
+ // Loop to make sure SurfaceFlinger has retired a protected buffer.
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+ ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+ }
+ heap = 0;
+ w = h = fmt = 0;
+ ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
+ 64, 64, 0, 40000));
+ ASSERT_TRUE(heap == NULL);
+
+ // XXX: This should not be needed, but it seems that the new buffers don't
+ // correctly show up after the upcoming dequeue/lock/queue loop without it.
+ // We should look into this at some point.
+ ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+
+ // Un-set the PROTECTED usage bit and verify that the screenshot works
+ // again. Note that we have to change the buffers geometry to ensure that
+ // the buffers get reallocated, as the new usage bits are a subset of the
+ // old.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0));
+ for (int i = 0; i < 4; i++) {
+ // Loop to make sure SurfaceFlinger has retired a protected buffer.
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+ ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+ }
+ heap = 0;
+ w = h = fmt = 0;
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+ 40000));
+ ASSERT_TRUE(heap != NULL);
+}
+
}
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0ed0866..e2e698e 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -657,23 +657,30 @@
mMotionRanges.clear();
}
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
- ssize_t index = mMotionRanges.indexOfKey(axis);
- return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
+ int32_t axis, uint32_t source) const {
+ size_t numRanges = mMotionRanges.size();
+ for (size_t i = 0; i < numRanges; i++) {
+ const MotionRange& range = mMotionRanges.itemAt(i);
+ if (range.axis == axis && range.source == source) {
+ return ⦥
+ }
+ }
+ return NULL;
}
void InputDeviceInfo::addSource(uint32_t source) {
mSources |= source;
}
-void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
+void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
float flat, float fuzz) {
- MotionRange range = { min, max, flat, fuzz };
- addMotionRange(axis, range);
+ MotionRange range = { axis, source, min, max, flat, fuzz };
+ mMotionRanges.add(range);
}
-void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
- mMotionRanges.add(axis, range);
+void InputDeviceInfo::addMotionRange(const MotionRange& range) {
+ mMotionRanges.add(range);
}
} // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 57af001..1297363 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -57,7 +57,6 @@
mNeedsDithering(false),
mSecure(false),
mProtectedByApp(false),
- mProtectedByDRM(false),
mTextureManager(),
mBufferManager(mTextureManager),
mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
@@ -191,7 +190,6 @@
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
- mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
(flags & ISurfaceComposer::eOpaque) == 0;
@@ -392,6 +390,12 @@
return LayerBase::needsFiltering();
}
+bool Layer::isProtected() const
+{
+ sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer());
+ return (activeBuffer != 0) &&
+ (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+}
status_t Layer::setBufferCount(int bufferCount)
{
@@ -515,7 +519,7 @@
// request EGLImage for all buffers
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
}
- if (mProtectedByApp || mProtectedByDRM) {
+ if (mProtectedByApp) {
// need a hardware-protected path to external video sink
usage |= GraphicBuffer::USAGE_PROTECTED;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index bccc900..128f93d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -80,8 +80,7 @@
virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool needsFiltering() const;
virtual bool isSecure() const { return mSecure; }
- virtual bool isProtectedByApp() const { return mProtectedByApp; }
- virtual bool isProtectedByDRM() const { return mProtectedByDRM; }
+ virtual bool isProtected() const;
virtual sp<Surface> createSurface() const;
virtual status_t ditch();
virtual void onRemoved();
@@ -222,7 +221,6 @@
// page-flip thread (currently main thread)
bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
- bool mProtectedByDRM; // DRM agent requires protected path to external sink
Region mPostedDirtyRegion;
// page-flip thread and transaction thread (currently main thread)
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index bfe92e6..7162e47 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -197,16 +197,10 @@
virtual bool isSecure() const { return false; }
/**
- * isProtectedByApp - true if application says this surface is protected, that
- * is if it requires a hardware-protected data path to an external sink.
+ * isProtected - true if the layer may contain protected content in the
+ * GRALLOC_USAGE_PROTECTED sense.
*/
- virtual bool isProtectedByApp() const { return false; }
-
- /**
- * isProtectedByDRM - true if DRM agent says this surface is protected, that
- * is if it requires a hardware-protected data path to an external sink.
- */
- virtual bool isProtectedByDRM() const { return false; }
+ virtual bool isProtected() const { return false; }
/** Called from the main thread, when the surface is removed from the
* draw list */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7b19a4c..a9fa1ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2169,6 +2169,19 @@
if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
return BAD_VALUE;
+ // make sure none of the layers are protected
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
+ const sp<LayerBase>& layer(layers[i]);
+ const uint32_t z = layer->drawingState().z;
+ if (z >= minLayerZ && z <= maxLayerZ) {
+ if (layer->isProtected()) {
+ return INVALID_OPERATION;
+ }
+ }
+ }
+
if (!GLExtensions::getInstance().haveFramebufferObject())
return INVALID_OPERATION;
@@ -2217,8 +2230,6 @@
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
const uint32_t z = layer->drawingState().z;