Merge "Validate axes and led labels correctly"
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 44ff62b..0aca163 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -375,6 +375,10 @@
return (mDataSize > mDataPos ? mDataSize : mDataPos);
}
+size_t Parcel::dataBufferSize() const {
+ return mDataSize;
+}
+
size_t Parcel::dataAvail() const
{
size_t result = dataSize() - dataPosition();
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 342e4a3..04cb61f 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -52,6 +52,9 @@
"name": "memunreachable_binder_test"
},
{
+ "name": "resolv_integration_test"
+ },
+ {
"name": "libbinderthreadstateutils_test"
},
{
@@ -96,5 +99,19 @@
{
"name": "binderLibTest"
}
+ ],
+ "kernel-presubmit": [
+ {
+ "name": "binderDriverInterfaceTest"
+ },
+ {
+ "name": "binderLibTest"
+ },
+ {
+ "name": "binderSafeInterfaceTest"
+ },
+ {
+ "name": "memunreachable_binder_test"
+ }
]
}
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index f730acb..162cd40 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -75,6 +75,7 @@
size_t dataAvail() const;
size_t dataPosition() const;
size_t dataCapacity() const;
+ size_t dataBufferSize() const;
status_t setDataSize(size_t size);
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 8693022..b5a2e2f 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -695,11 +695,17 @@
if (parcel->get()->objectsCount()) {
return STATUS_INVALID_OPERATION;
}
- int32_t dataSize = AParcel_getDataSize(parcel);
+ // b/264739302 - getDataSize will return dataPos if it is greater than dataSize
+ // which will cause crashes in memcpy at later point. Instead compare with
+ // actual length of internal buffer
+ int32_t dataSize = parcel->get()->dataBufferSize();
if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
return STATUS_BAD_VALUE;
}
const uint8_t* internalBuffer = parcel->get()->data();
+ if (internalBuffer == nullptr) {
+ return STATUS_UNEXPECTED_NULL;
+ }
memcpy(buffer, internalBuffer + start, len);
return STATUS_OK;
}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index a0e61d9..0c8b48f 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -94,14 +94,12 @@
//! ```
#[macro_use]
-mod proxy;
-
-#[macro_use]
mod binder;
mod binder_async;
mod error;
mod native;
mod parcel;
+mod proxy;
mod state;
use binder_ndk_sys as sys;
diff --git a/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
index c5c7719..29bf92c 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
+++ b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
@@ -17,9 +17,6 @@
#![allow(missing_docs)]
#![no_main]
-#[macro_use]
-extern crate libfuzzer_sys;
-
mod read_utils;
use crate::read_utils::READ_FUNCS;
@@ -31,7 +28,7 @@
StatusCode,
};
use binder_random_parcel_rs::create_random_parcel;
-use libfuzzer_sys::arbitrary::Arbitrary;
+use libfuzzer_sys::{arbitrary::Arbitrary, fuzz_target};
#[derive(Arbitrary, Debug)]
enum ReadOperation {
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs
index a427f28..c530382 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs
@@ -16,8 +16,8 @@
#![allow(missing_docs)]
#![no_main]
-#[macro_use]
-extern crate libfuzzer_sys;
+
+use libfuzzer_sys::fuzz_target;
use binder::{self, BinderFeatures, Interface};
use binder_random_parcel_rs::fuzz_service;
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a77ca04..cefb9a7 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -63,7 +63,8 @@
Vector<ComposerState>& state, const Vector<DisplayState>& displays,
uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& commands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const client_cache_t& uncacheBuffer,
+ bool isAutoTimestamp,
+ const std::vector<client_cache_t>& uncacheBuffers,
bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) override {
@@ -87,8 +88,11 @@
SAFE_PARCEL(commands.write, data);
SAFE_PARCEL(data.writeInt64, desiredPresentTime);
SAFE_PARCEL(data.writeBool, isAutoTimestamp);
- SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote());
- SAFE_PARCEL(data.writeUint64, uncacheBuffer.id);
+ SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size()));
+ for (const client_cache_t& uncacheBuffer : uncacheBuffers) {
+ SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote());
+ SAFE_PARCEL(data.writeUint64, uncacheBuffer.id);
+ }
SAFE_PARCEL(data.writeBool, hasListenerCallbacks);
SAFE_PARCEL(data.writeVectorSize, listenerCallbacks);
@@ -158,11 +162,14 @@
SAFE_PARCEL(data.readInt64, &desiredPresentTime);
SAFE_PARCEL(data.readBool, &isAutoTimestamp);
- client_cache_t uncachedBuffer;
+ SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
+ std::vector<client_cache_t> uncacheBuffers(count);
sp<IBinder> tmpBinder;
- SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder);
- uncachedBuffer.token = tmpBinder;
- SAFE_PARCEL(data.readUint64, &uncachedBuffer.id);
+ for (size_t i = 0; i < count; i++) {
+ SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder);
+ uncacheBuffers[i].token = tmpBinder;
+ SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id);
+ }
bool hasListenerCallbacks = false;
SAFE_PARCEL(data.readBool, &hasListenerCallbacks);
@@ -182,7 +189,7 @@
return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken,
inputWindowCommands, desiredPresentTime, isAutoTimestamp,
- uncachedBuffer, hasListenerCallbacks, listenerCallbacks,
+ uncacheBuffers, hasListenerCallbacks, listenerCallbacks,
transactionId);
}
default: {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 92125ea..21a7f78 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -565,11 +565,13 @@
return NO_ERROR;
}
- uint64_t cache(const sp<GraphicBuffer>& buffer) {
+ uint64_t cache(const sp<GraphicBuffer>& buffer,
+ std::optional<client_cache_t>& outUncacheBuffer) {
std::lock_guard<std::mutex> lock(mMutex);
if (mBuffers.size() >= BUFFER_CACHE_MAX_SIZE) {
- evictLeastRecentlyUsedBuffer();
+ outUncacheBuffer = findLeastRecentlyUsedBuffer();
+ mBuffers.erase(outUncacheBuffer->id);
}
buffer->addDeathCallback(removeDeadBufferCallback, nullptr);
@@ -580,16 +582,13 @@
void uncache(uint64_t cacheId) {
std::lock_guard<std::mutex> lock(mMutex);
- uncacheLocked(cacheId);
- }
-
- void uncacheLocked(uint64_t cacheId) REQUIRES(mMutex) {
- mBuffers.erase(cacheId);
- SurfaceComposerClient::doUncacheBufferTransaction(cacheId);
+ if (mBuffers.erase(cacheId)) {
+ SurfaceComposerClient::doUncacheBufferTransaction(cacheId);
+ }
}
private:
- void evictLeastRecentlyUsedBuffer() REQUIRES(mMutex) {
+ client_cache_t findLeastRecentlyUsedBuffer() REQUIRES(mMutex) {
auto itr = mBuffers.begin();
uint64_t minCounter = itr->second;
auto minBuffer = itr;
@@ -603,7 +602,8 @@
}
itr++;
}
- uncacheLocked(minBuffer->first);
+
+ return {.token = getToken(), .id = minBuffer->first};
}
uint64_t getCounter() REQUIRES(mMutex) {
@@ -741,6 +741,18 @@
InputWindowCommands inputWindowCommands;
inputWindowCommands.read(*parcel);
+ count = static_cast<size_t>(parcel->readUint32());
+ if (count > parcel->dataSize()) {
+ return BAD_VALUE;
+ }
+ std::vector<client_cache_t> uncacheBuffers(count);
+ for (size_t i = 0; i < count; i++) {
+ sp<IBinder> tmpBinder;
+ SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder);
+ uncacheBuffers[i].token = tmpBinder;
+ SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id);
+ }
+
// Parsing was successful. Update the object.
mId = transactionId;
mTransactionNestCount = transactionNestCount;
@@ -755,6 +767,7 @@
mComposerStates = composerStates;
mInputWindowCommands = inputWindowCommands;
mApplyToken = applyToken;
+ mUncacheBuffers = std::move(uncacheBuffers);
return NO_ERROR;
}
@@ -806,6 +819,13 @@
}
mInputWindowCommands.write(*parcel);
+
+ SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size()));
+ for (const client_cache_t& uncacheBuffer : mUncacheBuffers) {
+ SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote());
+ SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id);
+ }
+
return NO_ERROR;
}
@@ -873,6 +893,10 @@
}
}
+ for (const auto& cacheId : other.mUncacheBuffers) {
+ mUncacheBuffers.push_back(cacheId);
+ }
+
mInputWindowCommands.merge(other.mInputWindowCommands);
mMayContainBuffer |= other.mMayContainBuffer;
@@ -891,6 +915,7 @@
mDisplayStates.clear();
mListenerCallbacks.clear();
mInputWindowCommands.clear();
+ mUncacheBuffers.clear();
mMayContainBuffer = false;
mTransactionNestCount = 0;
mAnimation = false;
@@ -913,10 +938,10 @@
uncacheBuffer.token = BufferCache::getInstance().getToken();
uncacheBuffer.id = cacheId;
Vector<ComposerState> composerStates;
- status_t status =
- sf->setTransactionState(FrameTimelineInfo{}, composerStates, {},
- ISurfaceComposer::eOneWay, Transaction::getDefaultApplyToken(),
- {}, systemTime(), true, uncacheBuffer, false, {}, generateId());
+ status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, {},
+ ISurfaceComposer::eOneWay,
+ Transaction::getDefaultApplyToken(), {}, systemTime(),
+ true, {uncacheBuffer}, false, {}, generateId());
if (status != NO_ERROR) {
ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s",
strerror(-status));
@@ -954,7 +979,11 @@
s->bufferData->buffer = nullptr;
} else {
// Cache-miss. Include the buffer and send the new cacheId.
- cacheId = BufferCache::getInstance().cache(s->bufferData->buffer);
+ std::optional<client_cache_t> uncacheBuffer;
+ cacheId = BufferCache::getInstance().cache(s->bufferData->buffer, uncacheBuffer);
+ if (uncacheBuffer) {
+ mUncacheBuffers.push_back(*uncacheBuffer);
+ }
}
s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged;
s->bufferData->cachedBuffer.token = BufferCache::getInstance().getToken();
@@ -1087,8 +1116,7 @@
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
- {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
- hasListenerCallbacks, listenerCallbacks, mId);
+ mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId);
mId = generateId();
// Clear the current states and flags
diff --git a/libs/gui/aidl/android/gui/OverlayProperties.aidl b/libs/gui/aidl/android/gui/OverlayProperties.aidl
index 1af5746..5fb1a83 100644
--- a/libs/gui/aidl/android/gui/OverlayProperties.aidl
+++ b/libs/gui/aidl/android/gui/OverlayProperties.aidl
@@ -20,7 +20,9 @@
parcelable OverlayProperties {
parcelable SupportedBufferCombinations {
int[] pixelFormats;
- int[] dataspaces;
+ int[] standards;
+ int[] transfers;
+ int[] ranges;
}
SupportedBufferCombinations[] combinations;
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 045cc2a..ae56f9f 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -113,8 +113,9 @@
const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) = 0;
+ bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer,
+ bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
+ uint64_t transactionId) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 2458a40..0e51dcf 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -402,6 +402,7 @@
SortedVector<DisplayState> mDisplayStates;
std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
mListenerCallbacks;
+ std::vector<client_cache_t> mUncacheBuffers;
uint64_t mId;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 3014804..32d60cd 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -701,7 +701,7 @@
const sp<IBinder>& /*applyToken*/,
const InputWindowCommands& /*inputWindowCommands*/,
int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
- const client_cache_t& /*cachedBuffer*/,
+ const std::vector<client_cache_t>& /*cachedBuffer*/,
bool /*hasListenerCallbacks*/,
const std::vector<ListenerCallbacks>& /*listenerCallbacks*/,
uint64_t /*transactionId*/) override {
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
index 164ea64..8b2672f 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
#define ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
+#include <jpegrecoverymap/recoverymap.h>
+
#include <sstream>
#include <stdint.h>
#include <string>
@@ -26,6 +28,26 @@
struct jpegr_metadata;
+// If the EXIF package doesn't exist in the input JPEG, we'll create one with one entry
+// where the length is represented by this value.
+const size_t PSEUDO_EXIF_PACKAGE_LENGTH = 28;
+// If the EXIF package exists in the input JPEG, we'll add an "JR" entry where the length is
+// represented by this value.
+const size_t EXIF_J_R_ENTRY_LENGTH = 12;
+
+/*
+ * Helper function used for writing data to destination.
+ *
+ * @param destination destination of the data to be written.
+ * @param source source of data being written.
+ * @param length length of the data to be written.
+ * @param position cursor in desitination where the data is to be written.
+ * @return status of succeed or error code.
+ */
+status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position);
+status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position);
+
+
/*
* Parses XMP packet and fills metadata with data from XMP
*
@@ -83,6 +105,83 @@
* @return XMP metadata in type of string
*/
std::string generateXmp(int secondary_image_length, jpegr_metadata& metadata);
+
+/*
+ * Add J R entry to existing exif, or create a new one with J R entry if it's null.
+ * EXIF syntax / change:
+ * ori:
+ * FF E1 - APP1
+ * 01 FC - size of APP1 (to be calculated)
+ * -----------------------------------------------------
+ * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
+ * 49 49 2A 00 - TIFF Header
+ * 08 00 00 00 - offset to the IFD (image file directory)
+ * 06 00 - 6 entries
+ * 00 01 - Width Tag
+ * 03 00 - 'Short' type
+ * 01 00 00 00 - 1 component
+ * 00 05 00 00 - image with 0x500
+ *--------------------------------------------------------------------------
+ * new:
+ * FF E1 - APP1
+ * 02 08 - new size, equals to old size + EXIF_J_R_ENTRY_LENGTH (12)
+ *-----------------------------------------------------
+ * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
+ * 49 49 2A 00 - TIFF Header
+ * 08 00 00 00 - offset to the IFD (image file directory)
+ * 07 00 - +1 entry
+ * 4A 52 Custom ('J''R') Tag
+ * 07 00 - Unknown type
+ * 01 00 00 00 - 1 component
+ * 00 00 00 00 - empty data
+ * 00 01 - Width Tag
+ * 03 00 - 'Short' type
+ * 01 00 00 00 - 1 component
+ * 00 05 00 00 - image with 0x500
+ */
+status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest);
+
+/*
+ * Modify offsets in EXIF in place.
+ *
+ * Each tag has the following structure:
+ *
+ * 00 01 - Tag
+ * 03 00 - data format
+ * 01 00 00 00 - number of components
+ * 00 05 00 00 - value
+ *
+ * The value means offset if
+ * (1) num_of_components * bytes_per_component > 4 bytes, or
+ * (2) tag == 0x8769 (ExifOffset).
+ * In both cases, the method will add EXIF_J_R_ENTRY_LENGTH (12) to the offsets.
+ */
+void updateExifOffsets(jr_exif_ptr exif, int pos, bool use_big_endian);
+void updateExifOffsets(jr_exif_ptr exif, int pos, int num_entry, bool use_big_endian);
+
+/*
+ * Read data from the target position and target length in bytes;
+ */
+int readValue(uint8_t* data, int pos, int length, bool use_big_endian);
+
+/*
+ * Returns the length of data format in bytes
+ *
+ * ----------------------------------------------------------------------------------------------
+ * | value | 1 | 2 | 3 | 4 |
+ * | format | unsigned byte | ascii strings | unsigned short | unsigned long |
+ * | bytes/component | 1 | 1 | 2 | 4 |
+ * ----------------------------------------------------------------------------------------------
+ * | value | 5 | 6 | 7 | 8 |
+ * | format |unsigned rational| signed byte | undefined | signed short |
+ * | bytes/component | 8 | 1 | 1 | 2 |
+ * ----------------------------------------------------------------------------------------------
+ * | value | 9 | 10 | 11 | 12 |
+ * | format | signed long | signed rational | single float | double float |
+ * | bytes/component | 4 | 8 | 4 | 8 |
+ * ----------------------------------------------------------------------------------------------
+ */
+int findFormatLengthInBytes(int data_format);
}
#endif //ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index eb557e5..22289de 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -94,135 +94,6 @@
}
/*
- * Helper function used for writing data to destination.
- *
- * @param destination destination of the data to be written.
- * @param source source of data being written.
- * @param length length of the data to be written.
- * @param position cursor in desitination where the data is to be written.
- * @return status of succeed or error code.
- */
-status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position) {
- if (position + length > destination->maxLength) {
- return ERROR_JPEGR_BUFFER_TOO_SMALL;
- }
-
- memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
- position += length;
- return NO_ERROR;
-}
-
-status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position) {
- memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
- position += length;
- return NO_ERROR;
-}
-
-// If the EXIF package doesn't exist in the input JPEG, we'll create one with one entry
-// where the length is represented by this value.
-const size_t PSEUDO_EXIF_PACKAGE_LENGTH = 28;
-// If the EXIF package exists in the input JPEG, we'll add an "JR" entry where the length is
-// represented by this value.
-const size_t EXIF_J_R_ENTRY_LENGTH = 12;
-
-/*
- * Helper function
- * Add J R entry to existing exif, or create a new one with J R entry if it's null.
- * EXIF syntax / change:
- * ori:
- * FF E1 - APP1
- * 01 FC - size of APP1 (to be calculated)
- * -----------------------------------------------------
- * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
- * 49 49 2A 00 - TIFF Header
- * 08 00 00 00 - offset to the IFD (image file directory)
- * 06 00 - 6 entries
- * 00 01 - Width Tag
- * 03 00 - 'Short' type
- * 01 00 00 00 - one entry
- * 00 05 00 00 - image with 0x500
- *--------------------------------------------------------------------------
- * new:
- * FF E1 - APP1
- * 02 08 - new size, equals to old size + EXIF_J_R_ENTRY_LENGTH (12)
- *-----------------------------------------------------
- * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
- * 49 49 2A 00 - TIFF Header
- * 08 00 00 00 - offset to the IFD (image file directory)
- * 07 00 - +1 entry
- * 4A 52 Custom ('J''R') Tag
- * 07 00 - Unknown type
- * 01 00 00 00 - one element
- * 00 00 00 00 - empty data
- * 00 01 - Width Tag
- * 03 00 - 'Short' type
- * 01 00 00 00 - one entry
- * 00 05 00 00 - image with 0x500
- */
-status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest) {
- if (exif == nullptr || exif->data == nullptr) {
- uint8_t data[PSEUDO_EXIF_PACKAGE_LENGTH] = {
- 0x45, 0x78, 0x69, 0x66, 0x00, 0x00,
- 0x49, 0x49, 0x2A, 0x00,
- 0x08, 0x00, 0x00, 0x00,
- 0x01, 0x00,
- 0x4A, 0x52,
- 0x07, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- int pos = 0;
- Write(dest, data, PSEUDO_EXIF_PACKAGE_LENGTH, pos);
- return NO_ERROR;
- }
-
- int num_entry = 0;
- uint8_t num_entry_low = 0;
- uint8_t num_entry_high = 0;
- bool use_big_endian = false;
- if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4949) {
- num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[14];
- num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[15];
- } else if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4d4d) {
- use_big_endian = true;
- num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[14];
- num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[15];
- } else {
- return ERROR_JPEGR_METADATA_ERROR;
- }
- num_entry = (num_entry_high << 8) | num_entry_low;
- num_entry += 1;
- num_entry_low = num_entry & 0xff;
- num_entry_high = (num_entry << 8) & 0xff;
-
- int pos = 0;
- Write(dest, (uint8_t*)exif->data, 14, pos);
-
- if (use_big_endian) {
- Write(dest, &num_entry_high, 1, pos);
- Write(dest, &num_entry_low, 1, pos);
- uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
- 0x4A, 0x52,
- 0x07, 0x00,
- 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
- Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
- } else {
- Write(dest, &num_entry_low, 1, pos);
- Write(dest, &num_entry_high, 1, pos);
- uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
- 0x4A, 0x52,
- 0x00, 0x07,
- 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00};
- Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
- }
-
- Write(dest, (uint8_t*)exif->data + 16, exif->length - 16, pos);
-
- return NO_ERROR;
-}
-
-/*
* Helper function copies the JPEG image from without EXIF.
*
* @param dest destination of the data to be written.
diff --git a/libs/jpegrecoverymap/recoverymaputils.cpp b/libs/jpegrecoverymap/recoverymaputils.cpp
index 8997b4d..d5ad9a5 100644
--- a/libs/jpegrecoverymap/recoverymaputils.cpp
+++ b/libs/jpegrecoverymap/recoverymaputils.cpp
@@ -15,7 +15,6 @@
*/
#include <jpegrecoverymap/recoverymaputils.h>
-#include <jpegrecoverymap/recoverymap.h>
#include <image_io/xml/xml_reader.h>
#include <image_io/xml/xml_writer.h>
#include <image_io/base/message_handler.h>
@@ -23,6 +22,8 @@
#include <image_io/xml/xml_handler.h>
#include <image_io/xml/xml_rule.h>
+#include <utils/Log.h>
+
using namespace photos_editing_formats::image_io;
using namespace std;
@@ -41,6 +42,25 @@
return ss.str();
}
+/*
+ * Helper function used for writing data to destination.
+ */
+status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position) {
+ if (position + length > destination->maxLength) {
+ return ERROR_JPEGR_BUFFER_TOO_SMALL;
+ }
+
+ memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
+ position += length;
+ return NO_ERROR;
+}
+
+status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position) {
+ memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
+ position += length;
+ return NO_ERROR;
+}
+
// Extremely simple XML Handler - just searches for interesting elements
class XMPXmlHandler : public XmlHandler {
public:
@@ -324,4 +344,185 @@
return ss.str();
}
-} // namespace android::recoverymap
+/*
+ * Helper function
+ * Add J R entry to existing exif, or create a new one with J R entry if it's null.
+ */
+status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest) {
+ if (exif == nullptr || exif->data == nullptr) {
+ uint8_t data[PSEUDO_EXIF_PACKAGE_LENGTH] = {
+ 0x45, 0x78, 0x69, 0x66, 0x00, 0x00,
+ 0x49, 0x49, 0x2A, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x01, 0x00,
+ 0x4A, 0x52,
+ 0x07, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+ int pos = 0;
+ Write(dest, data, PSEUDO_EXIF_PACKAGE_LENGTH, pos);
+ return NO_ERROR;
+ }
+
+ int num_entry = 0;
+ uint8_t num_entry_low = 0;
+ uint8_t num_entry_high = 0;
+ bool use_big_endian = false;
+ if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4949) {
+ num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[14];
+ num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[15];
+ } else if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4d4d) {
+ use_big_endian = true;
+ num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[14];
+ num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[15];
+ } else {
+ return ERROR_JPEGR_METADATA_ERROR;
+ }
+ num_entry = (num_entry_high << 8) | num_entry_low;
+ num_entry += 1;
+ num_entry_low = num_entry & 0xff;
+ num_entry_high = (num_entry >> 8) & 0xff;
+
+ int pos = 0;
+ Write(dest, (uint8_t*)exif->data, 14, pos);
+
+ if (use_big_endian) {
+ Write(dest, &num_entry_high, 1, pos);
+ Write(dest, &num_entry_low, 1, pos);
+ uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
+ 0x4A, 0x52,
+ 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00};
+ Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
+ } else {
+ Write(dest, &num_entry_low, 1, pos);
+ Write(dest, &num_entry_high, 1, pos);
+ uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
+ 0x4A, 0x52,
+ 0x07, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+ Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
+ }
+
+ Write(dest, (uint8_t*)exif->data + 16, exif->length - 16, pos);
+
+ updateExifOffsets(dest,
+ 28, // start from the second tag, skip the "JR" tag
+ num_entry - 1,
+ use_big_endian);
+
+ return NO_ERROR;
+}
+
+/*
+ * Helper function
+ * Modify offsets in EXIF in place.
+ */
+void updateExifOffsets(jr_exif_ptr exif, int pos, bool use_big_endian) {
+ int num_entry = readValue(reinterpret_cast<uint8_t*>(exif->data), pos, 2, use_big_endian);
+ updateExifOffsets(exif, pos + 2, num_entry, use_big_endian);
+}
+
+void updateExifOffsets(jr_exif_ptr exif, int pos, int num_entry, bool use_big_endian) {
+ for (int i = 0; i < num_entry; pos += EXIF_J_R_ENTRY_LENGTH, i++) {
+ int tag = readValue(reinterpret_cast<uint8_t*>(exif->data), pos, 2, use_big_endian);
+ bool need_to_update_offset = false;
+ if (tag == 0x8769) {
+ need_to_update_offset = true;
+ int sub_ifd_offset =
+ readValue(reinterpret_cast<uint8_t*>(exif->data), pos + 8, 4, use_big_endian)
+ + 6 // "Exif\0\0";
+ + EXIF_J_R_ENTRY_LENGTH;
+ updateExifOffsets(exif, sub_ifd_offset, use_big_endian);
+ } else {
+ int data_format =
+ readValue(reinterpret_cast<uint8_t*>(exif->data), pos + 2, 2, use_big_endian);
+ int num_of_components =
+ readValue(reinterpret_cast<uint8_t*>(exif->data), pos + 4, 4, use_big_endian);
+ int data_length = findFormatLengthInBytes(data_format) * num_of_components;
+ if (data_length > 4) {
+ need_to_update_offset = true;
+ }
+ }
+
+ if (!need_to_update_offset) {
+ continue;
+ }
+
+ int offset = readValue(reinterpret_cast<uint8_t*>(exif->data), pos + 8, 4, use_big_endian);
+
+ offset += EXIF_J_R_ENTRY_LENGTH;
+
+ if (use_big_endian) {
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 11] = offset & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 10] = (offset >> 8) & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 9] = (offset >> 16) & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 8] = (offset >> 24) & 0xff;
+ } else {
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 8] = offset & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 9] = (offset >> 8) & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 10] = (offset >> 16) & 0xff;
+ reinterpret_cast<uint8_t*>(exif->data)[pos + 11] = (offset >> 24) & 0xff;
+ }
+ }
+}
+
+/*
+ * Read data from the target position and target length in bytes;
+ */
+int readValue(uint8_t* data, int pos, int length, bool use_big_endian) {
+ if (length == 2) {
+ if (use_big_endian) {
+ return (data[pos] << 8) | data[pos + 1];
+ } else {
+ return (data[pos + 1] << 8) | data[pos];
+ }
+ } else if (length == 4) {
+ if (use_big_endian) {
+ return (data[pos] << 24) | (data[pos + 1] << 16) | (data[pos + 2] << 8) | data[pos + 3];
+ } else {
+ return (data[pos + 3] << 24) | (data[pos + 2] << 16) | (data[pos + 1] << 8) | data[pos];
+ }
+ } else {
+ // Not support for now.
+ ALOGE("Error in readValue(): pos=%d, length=%d", pos, length);
+ return -1;
+ }
+}
+
+/*
+ * Helper function
+ * Returns the length of data format in bytes
+ */
+int findFormatLengthInBytes(int data_format) {
+ switch (data_format) {
+ case 1: // unsigned byte
+ case 2: // ascii strings
+ case 6: // signed byte
+ case 7: // undefined
+ return 1;
+
+ case 3: // unsigned short
+ case 8: // signed short
+ return 2;
+
+ case 4: // unsigned long
+ case 9: // signed long
+ case 11: // single float
+ return 4;
+
+ case 5: // unsigned rational
+ case 10: // signed rational
+ case 12: // double float
+ return 8;
+
+ default:
+ // should not hit here
+ ALOGE("Error in findFormatLengthInBytes(): data_format=%d", data_format);
+ return -1;
+ }
+}
+
+} // namespace android::recoverymap
\ No newline at end of file
diff --git a/services/batteryservice/include/batteryservice/BatteryService.h b/services/batteryservice/include/batteryservice/BatteryService.h
index 178bc29..a2e4115 100644
--- a/services/batteryservice/include/batteryservice/BatteryService.h
+++ b/services/batteryservice/include/batteryservice/BatteryService.h
@@ -34,6 +34,9 @@
BATTERY_PROP_CAPACITY = 4, // equals BATTERY_PROPERTY_CAPACITY
BATTERY_PROP_ENERGY_COUNTER = 5, // equals BATTERY_PROPERTY_ENERGY_COUNTER
BATTERY_PROP_BATTERY_STATUS = 6, // equals BATTERY_PROPERTY_BATTERY_STATUS
+ BATTERY_PROP_CHARGING_POLICY = 7, // equals BATTERY_PROPERTY_CHARGING_POLICY
+ BATTERY_PROP_MANUFACTURING_DATE = 8, // equals BATTERY_PROPERTY_MANUFACTURING_DATE
+ BATTERY_PROP_FIRST_USAGE_DATE = 9, // equals BATTERY_PROPERTY_FIRST_USAGE_DATE
};
struct BatteryProperties {
diff --git a/services/batteryservice/include/batteryservice/BatteryServiceConstants.h b/services/batteryservice/include/batteryservice/BatteryServiceConstants.h
index 8a90a12..2d7072d 100644
--- a/services/batteryservice/include/batteryservice/BatteryServiceConstants.h
+++ b/services/batteryservice/include/batteryservice/BatteryServiceConstants.h
@@ -1,7 +1,5 @@
-// This file is autogenerated by hidl-gen. Do not edit manually.
-
-#ifndef HIDL_GENERATED_android_hardware_health_V1_0_EXPORTED_CONSTANTS_H_
-#define HIDL_GENERATED_android_hardware_health_V1_0_EXPORTED_CONSTANTS_H_
+#ifndef AIDL_android_hardware_health_V2_EXPORTED_CONSTANTS_H_
+#define AIDL_android_hardware_health_V2_EXPORTED_CONSTANTS_H_
#ifdef __cplusplus
extern "C" {
@@ -15,6 +13,8 @@
BATTERY_STATUS_FULL = 5,
};
+// must be kept in sync with definitions in
+// hardware/interfaces/health/aidl/android/hardware/health/BatteryHealth.aidl
enum {
BATTERY_HEALTH_UNKNOWN = 1,
BATTERY_HEALTH_GOOD = 2,
@@ -23,10 +23,23 @@
BATTERY_HEALTH_OVER_VOLTAGE = 5,
BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6,
BATTERY_HEALTH_COLD = 7,
+ BATTERY_HEALTH_FAIR = 8,
+ BATTERY_HEALTH_NOT_AVAILABLE = 11,
+ BATTERY_HEALTH_INCONSISTENT = 12,
+};
+
+// must be kept in sync with definitions in
+// hardware/interfaces/health/aidl/android/hardware/health/BatteryChargingState.aidl
+enum {
+ BATTERY_STATUS_NORMAL = 1,
+ BATTERY_STATUS_TOO_COLD = 2,
+ BATTERY_STATUS_TOO_HOT = 3,
+ BATTERY_STATUS_LONG_LIFE = 4,
+ BATTERY_STATUS_ADAPTIVE = 5,
};
#ifdef __cplusplus
}
#endif
-#endif // HIDL_GENERATED_android_hardware_health_V1_0_EXPORTED_CONSTANTS_H_
+#endif // AIDL_android_hardware_health_V2_EXPORTED_CONSTANTS_H_
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index 3d7242e..cacf30b 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -61,6 +61,7 @@
"name": "FrameworksCoreTests",
"options": [
{
+ "include-filter": "android.hardware.input",
"include-filter": "android.view.VerifiedKeyEventTest",
"include-filter": "android.view.VerifiedMotionEventTest"
}
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 6ac6b5b..bd41fa5 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -209,10 +209,10 @@
// Touchscreens and touchpad devices.
static const bool ENABLE_TOUCHPAD_GESTURES_LIBRARY =
- sysprop::InputProperties::enable_touchpad_gestures_library().value_or(true);
+ sysprop::InputProperties::enable_touchpad_gestures_library().value_or(false);
// TODO(b/246587538): Fix the new touchpad stack for Sony DualShock 4 (5c4, 9cc) and DualSense
// (ce6) touchpads, or at least load this setting from the IDC file.
- const InputDeviceIdentifier& identifier = getDeviceInfo().getIdentifier();
+ const InputDeviceIdentifier& identifier = contextPtr->getDeviceIdentifier();
const bool isSonyGamepadTouchpad = identifier.vendor == 0x054c &&
(identifier.product == 0x05c4 || identifier.product == 0x09cc ||
identifier.product == 0x0ce6);
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index ddddca2..0c57628 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -884,8 +884,6 @@
mDeviceMode = DeviceMode::POINTER;
if (hasStylus()) {
mSource |= AINPUT_SOURCE_STYLUS;
- } else {
- mSource |= AINPUT_SOURCE_TOUCHPAD;
}
} else if (isTouchScreen()) {
mSource = AINPUT_SOURCE_TOUCHSCREEN;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 95d35f4..feda191 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -5036,7 +5036,7 @@
prepareAxes(POSITION);
SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
- ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
}
TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
@@ -8865,8 +8865,8 @@
prepareAxes(POSITION);
MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
- // Check source is a touchpad that would obtain the PointerController.
- ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
+ // Check source is mouse that would obtain the PointerController.
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
NotifyMotionArgs motionArgs;
processPosition(mapper, 100, 100);
@@ -9936,11 +9936,11 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
- // A non captured touchpad should have a mouse and touchpad source.
+ // non captured touchpad should be a mouse source
mFakePolicy->setPointerCapture(false);
configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
- ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
}
TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
@@ -9999,10 +9999,10 @@
mFakePolicy->setPointerCapture(false);
MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
- // An uncaptured touchpad should be a pointer device, with additional touchpad source.
- ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
+ // uncaptured touchpad should be a pointer device
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
- // A captured touchpad should just have a touchpad source.
+ // captured touchpad should be a touchpad device
mFakePolicy->setPointerCapture(true);
configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0179d62..b519bd2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2662,18 +2662,18 @@
void Layer::onSurfaceFrameCreated(
const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
- if (!hasBufferOrSidebandStreamInDrawing()) {
- return;
- }
-
while (mPendingJankClassifications.size() >= kPendingClassificationMaxSurfaceFrames) {
// Too many SurfaceFrames pending classification. The front of the deque is probably not
// tracked by FrameTimeline and will never be presented. This will only result in a memory
// leak.
- ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
- mName.c_str());
- std::string miniDump = mPendingJankClassifications.front()->miniDump();
- ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
+ if (hasBufferOrSidebandStreamInDrawing()) {
+ // Only log for layers with a buffer, since we expect the jank data to be drained for
+ // these, while there may be no jank listeners for bufferless layers.
+ ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
+ mName.c_str());
+ std::string miniDump = mPendingJankClassifications.front()->miniDump();
+ ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
+ }
mPendingJankClassifications.pop_front();
}
mPendingJankClassifications.emplace_back(surfaceFrame);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 40de4d6..19445e0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1488,14 +1488,26 @@
std::transform(combination.pixelFormats.cbegin(), combination.pixelFormats.cend(),
std::back_inserter(pixelFormats),
[](const auto& val) { return static_cast<int32_t>(val); });
- std::vector<int32_t> dataspaces;
- dataspaces.reserve(combination.dataspaces.size());
- std::transform(combination.dataspaces.cbegin(), combination.dataspaces.cend(),
- std::back_inserter(dataspaces),
+ std::vector<int32_t> standards;
+ standards.reserve(combination.standards.size());
+ std::transform(combination.standards.cbegin(), combination.standards.cend(),
+ std::back_inserter(standards),
+ [](const auto& val) { return static_cast<int32_t>(val); });
+ std::vector<int32_t> transfers;
+ transfers.reserve(combination.transfers.size());
+ std::transform(combination.transfers.cbegin(), combination.transfers.cend(),
+ std::back_inserter(transfers),
+ [](const auto& val) { return static_cast<int32_t>(val); });
+ std::vector<int32_t> ranges;
+ ranges.reserve(combination.ranges.size());
+ std::transform(combination.ranges.cbegin(), combination.ranges.cend(),
+ std::back_inserter(ranges),
[](const auto& val) { return static_cast<int32_t>(val); });
gui::OverlayProperties::SupportedBufferCombinations outCombination;
outCombination.pixelFormats = std::move(pixelFormats);
- outCombination.dataspaces = std::move(dataspaces);
+ outCombination.standards = std::move(standards);
+ outCombination.transfers = std::move(transfers);
+ outCombination.ranges = std::move(ranges);
outProperties->combinations.emplace_back(outCombination);
}
outProperties->supportMixedColorSpaces = aidlProperties.supportMixedColorSpaces;
@@ -2961,15 +2973,15 @@
const auto enableFrameRateOverride = [&] {
using Config = scheduler::RefreshRateSelector::Config;
- if (!sysprop::enable_frame_rate_override(true)) {
+ if (!sysprop::enable_frame_rate_override(false)) {
return Config::FrameRateOverride::Disabled;
}
- if (sysprop::frame_rate_override_for_native_rates(false)) {
+ if (sysprop::frame_rate_override_for_native_rates(true)) {
return Config::FrameRateOverride::AppOverrideNativeRefreshRates;
}
- if (!sysprop::frame_rate_override_global(true)) {
+ if (!sysprop::frame_rate_override_global(false)) {
return Config::FrameRateOverride::AppOverride;
}
@@ -3843,6 +3855,10 @@
if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled) {
scheduleCommit(frameHint);
+ } else if (frameHint == FrameHint::kActive) {
+ // Even if the next frame is already scheduled, we should reset the idle timer
+ // as a new activity just happened.
+ mScheduler->resetIdleTimer();
}
}
@@ -3973,7 +3989,7 @@
transaction.displays, transaction.flags,
transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.isAutoTimestamp,
- transaction.buffer, transaction.postTime,
+ std::move(transaction.uncacheBufferIds), transaction.postTime,
transaction.permissions, transaction.hasListenerCallbacks,
transaction.listenerCallbacks, transaction.originPid,
transaction.originUid, transaction.id);
@@ -4061,8 +4077,9 @@
const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
+ bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers,
+ bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
+ uint64_t transactionId) {
ATRACE_CALL();
uint32_t permissions =
@@ -4096,6 +4113,15 @@
const int originPid = ipc->getCallingPid();
const int originUid = ipc->getCallingUid();
+ std::vector<uint64_t> uncacheBufferIds;
+ uncacheBufferIds.reserve(uncacheBuffers.size());
+ for (const auto& uncacheBuffer : uncacheBuffers) {
+ sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer);
+ if (buffer != nullptr) {
+ uncacheBufferIds.push_back(buffer->getId());
+ }
+ }
+
std::vector<ResolvedComposerState> resolvedStates;
resolvedStates.reserve(states.size());
for (auto& state : states) {
@@ -4113,14 +4139,22 @@
}
}
- TransactionState state{frameTimelineInfo, resolvedStates,
- displays, flags,
- applyToken, inputWindowCommands,
- desiredPresentTime, isAutoTimestamp,
- uncacheBuffer, postTime,
- permissions, hasListenerCallbacks,
- listenerCallbacks, originPid,
- originUid, transactionId};
+ TransactionState state{frameTimelineInfo,
+ resolvedStates,
+ displays,
+ flags,
+ applyToken,
+ inputWindowCommands,
+ desiredPresentTime,
+ isAutoTimestamp,
+ std::move(uncacheBufferIds),
+ postTime,
+ permissions,
+ hasListenerCallbacks,
+ listenerCallbacks,
+ originPid,
+ originUid,
+ transactionId};
if (mTransactionTracing) {
mTransactionTracing->addQueuedTransaction(state);
@@ -4144,7 +4178,7 @@
Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer,
+ const std::vector<uint64_t>& uncacheBufferIds,
const int64_t postTime, uint32_t permissions,
bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
@@ -4185,11 +4219,8 @@
ALOGE("Only privileged callers are allowed to send input commands.");
}
- if (uncacheBuffer.isValid()) {
- sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer);
- if (buffer != nullptr) {
- mBufferIdsToUncache.push_back(buffer->getId());
- }
+ for (uint64_t uncacheBufferId : uncacheBufferIds) {
+ mBufferIdsToUncache.push_back(uncacheBufferId);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5457be8..9245399 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -501,7 +501,8 @@
uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
+ const std::vector<client_cache_t>& uncacheBuffers,
+ bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) override;
void bootFinished();
@@ -714,16 +715,14 @@
/*
* Transactions
*/
- bool applyTransactionState(const FrameTimelineInfo& info,
- std::vector<ResolvedComposerState>& state,
- Vector<DisplayState>& displays, uint32_t flags,
- const InputWindowCommands& inputWindowCommands,
- const int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer, const int64_t postTime,
- uint32_t permissions, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks,
- int originPid, int originUid, uint64_t transactionId)
- REQUIRES(mStateLock);
+ bool applyTransactionState(
+ const FrameTimelineInfo& info, std::vector<ResolvedComposerState>& state,
+ Vector<DisplayState>& displays, uint32_t flags,
+ const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
+ bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds,
+ const int64_t postTime, uint32_t permissions, bool hasListenerCallbacks,
+ const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid,
+ uint64_t transactionId) REQUIRES(mStateLock);
// Flush pending transactions that were presented after desiredPresentTime.
bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
// Returns true if there is at least one transaction that needs to be flushed
diff --git a/services/surfaceflinger/TransactionState.h b/services/surfaceflinger/TransactionState.h
index 366b09d..5025c49 100644
--- a/services/surfaceflinger/TransactionState.h
+++ b/services/surfaceflinger/TransactionState.h
@@ -43,7 +43,7 @@
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer, int64_t postTime, uint32_t permissions,
+ std::vector<uint64_t> uncacheBufferIds, int64_t postTime, uint32_t permissions,
bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks,
int originPid, int originUid, uint64_t transactionId)
: frameTimelineInfo(frameTimelineInfo),
@@ -54,7 +54,7 @@
inputWindowCommands(inputWindowCommands),
desiredPresentTime(desiredPresentTime),
isAutoTimestamp(isAutoTimestamp),
- buffer(uncacheBuffer),
+ uncacheBufferIds(std::move(uncacheBufferIds)),
postTime(postTime),
permissions(permissions),
hasListenerCallbacks(hasListenerCallbacks),
@@ -109,7 +109,7 @@
InputWindowCommands inputWindowCommands;
int64_t desiredPresentTime;
bool isAutoTimestamp;
- client_cache_t buffer;
+ std::vector<uint64_t> uncacheBufferIds;
int64_t postTime;
uint32_t permissions;
bool hasListenerCallbacks;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 81ca659..c22d78b 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -730,17 +730,18 @@
return mFlinger->mTransactionHandler.mPendingTransactionQueues;
}
- auto setTransactionState(const FrameTimelineInfo &frameTimelineInfo,
- Vector<ComposerState> &states, const Vector<DisplayState> &displays,
- uint32_t flags, const sp<IBinder> &applyToken,
- const InputWindowCommands &inputWindowCommands,
+ auto setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
+ Vector<ComposerState>& states, const Vector<DisplayState>& displays,
+ uint32_t flags, const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t &uncacheBuffer, bool hasListenerCallbacks,
- std::vector<ListenerCallbacks> &listenerCallbacks,
+ const std::vector<client_cache_t>& uncacheBuffers,
+ bool hasListenerCallbacks,
+ std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) {
return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken,
inputWindowCommands, desiredPresentTime,
- isAutoTimestamp, uncacheBuffer, hasListenerCallbacks,
+ isAutoTimestamp, uncacheBuffers, hasListenerCallbacks,
listenerCallbacks, transactionId);
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 584d52c..72e0c7b 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -439,12 +439,13 @@
uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
+ const std::vector<client_cache_t>& uncacheBuffers,
+ bool hasListenerCallbacks,
std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) {
return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken,
inputWindowCommands, desiredPresentTime,
- isAutoTimestamp, uncacheBuffer, hasListenerCallbacks,
+ isAutoTimestamp, uncacheBuffers, hasListenerCallbacks,
listenerCallbacks, transactionId);
}
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index d84698f..a28d1cd 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -102,7 +102,7 @@
int64_t desiredPresentTime = 0;
bool isAutoTimestamp = true;
FrameTimelineInfo frameTimelineInfo;
- client_cache_t uncacheBuffer;
+ std::vector<client_cache_t> uncacheBuffers;
uint64_t id = static_cast<uint64_t>(-1);
static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
};
@@ -138,7 +138,7 @@
transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.isAutoTimestamp,
- transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
transaction.id);
// If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
@@ -165,7 +165,7 @@
transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.isAutoTimestamp,
- transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
transaction.id);
nsecs_t returnedTime = systemTime();
@@ -196,7 +196,7 @@
transactionA.displays, transactionA.flags,
transactionA.applyToken, transactionA.inputWindowCommands,
transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
- transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
transactionA.id);
// This thread should not have been blocked by the above transaction
@@ -211,7 +211,7 @@
transactionB.displays, transactionB.flags,
transactionB.applyToken, transactionB.inputWindowCommands,
transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
- transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
transactionB.id);
// this thread should have been blocked by the above transaction
@@ -243,7 +243,7 @@
mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
transactionA.displays, transactionA.flags, transactionA.applyToken,
transactionA.inputWindowCommands, transactionA.desiredPresentTime,
- transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
+ transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
mHasListenerCallbacks, mCallbacks, transactionA.id);
auto& transactionQueue = mFlinger.getTransactionQueue();
@@ -263,7 +263,7 @@
mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
transactionA.displays, transactionA.flags, transactionA.applyToken,
transactionA.inputWindowCommands, transactionA.desiredPresentTime,
- transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
+ transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
mHasListenerCallbacks, mCallbacks, transactionA.id);
auto& transactionQueue = mFlinger.getTransactionQueue();
@@ -277,7 +277,7 @@
mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
empty.applyToken, empty.inputWindowCommands,
empty.desiredPresentTime, empty.isAutoTimestamp,
- empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
+ empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id);
// flush transaction queue should flush as desiredPresentTime has
// passed
@@ -374,8 +374,7 @@
transaction.applyToken,
transaction.inputWindowCommands,
transaction.desiredPresentTime,
- transaction.isAutoTimestamp,
- transaction.uncacheBuffer, systemTime(), 0,
+ transaction.isAutoTimestamp, {}, systemTime(), 0,
mHasListenerCallbacks, mCallbacks, getpid(),
static_cast<int>(getuid()), transaction.id);
mFlinger.setTransactionStateInternal(transactionState);