Merge "Report three- and four-finger swipes"
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index a80da4e..12a7cff 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -8,6 +8,7 @@
socket dumpstate stream 0660 shell log
disabled
oneshot
+ capabilities CHOWN DAC_OVERRIDE DAC_READ_SEARCH FOWNER FSETID KILL NET_ADMIN NET_RAW SETGID SETUID SYS_PTRACE SYS_RESOURCE BLOCK_SUSPEND SYSLOG
# dumpstatez generates a zipped bugreport but also uses a socket to print the file location once
# it is finished.
@@ -16,9 +17,11 @@
class main
disabled
oneshot
+ capabilities CHOWN DAC_OVERRIDE DAC_READ_SEARCH FOWNER FSETID KILL NET_ADMIN NET_RAW SETGID SETUID SYS_PTRACE SYS_RESOURCE BLOCK_SUSPEND SYSLOG
# bugreportd starts dumpstate binder service and makes it wait for a listener to connect.
service bugreportd /system/bin/dumpstate -w
class main
disabled
oneshot
+ capabilities CHOWN DAC_OVERRIDE DAC_READ_SEARCH FOWNER FSETID KILL NET_ADMIN NET_RAW SETGID SETUID SYS_PTRACE SYS_RESOURCE BLOCK_SUSPEND SYSLOG
diff --git a/cmds/installd/installd.rc b/cmds/installd/installd.rc
index 240aa49..5b08c77 100644
--- a/cmds/installd/installd.rc
+++ b/cmds/installd/installd.rc
@@ -1,6 +1,7 @@
service installd /system/bin/installd
class main
+ capabilities CHOWN DAC_OVERRIDE DAC_READ_SEARCH FOWNER FSETID KILL SETGID SETUID SYS_ADMIN
on early-boot
mkdir /config/sdcardfs/extensions/1055
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 5fa9fda..09933d3 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -24,7 +24,6 @@
#include <vector>
#include <android/os/IInputConstants.h>
-#include "android/hardware/input/InputDeviceCountryCode.h"
namespace android {
@@ -236,9 +235,7 @@
void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
- bool isExternal, bool hasMic,
- hardware::input::InputDeviceCountryCode countryCode =
- hardware::input::InputDeviceCountryCode::INVALID);
+ bool isExternal, bool hasMic);
inline int32_t getId() const { return mId; }
inline int32_t getControllerNumber() const { return mControllerNumber; }
@@ -250,7 +247,6 @@
}
inline bool isExternal() const { return mIsExternal; }
inline bool hasMic() const { return mHasMic; }
- inline hardware::input::InputDeviceCountryCode getCountryCode() const { return mCountryCode; }
inline uint32_t getSources() const { return mSources; }
const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
@@ -310,7 +306,6 @@
std::string mAlias;
bool mIsExternal;
bool mHasMic;
- hardware::input::InputDeviceCountryCode mCountryCode;
std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
uint32_t mSources;
int32_t mKeyboardType;
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 53a24af..e4c568e 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -566,9 +566,6 @@
impl<'a> ReadableSubParcel<'a> {
/// Read a type that implements [`Deserialize`] from the sub-parcel.
pub fn read<D: Deserialize>(&self) -> Result<D> {
- // The caller should have checked this,
- // but it can't hurt to double-check
- assert!(self.has_more_data());
D::deserialize(&self.parcel)
}
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index c241e4d..6f4c375 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -23,7 +23,7 @@
use std::convert::{TryFrom, TryInto};
use std::ffi::c_void;
use std::mem::{self, ManuallyDrop, MaybeUninit};
-use std::os::raw::{c_char, c_ulong};
+use std::os::raw::c_char;
use std::ptr;
use std::slice;
@@ -103,12 +103,8 @@
unsafe extern "C" fn serialize_element<T: Serialize>(
parcel: *mut sys::AParcel,
array: *const c_void,
- index: c_ulong,
+ index: usize,
) -> status_t {
- // c_ulong and usize are the same, but we need the explicitly sized version
- // so the function signature matches what bindgen generates.
- let index = index as usize;
-
let slice: &[T] = slice::from_raw_parts(array.cast(), index + 1);
let mut parcel = match BorrowedParcel::from_raw(parcel) {
@@ -158,12 +154,8 @@
unsafe extern "C" fn deserialize_element<T: Deserialize>(
parcel: *const sys::AParcel,
array: *mut c_void,
- index: c_ulong,
+ index: usize,
) -> status_t {
- // c_ulong and usize are the same, but we need the explicitly sized version
- // so the function signature matches what bindgen generates.
- let index = index as usize;
-
let vec = &mut *(array as *mut Option<Vec<MaybeUninit<T>>>);
let vec = match vec {
Some(v) => v,
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index a999d59..5db3187 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -100,6 +100,7 @@
"binderBinderUnitTest.cpp",
"binderStatusUnitTest.cpp",
"binderMemoryHeapBaseUnitTest.cpp",
+ "binderRecordedTransactionTest.cpp",
],
shared_libs: [
"libbinder",
diff --git a/libs/binder/tests/binderRecordedTransactionTest.cpp b/libs/binder/tests/binderRecordedTransactionTest.cpp
new file mode 100644
index 0000000..23864e6
--- /dev/null
+++ b/libs/binder/tests/binderRecordedTransactionTest.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/BinderRecordReplay.h>
+#include <gtest/gtest.h>
+
+using android::Parcel;
+using android::status_t;
+using android::base::unique_fd;
+using android::binder::debug::RecordedTransaction;
+
+TEST(BinderRecordedTransaction, RoundTripEncoding) {
+ Parcel d;
+ d.writeInt32(12);
+ d.writeInt64(2);
+ Parcel r;
+ r.writeInt32(99);
+ auto transaction = RecordedTransaction::fromDetails(1, 42, d, r, 0);
+
+ auto file = std::tmpfile();
+ auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1));
+
+ status_t status = transaction->dumpToFile(fd);
+ ASSERT_EQ(android::NO_ERROR, status);
+
+ std::rewind(file);
+
+ auto retrievedTransaction = RecordedTransaction::fromFile(fd);
+
+ EXPECT_EQ(retrievedTransaction->getCode(), 1);
+ EXPECT_EQ(retrievedTransaction->getFlags(), 42);
+ EXPECT_EQ(retrievedTransaction->getDataSize(), 12);
+ EXPECT_EQ(retrievedTransaction->getReplySize(), 4);
+ EXPECT_EQ(retrievedTransaction->getReturnedStatus(), 0);
+ EXPECT_EQ(retrievedTransaction->getVersion(), 0);
+
+ EXPECT_EQ(retrievedTransaction->getDataParcel().readInt32(), 12);
+ EXPECT_EQ(retrievedTransaction->getDataParcel().readInt64(), 2);
+ EXPECT_EQ(retrievedTransaction->getReplyParcel().readInt32(), 99);
+}
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 8ddd18d..8f41cc1 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -26,7 +26,6 @@
filegroup {
name: "inputconstants_aidl",
srcs: [
- "android/hardware/input/InputDeviceCountryCode.aidl",
"android/os/IInputConstants.aidl",
"android/os/InputEventInjectionResult.aidl",
"android/os/InputEventInjectionSync.aidl",
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index fb6c590..87333f2 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -26,7 +26,6 @@
#include <input/InputEventLabels.h>
using android::base::StringPrintf;
-using android::hardware::input::InputDeviceCountryCode;
namespace android {
@@ -178,7 +177,6 @@
mAlias(other.mAlias),
mIsExternal(other.mIsExternal),
mHasMic(other.mHasMic),
- mCountryCode(other.mCountryCode),
mKeyboardLayoutInfo(other.mKeyboardLayoutInfo),
mSources(other.mSources),
mKeyboardType(other.mKeyboardType),
@@ -197,7 +195,7 @@
void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
- bool isExternal, bool hasMic, InputDeviceCountryCode countryCode) {
+ bool isExternal, bool hasMic) {
mId = id;
mGeneration = generation;
mControllerNumber = controllerNumber;
@@ -205,7 +203,6 @@
mAlias = alias;
mIsExternal = isExternal;
mHasMic = hasMic;
- mCountryCode = countryCode;
mSources = 0;
mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
mHasVibrator = false;
diff --git a/libs/input/android/hardware/input/InputDeviceCountryCode.aidl b/libs/input/android/hardware/input/InputDeviceCountryCode.aidl
deleted file mode 100644
index 6bb1a60..0000000
--- a/libs/input/android/hardware/input/InputDeviceCountryCode.aidl
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2022 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.
- */
-
-package android.hardware.input;
-
-/**
- * Constant for HID country code declared by a HID device. These constants are declared as AIDL to
- * be used by java and native input code.
- *
- * @hide
- */
-@Backing(type="int")
-enum InputDeviceCountryCode {
- /**
- * Used as default value where country code is not set in the device HID descriptor
- */
- INVALID = -1,
-
- /**
- * Used as default value when country code is not supported by the HID device. The HID
- * descriptor sets "00" as the country code in this case.
- */
- NOT_SUPPORTED = 0,
-
- /**
- * Arabic
- */
- ARABIC = 1,
-
- /**
- * Belgian
- */
- BELGIAN = 2,
-
- /**
- * Canadian (Bilingual)
- */
- CANADIAN_BILINGUAL = 3,
-
- /**
- * Canadian (French)
- */
- CANADIAN_FRENCH = 4,
-
- /**
- * Czech Republic
- */
- CZECH_REPUBLIC = 5,
-
- /**
- * Danish
- */
- DANISH = 6,
-
- /**
- * Finnish
- */
- FINNISH = 7,
-
- /**
- * French
- */
- FRENCH = 8,
-
- /**
- * German
- */
- GERMAN = 9,
-
- /**
- * Greek
- */
- GREEK = 10,
-
- /**
- * Hebrew
- */
- HEBREW = 11,
-
- /**
- * Hungary
- */
- HUNGARY = 12,
-
- /**
- * International (ISO)
- */
- INTERNATIONAL = 13,
-
- /**
- * Italian
- */
- ITALIAN = 14,
-
- /**
- * Japan (Katakana)
- */
- JAPAN = 15,
-
- /**
- * Korean
- */
- KOREAN = 16,
-
- /**
- * Latin American
- */
- LATIN_AMERICAN = 17,
-
- /**
- * Netherlands (Dutch)
- */
- DUTCH = 18,
-
- /**
- * Norwegian
- */
- NORWEGIAN = 19,
-
- /**
- * Persian
- */
- PERSIAN = 20,
-
- /**
- * Poland
- */
- POLAND = 21,
-
- /**
- * Portuguese
- */
- PORTUGUESE = 22,
-
- /**
- * Russia
- */
- RUSSIA = 23,
-
- /**
- * Slovakia
- */
- SLOVAKIA = 24,
-
- /**
- * Spanish
- */
- SPANISH = 25,
-
- /**
- * Swedish
- */
- SWEDISH = 26,
-
- /**
- * Swiss (French)
- */
- SWISS_FRENCH = 27,
-
- /**
- * Swiss (German)
- */
- SWISS_GERMAN = 28,
-
- /**
- * Switzerland
- */
- SWITZERLAND = 29,
-
- /**
- * Taiwan
- */
- TAIWAN = 30,
-
- /**
- * Turkish_Q
- */
- TURKISH_Q = 31,
-
- /**
- * UK
- */
- UK = 32,
-
- /**
- * US
- */
- US = 33,
-
- /**
- * Yugoslavia
- */
- YUGOSLAVIA = 34,
-
- /**
- * Turkish_F
- */
- TURKISH_F = 35,
-}
\ No newline at end of file
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index 53fa8ce..1b69743 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -192,6 +192,31 @@
return NO_ERROR;
}
+/*
+ * Helper function copies the JPEG image from without EXIF.
+ *
+ * @param dest destination of the data to be written.
+ * @param source source of data being written.
+ * @param exif_pos position of the EXIF package, which is aligned with jpegdecoder.getEXIFPos().
+ * (4 bypes offset to FF sign, the byte after FF E1 XX XX <this byte>).
+ * @param exif_size exif size without the initial 4 bytes, aligned with jpegdecoder.getEXIFSize().
+ */
+void copyJpegWithoutExif(jr_compressed_ptr dest,
+ jr_compressed_ptr source,
+ size_t exif_pos,
+ size_t exif_size) {
+ memcpy(dest, source, sizeof(jpegr_compressed_struct));
+
+ const size_t exif_offset = 4; //exif_pos has 4 bypes offset to the FF sign
+ dest->length = source->length - exif_size - exif_offset;
+ dest->data = malloc(dest->length);
+
+ memcpy(dest->data, source->data, exif_pos - exif_offset);
+ memcpy((uint8_t*)dest->data + exif_pos - exif_offset,
+ (uint8_t*)source->data + exif_pos + exif_size,
+ source->length - exif_pos - exif_size);
+}
+
/* Encode API-0 */
status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
jpegr_transfer_function hdr_tf,
@@ -367,17 +392,18 @@
return ERROR_JPEGR_DECODE_ERROR;
}
+ // Update exif.
jpegr_exif_struct exif;
exif.data = nullptr;
exif.length = 0;
- // Delete EXIF package if it appears, and update exif.
+ jpegr_compressed_struct new_jpeg_image;
+ new_jpeg_image.data = nullptr;
+ new_jpeg_image.length = 0;
if (jpeg_decoder.getEXIFPos() != 0) {
- int new_length = compressed_jpeg_image->length - jpeg_decoder.getEXIFSize() - 4;
- memcpy((uint8_t*)compressed_jpeg_image->data + jpeg_decoder.getEXIFPos() - 4,
- (uint8_t*)compressed_jpeg_image->data + jpeg_decoder.getEXIFPos()
- + jpeg_decoder.getEXIFSize(),
- compressed_jpeg_image->length - jpeg_decoder.getEXIFPos() - jpeg_decoder.getEXIFSize());
- compressed_jpeg_image->length = new_length;
+ copyJpegWithoutExif(&new_jpeg_image,
+ compressed_jpeg_image,
+ jpeg_decoder.getEXIFPos(),
+ jpeg_decoder.getEXIFSize());
exif.data = jpeg_decoder.getEXIFPtr();
exif.length = jpeg_decoder.getEXIFSize();
}
@@ -395,7 +421,12 @@
JPEGR_CHECK(updateExif(&exif, &new_exif));
JPEGR_CHECK(appendRecoveryMap(
- compressed_jpeg_image, &compressed_map, &new_exif, &metadata, dest));
+ new_jpeg_image.data == nullptr ? compressed_jpeg_image : &new_jpeg_image,
+ &compressed_map, &new_exif, &metadata, dest));
+
+ if (new_jpeg_image.data != nullptr) {
+ free(new_jpeg_image.data);
+ }
return NO_ERROR;
}
@@ -421,17 +452,18 @@
uncompressed_yuv_420_image.height = jpeg_decoder.getDecompressedImageHeight();
uncompressed_yuv_420_image.colorGamut = compressed_jpeg_image->colorGamut;
+ // Update exif.
jpegr_exif_struct exif;
exif.data = nullptr;
exif.length = 0;
- // Delete EXIF package if it appears, and update exif.
+ jpegr_compressed_struct new_jpeg_image;
+ new_jpeg_image.data = nullptr;
+ new_jpeg_image.length = 0;
if (jpeg_decoder.getEXIFPos() != 0) {
- int new_length = compressed_jpeg_image->length - jpeg_decoder.getEXIFSize() - 4;
- memcpy((uint8_t*)compressed_jpeg_image->data + jpeg_decoder.getEXIFPos() - 4,
- (uint8_t*)compressed_jpeg_image->data + jpeg_decoder.getEXIFPos()
- + jpeg_decoder.getEXIFSize(),
- compressed_jpeg_image->length - jpeg_decoder.getEXIFPos() - jpeg_decoder.getEXIFSize());
- compressed_jpeg_image->length = new_length;
+ copyJpegWithoutExif(&new_jpeg_image,
+ compressed_jpeg_image,
+ jpeg_decoder.getEXIFPos(),
+ jpeg_decoder.getEXIFSize());
exif.data = jpeg_decoder.getEXIFPtr();
exif.length = jpeg_decoder.getEXIFSize();
}
@@ -472,7 +504,12 @@
JPEGR_CHECK(compressRecoveryMap(&map, &compressed_map));
JPEGR_CHECK(appendRecoveryMap(
- compressed_jpeg_image, &compressed_map, &new_exif, &metadata, dest));
+ new_jpeg_image.data == nullptr ? compressed_jpeg_image : &new_jpeg_image,
+ &compressed_map, &new_exif, &metadata, dest));
+
+ if (new_jpeg_image.data != nullptr) {
+ free(new_jpeg_image.data);
+ }
return NO_ERROR;
}
@@ -864,7 +901,7 @@
// 2 bytes: representing the length of the package
// 29 bytes: length of name space "http://ns.adobe.com/xap/1.0/\0",
// x bytes: length of xmp packet
- const int length = 3 + nameSpaceLength + xmp.size();
+ const int length = 2 + nameSpaceLength + xmp.size();
const uint8_t lengthH = ((length >> 8) & 0xff);
const uint8_t lengthL = (length & 0xff);
JPEGR_CHECK(Write(dest, &photos_editing_formats::image_io::JpegMarker::kStart, 1, pos));
diff --git a/libs/renderengine/include/renderengine/mock/FakeExternalTexture.h b/libs/renderengine/include/renderengine/mock/FakeExternalTexture.h
index 974e0fd..b95f011 100644
--- a/libs/renderengine/include/renderengine/mock/FakeExternalTexture.h
+++ b/libs/renderengine/include/renderengine/mock/FakeExternalTexture.h
@@ -23,7 +23,9 @@
namespace mock {
class FakeExternalTexture : public renderengine::ExternalTexture {
- const sp<GraphicBuffer> mNullBuffer = nullptr;
+ const sp<GraphicBuffer> mEmptyBuffer =
+ sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
uint32_t mWidth;
uint32_t mHeight;
uint64_t mId;
@@ -34,7 +36,7 @@
FakeExternalTexture(uint32_t width, uint32_t height, uint64_t id, PixelFormat pixelFormat,
uint64_t usage)
: mWidth(width), mHeight(height), mId(id), mPixelFormat(pixelFormat), mUsage(usage) {}
- const sp<GraphicBuffer>& getBuffer() const { return mNullBuffer; }
+ const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
return getId() == other.getId();
}
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index d33dd34..ec0ab4e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -48,7 +48,6 @@
integer_overflow: true,
misc_undefined: ["bounds"],
},
-
}
cc_library_static {
@@ -135,6 +134,7 @@
"Gralloc2.cpp",
"Gralloc3.cpp",
"Gralloc4.cpp",
+ "Gralloc5.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
@@ -176,6 +176,7 @@
"libsync",
"libutils",
"liblog",
+ "libvndksupport",
],
export_shared_lib_headers: [
@@ -214,6 +215,8 @@
"libnativewindow_headers",
"libhardware_headers",
"libui_headers",
+ "libimapper_stablec",
+ "libimapper_providerutils",
],
export_static_lib_headers: [
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index f23f10a..e9b5dec 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -161,7 +161,7 @@
return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
}
-status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+status_t Gralloc2Mapper::importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const {
Error error;
auto ret = mMapper->importBuffer(rawHandle,
diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp
index 15c60bc..474d381 100644
--- a/libs/ui/Gralloc3.cpp
+++ b/libs/ui/Gralloc3.cpp
@@ -138,7 +138,7 @@
return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
}
-status_t Gralloc3Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+status_t Gralloc3Mapper::importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const {
Error error;
auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index f6ab7b2..7459466 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -196,7 +196,7 @@
return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
}
-status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+status_t Gralloc4Mapper::importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const {
Error error;
auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
@@ -1233,7 +1233,10 @@
if (mAidlAllocator) {
AllocationResult result;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result);
+#pragma clang diagnostic pop // deprecation
if (!status.isOk()) {
error = status.getExceptionCode();
if (error == EX_SERVICE_SPECIFIC) {
diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
new file mode 100644
index 0000000..6f196b8
--- /dev/null
+++ b/libs/ui/Gralloc5.cpp
@@ -0,0 +1,903 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc5"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <ui/Gralloc5.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_manager.h>
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <binder/IPCThreadState.h>
+#include <dlfcn.h>
+#include <ui/FatVector.h>
+#include <vndksupport/linker.h>
+
+using namespace aidl::android::hardware::graphics::allocator;
+using namespace aidl::android::hardware::graphics::common;
+using namespace ::android::hardware::graphics::mapper;
+
+namespace android {
+
+static const auto kIAllocatorServiceName = IAllocator::descriptor + std::string("/default");
+static const auto kIAllocatorMinimumVersion = 2;
+
+// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
+static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));
+
+typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper *_Nullable *_Nonnull outImplementation);
+
+struct Gralloc5 {
+ std::shared_ptr<IAllocator> allocator;
+ AIMapper *mapper = nullptr;
+};
+
+static std::shared_ptr<IAllocator> waitForAllocator() {
+ if (__builtin_available(android 31, *)) {
+ if (!AServiceManager_isDeclared(kIAllocatorServiceName.c_str())) {
+ return nullptr;
+ }
+ auto allocator = IAllocator::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(kIAllocatorServiceName.c_str())));
+ if (!allocator) {
+ ALOGE("AIDL IAllocator declared but failed to get service");
+ return nullptr;
+ }
+
+ int32_t version = 0;
+ if (!allocator->getInterfaceVersion(&version).isOk()) {
+ ALOGE("Failed to query interface version");
+ return nullptr;
+ }
+ if (version < kIAllocatorMinimumVersion) {
+ return nullptr;
+ }
+ return allocator;
+ } else {
+ // TODO: LOG_ALWAYS_FATAL("libui is not backwards compatible");
+ return nullptr;
+ }
+}
+
+static void *loadIMapperLibrary() {
+ static void *imapperLibrary = []() -> void * {
+ auto allocator = waitForAllocator();
+ std::string mapperSuffix;
+ auto status = allocator->getIMapperLibrarySuffix(&mapperSuffix);
+ if (!status.isOk()) {
+ ALOGE("Failed to get IMapper library suffix");
+ return nullptr;
+ }
+
+ std::string lib_name = "mapper." + mapperSuffix + ".so";
+ void *so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ if (!so) {
+ ALOGE("Failed to load %s", lib_name.c_str());
+ }
+ return so;
+ }();
+ return imapperLibrary;
+}
+
+static const Gralloc5 &getInstance() {
+ static Gralloc5 instance = []() {
+ auto allocator = waitForAllocator();
+ if (!allocator) {
+ return Gralloc5{};
+ }
+ void *so = loadIMapperLibrary();
+ if (!so) {
+ return Gralloc5{};
+ }
+ auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
+ AIMapper *mapper = nullptr;
+ AIMapper_Error error = loadIMapper(&mapper);
+ if (error != AIMAPPER_ERROR_NONE) {
+ ALOGE("AIMapper_loadIMapper failed %d", error);
+ return Gralloc5{};
+ }
+ return Gralloc5{std::move(allocator), mapper};
+ }();
+ return instance;
+}
+
+template <StandardMetadataType T>
+static auto getStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle)
+ -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
+ using Value = typename StandardMetadata<T>::value;
+ // TODO: Tune for common-case better
+ FatVector<uint8_t, 128> buffer;
+ int32_t sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+ buffer.data(), buffer.size());
+ if (sizeRequired < 0) {
+ ALOGW_IF(-AIMAPPER_ERROR_UNSUPPORTED != sizeRequired,
+ "Unexpected error %d from valid getStandardMetadata call", -sizeRequired);
+ return std::nullopt;
+ }
+ if ((size_t)sizeRequired > buffer.size()) {
+ buffer.resize(sizeRequired);
+ sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+ buffer.data(), buffer.size());
+ }
+ if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
+ ALOGW("getStandardMetadata failed, received %d with buffer size %zd", sizeRequired,
+ buffer.size());
+ // Generate a fail type
+ return std::nullopt;
+ }
+ return Value::decode(buffer.data(), sizeRequired);
+}
+
+template <StandardMetadataType T>
+static AIMapper_Error setStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle,
+ const typename StandardMetadata<T>::value_type &value) {
+ using Value = typename StandardMetadata<T>::value;
+ int32_t sizeRequired = Value::encode(value, nullptr, 0);
+ if (sizeRequired < 0) {
+ ALOGW("Failed to calculate required size");
+ return static_cast<AIMapper_Error>(-sizeRequired);
+ }
+ FatVector<uint8_t, 128> buffer;
+ buffer.resize(sizeRequired);
+ sizeRequired = Value::encode(value, buffer.data(), buffer.size());
+ if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
+ ALOGW("Failed to encode with calculated size %d; buffer size %zd", sizeRequired,
+ buffer.size());
+ return static_cast<AIMapper_Error>(-sizeRequired);
+ }
+ return mapper->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T), buffer.data(),
+ sizeRequired);
+}
+
+Gralloc5Allocator::Gralloc5Allocator(const Gralloc5Mapper &mapper) : mMapper(mapper) {
+ mAllocator = getInstance().allocator;
+}
+
+bool Gralloc5Allocator::isLoaded() const {
+ return mAllocator != nullptr;
+}
+
+static uint64_t getValidUsageBits() {
+ static const uint64_t validUsageBits = []() -> uint64_t {
+ uint64_t bits = 0;
+ for (const auto bit : ndk::enum_range<BufferUsage>{}) {
+ bits |= static_cast<int64_t>(bit);
+ }
+ return bits;
+ }();
+ return validUsageBits | kRemovedUsageBits;
+}
+
+static std::optional<BufferDescriptorInfo> makeDescriptor(std::string requestorName, uint32_t width,
+ uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage) {
+ uint64_t validUsageBits = getValidUsageBits();
+ if (usage & ~validUsageBits) {
+ ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, usage & ~validUsageBits);
+ return std::nullopt;
+ }
+
+ BufferDescriptorInfo descriptorInfo{
+ .width = static_cast<int32_t>(width),
+ .height = static_cast<int32_t>(height),
+ .layerCount = static_cast<int32_t>(layerCount),
+ .format = static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format),
+ .usage = static_cast<BufferUsage>(usage),
+ };
+ auto nameLength = std::min(requestorName.length(), descriptorInfo.name.size() - 1);
+ memcpy(descriptorInfo.name.data(), requestorName.data(), nameLength);
+ requestorName.data()[nameLength] = 0;
+ return descriptorInfo;
+}
+
+std::string Gralloc5Allocator::dumpDebugInfo(bool less) const {
+ return mMapper.dumpBuffers(less);
+}
+
+status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
+ android::PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t *outStride,
+ buffer_handle_t *outBufferHandles, bool importBuffers) const {
+ auto descriptorInfo = makeDescriptor(requestorName, width, height, format, layerCount, usage);
+ if (!descriptorInfo) {
+ return BAD_VALUE;
+ }
+
+ AllocationResult result;
+ auto status = mAllocator->allocate2(*descriptorInfo, bufferCount, &result);
+ if (!status.isOk()) {
+ auto error = status.getExceptionCode();
+ if (error == EX_SERVICE_SPECIFIC) {
+ error = status.getServiceSpecificError();
+ }
+ if (error == OK) {
+ error = UNKNOWN_ERROR;
+ }
+ return error;
+ }
+
+ if (importBuffers) {
+ for (uint32_t i = 0; i < bufferCount; i++) {
+ auto handle = makeFromAidl(result.buffers[i]);
+ auto error = mMapper.importBuffer(handle, &outBufferHandles[i]);
+ native_handle_delete(handle);
+ if (error != NO_ERROR) {
+ for (uint32_t j = 0; j < i; j++) {
+ mMapper.freeBuffer(outBufferHandles[j]);
+ outBufferHandles[j] = nullptr;
+ }
+ return error;
+ }
+ }
+ } else {
+ for (uint32_t i = 0; i < bufferCount; i++) {
+ outBufferHandles[i] = dupFromAidl(result.buffers[i]);
+ if (!outBufferHandles[i]) {
+ for (uint32_t j = 0; j < i; j++) {
+ auto buffer = const_cast<native_handle_t *>(outBufferHandles[j]);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ outBufferHandles[j] = nullptr;
+ }
+ return NO_MEMORY;
+ }
+ }
+ }
+
+ *outStride = result.stride;
+
+ // Release all the resources held by AllocationResult (specifically any remaining FDs)
+ result = {};
+ // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
+ // TODO: Re-enable this at some point if it's necessary. We can't do it now because libui
+ // is marked apex_available (b/214400477) and libbinder isn't (which of course is correct)
+ // IPCThreadState::self()->flushCommands();
+
+ return OK;
+}
+
+void Gralloc5Mapper::preload() {
+ // TODO(b/261858155): Implement. We can't bounce off of IAllocator for this because zygote can't
+ // use binder. So when an alternate strategy of retrieving the library prefix is available,
+ // use that here.
+}
+
+Gralloc5Mapper::Gralloc5Mapper() {
+ mMapper = getInstance().mapper;
+}
+
+bool Gralloc5Mapper::isLoaded() const {
+ return mMapper != nullptr && mMapper->version >= AIMAPPER_VERSION_5;
+}
+
+std::string Gralloc5Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
+ // TODO(b/261858392): Implement
+ (void)bufferHandle;
+ (void)less;
+ return {};
+}
+
+std::string Gralloc5Mapper::dumpBuffers(bool less) const {
+ // TODO(b/261858392): Implement
+ (void)less;
+ return {};
+}
+
+status_t Gralloc5Mapper::importBuffer(const native_handle_t *rawHandle,
+ buffer_handle_t *outBufferHandle) const {
+ return mMapper->v5.importBuffer(rawHandle, outBufferHandle);
+}
+
+void Gralloc5Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
+ mMapper->v5.freeBuffer(bufferHandle);
+}
+
+status_t Gralloc5Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
+ uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint32_t stride) const {
+ {
+ auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
+ if (width != value) {
+ ALOGW("Width didn't match, expected %d got %" PRId64, width, value.value_or(-1));
+ return BAD_VALUE;
+ }
+ }
+ {
+ auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
+ if (height != value) {
+ ALOGW("Height didn't match, expected %d got %" PRId64, height, value.value_or(-1));
+ return BAD_VALUE;
+ }
+ }
+ {
+ auto value =
+ getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
+ bufferHandle);
+ if (static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format) !=
+ value) {
+ ALOGW("Format didn't match, expected %d got %s", format,
+ value.has_value() ? toString(*value).c_str() : "<null>");
+ return BAD_VALUE;
+ }
+ }
+ {
+ auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
+ if (layerCount != value) {
+ ALOGW("Layer count didn't match, expected %d got %" PRId64, layerCount,
+ value.value_or(-1));
+ return BAD_VALUE;
+ }
+ }
+ {
+ auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
+ if (static_cast<BufferUsage>(usage) != value) {
+ ALOGW("Usage didn't match, expected %" PRIu64 " got %" PRId64, usage,
+ static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
+ return BAD_VALUE;
+ }
+ }
+ {
+ (void)stride;
+ // TODO(b/261856851): Add StandardMetadataType::STRIDE && enable this
+ // auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper,
+ // bufferHandle); if (static_cast<BufferUsage>(usage) != value) {
+ // ALOGW("Layer count didn't match, expected %" PRIu64 " got %" PRId64, usage,
+ // static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
+ // return BAD_VALUE;
+ // }
+ }
+ return OK;
+}
+
+void Gralloc5Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds,
+ uint32_t *outNumInts) const {
+ mMapper->v5.getTransportSize(bufferHandle, outNumFds, outNumInts);
+}
+
+status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
+ int acquireFence, void **outData, int32_t *outBytesPerPixel,
+ int32_t *outBytesPerStride) const {
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
+
+ if (err == NO_ERROR && !planeLayouts.empty()) {
+ if (outBytesPerPixel) {
+ int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
+ for (const auto &planeLayout : planeLayouts) {
+ if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
+ bitsPerPixel = -1;
+ }
+ }
+ if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
+ *outBytesPerPixel = bitsPerPixel / 8;
+ } else {
+ *outBytesPerPixel = -1;
+ }
+ }
+ if (outBytesPerStride) {
+ int32_t bytesPerStride = planeLayouts.front().strideInBytes;
+ for (const auto &planeLayout : planeLayouts) {
+ if (bytesPerStride != planeLayout.strideInBytes) {
+ bytesPerStride = -1;
+ }
+ }
+ if (bytesPerStride >= 0) {
+ *outBytesPerStride = bytesPerStride;
+ } else {
+ *outBytesPerStride = -1;
+ }
+ }
+ }
+
+ auto status = mMapper->v5.lock(bufferHandle, usage, bounds, acquireFence, outData);
+
+ ALOGW_IF(status != AIMAPPER_ERROR_NONE, "lock(%p, ...) failed: %d", bufferHandle, status);
+ return static_cast<status_t>(status);
+}
+
+status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
+ int acquireFence, android_ycbcr *outYcbcr) const {
+ if (!outYcbcr) {
+ return BAD_VALUE;
+ }
+
+ // TODO(b/262279301): Change the return type of ::unlock to unique_fd instead of int so that
+ // ignoring the return value "just works" instead
+ auto unlock = [this](buffer_handle_t bufferHandle) {
+ int fence = this->unlock(bufferHandle);
+ if (fence != -1) {
+ ::close(fence);
+ }
+ };
+
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ void *data = nullptr;
+ error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ android_ycbcr ycbcr;
+
+ ycbcr.y = nullptr;
+ ycbcr.cb = nullptr;
+ ycbcr.cr = nullptr;
+ ycbcr.ystride = 0;
+ ycbcr.cstride = 0;
+ ycbcr.chroma_step = 0;
+
+ for (const auto &planeLayout : planeLayouts) {
+ for (const auto &planeLayoutComponent : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+ continue;
+ }
+
+ uint8_t *tmpData = static_cast<uint8_t *>(data) + planeLayout.offsetInBytes;
+
+ // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
+ // but we still want to point to the start of the first byte.
+ tmpData += (planeLayoutComponent.offsetInBits / 8);
+
+ uint64_t sampleIncrementInBytes;
+
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.y = tmpData;
+ ycbcr.ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ if (planeLayout.sampleIncrementInBits % 8 != 0) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+
+ sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+ if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
+ (sampleIncrementInBytes != 4)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+
+ if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
+ ycbcr.cstride = planeLayout.strideInBytes;
+ ycbcr.chroma_step = sampleIncrementInBytes;
+ } else {
+ if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
+ (ycbcr.chroma_step != sampleIncrementInBytes)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ if (ycbcr.cb != nullptr) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.cb = tmpData;
+ } else {
+ if (ycbcr.cr != nullptr) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.cr = tmpData;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ *outYcbcr = ycbcr;
+ return OK;
+}
+
+int Gralloc5Mapper::unlock(buffer_handle_t bufferHandle) const {
+ int fence = -1;
+ AIMapper_Error error = mMapper->v5.unlock(bufferHandle, &fence);
+ if (error != AIMAPPER_ERROR_NONE) {
+ ALOGW("unlock failed with error %d", error);
+ }
+ return fence;
+}
+
+status_t Gralloc5Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ bool *outSupported) const {
+ auto descriptorInfo = makeDescriptor("", width, height, format, layerCount, usage);
+ if (!descriptorInfo) {
+ *outSupported = false;
+ return OK;
+ }
+ auto status = getInstance().allocator->isSupported(*descriptorInfo, outSupported);
+ if (!status.isOk()) {
+ ALOGW("IAllocator::isSupported error %d (%s)", status.getStatus(), status.getMessage());
+ *outSupported = false;
+ }
+ return OK;
+}
+
+status_t Gralloc5Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t *outBufferId) const {
+ auto value = getStandardMetadata<StandardMetadataType::BUFFER_ID>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outBufferId = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getName(buffer_handle_t bufferHandle, std::string *outName) const {
+ auto value = getStandardMetadata<StandardMetadataType::NAME>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outName = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t *outWidth) const {
+ auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outWidth = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t *outHeight) const {
+ auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outHeight = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getLayerCount(buffer_handle_t bufferHandle,
+ uint64_t *outLayerCount) const {
+ auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outLayerCount = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
+ ui::PixelFormat *outPixelFormatRequested) const {
+ auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
+ bufferHandle);
+ if (value.has_value()) {
+ *outPixelFormatRequested = static_cast<ui::PixelFormat>(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
+ uint32_t *outPixelFormatFourCC) const {
+ auto value =
+ getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outPixelFormatFourCC = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
+ uint64_t *outPixelFormatModifier) const {
+ auto value =
+ getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outPixelFormatModifier = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t *outUsage) const {
+ auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outUsage = static_cast<uint64_t>(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getAllocationSize(buffer_handle_t bufferHandle,
+ uint64_t *outAllocationSize) const {
+ auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outAllocationSize = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getProtectedContent(buffer_handle_t bufferHandle,
+ uint64_t *outProtectedContent) const {
+ auto value =
+ getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outProtectedContent = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getCompression(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType *outCompression) const {
+ auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outCompression = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getCompression(buffer_handle_t bufferHandle,
+ ui::Compression *outCompression) const {
+ auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
+ if (!value.has_value()) {
+ return UNKNOWN_TRANSACTION;
+ }
+ if (!gralloc4::isStandardCompression(*value)) {
+ return BAD_TYPE;
+ }
+ *outCompression = gralloc4::getStandardCompressionValue(*value);
+ return OK;
+}
+
+status_t Gralloc5Mapper::getInterlaced(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType *outInterlaced) const {
+ auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outInterlaced = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getInterlaced(buffer_handle_t bufferHandle,
+ ui::Interlaced *outInterlaced) const {
+ if (!outInterlaced) {
+ return BAD_VALUE;
+ }
+ ExtendableType interlaced;
+ status_t error = getInterlaced(bufferHandle, &interlaced);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardInterlaced(interlaced)) {
+ return BAD_TYPE;
+ }
+ *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
+ return NO_ERROR;
+}
+
+status_t Gralloc5Mapper::getChromaSiting(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting) const {
+ auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outChromaSiting = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getChromaSiting(buffer_handle_t bufferHandle,
+ ui::ChromaSiting *outChromaSiting) const {
+ if (!outChromaSiting) {
+ return BAD_VALUE;
+ }
+ ExtendableType chromaSiting;
+ status_t error = getChromaSiting(bufferHandle, &chromaSiting);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
+ return BAD_TYPE;
+ }
+ *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
+ return NO_ERROR;
+}
+
+status_t Gralloc5Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout> *outPlaneLayouts) const {
+ auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outPlaneLayouts = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDataspace(buffer_handle_t bufferHandle,
+ ui::Dataspace *outDataspace) const {
+ auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outDataspace = static_cast<ui::Dataspace>(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
+ return setStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle,
+ static_cast<Dataspace>(dataspace));
+}
+
+status_t Gralloc5Mapper::getBlendMode(buffer_handle_t bufferHandle,
+ ui::BlendMode *outBlendMode) const {
+ auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outBlendMode = static_cast<ui::BlendMode>(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getSmpte2086(buffer_handle_t bufferHandle,
+ std::optional<ui::Smpte2086> *outSmpte2086) const {
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outSmpte2086 = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::setSmpte2086(buffer_handle_t bufferHandle,
+ std::optional<ui::Smpte2086> smpte2086) const {
+ return setStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle, smpte2086);
+}
+
+status_t Gralloc5Mapper::getCta861_3(buffer_handle_t bufferHandle,
+ std::optional<ui::Cta861_3> *outCta861_3) const {
+ auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outCta861_3 = *value;
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::setCta861_3(buffer_handle_t bufferHandle,
+ std::optional<ui::Cta861_3> cta861_3) const {
+ return setStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle, cta861_3);
+}
+
+status_t Gralloc5Mapper::getSmpte2094_40(
+ buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_40) const {
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outSmpte2094_40 = std::move(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> smpte2094_40) const {
+ return setStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle,
+ smpte2094_40);
+}
+
+status_t Gralloc5Mapper::getSmpte2094_10(
+ buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_10) const {
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle);
+ if (value.has_value()) {
+ *outSmpte2094_10 = std::move(*value);
+ return OK;
+ }
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> smpte2094_10) const {
+ return setStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle,
+ smpte2094_10);
+}
+
+status_t Gralloc5Mapper::getDefaultPixelFormatFourCC(uint32_t, uint32_t, PixelFormat, uint32_t,
+ uint64_t, uint32_t *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultPixelFormatModifier(uint32_t, uint32_t, PixelFormat, uint32_t,
+ uint64_t, uint64_t *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultAllocationSize(uint32_t, uint32_t, PixelFormat, uint32_t,
+ uint64_t, uint64_t *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultProtectedContent(uint32_t, uint32_t, PixelFormat, uint32_t,
+ uint64_t, uint64_t *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultCompression(
+ uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ aidl::android::hardware::graphics::common::ExtendableType *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultCompression(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ ui::Compression *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultInterlaced(
+ uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ aidl::android::hardware::graphics::common::ExtendableType *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultInterlaced(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ ui::Interlaced *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultChromaSiting(
+ uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ aidl::android::hardware::graphics::common::ExtendableType *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultChromaSiting(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ ui::ChromaSiting *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+status_t Gralloc5Mapper::getDefaultPlaneLayouts(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
+ std::vector<ui::PlaneLayout> *) const {
+ // TODO(b/261857910): Remove
+ return UNKNOWN_TRANSACTION;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3f958ba..c0abec2 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -34,6 +34,7 @@
#include <ui/Gralloc2.h>
#include <ui/Gralloc3.h>
#include <ui/Gralloc4.h>
+#include <ui/Gralloc5.h>
#include <ui/GraphicBufferMapper.h>
namespace android {
@@ -48,23 +49,27 @@
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
- mAllocator = std::make_unique<const Gralloc4Allocator>(
- reinterpret_cast<const Gralloc4Mapper&>(mMapper.getGrallocMapper()));
- if (mAllocator->isLoaded()) {
- return;
+ switch (mMapper.getMapperVersion()) {
+ case GraphicBufferMapper::GRALLOC_5:
+ mAllocator = std::make_unique<const Gralloc5Allocator>(
+ reinterpret_cast<const Gralloc5Mapper&>(mMapper.getGrallocMapper()));
+ break;
+ case GraphicBufferMapper::GRALLOC_4:
+ mAllocator = std::make_unique<const Gralloc4Allocator>(
+ reinterpret_cast<const Gralloc4Mapper&>(mMapper.getGrallocMapper()));
+ break;
+ case GraphicBufferMapper::GRALLOC_3:
+ mAllocator = std::make_unique<const Gralloc3Allocator>(
+ reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
+ break;
+ case GraphicBufferMapper::GRALLOC_2:
+ mAllocator = std::make_unique<const Gralloc2Allocator>(
+ reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
+ break;
}
- mAllocator = std::make_unique<const Gralloc3Allocator>(
- reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
- if (mAllocator->isLoaded()) {
- return;
- }
- mAllocator = std::make_unique<const Gralloc2Allocator>(
- reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
- if (mAllocator->isLoaded()) {
- return;
- }
-
- LOG_ALWAYS_FATAL("gralloc-allocator is missing");
+ LOG_ALWAYS_FATAL_IF(!mAllocator->isLoaded(),
+ "Failed to load matching allocator for mapper version %d",
+ mMapper.getMapperVersion());
}
GraphicBufferAllocator::~GraphicBufferAllocator() {}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index a98e697..6002a6d 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -36,6 +36,7 @@
#include <ui/Gralloc2.h>
#include <ui/Gralloc3.h>
#include <ui/Gralloc4.h>
+#include <ui/Gralloc5.h>
#include <ui/GraphicBuffer.h>
#include <system/graphics.h>
@@ -49,9 +50,15 @@
Gralloc2Mapper::preload();
Gralloc3Mapper::preload();
Gralloc4Mapper::preload();
+ Gralloc5Mapper::preload();
}
GraphicBufferMapper::GraphicBufferMapper() {
+ mMapper = std::make_unique<const Gralloc5Mapper>();
+ if (mMapper->isLoaded()) {
+ mMapperVersion = Version::GRALLOC_5;
+ return;
+ }
mMapper = std::make_unique<const Gralloc4Mapper>();
if (mMapper->isLoaded()) {
mMapperVersion = Version::GRALLOC_4;
@@ -82,15 +89,14 @@
ALOGD("%s", s.c_str());
}
-status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
- uint32_t width, uint32_t height, uint32_t layerCount,
- PixelFormat format, uint64_t usage, uint32_t stride,
- buffer_handle_t* outHandle)
-{
+status_t GraphicBufferMapper::importBuffer(const native_handle_t* rawHandle, uint32_t width,
+ uint32_t height, uint32_t layerCount, PixelFormat format,
+ uint64_t usage, uint32_t stride,
+ buffer_handle_t* outHandle) {
ATRACE_CALL();
buffer_handle_t bufferHandle;
- status_t error = mMapper->importBuffer(hardware::hidl_handle(rawHandle), &bufferHandle);
+ status_t error = mMapper->importBuffer(rawHandle, &bufferHandle);
if (error != NO_ERROR) {
ALOGW("importBuffer(%p) failed: %d", rawHandle, error);
return error;
@@ -109,6 +115,11 @@
return NO_ERROR;
}
+status_t GraphicBufferMapper::importBufferNoValidate(const native_handle_t* rawHandle,
+ buffer_handle_t* outHandle) {
+ return mMapper->importBuffer(rawHandle, outHandle);
+}
+
void GraphicBufferMapper::getTransportSize(buffer_handle_t handle,
uint32_t* outTransportNumFds, uint32_t* outTransportNumInts)
{
diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h
index 6101d4b..b494cbe 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -39,14 +39,11 @@
return "";
}
- virtual status_t createDescriptor(void* bufferDescriptorInfo,
- void* outBufferDescriptor) const = 0;
-
// Import a buffer that is from another HAL, another process, or is
// cloned.
//
// The returned handle must be freed with freeBuffer.
- virtual status_t importBuffer(const hardware::hidl_handle& rawHandle,
+ virtual status_t importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const = 0;
virtual void freeBuffer(buffer_handle_t bufferHandle) const = 0;
@@ -269,11 +266,6 @@
std::vector<ui::PlaneLayout>* /*outPlaneLayouts*/) const {
return INVALID_OPERATION;
}
-
- virtual std::vector<android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription>
- listSupportedMetadataTypes() const {
- return {};
- }
};
// A wrapper to IAllocator
diff --git a/libs/ui/include/ui/Gralloc2.h b/libs/ui/include/ui/Gralloc2.h
index f570c42..a7b6f492 100644
--- a/libs/ui/include/ui/Gralloc2.h
+++ b/libs/ui/include/ui/Gralloc2.h
@@ -38,9 +38,9 @@
bool isLoaded() const override;
- status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
+ status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const;
- status_t importBuffer(const hardware::hidl_handle& rawHandle,
+ status_t importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const override;
void freeBuffer(buffer_handle_t bufferHandle) const override;
diff --git a/libs/ui/include/ui/Gralloc3.h b/libs/ui/include/ui/Gralloc3.h
index 93a5077..7367549 100644
--- a/libs/ui/include/ui/Gralloc3.h
+++ b/libs/ui/include/ui/Gralloc3.h
@@ -37,9 +37,9 @@
bool isLoaded() const override;
- status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
+ status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const;
- status_t importBuffer(const hardware::hidl_handle& rawHandle,
+ status_t importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const override;
void freeBuffer(buffer_handle_t bufferHandle) const override;
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
index cf023c9..6bc5ce5 100644
--- a/libs/ui/include/ui/Gralloc4.h
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -42,9 +42,9 @@
std::string dumpBuffer(buffer_handle_t bufferHandle, bool less = true) const override;
std::string dumpBuffers(bool less = true) const;
- status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
+ status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const;
- status_t importBuffer(const hardware::hidl_handle& rawHandle,
+ status_t importBuffer(const native_handle_t* rawHandle,
buffer_handle_t* outBufferHandle) const override;
void freeBuffer(buffer_handle_t bufferHandle) const override;
diff --git a/libs/ui/include/ui/Gralloc5.h b/libs/ui/include/ui/Gralloc5.h
new file mode 100644
index 0000000..bc10169
--- /dev/null
+++ b/libs/ui/include/ui/Gralloc5.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/graphics/allocator/IAllocator.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <ui/Gralloc.h>
+
+namespace android {
+
+class Gralloc5Mapper : public GrallocMapper {
+public:
+public:
+ static void preload();
+
+ Gralloc5Mapper();
+
+ [[nodiscard]] bool isLoaded() const override;
+
+ [[nodiscard]] std::string dumpBuffer(buffer_handle_t bufferHandle, bool less) const override;
+
+ [[nodiscard]] std::string dumpBuffers(bool less = true) const;
+
+ [[nodiscard]] status_t importBuffer(const native_handle_t *rawHandle,
+ buffer_handle_t *outBufferHandle) const override;
+
+ void freeBuffer(buffer_handle_t bufferHandle) const override;
+
+ [[nodiscard]] status_t validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
+ uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint32_t stride) const override;
+
+ void getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds,
+ uint32_t *outNumInts) const override;
+
+ [[nodiscard]] status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
+ int acquireFence, void **outData, int32_t *outBytesPerPixel,
+ int32_t *outBytesPerStride) const override;
+
+ [[nodiscard]] status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
+ int acquireFence, android_ycbcr *ycbcr) const override;
+
+ [[nodiscard]] int unlock(buffer_handle_t bufferHandle) const override;
+
+ [[nodiscard]] status_t isSupported(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ bool *outSupported) const override;
+
+ [[nodiscard]] status_t getBufferId(buffer_handle_t bufferHandle,
+ uint64_t *outBufferId) const override;
+
+ [[nodiscard]] status_t getName(buffer_handle_t bufferHandle,
+ std::string *outName) const override;
+
+ [[nodiscard]] status_t getWidth(buffer_handle_t bufferHandle,
+ uint64_t *outWidth) const override;
+
+ [[nodiscard]] status_t getHeight(buffer_handle_t bufferHandle,
+ uint64_t *outHeight) const override;
+
+ [[nodiscard]] status_t getLayerCount(buffer_handle_t bufferHandle,
+ uint64_t *outLayerCount) const override;
+
+ [[nodiscard]] status_t getPixelFormatRequested(
+ buffer_handle_t bufferHandle, ui::PixelFormat *outPixelFormatRequested) const override;
+
+ [[nodiscard]] status_t getPixelFormatFourCC(buffer_handle_t bufferHandle,
+ uint32_t *outPixelFormatFourCC) const override;
+
+ [[nodiscard]] status_t getPixelFormatModifier(buffer_handle_t bufferHandle,
+ uint64_t *outPixelFormatModifier) const override;
+
+ [[nodiscard]] status_t getUsage(buffer_handle_t bufferHandle,
+ uint64_t *outUsage) const override;
+
+ [[nodiscard]] status_t getAllocationSize(buffer_handle_t bufferHandle,
+ uint64_t *outAllocationSize) const override;
+
+ [[nodiscard]] status_t getProtectedContent(buffer_handle_t bufferHandle,
+ uint64_t *outProtectedContent) const override;
+
+ [[nodiscard]] status_t getCompression(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType
+ *outCompression) const override;
+
+ [[nodiscard]] status_t getCompression(buffer_handle_t bufferHandle,
+ ui::Compression *outCompression) const override;
+
+ [[nodiscard]] status_t getInterlaced(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType
+ *outInterlaced) const override;
+
+ [[nodiscard]] status_t getInterlaced(buffer_handle_t bufferHandle,
+ ui::Interlaced *outInterlaced) const override;
+
+ [[nodiscard]] status_t getChromaSiting(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType
+ *outChromaSiting) const override;
+
+ [[nodiscard]] status_t getChromaSiting(buffer_handle_t bufferHandle,
+ ui::ChromaSiting *outChromaSiting) const override;
+
+ [[nodiscard]] status_t getPlaneLayouts(
+ buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout> *outPlaneLayouts) const override;
+
+ [[nodiscard]] status_t getDataspace(buffer_handle_t bufferHandle,
+ ui::Dataspace *outDataspace) const override;
+
+ [[nodiscard]] status_t setDataspace(buffer_handle_t bufferHandle,
+ ui::Dataspace dataspace) const override;
+
+ [[nodiscard]] status_t getBlendMode(buffer_handle_t bufferHandle,
+ ui::BlendMode *outBlendMode) const override;
+
+ [[nodiscard]] status_t getSmpte2086(buffer_handle_t bufferHandle,
+ std::optional<ui::Smpte2086> *outSmpte2086) const override;
+
+ [[nodiscard]] status_t setSmpte2086(buffer_handle_t bufferHandle,
+ std::optional<ui::Smpte2086> smpte2086) const override;
+
+ [[nodiscard]] status_t getCta861_3(buffer_handle_t bufferHandle,
+ std::optional<ui::Cta861_3> *outCta861_3) const override;
+
+ [[nodiscard]] status_t setCta861_3(buffer_handle_t bufferHandle,
+ std::optional<ui::Cta861_3> cta861_3) const override;
+
+ [[nodiscard]] status_t getSmpte2094_40(
+ buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> *outSmpte2094_40) const override;
+
+ [[nodiscard]] status_t setSmpte2094_40(
+ buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> smpte2094_40) const override;
+
+ [[nodiscard]] status_t getSmpte2094_10(
+ buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> *outSmpte2094_10) const override;
+
+ [[nodiscard]] status_t setSmpte2094_10(
+ buffer_handle_t bufferHandle,
+ std::optional<std::vector<uint8_t>> smpte2094_10) const override;
+
+ [[nodiscard]] status_t getDefaultPixelFormatFourCC(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t *outPixelFormatFourCC) const override;
+
+ [[nodiscard]] status_t getDefaultPixelFormatModifier(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint64_t *outPixelFormatModifier) const override;
+
+ [[nodiscard]] status_t getDefaultAllocationSize(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t *outAllocationSize) const override;
+
+ [[nodiscard]] status_t getDefaultProtectedContent(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t *outProtectedContent) const override;
+
+ [[nodiscard]] status_t getDefaultCompression(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType *outCompression)
+ const override;
+
+ [[nodiscard]] status_t getDefaultCompression(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ ui::Compression *outCompression) const override;
+
+ [[nodiscard]] status_t getDefaultInterlaced(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType *outInterlaced)
+ const override;
+
+ [[nodiscard]] status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Interlaced *outInterlaced) const override;
+
+ [[nodiscard]] status_t getDefaultChromaSiting(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting)
+ const override;
+
+ [[nodiscard]] status_t getDefaultChromaSiting(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ ui::ChromaSiting *outChromaSiting) const override;
+
+ [[nodiscard]] status_t getDefaultPlaneLayouts(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, std::vector<ui::PlaneLayout> *outPlaneLayouts) const override;
+
+private:
+ void unlockBlocking(buffer_handle_t bufferHandle) const;
+
+ AIMapper *mMapper = nullptr;
+};
+
+class Gralloc5Allocator : public GrallocAllocator {
+public:
+ Gralloc5Allocator(const Gralloc5Mapper &mapper);
+
+ [[nodiscard]] bool isLoaded() const override;
+
+ [[nodiscard]] std::string dumpDebugInfo(bool less) const override;
+
+ [[nodiscard]] status_t allocate(std::string requestorName, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage,
+ uint32_t bufferCount, uint32_t *outStride,
+ buffer_handle_t *outBufferHandles,
+ bool importBuffers) const override;
+
+private:
+ const Gralloc5Mapper &mMapper;
+ std::shared_ptr<aidl::android::hardware::graphics::allocator::IAllocator> mAllocator;
+};
+
+} // namespace android
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 507fa35..51c6e92 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -42,9 +42,10 @@
{
public:
enum Version {
- GRALLOC_2,
+ GRALLOC_2 = 2,
GRALLOC_3,
GRALLOC_4,
+ GRALLOC_5,
};
static void preloadHal();
static inline GraphicBufferMapper& get() { return getInstance(); }
@@ -54,10 +55,11 @@
// The imported outHandle must be freed with freeBuffer when no longer
// needed. rawHandle is owned by the caller.
- status_t importBuffer(buffer_handle_t rawHandle,
- uint32_t width, uint32_t height, uint32_t layerCount,
- PixelFormat format, uint64_t usage, uint32_t stride,
- buffer_handle_t* outHandle);
+ status_t importBuffer(const native_handle_t* rawHandle, uint32_t width, uint32_t height,
+ uint32_t layerCount, PixelFormat format, uint64_t usage, uint32_t stride,
+ buffer_handle_t* outHandle);
+
+ status_t importBufferNoValidate(const native_handle_t* rawHandle, buffer_handle_t* outHandle);
status_t freeBuffer(buffer_handle_t handle);
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index e9fa599..b214750 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -62,7 +62,6 @@
#define INDENT3 " "
using android::base::StringPrintf;
-using android::hardware::input::InputDeviceCountryCode;
namespace android {
@@ -135,6 +134,46 @@
{"green", LightColor::GREEN},
{"blue", LightColor::BLUE}};
+// Mapping for country code to Layout info.
+// See bCountryCode in 6.2.1 of https://usb.org/sites/default/files/hid1_11.pdf.
+const std::unordered_map<std::int32_t, RawLayoutInfo> LAYOUT_INFOS =
+ {{0, RawLayoutInfo{.languageTag = "", .layoutType = ""}}, // NOT_SUPPORTED
+ {1, RawLayoutInfo{.languageTag = "ar-Arab", .layoutType = ""}}, // ARABIC
+ {2, RawLayoutInfo{.languageTag = "fr-BE", .layoutType = ""}}, // BELGIAN
+ {3, RawLayoutInfo{.languageTag = "fr-CA", .layoutType = ""}}, // CANADIAN_BILINGUAL
+ {4, RawLayoutInfo{.languageTag = "fr-CA", .layoutType = ""}}, // CANADIAN_FRENCH
+ {5, RawLayoutInfo{.languageTag = "cs", .layoutType = ""}}, // CZECH_REPUBLIC
+ {6, RawLayoutInfo{.languageTag = "da", .layoutType = ""}}, // DANISH
+ {7, RawLayoutInfo{.languageTag = "fi", .layoutType = ""}}, // FINNISH
+ {8, RawLayoutInfo{.languageTag = "fr-FR", .layoutType = ""}}, // FRENCH
+ {9, RawLayoutInfo{.languageTag = "de", .layoutType = ""}}, // GERMAN
+ {10, RawLayoutInfo{.languageTag = "el", .layoutType = ""}}, // GREEK
+ {11, RawLayoutInfo{.languageTag = "iw", .layoutType = ""}}, // HEBREW
+ {12, RawLayoutInfo{.languageTag = "hu", .layoutType = ""}}, // HUNGARY
+ {13, RawLayoutInfo{.languageTag = "en", .layoutType = "extended"}}, // INTERNATIONAL (ISO)
+ {14, RawLayoutInfo{.languageTag = "it", .layoutType = ""}}, // ITALIAN
+ {15, RawLayoutInfo{.languageTag = "ja", .layoutType = ""}}, // JAPAN
+ {16, RawLayoutInfo{.languageTag = "ko", .layoutType = ""}}, // KOREAN
+ {17, RawLayoutInfo{.languageTag = "es-419", .layoutType = ""}}, // LATIN_AMERICA
+ {18, RawLayoutInfo{.languageTag = "nl", .layoutType = ""}}, // DUTCH
+ {19, RawLayoutInfo{.languageTag = "nb", .layoutType = ""}}, // NORWEGIAN
+ {20, RawLayoutInfo{.languageTag = "fa", .layoutType = ""}}, // PERSIAN
+ {21, RawLayoutInfo{.languageTag = "pl", .layoutType = ""}}, // POLAND
+ {22, RawLayoutInfo{.languageTag = "pt", .layoutType = ""}}, // PORTUGUESE
+ {23, RawLayoutInfo{.languageTag = "ru", .layoutType = ""}}, // RUSSIA
+ {24, RawLayoutInfo{.languageTag = "sk", .layoutType = ""}}, // SLOVAKIA
+ {25, RawLayoutInfo{.languageTag = "es-ES", .layoutType = ""}}, // SPANISH
+ {26, RawLayoutInfo{.languageTag = "sv", .layoutType = ""}}, // SWEDISH
+ {27, RawLayoutInfo{.languageTag = "fr-CH", .layoutType = ""}}, // SWISS_FRENCH
+ {28, RawLayoutInfo{.languageTag = "de-CH", .layoutType = ""}}, // SWISS_GERMAN
+ {29, RawLayoutInfo{.languageTag = "de-CH", .layoutType = ""}}, // SWITZERLAND
+ {30, RawLayoutInfo{.languageTag = "zh-TW", .layoutType = ""}}, // TAIWAN
+ {31, RawLayoutInfo{.languageTag = "tr", .layoutType = "turkish_q"}}, // TURKISH_Q
+ {32, RawLayoutInfo{.languageTag = "en-GB", .layoutType = ""}}, // UK
+ {33, RawLayoutInfo{.languageTag = "en-US", .layoutType = ""}}, // US
+ {34, RawLayoutInfo{.languageTag = "", .layoutType = ""}}, // YUGOSLAVIA
+ {35, RawLayoutInfo{.languageTag = "tr", .layoutType = "turkish_f"}}}; // TURKISH_F
+
static std::string sha1(const std::string& in) {
SHA_CTX ctx;
SHA1_Init(&ctx);
@@ -311,22 +350,27 @@
}
/**
- * Read country code information exposed through the sysfs path.
+ * Read country code information exposed through the sysfs path and convert it to Layout info.
*/
-static InputDeviceCountryCode readCountryCodeLocked(const std::filesystem::path& sysfsRootPath) {
+static std::optional<RawLayoutInfo> readLayoutConfiguration(
+ const std::filesystem::path& sysfsRootPath) {
// Check the sysfs root path
- int hidCountryCode = static_cast<int>(InputDeviceCountryCode::INVALID);
+ int32_t hidCountryCode = -1;
std::string str;
if (base::ReadFileToString(sysfsRootPath / "country", &str)) {
hidCountryCode = std::stoi(str, nullptr, 16);
+ // Update this condition if new supported country codes are added to HID spec.
if (hidCountryCode > 35 || hidCountryCode < 0) {
ALOGE("HID country code should be in range [0, 35], but for sysfs path %s it was %d",
sysfsRootPath.c_str(), hidCountryCode);
- return InputDeviceCountryCode::INVALID;
}
}
+ const auto it = LAYOUT_INFOS.find(hidCountryCode);
+ if (it != LAYOUT_INFOS.end()) {
+ return it->second;
+ }
- return static_cast<InputDeviceCountryCode>(hidCountryCode);
+ return std::nullopt;
}
/**
@@ -1299,13 +1343,13 @@
}
}
-InputDeviceCountryCode EventHub::getCountryCode(int32_t deviceId) const {
+std::optional<RawLayoutInfo> EventHub::getRawLayoutInfo(int32_t deviceId) const {
std::scoped_lock _l(mLock);
Device* device = getDeviceLocked(deviceId);
if (device == nullptr || !device->associatedDevice) {
- return InputDeviceCountryCode::INVALID;
+ return std::nullopt;
}
- return device->associatedDevice->countryCode;
+ return device->associatedDevice->layoutInfo;
}
void EventHub::setExcludedDevices(const std::vector<std::string>& devices) {
@@ -1449,9 +1493,9 @@
std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
AssociatedDevice{.sysfsRootPath = path,
- .countryCode = readCountryCodeLocked(path),
.batteryInfos = readBatteryConfiguration(path),
- .lightInfos = readLightsConfiguration(path)});
+ .lightInfos = readLightsConfiguration(path),
+ .layoutInfo = readLayoutConfiguration(path)});
bool associatedDeviceChanged = false;
for (const auto& [id, dev] : mDevices) {
@@ -2686,9 +2730,12 @@
device->keyMap.keyLayoutFile.c_str());
dump += StringPrintf(INDENT3 "KeyCharacterMapFile: %s\n",
device->keyMap.keyCharacterMapFile.c_str());
- dump += StringPrintf(INDENT3 "CountryCode: %d\n",
- device->associatedDevice ? device->associatedDevice->countryCode
- : InputDeviceCountryCode::INVALID);
+ if (device->associatedDevice && device->associatedDevice->layoutInfo) {
+ dump += StringPrintf(INDENT3 "LanguageTag: %s\n",
+ device->associatedDevice->layoutInfo->languageTag.c_str());
+ dump += StringPrintf(INDENT3 "LayoutType: %s\n",
+ device->associatedDevice->layoutInfo->layoutType.c_str());
+ }
dump += StringPrintf(INDENT3 "ConfigurationFile: %s\n",
device->configurationFile.c_str());
dump += StringPrintf(INDENT3 "VideoDevice: %s\n",
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 13f40ee..6e78e82 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -37,8 +37,6 @@
#include "TouchpadInputMapper.h"
#include "VibratorInputMapper.h"
-using android::hardware::input::InputDeviceCountryCode;
-
namespace android {
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
@@ -256,7 +254,6 @@
mSources = 0;
mClasses = ftl::Flags<InputDeviceClass>(0);
mControllerNumber = 0;
- mCountryCode = InputDeviceCountryCode::INVALID;
for_each_subdevice([this](InputDeviceContext& context) {
mClasses |= context.getDeviceClasses();
@@ -268,16 +265,6 @@
}
mControllerNumber = controllerNumber;
}
-
- InputDeviceCountryCode countryCode = context.getCountryCode();
- if (countryCode != InputDeviceCountryCode::INVALID) {
- if (mCountryCode != InputDeviceCountryCode::INVALID && mCountryCode != countryCode) {
- ALOGW("InputDevice::configure(): %s device contains multiple unique country "
- "codes",
- getName().c_str());
- }
- mCountryCode = countryCode;
- }
});
mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
@@ -465,7 +452,7 @@
InputDeviceInfo InputDevice::getDeviceInfo() {
InputDeviceInfo outDeviceInfo;
outDeviceInfo.initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
- mHasMic, mCountryCode);
+ mHasMic);
for_each_mapper(
[&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(&outDeviceInfo); });
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 8a844b2..a3ecf41 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -42,7 +42,6 @@
#include "TouchVideoDevice.h"
#include "VibrationElement.h"
-#include "android/hardware/input/InputDeviceCountryCode.h"
struct inotify_event;
@@ -207,6 +206,15 @@
bool operator!=(const RawBatteryInfo&) const = default;
};
+/* Layout information associated with the device */
+struct RawLayoutInfo {
+ std::string languageTag;
+ std::string layoutType;
+
+ bool operator==(const RawLayoutInfo&) const = default;
+ bool operator!=(const RawLayoutInfo&) const = default;
+};
+
/*
* Gets the class that owns an axis, in cases where multiple classes might claim
* the same axis for different purposes.
@@ -308,8 +316,8 @@
int32_t deviceId, int32_t lightId) const = 0;
virtual void setLightIntensities(int32_t deviceId, int32_t lightId,
std::unordered_map<LightColor, int32_t> intensities) = 0;
- /* Query Country code associated with the input device. */
- virtual hardware::input::InputDeviceCountryCode getCountryCode(int32_t deviceId) const = 0;
+ /* Query Layout info associated with the input device. */
+ virtual std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const = 0;
/* Query current input state. */
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
@@ -493,7 +501,7 @@
void setLightIntensities(int32_t deviceId, int32_t lightId,
std::unordered_map<LightColor, int32_t> intensities) override final;
- hardware::input::InputDeviceCountryCode getCountryCode(int32_t deviceId) const override final;
+ std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override final;
void setExcludedDevices(const std::vector<std::string>& devices) override final;
@@ -556,9 +564,9 @@
struct AssociatedDevice {
// The sysfs root path of the misc device.
std::filesystem::path sysfsRootPath;
- hardware::input::InputDeviceCountryCode countryCode;
std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
+ std::optional<RawLayoutInfo> layoutInfo;
bool operator==(const AssociatedDevice&) const = default;
bool operator!=(const AssociatedDevice&) const = default;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index b173618..7867029 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -167,7 +167,6 @@
int32_t mId;
int32_t mGeneration;
int32_t mControllerNumber;
- hardware::input::InputDeviceCountryCode mCountryCode;
InputDeviceIdentifier mIdentifier;
std::string mAlias;
ftl::Flags<InputDeviceClass> mClasses;
@@ -326,9 +325,6 @@
}
inline std::vector<TouchVideoFrame> getVideoFrames() { return mEventHub->getVideoFrames(mId); }
- inline hardware::input::InputDeviceCountryCode getCountryCode() const {
- return mEventHub->getCountryCode(mId);
- }
inline int32_t getScanCodeState(int32_t scanCode) const {
return mEventHub->getScanCodeState(mId, scanCode);
}
@@ -361,6 +357,9 @@
inline bool setKeyboardLayoutOverlay(std::shared_ptr<KeyCharacterMap> map) {
return mEventHub->setKeyboardLayoutOverlay(mId, map);
}
+ inline const std::optional<RawLayoutInfo> getRawLayoutInfo() {
+ return mEventHub->getRawLayoutInfo(mId);
+ }
inline void vibrate(const VibrationElement& element) {
return mEventHub->vibrate(mId, element);
}
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 6f01449..d147d60 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -123,6 +123,12 @@
if (mKeyboardLayoutInfo) {
info->setKeyboardLayoutInfo(*mKeyboardLayoutInfo);
+ } else {
+ std::optional<RawLayoutInfo> layoutInfo = getDeviceContext().getRawLayoutInfo();
+ if (layoutInfo) {
+ info->setKeyboardLayoutInfo(
+ KeyboardLayoutInfo(layoutInfo->languageTag, layoutInfo->layoutType));
+ }
}
}
diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp
index 289a780..6ac0bfb 100644
--- a/services/inputflinger/tests/FakeEventHub.cpp
+++ b/services/inputflinger/tests/FakeEventHub.cpp
@@ -120,8 +120,8 @@
getDevice(deviceId)->keyCodeStates.replaceValueFor(keyCode, state);
}
-void FakeEventHub::setCountryCode(int32_t deviceId, InputDeviceCountryCode countryCode) {
- getDevice(deviceId)->countryCode = countryCode;
+void FakeEventHub::setRawLayoutInfo(int32_t deviceId, RawLayoutInfo info) {
+ getDevice(deviceId)->layoutInfo = info;
}
void FakeEventHub::setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
@@ -389,9 +389,9 @@
return AKEY_STATE_UNKNOWN;
}
-InputDeviceCountryCode FakeEventHub::getCountryCode(int32_t deviceId) const {
+std::optional<RawLayoutInfo> FakeEventHub::getRawLayoutInfo(int32_t deviceId) const {
Device* device = getDevice(deviceId);
- return device ? device->countryCode : InputDeviceCountryCode::INVALID;
+ return device ? device->layoutInfo : std::nullopt;
}
int32_t FakeEventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h
index fb3c859..72f8ac0 100644
--- a/services/inputflinger/tests/FakeEventHub.h
+++ b/services/inputflinger/tests/FakeEventHub.h
@@ -30,10 +30,6 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
-#include "android/hardware/input/InputDeviceCountryCode.h"
-
-using android::hardware::input::InputDeviceCountryCode;
-
namespace android {
class FakeEventHub : public EventHubInterface {
@@ -67,7 +63,7 @@
BitArray<MSC_MAX> mscBitmask;
std::vector<VirtualKeyDefinition> virtualKeys;
bool enabled;
- InputDeviceCountryCode countryCode;
+ std::optional<RawLayoutInfo> layoutInfo;
status_t enable() {
enabled = true;
@@ -124,7 +120,7 @@
void addRelativeAxis(int32_t deviceId, int32_t axis);
void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value);
- void setCountryCode(int32_t deviceId, InputDeviceCountryCode countryCode);
+ void setRawLayoutInfo(int32_t deviceId, RawLayoutInfo info);
void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state);
void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state);
@@ -180,7 +176,7 @@
std::vector<RawEvent> getEvents(int) override;
std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override;
int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override;
- InputDeviceCountryCode getCountryCode(int32_t deviceId) const override;
+ std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override;
int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override;
int32_t getSwitchState(int32_t deviceId, int32_t sw) const override;
status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const override;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 96d27b8..a464639 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -48,12 +48,9 @@
#include "InputMapperTest.h"
#include "InstrumentedInputReader.h"
#include "TestConstants.h"
-#include "android/hardware/input/InputDeviceCountryCode.h"
#include "input/DisplayViewport.h"
#include "input/Input.h"
-using android::hardware::input::InputDeviceCountryCode;
-
namespace android {
using namespace ftl::flag_operators;
@@ -2240,17 +2237,6 @@
ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
}
-TEST_F(InputDeviceTest, CountryCodeCorrectlyMapped) {
- mFakeEventHub->setCountryCode(EVENTHUB_ID, InputDeviceCountryCode::INTERNATIONAL);
-
- // Configuration
- mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
- InputReaderConfiguration config;
- std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
-
- ASSERT_EQ(InputDeviceCountryCode::INTERNATIONAL, mDevice->getDeviceInfo().getCountryCode());
-}
-
TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
ASSERT_EQ(mDevice->isEnabled(), false);
}
@@ -3600,6 +3586,20 @@
deviceInfo.getKeyboardLayoutInfo()->layoutType);
}
+TEST_F(KeyboardInputMapperTest, LayoutInfoCorrectlyMapped) {
+ mFakeEventHub->setRawLayoutInfo(EVENTHUB_ID,
+ RawLayoutInfo{.languageTag = "en", .layoutType = "extended"});
+
+ // Configuration
+ addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+ InputReaderConfiguration config;
+ std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
+
+ ASSERT_EQ("en", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->languageTag);
+ ASSERT_EQ("extended", mDevice->getDeviceInfo().getKeyboardLayoutInfo()->layoutType);
+}
+
// --- KeyboardInputMapperTest_ExternalDevice ---
class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index a0910ea..7c9be5c 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -19,9 +19,6 @@
#include <InputMapper.h>
#include <InputReader.h>
#include <ThreadSafeFuzzedDataProvider.h>
-#include "android/hardware/input/InputDeviceCountryCode.h"
-
-using android::hardware::input::InputDeviceCountryCode;
constexpr size_t kValidTypes[] = {EV_SW,
EV_SYN,
@@ -65,46 +62,6 @@
BTN_TASK,
};
-constexpr InputDeviceCountryCode kCountryCodes[] = {
- InputDeviceCountryCode::INVALID,
- InputDeviceCountryCode::NOT_SUPPORTED,
- InputDeviceCountryCode::ARABIC,
- InputDeviceCountryCode::BELGIAN,
- InputDeviceCountryCode::CANADIAN_BILINGUAL,
- InputDeviceCountryCode::CANADIAN_FRENCH,
- InputDeviceCountryCode::CZECH_REPUBLIC,
- InputDeviceCountryCode::DANISH,
- InputDeviceCountryCode::FINNISH,
- InputDeviceCountryCode::FRENCH,
- InputDeviceCountryCode::GERMAN,
- InputDeviceCountryCode::GREEK,
- InputDeviceCountryCode::HEBREW,
- InputDeviceCountryCode::HUNGARY,
- InputDeviceCountryCode::INTERNATIONAL,
- InputDeviceCountryCode::ITALIAN,
- InputDeviceCountryCode::JAPAN,
- InputDeviceCountryCode::KOREAN,
- InputDeviceCountryCode::LATIN_AMERICAN,
- InputDeviceCountryCode::DUTCH,
- InputDeviceCountryCode::NORWEGIAN,
- InputDeviceCountryCode::PERSIAN,
- InputDeviceCountryCode::POLAND,
- InputDeviceCountryCode::PORTUGUESE,
- InputDeviceCountryCode::RUSSIA,
- InputDeviceCountryCode::SLOVAKIA,
- InputDeviceCountryCode::SPANISH,
- InputDeviceCountryCode::SWEDISH,
- InputDeviceCountryCode::SWISS_FRENCH,
- InputDeviceCountryCode::SWISS_GERMAN,
- InputDeviceCountryCode::SWITZERLAND,
- InputDeviceCountryCode::TAIWAN,
- InputDeviceCountryCode::TURKISH_Q,
- InputDeviceCountryCode::UK,
- InputDeviceCountryCode::US,
- InputDeviceCountryCode::YUGOSLAVIA,
- InputDeviceCountryCode::TURKISH_F,
-};
-
constexpr size_t kMaxSize = 256;
namespace android {
@@ -197,8 +154,8 @@
void setLightIntensities(int32_t deviceId, int32_t lightId,
std::unordered_map<LightColor, int32_t> intensities) override{};
- InputDeviceCountryCode getCountryCode(int32_t deviceId) const override {
- return mFdp->PickValueInArray<InputDeviceCountryCode>(kCountryCodes);
+ std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override {
+ return std::nullopt;
};
int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 2a5bfae..b86782f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -137,6 +137,7 @@
HwcBufferCache hwcBufferCache;
// The previously-active buffer for this layer.
+ uint64_t activeBufferId;
uint32_t activeBufferSlot;
// Set to true when overridden info has been sent to HW composer
diff --git a/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp b/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
index 34ed214..f0105b2 100644
--- a/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
@@ -28,11 +28,6 @@
}
HwcSlotAndBuffer HwcBufferCache::getHwcSlotAndBuffer(const sp<GraphicBuffer>& buffer) {
- // TODO(b/261930578): This is for unit tests which don't mock GraphicBuffers but instead send
- // in nullptrs.
- if (buffer == nullptr) {
- return {0, nullptr};
- }
if (auto i = mCacheByBufferId.find(buffer->getId()); i != mCacheByBufferId.end()) {
Cache& cache = i->second;
// mark this cache slot as more recently used so it won't get evicted anytime soon
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 766d7ea..60a2c83 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -617,13 +617,24 @@
return;
}
+ // Uncache the active buffer last so that it's the first buffer to be purged from the cache
+ // next time a buffer is sent to this layer.
+ bool uncacheActiveBuffer = false;
+
std::vector<uint32_t> slotsToClear;
for (uint64_t bufferId : bufferIdsToUncache) {
- uint32_t slot = state.hwc->hwcBufferCache.uncache(bufferId);
- if (slot != UINT32_MAX) {
- slotsToClear.push_back(slot);
+ if (bufferId == state.hwc->activeBufferId) {
+ uncacheActiveBuffer = true;
+ } else {
+ uint32_t slot = state.hwc->hwcBufferCache.uncache(bufferId);
+ if (slot != UINT32_MAX) {
+ slotsToClear.push_back(slot);
+ }
}
}
+ if (uncacheActiveBuffer) {
+ slotsToClear.push_back(state.hwc->hwcBufferCache.uncache(state.hwc->activeBufferId));
+ }
hal::Error error =
state.hwc->hwcLayer->setBufferSlotsToClear(slotsToClear, state.hwc->activeBufferSlot);
@@ -655,17 +666,20 @@
hwcSlotAndBuffer = state.hwc->hwcBufferCache.getOverrideHwcSlotAndBuffer(
state.overrideInfo.buffer->getBuffer());
hwcFence = state.overrideInfo.acquireFence;
+ // Keep track of the active buffer ID so when it's discarded we uncache it last so its
+ // slot will be used first, allowing the memory to be freed as soon as possible.
+ state.hwc->activeBufferId = state.overrideInfo.buffer->getBuffer()->getId();
} else {
hwcSlotAndBuffer =
state.hwc->hwcBufferCache.getHwcSlotAndBuffer(outputIndependentState.buffer);
hwcFence = outputIndependentState.acquireFence;
+ // Keep track of the active buffer ID so when it's discarded we uncache it last so its
+ // slot will be used first, allowing the memory to be freed as soon as possible.
+ state.hwc->activeBufferId = outputIndependentState.buffer->getId();
}
-
// Keep track of the active buffer slot, so we can restore it after clearing other buffer
// slots.
- if (hwcSlotAndBuffer.buffer) {
- state.hwc->activeBufferSlot = hwcSlotAndBuffer.slot;
- }
+ state.hwc->activeBufferSlot = hwcSlotAndBuffer.slot;
}
if (auto error = hwcLayer->setBuffer(hwcSlotAndBuffer.slot, hwcSlotAndBuffer.buffer, hwcFence);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 0edc226..9ad2edb 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -1318,6 +1318,7 @@
struct OutputLayerUncacheBufferTest : public OutputLayerTest {
static const sp<GraphicBuffer> kBuffer1;
static const sp<GraphicBuffer> kBuffer2;
+ static const sp<GraphicBuffer> kBuffer3;
static const sp<Fence> kFence;
OutputLayerUncacheBufferTest() {
@@ -1343,6 +1344,10 @@
sp<GraphicBuffer>::make(2, 3, PIXEL_FORMAT_RGBA_8888,
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
+const sp<GraphicBuffer> OutputLayerUncacheBufferTest::kBuffer3 =
+ sp<GraphicBuffer>::make(4, 5, PIXEL_FORMAT_RGBA_8888,
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+ AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
const sp<Fence> OutputLayerUncacheBufferTest::kFence = sp<Fence>::make();
TEST_F(OutputLayerUncacheBufferTest, canUncacheAndReuseSlot) {
@@ -1360,26 +1365,38 @@
/*zIsOverridden*/ false, /*isPeekingThrough*/ false);
Mock::VerifyAndClearExpectations(&mHwcLayer);
- // buffer slots are cleared in HWC
- std::vector<uint32_t> slotsToClear = {0, 1};
- EXPECT_CALL(mHwcLayer,
- setBufferSlotsToClear(/*slotsToClear*/ slotsToClear, /*activeBufferSlot*/ 1));
- mOutputLayer.uncacheBuffers({kBuffer1->getId(), kBuffer2->getId()});
+ // Buffer3 is stored in slot 2
+ mLayerFEState.buffer = kBuffer3;
+ EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 2, kBuffer3, kFence));
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
Mock::VerifyAndClearExpectations(&mHwcLayer);
- // rather than allocating a new slot, the active buffer slot (slot 1) is reused first to free
- // the memory as soon as possible
+ // Buffer2 becomes the active buffer again (with a nullptr) and reuses slot 1
+ mLayerFEState.buffer = kBuffer2;
+ sp<GraphicBuffer> nullBuffer = nullptr;
+ EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, nullBuffer, kFence));
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+ Mock::VerifyAndClearExpectations(&mHwcLayer);
+
+ // Buffer slots are cleared
+ std::vector<uint32_t> slotsToClear = {0, 2, 1}; // order doesn't matter
+ EXPECT_CALL(mHwcLayer, setBufferSlotsToClear(slotsToClear, /*activeBufferSlot*/ 1));
+ // Uncache the active buffer in between other buffers to exercise correct algorithmic behavior.
+ mOutputLayer.uncacheBuffers({kBuffer1->getId(), kBuffer2->getId(), kBuffer3->getId()});
+ Mock::VerifyAndClearExpectations(&mHwcLayer);
+
+ // Buffer1 becomes active again, and rather than allocating a new slot, or re-using slot 0,
+ // the active buffer slot (slot 1 for Buffer2) is reused first, which allows HWC to free the
+ // memory for the active buffer. Note: slot 1 is different from the first and last buffer slot
+ // requested to be cleared in slotsToClear (slot 1), above, indicating that the algorithm
+ // correctly identifies the active buffer as the buffer in slot 1, despite ping-ponging.
mLayerFEState.buffer = kBuffer1;
EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, kBuffer1, kFence));
mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false);
Mock::VerifyAndClearExpectations(&mHwcLayer);
-
- // rather than allocating a new slot, slot 0 is reused
- mLayerFEState.buffer = kBuffer2;
- EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 0, kBuffer2, kFence));
- mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
- /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
}
/*
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index f1a6c0e..ab98dbf 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -27,7 +27,6 @@
#include <log/log.h>
#include <mock/MockEventThread.h>
#include <renderengine/ExternalTexture.h>
-#include <renderengine/mock/FakeExternalTexture.h>
#include <renderengine/mock/RenderEngine.h>
#include <utils/String16.h>
#include <string>
@@ -95,6 +94,30 @@
}
};
+class FakeExternalTexture : public renderengine::ExternalTexture {
+ const sp<GraphicBuffer> mNullBuffer = nullptr;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint64_t mId;
+ PixelFormat mPixelFormat;
+ uint64_t mUsage;
+
+public:
+ FakeExternalTexture(uint32_t width, uint32_t height, uint64_t id, PixelFormat pixelFormat,
+ uint64_t usage)
+ : mWidth(width), mHeight(height), mId(id), mPixelFormat(pixelFormat), mUsage(usage) {}
+ const sp<GraphicBuffer>& getBuffer() const { return mNullBuffer; }
+ bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
+ return getId() == other.getId();
+ }
+ uint32_t getWidth() const override { return mWidth; }
+ uint32_t getHeight() const override { return mHeight; }
+ uint64_t getId() const override { return mId; }
+ PixelFormat getPixelFormat() const override { return mPixelFormat; }
+ uint64_t getUsage() const override { return mUsage; }
+ ~FakeExternalTexture() = default;
+};
+
class MockSurfaceFlinger : public SurfaceFlinger {
public:
MockSurfaceFlinger(Factory& factory)
@@ -102,12 +125,10 @@
std::shared_ptr<renderengine::ExternalTexture> getExternalTextureFromBufferData(
BufferData& bufferData, const char* /* layerName */,
uint64_t /* transactionId */) override {
- return std::make_shared<renderengine::mock::FakeExternalTexture>(bufferData.getWidth(),
- bufferData.getHeight(),
- bufferData.getId(),
- bufferData
- .getPixelFormat(),
- bufferData.getUsage());
+ return std::make_shared<FakeExternalTexture>(bufferData.getWidth(), bufferData.getHeight(),
+ bufferData.getId(),
+ bufferData.getPixelFormat(),
+ bufferData.getUsage());
};
// b/220017192 migrate from transact codes to ISurfaceComposer apis
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 06b9caa..ba77600 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -182,7 +182,9 @@
sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
std::vector<sp<Layer>> mAuxiliaryLayers;
- sp<GraphicBuffer> mBuffer = sp<GraphicBuffer>::make();
+ sp<GraphicBuffer> mBuffer =
+ sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
Hwc2::mock::Composer* mComposer = nullptr;
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index d58e644..223f4db 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -115,7 +115,9 @@
TestableSurfaceFlinger mFlinger;
sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
- sp<GraphicBuffer> mBuffer = sp<GraphicBuffer>::make();
+ sp<GraphicBuffer> mBuffer =
+ sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
Hwc2::mock::PowerAdvisor mPowerAdvisor;
FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow};
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index c9fefe3..a78f42c 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -2508,10 +2508,6 @@
// b/190578904
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withCloseRefreshRates_LayerVoteType_Heuristic) {
- if (g_noSlowTests) {
- GTEST_SKIP();
- }
-
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;
@@ -2540,10 +2536,6 @@
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withCloseRefreshRates_LayerVoteType_ExplicitDefault) {
- if (g_noSlowTests) {
- GTEST_SKIP();
- }
-
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;
@@ -2572,10 +2564,6 @@
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withCloseRefreshRates_LayerVoteType_ExplicitExactOrMultiple) {
- if (g_noSlowTests) {
- GTEST_SKIP();
- }
-
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;
@@ -2604,10 +2592,6 @@
}
TEST_P(RefreshRateSelectorTest,
getBestFrameRateMode_withCloseRefreshRates_LayerVoteType_ExplicitExact) {
- if (g_noSlowTests) {
- GTEST_SKIP();
- }
-
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;