Merge "SurfaceFlinger: Support out of order transactions"
diff --git a/libs/adbd_auth/adbd_auth.cpp b/libs/adbd_auth/adbd_auth.cpp
index dae6eeb..15bd5c3 100644
--- a/libs/adbd_auth/adbd_auth.cpp
+++ b/libs/adbd_auth/adbd_auth.cpp
@@ -282,9 +282,8 @@
LOG(FATAL) << "adbd_auth: unhandled packet type?";
}
- output_queue_.pop_front();
-
ssize_t rc = writev(framework_fd_.get(), iovs, iovcnt);
+ output_queue_.pop_front();
if (rc == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
PLOG(ERROR) << "adbd_auth: failed to write to framework fd";
ReplaceFrameworkFd(unique_fd());
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 7024a4b..ff0a686 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -52,53 +52,59 @@
}
template <typename T>
- bool setParcelable(T&& p) {
+ status_t setParcelable(T&& p) {
using Tt = typename std::decay<T>::type;
return setParcelable<Tt>(std::make_shared<Tt>(std::forward<T>(p)));
}
template <typename T>
- bool setParcelable(std::shared_ptr<T> p) {
+ status_t setParcelable(std::shared_ptr<T> p) {
static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
if (p && this->getStability() > p->getStability()) {
- return false;
+ return android::BAD_VALUE;
}
this->mParcelable = p;
this->mParcelableName = T::getParcelableDescriptor();
this->mParcelPtr = nullptr;
- return true;
+ return android::OK;
}
template <typename T>
- std::shared_ptr<T> getParcelable() const {
+ status_t getParcelable(std::shared_ptr<T>* ret) const {
static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
const std::string& parcelableDesc = T::getParcelableDescriptor();
if (!this->mParcelPtr) {
if (!this->mParcelable || !this->mParcelableName) {
ALOGD("empty ParcelableHolder");
- return nullptr;
+ *ret = nullptr;
+ return android::OK;
} else if (parcelableDesc != *mParcelableName) {
ALOGD("extension class name mismatch expected:%s actual:%s",
mParcelableName->c_str(), parcelableDesc.c_str());
- return nullptr;
+ *ret = nullptr;
+ return android::BAD_VALUE;
}
- return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ return android::OK;
}
this->mParcelPtr->setDataPosition(0);
status_t status = this->mParcelPtr->readUtf8FromUtf16(&this->mParcelableName);
if (status != android::OK || parcelableDesc != this->mParcelableName) {
this->mParcelableName = std::nullopt;
- return nullptr;
+ *ret = nullptr;
+ return status;
}
this->mParcelable = std::make_shared<T>();
status = mParcelable.get()->readFromParcel(this->mParcelPtr.get());
if (status != android::OK) {
this->mParcelableName = std::nullopt;
this->mParcelable = nullptr;
- return nullptr;
+ *ret = nullptr;
+ return status;
}
this->mParcelPtr = nullptr;
- return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ return android::OK;
}
Stability getStability() const override { return mStability; }
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index e1d6c34..6636a41 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -82,34 +82,37 @@
}
template <typename T>
- bool setParcelable(const T& p) {
+ binder_status_t setParcelable(const T& p) {
if (this->mStability > T::_aidl_stability) {
- return false;
+ return STATUS_BAD_VALUE;
}
AParcel_reset(mParcel.get());
AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor));
p.writeToParcel(mParcel.get());
- return true;
+ return STATUS_OK;
}
template <typename T>
- std::unique_ptr<T> getParcelable() const {
+ binder_status_t getParcelable(std::optional<T>* ret) const {
const std::string parcelableDesc(T::descriptor);
AParcel_setDataPosition(mParcel.get(), 0);
if (AParcel_getDataSize(mParcel.get()) == 0) {
- return nullptr;
+ *ret = std::nullopt;
+ return STATUS_OK;
}
std::string parcelableDescInParcel;
binder_status_t status = AParcel_readString(mParcel.get(), &parcelableDescInParcel);
if (status != STATUS_OK || parcelableDesc != parcelableDescInParcel) {
- return nullptr;
+ *ret = std::nullopt;
+ return status;
}
- std::unique_ptr<T> ret = std::make_unique<T>();
- status = ret->readFromParcel(this->mParcel.get());
+ *ret = std::make_optional<T>();
+ status = (*ret)->readFromParcel(this->mParcel.get());
if (status != STATUS_OK) {
- return nullptr;
+ *ret = std::nullopt;
+ return status;
}
- return std::move(ret);
+ return STATUS_OK;
}
void reset() { AParcel_reset(mParcel.get()); }
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index af9ef06..7dd584d 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -38,9 +38,10 @@
cc_library_shared {
name: "libgui",
- vendor_available: false,
+ vendor_available: true,
vndk: {
enabled: true,
+ private: true,
},
double_loadable: true,
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 3d6b7af..46ae18c 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -672,13 +672,17 @@
? getSkRect(layer->geometry.roundedCornersCrop)
: dest;
drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow);
+ } else {
+ // Shadows are assumed to live only on their own layer - it's not valid
+ // to draw the boundary retangles when there is already a caster shadow
+ // TODO(b/175915334): consider relaxing this restriction to enable more flexible
+ // composition - using a well-defined invalid color is long-term less error-prone.
+ // Push the clipRRect onto the clip stack. Draw the image. Pop the clip.
+ if (layer->geometry.roundedCornersRadius > 0) {
+ canvas->clipRRect(getRoundedRect(layer), true);
+ }
+ canvas->drawRect(dest, paint);
}
-
- // Push the clipRRect onto the clip stack. Draw the image. Pop the clip.
- if (layer->geometry.roundedCornersRadius > 0) {
- canvas->clipRRect(getRoundedRect(layer), true);
- }
- canvas->drawRect(dest, paint);
canvas->restore();
}
canvas->restore();
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 47b8cad..15fb1b8 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -306,6 +306,26 @@
backgroundColor.a);
}
+ void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
+ const renderengine::ShadowSettings& shadow,
+ const ubyte4& backgroundColor) {
+ const float shadowInset = shadow.length * -1.0f;
+ const Rect casterRect(casterBounds);
+ const Rect shadowRect =
+ Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
+
+ const Region backgroundRegion =
+ Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
+
+ expectAlpha(shadowRect, 255);
+ // (0, 0, 0) fill on the bounds of the layer should be ignored.
+ expectBufferColor(casterRect, 255, 255, 255, 255, 254);
+
+ // verify background
+ expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
+ backgroundColor.a);
+ }
+
static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
bool casterIsTranslucent) {
renderengine::ShadowSettings shadow;
@@ -447,6 +467,10 @@
const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
const ubyte4& backgroundColor);
+ void drawShadowWithoutCaster(const FloatRect& castingBounds,
+ const renderengine::ShadowSettings& shadow,
+ const ubyte4& backgroundColor);
+
std::unique_ptr<renderengine::gl::GLESRenderEngine> mRE;
// Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to
@@ -1119,6 +1143,37 @@
invokeDraw(settings, layers, mBuffer);
}
+void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
+ const renderengine::ShadowSettings& shadow,
+ const ubyte4& backgroundColor) {
+ renderengine::DisplaySettings settings;
+ settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
+ settings.physicalDisplay = fullscreenRect();
+ settings.clip = fullscreenRect();
+
+ std::vector<const renderengine::LayerSettings*> layers;
+
+ // add background layer
+ renderengine::LayerSettings bgLayer;
+ bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
+ bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
+ ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
+ backgroundColor.b / 255.0f, this);
+ bgLayer.alpha = backgroundColor.a / 255.0f;
+ layers.push_back(&bgLayer);
+
+ // add shadow layer
+ renderengine::LayerSettings shadowLayer;
+ shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
+ shadowLayer.geometry.boundaries = castingBounds;
+ shadowLayer.alpha = 1.0f;
+ ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
+ shadowLayer.shadow = shadow;
+ layers.push_back(&shadowLayer);
+
+ invokeDraw(settings, layers, mBuffer);
+}
+
INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
testing::Values(std::make_shared<GLESRenderEngineFactory>(),
std::make_shared<GLESCMRenderEngineFactory>(),
@@ -1609,6 +1664,22 @@
EXPECT_FALSE(mRE->isImageCachedForTesting(bufferId));
}
+TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
+ const auto& renderEngineFactory = GetParam();
+ mRE = renderEngineFactory->createRenderEngine();
+
+ const ubyte4 backgroundColor(255, 255, 255, 255);
+ const float shadowLength = 5.0f;
+ Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
+ casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
+ renderengine::ShadowSettings settings =
+ getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
+ false /* casterIsTranslucent */);
+
+ drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
+ expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
+}
+
TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
const auto& renderEngineFactory = GetParam();
mRE = renderEngineFactory->createRenderEngine();
diff --git a/opengl/Android.bp b/opengl/Android.bp
index 48abdce..8b94f61 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -54,6 +54,7 @@
cc_library_headers {
name: "gl_headers",
+ host_supported: true,
vendor_available: true,
export_include_dirs: ["include"],
}
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index ac72ac4..c7c8e7c 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -54,10 +54,11 @@
if (!hasEventHubDevices()) {
return false;
}
- // devices are either all enabled or all disabled, so we only need to check the first
- auto& devicePair = mDevices.begin()->second;
- auto& contextPtr = devicePair.first;
- return contextPtr->isDeviceEnabled();
+ // An input device composed of sub devices can be individually enabled or disabled.
+ // If any of the sub device is enabled then the input device is considered as enabled.
+ bool enabled = false;
+ for_each_subdevice([&enabled](auto& context) { enabled |= context.isDeviceEnabled(); });
+ return enabled;
}
void InputDevice::setEnabled(bool enabled, nsecs_t when) {
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index be21ace..6c493ff 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -222,7 +222,9 @@
}
// Sensor input device is noisy, to save power disable it by default.
- if (device->getClasses().test(InputDeviceClass::SENSOR)) {
+ // Input device is classified as SENSOR when any sub device is a SENSOR device, check Eventhub
+ // device class to disable SENSOR sub device only.
+ if (mEventHub->getDeviceClasses(eventHubId).test(InputDeviceClass::SENSOR)) {
mEventHub->disableDevice(eventHubId);
}
}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 23f3026..6a06c9e 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1481,6 +1481,32 @@
ASSERT_EQ(1U, mReader->getInputDevices().size());
}
+TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
+ constexpr int32_t deviceId = END_RESERVED_ID + 1000;
+ constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
+ // Add two subdevices to device
+ std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
+ // Must add at least one mapper or the device will be ignored!
+ device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
+ device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
+
+ // Push same device instance for next device to be added, so they'll have same identifier.
+ mReader->pushNextDevice(device);
+ mReader->pushNextDevice(device);
+ // Sensor device is initially disabled
+ ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
+ InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
+ nullptr));
+ // Device is disabled because the only sub device is a sensor device and disabled initially.
+ ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
+ ASSERT_FALSE(device->isEnabled());
+ ASSERT_NO_FATAL_FAILURE(
+ addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
+ // The merged device is enabled if any sub device is enabled
+ ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
+ ASSERT_TRUE(device->isEnabled());
+}
+
TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
@@ -2721,6 +2747,7 @@
ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
std::chrono::microseconds(10000),
std::chrono::microseconds(0)));
+ ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_X, 20000);
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Y, -20000);
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Z, 40000);
@@ -2750,6 +2777,7 @@
ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
std::chrono::microseconds(10000),
std::chrono::microseconds(0)));
+ ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_RX, 20000);
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_RY, -20000);
process(mapper, ARBITRARY_TIME, EV_ABS, ABS_RZ, 40000);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4731f50..a545d18 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -688,6 +688,7 @@
shadowLayer.source.buffer.fence = nullptr;
shadowLayer.frameNumber = 0;
shadowLayer.bufferId = 0;
+ shadowLayer.name = getName();
if (shadowLayer.shadow.ambientColor.a <= 0.f && shadowLayer.shadow.spotColor.a <= 0.f) {
return {};
@@ -723,6 +724,7 @@
// If layer is blacked out, force alpha to 1 so that we draw a black color layer.
layerSettings.alpha = blackout ? 1.0f : 0.0f;
+ layerSettings.name = getName();
}
std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionList(