Merge "Separate function to add fd to epoll"
diff --git a/data/etc/android.hardware.face.xml b/data/etc/android.hardware.biometrics.face.xml
similarity index 93%
rename from data/etc/android.hardware.face.xml
rename to data/etc/android.hardware.biometrics.face.xml
index abd23fb..7fa0bf9 100644
--- a/data/etc/android.hardware.face.xml
+++ b/data/etc/android.hardware.biometrics.face.xml
@@ -16,5 +16,5 @@
<!-- This is the standard set of features for a biometric face authentication sensor. -->
<permissions>
- <feature name="android.hardware.face" />
+ <feature name="android.hardware.biometrics.face" />
</permissions>
diff --git a/data/etc/android.hardware.biometrics.fingerprint.xml b/data/etc/android.hardware.biometrics.fingerprint.xml
new file mode 100644
index 0000000..e5af541
--- /dev/null
+++ b/data/etc/android.hardware.biometrics.fingerprint.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2018 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 set of features for a biometric fingerprint sensor. -->
+<permissions>
+ <feature name="android.hardware.biometrics.fingerprint" />
+</permissions>
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 1395551..53b0e4c 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -242,23 +242,43 @@
bool useContextPriority = extensions.hasContextPriority() &&
(featureFlags & RenderEngine::USE_HIGH_PRIORITY_CONTEXT);
- EGLContext ctxt = createEglContext(display, config, EGL_NO_CONTEXT, useContextPriority);
+ EGLContext protectedContext = EGL_NO_CONTEXT;
+ if (extensions.hasProtectedContent()) {
+ protectedContext = createEglContext(display, config, nullptr, useContextPriority,
+ Protection::PROTECTED);
+ ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
+ }
+
+ EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority,
+ Protection::UNPROTECTED);
// if can't create a GL context, we can only abort.
LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
EGLSurface dummy = EGL_NO_SURFACE;
if (!extensions.hasSurfacelessContext()) {
- dummy = createDummyEglPbufferSurface(display, config, hwcFormat);
+ dummy = createDummyEglPbufferSurface(display, config, hwcFormat, Protection::UNPROTECTED);
LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
}
-
EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
-
extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));
+ // In order to have protected contents in GPU composition, the OpenGL ES extension
+ // GL_EXT_protected_textures must be supported. If it's not supported, reset
+ // protected context to EGL_NO_CONTEXT to indicate that protected contents is not supported.
+ if (!extensions.hasProtectedTexture()) {
+ protectedContext = EGL_NO_CONTEXT;
+ }
+
+ EGLSurface protectedDummy = EGL_NO_SURFACE;
+ if (protectedContext != EGL_NO_CONTEXT && !extensions.hasSurfacelessContext()) {
+ protectedDummy =
+ createDummyEglPbufferSurface(display, config, hwcFormat, Protection::PROTECTED);
+ ALOGE_IF(protectedDummy == EGL_NO_SURFACE, "can't create protected dummy pbuffer");
+ }
+
// now figure out what version of GL did we actually get
GlesVersion version = parseGlesVersion(extensions.getVersion());
@@ -271,7 +291,8 @@
break;
case GLES_VERSION_2_0:
case GLES_VERSION_3_0:
- engine = std::make_unique<GLESRenderEngine>(featureFlags, display, config, ctxt, dummy);
+ engine = std::make_unique<GLESRenderEngine>(featureFlags, display, config, ctxt, dummy,
+ protectedContext, protectedDummy);
break;
}
@@ -326,12 +347,15 @@
}
GLESRenderEngine::GLESRenderEngine(uint32_t featureFlags, EGLDisplay display, EGLConfig config,
- EGLContext ctxt, EGLSurface dummy)
+ EGLContext ctxt, EGLSurface dummy, EGLContext protectedContext,
+ EGLSurface protectedDummy)
: renderengine::impl::RenderEngine(featureFlags),
mEGLDisplay(display),
mEGLConfig(config),
mEGLContext(ctxt),
mDummySurface(dummy),
+ mProtectedEGLContext(protectedContext),
+ mProtectedDummySurface(protectedDummy),
mVpWidth(0),
mVpHeight(0),
mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
@@ -341,6 +365,17 @@
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ // Initialize protected EGL Context.
+ if (mProtectedEGLContext != EGL_NO_CONTEXT) {
+ EGLBoolean success = eglMakeCurrent(display, mProtectedDummySurface, mProtectedDummySurface,
+ mProtectedEGLContext);
+ ALOGE_IF(!success, "can't make protected context current");
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ success = eglMakeCurrent(display, mDummySurface, mDummySurface, mEGLContext);
+ LOG_ALWAYS_FATAL_IF(!success, "can't make default context current");
+ }
+
const uint16_t protTexData[] = {0};
glGenTextures(1, &mProtectedTexName);
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
@@ -395,7 +430,8 @@
}
void GLESRenderEngine::primeCache() const {
- ProgramCache::getInstance().primeCache(mFeatureFlags & USE_COLOR_MANAGEMENT);
+ ProgramCache::getInstance().primeCache(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
+ mFeatureFlags & USE_COLOR_MANAGEMENT);
}
bool GLESRenderEngine::isCurrent() const {
@@ -539,6 +575,10 @@
const GLenum target = GL_TEXTURE_EXTERNAL_OES;
glBindTexture(target, texName);
+ if (supportsProtectedContent()) {
+ glTexParameteri(target, GL_TEXTURE_PROTECTED_EXT,
+ glImage.isProtected() ? GL_TRUE : GL_FALSE);
+ }
if (glImage.getEGLImage() != EGL_NO_IMAGE_KHR) {
glEGLImageTargetTexture2DOES(target, static_cast<GLeglImageOES>(glImage.getEGLImage()));
}
@@ -552,6 +592,10 @@
// Bind the texture and turn our EGLImage into a texture
glBindTexture(GL_TEXTURE_2D, textureName);
+ if (supportsProtectedContent()) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_PROTECTED_EXT,
+ mInProtectedContext ? GL_TRUE : GL_FALSE);
+ }
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglImage);
// Bind the Framebuffer to render into
@@ -584,6 +628,26 @@
} while (true);
}
+bool GLESRenderEngine::supportsProtectedContent() const {
+ return mProtectedEGLContext != EGL_NO_CONTEXT;
+}
+
+bool GLESRenderEngine::useProtectedContext(bool useProtectedContext) {
+ if (useProtectedContext == mInProtectedContext) {
+ return true;
+ }
+ if (useProtectedContext && mProtectedEGLContext == EGL_NO_CONTEXT) {
+ return false;
+ }
+ const EGLSurface surface = useProtectedContext ? mProtectedDummySurface : mDummySurface;
+ const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext;
+ const bool success = eglMakeCurrent(mEGLDisplay, surface, surface, context) == EGL_TRUE;
+ if (success) {
+ mInProtectedContext = useProtectedContext;
+ }
+ return success;
+}
+
status_t GLESRenderEngine::drawLayers(const DisplaySettings& /*settings*/,
const std::vector<LayerSettings>& /*layers*/,
ANativeWindowBuffer* const /*buffer*/,
@@ -822,7 +886,9 @@
Description::dataSpaceToTransferFunction(outputTransfer);
}
- ProgramCache::getInstance().useProgram(managedState);
+ ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
+ : mEGLContext,
+ managedState);
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
@@ -833,7 +899,9 @@
writePPM(out.str().c_str(), mVpWidth, mVpHeight);
}
} else {
- ProgramCache::getInstance().useProgram(mState);
+ ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
+ : mEGLContext,
+ mState);
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
}
@@ -857,17 +925,18 @@
void GLESRenderEngine::dump(std::string& result) {
const GLExtensions& extensions = GLExtensions::getInstance();
+ ProgramCache& cache = ProgramCache::getInstance();
StringAppendF(&result, "EGL implementation : %s\n", extensions.getEGLVersion());
StringAppendF(&result, "%s\n", extensions.getEGLExtensions());
-
StringAppendF(&result, "GLES: %s, %s, %s\n", extensions.getVendor(), extensions.getRenderer(),
extensions.getVersion());
StringAppendF(&result, "%s\n", extensions.getExtensions());
-
- StringAppendF(&result, "RenderEngine program cache size: %zu\n",
- ProgramCache::getInstance().getSize());
-
+ StringAppendF(&result, "RenderEngine is in protected context : %d\n", mInProtectedContext);
+ StringAppendF(&result, "RenderEngine program cache size for unprotected context: %zu\n",
+ cache.getSize(mEGLContext));
+ StringAppendF(&result, "RenderEngine program cache size for protected context: %zu\n",
+ cache.getSize(mProtectedEGLContext));
StringAppendF(&result, "RenderEngine last dataspace conversion: (%s) to (%s)\n",
dataspaceDetails(static_cast<android_dataspace>(mDataSpace)).c_str(),
dataspaceDetails(static_cast<android_dataspace>(mOutputDataSpace)).c_str());
@@ -892,7 +961,8 @@
}
EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig config,
- EGLContext shareContext, bool useContextPriority) {
+ EGLContext shareContext, bool useContextPriority,
+ Protection protection) {
EGLint renderableType = 0;
if (config == EGL_NO_CONFIG) {
renderableType = EGL_OPENGL_ES3_BIT;
@@ -911,13 +981,17 @@
}
std::vector<EGLint> contextAttributes;
- contextAttributes.reserve(5);
+ contextAttributes.reserve(7);
contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
contextAttributes.push_back(contextClientVersion);
if (useContextPriority) {
contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
}
+ if (protection == Protection::PROTECTED) {
+ contextAttributes.push_back(EGL_PROTECTED_CONTENT_EXT);
+ contextAttributes.push_back(EGL_TRUE);
+ }
contextAttributes.push_back(EGL_NONE);
EGLContext context = eglCreateContext(display, config, shareContext, contextAttributes.data());
@@ -938,17 +1012,21 @@
}
EGLSurface GLESRenderEngine::createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
- int hwcFormat) {
+ int hwcFormat, Protection protection) {
EGLConfig dummyConfig = config;
if (dummyConfig == EGL_NO_CONFIG) {
dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
}
std::vector<EGLint> attributes;
- attributes.reserve(5);
+ attributes.reserve(7);
attributes.push_back(EGL_WIDTH);
attributes.push_back(1);
attributes.push_back(EGL_HEIGHT);
attributes.push_back(1);
+ if (protection == Protection::PROTECTED) {
+ attributes.push_back(EGL_PROTECTED_CONTENT_EXT);
+ attributes.push_back(EGL_TRUE);
+ }
attributes.push_back(EGL_NONE);
return eglCreatePbufferSurface(display, dummyConfig, attributes.data());
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 21d5b81..07e5585 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -45,7 +45,8 @@
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
GLESRenderEngine(uint32_t featureFlags, // See RenderEngine::FeatureFlag
- EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
+ EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy,
+ EGLContext protectedContext, EGLSurface protectedDummy);
~GLESRenderEngine() override;
std::unique_ptr<Framebuffer> createFramebuffer() override;
@@ -68,6 +69,9 @@
void unbindFrameBuffer(Framebuffer* framebuffer) override;
void checkErrors() const override;
+ bool isProtected() const override { return mInProtectedContext; }
+ bool supportsProtectedContent() const override;
+ bool useProtectedContext(bool useProtectedContext) override;
status_t drawLayers(const DisplaySettings& settings, const std::vector<LayerSettings>& layers,
ANativeWindowBuffer* const buffer,
base::unique_fd* displayFence) const override;
@@ -112,20 +116,22 @@
static GlesVersion parseGlesVersion(const char* str);
static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
- EGLContext shareContext, bool useContextPriority);
+ EGLContext shareContext, bool useContextPriority,
+ Protection protection);
static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
- int hwcFormat);
+ int hwcFormat, Protection protection);
// A data space is considered HDR data space if it has BT2020 color space
// with PQ or HLG transfer function.
bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
bool needsXYZTransformMatrix() const;
- void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
EGLContext mEGLContext;
EGLSurface mDummySurface;
+ EGLContext mProtectedEGLContext;
+ EGLSurface mProtectedDummySurface;
GLuint mProtectedTexName;
GLint mMaxViewportDims[2];
GLint mMaxTextureSize;
@@ -146,6 +152,7 @@
mat4 mBt2020ToSrgb;
mat4 mBt2020ToDisplayP3;
+ bool mInProtectedContext = false;
int32_t mFboHeight = 0;
// Current dataspace of layer being rendered
diff --git a/libs/renderengine/gl/GLExtensions.cpp b/libs/renderengine/gl/GLExtensions.cpp
index ce83dd5..2924b0e 100644
--- a/libs/renderengine/gl/GLExtensions.cpp
+++ b/libs/renderengine/gl/GLExtensions.cpp
@@ -60,6 +60,11 @@
mRenderer = (char const*)renderer;
mVersion = (char const*)version;
mExtensions = (char const*)extensions;
+
+ ExtensionSet extensionSet(mExtensions.c_str());
+ if (extensionSet.hasExtension("GL_EXT_protected_textures")) {
+ mHasProtectedTexture = true;
+ }
}
char const* GLExtensions::getVendor() const {
diff --git a/libs/renderengine/gl/GLExtensions.h b/libs/renderengine/gl/GLExtensions.h
index 2a654d5..ef00009 100644
--- a/libs/renderengine/gl/GLExtensions.h
+++ b/libs/renderengine/gl/GLExtensions.h
@@ -40,6 +40,7 @@
bool hasProtectedContent() const { return mHasProtectedContent; }
bool hasContextPriority() const { return mHasContextPriority; }
bool hasSurfacelessContext() const { return mHasSurfacelessContext; }
+ bool hasProtectedTexture() const { return mHasProtectedTexture; }
void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
GLubyte const* extensions);
@@ -65,12 +66,12 @@
bool mHasProtectedContent = false;
bool mHasContextPriority = false;
bool mHasSurfacelessContext = false;
+ bool mHasProtectedTexture = false;
String8 mVendor;
String8 mRenderer;
String8 mVersion;
String8 mExtensions;
-
String8 mEGLVersion;
String8 mEGLExtensions;
diff --git a/libs/renderengine/gl/GLFramebuffer.cpp b/libs/renderengine/gl/GLFramebuffer.cpp
index f4de91a..4a519bb 100644
--- a/libs/renderengine/gl/GLFramebuffer.cpp
+++ b/libs/renderengine/gl/GLFramebuffer.cpp
@@ -39,7 +39,7 @@
eglDestroyImageKHR(mEGLDisplay, mEGLImage);
}
-bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) {
+bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) {
if (mEGLImage != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(mEGLDisplay, mEGLImage);
mEGLImage = EGL_NO_IMAGE_KHR;
@@ -48,8 +48,13 @@
}
if (nativeBuffer) {
+ EGLint attributes[] = {
+ isProtected ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
+ isProtected ? EGL_TRUE : EGL_NONE,
+ EGL_NONE,
+ };
mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- nativeBuffer, nullptr);
+ nativeBuffer, attributes);
if (mEGLImage == EGL_NO_IMAGE_KHR) {
return false;
}
diff --git a/libs/renderengine/gl/GLFramebuffer.h b/libs/renderengine/gl/GLFramebuffer.h
index 358ab47..5043c59 100644
--- a/libs/renderengine/gl/GLFramebuffer.h
+++ b/libs/renderengine/gl/GLFramebuffer.h
@@ -35,7 +35,7 @@
explicit GLFramebuffer(const GLESRenderEngine& engine);
~GLFramebuffer() override;
- bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) override;
+ bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) override;
EGLImageKHR getEGLImage() const { return mEGLImage; }
uint32_t getTextureName() const { return mTextureName; }
uint32_t getFramebufferName() const { return mFramebufferName; }
diff --git a/libs/renderengine/gl/GLImage.cpp b/libs/renderengine/gl/GLImage.cpp
index a9529a7..587cb31 100644
--- a/libs/renderengine/gl/GLImage.cpp
+++ b/libs/renderengine/gl/GLImage.cpp
@@ -65,6 +65,7 @@
ALOGE("failed to create EGLImage: %#x", eglGetError());
return false;
}
+ mProtected = isProtected;
}
return true;
diff --git a/libs/renderengine/gl/GLImage.h b/libs/renderengine/gl/GLImage.h
index c897d8e..59d6ce3 100644
--- a/libs/renderengine/gl/GLImage.h
+++ b/libs/renderengine/gl/GLImage.h
@@ -39,10 +39,12 @@
bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected) override;
EGLImageKHR getEGLImage() const { return mEGLImage; }
+ bool isProtected() const { return mProtected; }
private:
EGLDisplay mEGLDisplay;
EGLImageKHR mEGLImage = EGL_NO_IMAGE_KHR;
+ bool mProtected = false;
DISALLOW_COPY_AND_ASSIGN(GLImage);
};
diff --git a/libs/renderengine/gl/ProgramCache.cpp b/libs/renderengine/gl/ProgramCache.cpp
index 41870d2..bf2354d 100644
--- a/libs/renderengine/gl/ProgramCache.cpp
+++ b/libs/renderengine/gl/ProgramCache.cpp
@@ -77,7 +77,8 @@
return f;
}
-void ProgramCache::primeCache(bool useColorManagement) {
+void ProgramCache::primeCache(EGLContext context, bool useColorManagement) {
+ auto& cache = mCaches[context];
uint32_t shaderCount = 0;
uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | Key::ALPHA_MASK | Key::TEXTURE_MASK
| Key::ROUNDED_CORNERS_MASK;
@@ -92,8 +93,8 @@
if (tex != Key::TEXTURE_OFF && tex != Key::TEXTURE_EXT && tex != Key::TEXTURE_2D) {
continue;
}
- if (mCache.count(shaderKey) == 0) {
- mCache.emplace(shaderKey, generateProgram(shaderKey));
+ if (cache.count(shaderKey) == 0) {
+ cache.emplace(shaderKey, generateProgram(shaderKey));
shaderCount++;
}
}
@@ -109,8 +110,8 @@
shaderKey.set(Key::OPACITY_MASK,
(i & 1) ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT);
shaderKey.set(Key::ALPHA_MASK, (i & 2) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE);
- if (mCache.count(shaderKey) == 0) {
- mCache.emplace(shaderKey, generateProgram(shaderKey));
+ if (cache.count(shaderKey) == 0) {
+ cache.emplace(shaderKey, generateProgram(shaderKey));
shaderCount++;
}
}
@@ -695,20 +696,21 @@
return std::make_unique<Program>(needs, vs.string(), fs.string());
}
-void ProgramCache::useProgram(const Description& description) {
+void ProgramCache::useProgram(EGLContext context, const Description& description) {
// generate the key for the shader based on the description
Key needs(computeKey(description));
// look-up the program in the cache
- auto it = mCache.find(needs);
- if (it == mCache.end()) {
+ auto& cache = mCaches[context];
+ auto it = cache.find(needs);
+ if (it == cache.end()) {
// we didn't find our program, so generate one...
nsecs_t time = systemTime();
- it = mCache.emplace(needs, generateProgram(needs)).first;
+ it = cache.emplace(needs, generateProgram(needs)).first;
time = systemTime() - time;
- ALOGV(">>> generated new program: needs=%08X, time=%u ms (%zu programs)", needs.mKey,
- uint32_t(ns2ms(time)), mCache.size());
+ ALOGV(">>> generated new program for context %p: needs=%08X, time=%u ms (%zu programs)",
+ context, needs.mKey, uint32_t(ns2ms(time)), cache.size());
}
// here we have a suitable program for this description
diff --git a/libs/renderengine/gl/ProgramCache.h b/libs/renderengine/gl/ProgramCache.h
index 653aaf0..400ad74 100644
--- a/libs/renderengine/gl/ProgramCache.h
+++ b/libs/renderengine/gl/ProgramCache.h
@@ -20,6 +20,7 @@
#include <memory>
#include <unordered_map>
+#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <renderengine/private/Description.h>
#include <utils/Singleton.h>
@@ -178,13 +179,13 @@
~ProgramCache() = default;
// Generate shaders to populate the cache
- void primeCache(bool useColorManagement);
+ void primeCache(const EGLContext context, bool useColorManagement);
- size_t getSize() const { return mCache.size(); }
+ size_t getSize(const EGLContext context) { return mCaches[context].size(); }
// useProgram lookup a suitable program in the cache or generates one
// if none can be found.
- void useProgram(const Description& description);
+ void useProgram(const EGLContext context, const Description& description);
private:
// compute a cache Key from a Description
@@ -206,7 +207,8 @@
// Key/Value map used for caching Programs. Currently the cache
// is never shrunk (and the GL program objects are never deleted).
- std::unordered_map<Key, std::unique_ptr<Program>, Key::Hash> mCache;
+ std::unordered_map<EGLContext, std::unordered_map<Key, std::unique_ptr<Program>, Key::Hash>>
+ mCaches;
};
} // namespace gl
diff --git a/libs/renderengine/include/renderengine/Framebuffer.h b/libs/renderengine/include/renderengine/Framebuffer.h
index 558b9c7..66eb9ef 100644
--- a/libs/renderengine/include/renderengine/Framebuffer.h
+++ b/libs/renderengine/include/renderengine/Framebuffer.h
@@ -27,7 +27,7 @@
public:
virtual ~Framebuffer() = default;
- virtual bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) = 0;
+ virtual bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) = 0;
};
} // namespace renderengine
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 8eaa2d2..5e88159 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -53,6 +53,11 @@
class RenderEngine;
}
+enum class Protection {
+ UNPROTECTED = 1,
+ PROTECTED = 2,
+};
+
class RenderEngine {
public:
enum FeatureFlag {
@@ -150,6 +155,10 @@
// ----- BEGIN NEW INTERFACE -----
+ virtual bool isProtected() const = 0;
+ virtual bool supportsProtectedContent() const = 0;
+ virtual bool useProtectedContext(bool useProtectedContext) = 0;
+
// Renders layers for a particular display via GPU composition. This method
// should be called for every display that needs to be rendered via the GPU.
// @param settings The display-wide settings that should be applied prior to
@@ -182,12 +191,12 @@
public:
BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer)
: mEngine(engine), mFramebuffer(mEngine.createFramebuffer()), mStatus(NO_ERROR) {
- mStatus = mFramebuffer->setNativeWindowBuffer(buffer)
+ mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected())
? mEngine.bindFrameBuffer(mFramebuffer.get())
: NO_MEMORY;
}
~BindNativeBufferAsFramebuffer() {
- mFramebuffer->setNativeWindowBuffer(nullptr);
+ mFramebuffer->setNativeWindowBuffer(nullptr, false);
mEngine.unbindFrameBuffer(mFramebuffer.get());
}
status_t getStatus() const { return mStatus; }
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index a894f20..1b339a0 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -165,194 +165,6 @@
return;
}
-TEST_F(BufferHubBufferTest, AllocateAndFreeBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferHub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferHub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
- client = outClient;
- ret = outStatus;
- };
- EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
- EXPECT_EQ(BufferHubStatus::CLIENT_CLOSED, client->close());
-}
-
-TEST_F(BufferHubBufferTest, DuplicateFreedBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferHub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferHub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
- client = outClient;
- ret = outStatus;
- };
- EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- EXPECT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::CLIENT_CLOSED);
- EXPECT_EQ(token.getNativeHandle(), nullptr);
-}
-
-TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- ASSERT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(token.getNativeHandle(), nullptr);
- EXPECT_EQ(token->numInts, 1);
- EXPECT_EQ(token->numFds, 0);
-
- sp<IBufferClient> client2;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- ret = status;
- client2 = outClient;
- };
- ASSERT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- EXPECT_NE(nullptr, client2.get());
- // TODO(b/116681016): once BufferNode.id() is exposed via BufferHubBuffer, check origin.id =
- // improted.id here.
-}
-
-// nullptr must not crash the service
-TEST_F(BufferHubBufferTest, ImportNullToken) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- hidl_handle nullToken;
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->importBuffer(nullToken, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client.get());
-}
-
-// This test has a very little chance to fail (number of existing tokens / 2 ^ 32)
-TEST_F(BufferHubBufferTest, ImportInvalidToken) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- native_handle_t* tokenHandle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
- tokenHandle->data[0] = 0;
-
- hidl_handle invalidToken(tokenHandle);
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->importBuffer(invalidToken, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client.get());
-
- native_handle_delete(tokenHandle);
-}
-
-TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
- // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
- sp<IBufferHub> bufferhub = IBufferHub::getService();
- ASSERT_NE(nullptr, bufferhub.get());
-
- // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
- AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
- kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
- HardwareBufferDescription desc;
- memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
- sp<IBufferClient> client;
- BufferHubStatus ret;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
- client = outClient;
- ret = status;
- };
- ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(nullptr, client.get());
-
- hidl_handle token;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
- token = outToken;
- ret = status;
- };
- ASSERT_TRUE(client->duplicate(dup_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
- ASSERT_NE(token.getNativeHandle(), nullptr);
- EXPECT_EQ(token->numInts, 1);
- EXPECT_EQ(token->numFds, 0);
-
- // Close the client. Now the token should be invalid.
- client->close();
-
- sp<IBufferClient> client2;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
- client2 = outClient;
- ret = status;
- };
- EXPECT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
- EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
- EXPECT_EQ(nullptr, client2.get());
-}
-
TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) {
ASSERT_TRUE(IsBufferReleased(b1->buffer_state()));
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 50e30c2..f5cf3dc 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -554,33 +554,17 @@
property_get("ro.product.manufacturer", manufacturer, "UNSET");
property_get("ro.product.model", model, "UNSET");
- // TODO: Replace this with the new function name once the version-1 API is removed:
- fpANGLEGetUtilityAPI ANGLEGetUtilityAPI =
- (fpANGLEGetUtilityAPI)dlsym(so, "ANGLEGetUtilityAPI");
+ fpANGLEGetFeatureSupportUtilAPIVersion ANGLEGetFeatureSupportUtilAPIVersion =
+ (fpANGLEGetFeatureSupportUtilAPIVersion)dlsym(so, "ANGLEGetFeatureSupportUtilAPIVersion");
- if (ANGLEGetUtilityAPI) {
+ if (ANGLEGetFeatureSupportUtilAPIVersion) {
// Negotiate the interface version by requesting most recent known to the platform
unsigned int versionToUse = 2;
- // TODO: Replace this with the new function name once the version-1 API is removed:
- if ((ANGLEGetUtilityAPI)(&versionToUse)) {
+ if ((ANGLEGetFeatureSupportUtilAPIVersion)(&versionToUse)) {
// Add and remove versions below as needed
switch(versionToUse) {
- case 1: {
- ALOGV("Using version 1 of ANGLE feature-support library");
- fpAndroidUseANGLEForApplication AndroidUseANGLEForApplication =
- (fpAndroidUseANGLEForApplication)dlsym(so, "AndroidUseANGLEForApplication");
-
- if (AndroidUseANGLEForApplication) {
- use_angle = (AndroidUseANGLEForApplication)(rules_fd, rules_offset,
- rules_length, app_name_str.c_str(),
- manufacturer, model);
- } else {
- ALOGW("Cannot find AndroidUseANGLEForApplication in ANGLE feature-support library");
- }
- }
- break;
case 2: {
ALOGV("Using version 2 of ANGLE feature-support library");
void* rules_handle = nullptr;
@@ -647,7 +631,7 @@
ALOGW("Cannot use ANGLE feature-support library, it is older than supported by EGL, requested version %u", versionToUse);
}
} else {
- ALOGW("Cannot find ANGLEGetUtilityAPI function");
+ ALOGW("Cannot find ANGLEGetFeatureSupportUtilAPIVersion function");
}
ALOGV("Close temporarily-loaded ANGLE opt-in/out logic");
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 7e00f42..5d0b894 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2642,7 +2642,6 @@
mOrientation = internalViewport->orientation;
}
}
- getPolicy()->updatePointerDisplay();
bumpGeneration();
}
}
@@ -2788,7 +2787,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
- displayId = mPointerController->getDisplayId();
+ displayId = ADISPLAY_ID_DEFAULT;
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
@@ -3609,9 +3608,6 @@
(mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
if (mPointerController == nullptr) {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
- getPolicy()->updatePointerDisplay();
- } else if (viewportChanged) {
- getPolicy()->updatePointerDisplay();
}
} else {
mPointerController.clear();
@@ -5399,9 +5395,9 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- int32_t displayId = mPointerController->getDisplayId();
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, displayId, mSource,
- mViewport.displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
/* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, mPointerGesture.downTime);
@@ -6307,7 +6303,6 @@
void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
bool down, bool hovering) {
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t displayId = mViewport.displayId;
if (mPointerController != nullptr) {
if (down || hovering) {
@@ -6318,20 +6313,19 @@
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
}
- displayId = mPointerController->getDisplayId();
}
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
// Send up.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
- /* deviceTimestamp */ 0,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
+ AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
+ /* deviceTimestamp */ 0,
+ 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+ mOrientedXPrecision, mOrientedYPrecision,
+ mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
@@ -6339,8 +6333,8 @@
mPointerSimple.hovering = false;
// Send hover exit.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -6355,8 +6349,8 @@
mPointerSimple.downTime = when;
// Send down.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6366,8 +6360,8 @@
}
// Send move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -6381,8 +6375,8 @@
mPointerSimple.hovering = true;
// Send hover enter.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
@@ -6393,8 +6387,8 @@
}
// Send hover move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
@@ -6416,8 +6410,8 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
/* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &pointerCoords,
@@ -6479,10 +6473,9 @@
ALOG_ASSERT(false);
}
}
- int32_t displayId = mPointerController != nullptr ?
- mPointerController->getDisplayId() : mViewport.displayId;
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- source, displayId, policyFlags,
+
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+ source, mViewport.displayId, policyFlags,
action, actionButton, flags, metaState, buttonState, edgeFlags,
deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
xPrecision, yPrecision, downTime);
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 5a78df7..fe1c50b 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -342,9 +342,6 @@
/* Gets the affine calibration associated with the specified device. */
virtual TouchAffineTransformation getTouchAffineTransformation(
const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
-
- /* Update the pointer controller associated with the specified display. */
- virtual void updatePointerDisplay() = 0;
};
} // namespace android
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index e60b3f4..e94dd94 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -58,9 +58,6 @@
/* Gets the absolute location of the pointer. */
virtual void getPosition(float* outX, float* outY) const = 0;
- /* Gets the id of the display where the pointer should be shown. */
- virtual int32_t getDisplayId() const = 0;
-
enum Transition {
// Fade/unfade immediately.
TRANSITION_IMMEDIATE,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 855247f..167a624 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -57,7 +57,6 @@
float mMinX, mMinY, mMaxX, mMaxY;
float mX, mY;
int32_t mButtonState;
- int32_t mDisplayId;
protected:
virtual ~FakePointerController() { }
@@ -65,7 +64,7 @@
public:
FakePointerController() :
mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
- mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
+ mButtonState(0) {
}
void setBounds(float minX, float minY, float maxX, float maxY) {
@@ -76,10 +75,6 @@
mMaxY = maxY;
}
- void setDisplayId(int32_t displayId) {
- mDisplayId = displayId;
- }
-
virtual void setPosition(float x, float y) {
mX = x;
mY = y;
@@ -98,10 +93,6 @@
*outY = mY;
}
- virtual int32_t getDisplayId() const {
- return mDisplayId;
- }
-
private:
virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
*outMinX = mMinX;
@@ -271,9 +262,6 @@
virtual std::string getDeviceAlias(const InputDeviceIdentifier&) {
return "";
}
-
- virtual void updatePointerDisplay() {
- }
};
@@ -3177,30 +3165,6 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
}
-TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
- CursorInputMapper* mapper = new CursorInputMapper(mDevice);
- addMapperAndConfigure(mapper);
-
- // Setup PointerController for second display.
- constexpr int32_t SECOND_DISPLAY_ID = 1;
- mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
- mFakePointerController->setPosition(100, 200);
- mFakePointerController->setButtonState(0);
- mFakePointerController->setDisplayId(SECOND_DISPLAY_ID);
-
- NotifyMotionArgs args;
- process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
- ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
- ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
- ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId);
-}
-
// --- TouchInputMapperTest ---
@@ -4699,6 +4663,7 @@
toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
}
+
// --- MultiTouchInputMapperTest ---
class MultiTouchInputMapperTest : public TouchInputMapperTest {
@@ -6319,30 +6284,4 @@
ASSERT_EQ(DISPLAY_ID, args.displayId);
}
-TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
- // Setup PointerController for second display.
- sp<FakePointerController> fakePointerController = new FakePointerController();
- fakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
- fakePointerController->setPosition(100, 200);
- fakePointerController->setButtonState(0);
- fakePointerController->setDisplayId(SECONDARY_DISPLAY_ID);
- mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
-
- MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
- prepareDisplay(DISPLAY_ORIENTATION_0);
- prepareAxes(POSITION);
- addMapperAndConfigure(mapper);
-
- // Check source is mouse that would obtain the PointerController.
- ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
-
- NotifyMotionArgs motionArgs;
- processPosition(mapper, 100, 100);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
- ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
-}
-
} // namespace android
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 55d68f6..98ae286 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -71,6 +71,10 @@
// isVisible - true if this layer is visible, false otherwise
bool isVisible() const override EXCLUDES(mStateMutex);
+ // isProtected - true if the layer may contain protected content in the
+ // GRALLOC_USAGE_PROTECTED sense.
+ bool isProtected() const override;
+
// isFixedSize - true if content has a fixed size
bool isFixedSize() const override;
@@ -155,13 +159,6 @@
virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0;
- // -----------------------------------------------------------------------
-
-public:
- // isProtected - true if the layer may contain protected content in the
- // GRALLOC_USAGE_PROTECTED sense.
- bool isProtected() const;
-
protected:
// Loads the corresponding system property once per process
static bool latchUnsignaledBuffers();
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 3ad07ae..2003fb1 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -366,6 +366,15 @@
return mDisplaySurface->prepareFrame(compositionType);
}
+void DisplayDevice::setProtected(bool useProtected) {
+ uint64_t usageFlags = GRALLOC_USAGE_HW_RENDER;
+ if (useProtected) {
+ usageFlags |= GRALLOC_USAGE_PROTECTED;
+ }
+ const int status = native_window_set_usage(mNativeWindow.get(), usageFlags);
+ ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for protected content: %d", status);
+}
+
sp<GraphicBuffer> DisplayDevice::dequeueBuffer() {
int fd;
ANativeWindowBuffer* buffer;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index ba85432..2c2a3ab 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -146,6 +146,7 @@
ui::Dataspace* outDataspace, ui::ColorMode* outMode,
ui::RenderIntent* outIntent) const;
+ void setProtected(bool useProtected);
// Queues the drawn buffer for consumption by HWC.
void queueBuffer(HWComposer& hwc);
// Allocates a buffer as scratch space for GPU composition
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 57ef65a..fb75e4c 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -399,6 +399,12 @@
bool isHiddenByPolicy() const EXCLUDES(mStateMutex);
/*
+ * isProtected - true if the layer may contain protected content in the
+ * GRALLOC_USAGE_PROTECTED sense.
+ */
+ virtual bool isProtected() const { return false; }
+
+ /*
* isFixedSize - true if content has a fixed size
*/
virtual bool isFixedSize() const { return true; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e6a43c5..a5ba054 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5439,10 +5439,11 @@
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
+ auto& engine(getRenderEngine());
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
- renderengine::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer);
+ renderengine::BindNativeBufferAsFramebuffer bufferBond(engine, buffer);
if (bufferBond.getStatus() != NO_ERROR) {
ALOGE("got ANWB binding error while taking screenshot");
return INVALID_OPERATION;
@@ -5454,9 +5455,9 @@
// dependent on the context's EGLConfig.
renderScreenImplLocked(renderArea, traverseLayers, useIdentityTransform);
- base::unique_fd syncFd = getRenderEngine().flush();
+ base::unique_fd syncFd = engine.flush();
if (syncFd < 0) {
- getRenderEngine().finish();
+ engine.finish();
}
*outSyncFd = syncFd.release();
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 5a6aa92..b7c09ed 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -286,8 +286,10 @@
static void setupCommonScreensCaptureCallExpectations(CompositionTest* test) {
// Called once with a non-null value to set a framebuffer, and then
// again with nullptr to clear it.
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull())).WillOnce(Return(true));
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull())).WillOnce(Return(true));
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull(), false))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull(), false))
+ .WillOnce(Return(true));
EXPECT_CALL(*test->mRenderEngine, checkErrors()).WillRepeatedly(Return());
EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
@@ -344,8 +346,10 @@
Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
ui::Transform::ROT_0))
.Times(1);
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull())).WillOnce(Return(true));
- EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull())).WillOnce(Return(true));
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull(), false))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull(), false))
+ .WillOnce(Return(true));
EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
.WillOnce(Return(
ByMove(std::unique_ptr<renderengine::Framebuffer>(test->mReFrameBuffer))));
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 11e5631..1bee271 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -74,6 +74,9 @@
MOCK_METHOD1(drawMesh, void(const Mesh&));
MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
+ MOCK_CONST_METHOD0(isProtected, bool());
+ MOCK_CONST_METHOD0(supportsProtectedContent, bool());
+ MOCK_METHOD1(useProtectedContext, bool(bool));
MOCK_CONST_METHOD4(drawLayers,
status_t(const DisplaySettings&, const std::vector<LayerSettings>&,
ANativeWindowBuffer* const, base::unique_fd*));
@@ -84,8 +87,7 @@
Image();
~Image() override;
- MOCK_METHOD2(setNativeWindowBuffer,
- bool(ANativeWindowBuffer* buffer, bool isProtected));
+ MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
};
class Framebuffer : public renderengine::Framebuffer {
@@ -93,7 +95,7 @@
Framebuffer();
~Framebuffer() override;
- MOCK_METHOD1(setNativeWindowBuffer, bool(ANativeWindowBuffer*));
+ MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
};
} // namespace mock