summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2023-08-25 12:59:08 -0700
committer Xin Li <delphij@google.com> 2023-08-25 12:59:08 -0700
commit7d3ffbae618e9e728644a96647ed709bf39ae759 (patch)
treeab369a30c6a0e17a69c8f80c6353be4de3692e10 /native
parenta8a87bbca9162af7add830139198c4ee899fa123 (diff)
parent8a809c6e46007521f75ac035ad4b1dcc1d00d9cf (diff)
Merge Android U (ab/10368041)
Bug: 291102124 Merged-In: I3c9e9d15786fbead1b874636b46844f6c24bccc2 Change-Id: Id6cf6cc13baef4e67486c6271a1510146204affa
Diffstat (limited to 'native')
-rw-r--r--native/android/Android.bp1
-rw-r--r--native/android/OWNERS3
-rw-r--r--native/android/activity_manager.cpp4
-rw-r--r--native/android/configuration.cpp8
-rw-r--r--native/android/input.cpp20
-rw-r--r--native/android/libandroid.map.txt10
-rw-r--r--native/android/performance_hint.cpp162
-rw-r--r--native/android/surface_control.cpp90
-rw-r--r--native/android/system_fonts.cpp40
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp59
-rw-r--r--native/graphics/jni/Android.bp2
-rw-r--r--native/graphics/jni/imagedecoder.cpp10
-rw-r--r--native/webview/TEST_MAPPING8
13 files changed, 353 insertions, 64 deletions
diff --git a/native/android/Android.bp b/native/android/Android.bp
index f1b1d79265de..254eb4494ed8 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -95,6 +95,7 @@ cc_library_shared {
"libpowermanager",
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
+ "android.hardware.power-V4-ndk",
"libnativedisplay",
],
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 884f849feb6b..0b86909929b0 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -24,5 +24,8 @@ per-file native_window_jni.cpp = file:/graphics/java/android/graphics/OWNERS
per-file surface_control.cpp = file:/graphics/java/android/graphics/OWNERS
per-file surface_texture.cpp = file:/graphics/java/android/graphics/OWNERS
+# Input
+per-file input.cpp = file:/INPUT_OWNERS
+
# PerformanceHint
per-file performance_hint.cpp = file:/ADPF_OWNERS
diff --git a/native/android/activity_manager.cpp b/native/android/activity_manager.cpp
index 155a355241c8..bc6a84f01517 100644
--- a/native/android/activity_manager.cpp
+++ b/native/android/activity_manager.cpp
@@ -45,7 +45,7 @@ struct UidObserver : public BnUidObserver, public virtual IBinder::DeathRecipien
void onUidIdle(uid_t uid, bool disabled) override;
void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
int32_t capability) override;
- void onUidProcAdjChanged(uid_t uid) override;
+ void onUidProcAdjChanged(uid_t uid, int32_t adj) override;
// IBinder::DeathRecipient implementation
void binderDied(const wp<IBinder>& who) override;
@@ -121,7 +121,7 @@ void UidObserver::onUidActive(uid_t uid __unused) {}
void UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {}
-void UidObserver::onUidProcAdjChanged(uid_t uid __unused) {}
+void UidObserver::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {}
void UidObserver::onUidStateChanged(uid_t uid, int32_t procState,
int64_t procStateSeq __unused,
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
index 87fe9edb49c5..b50514d27bac 100644
--- a/native/android/configuration.cpp
+++ b/native/android/configuration.cpp
@@ -234,6 +234,14 @@ void AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value) {
| ((value<<ResTable_config::SHIFT_LAYOUTDIR)&ResTable_config::MASK_LAYOUTDIR);
}
+int32_t AConfiguration_getGrammaticalGender(AConfiguration* config) {
+ return config->grammaticalInflection;
+}
+
+void AConfiguration_setGrammaticalGender(AConfiguration* config, int32_t value) {
+ config->grammaticalInflection = value & ResTable_config::GRAMMATICAL_INFLECTION_GENDER_MASK;
+}
+
// ----------------------------------------------------------------------
int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2) {
diff --git a/native/android/input.cpp b/native/android/input.cpp
index a231d8f153e7..64e8efeaa4e8 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -33,6 +33,7 @@
#include <errno.h>
using android::InputEvent;
+using android::InputEventType;
using android::InputQueue;
using android::KeyEvent;
using android::Looper;
@@ -41,7 +42,8 @@ using android::sp;
using android::Vector;
int32_t AInputEvent_getType(const AInputEvent* event) {
- return static_cast<const InputEvent*>(event)->getType();
+ const InputEventType eventType = static_cast<const InputEvent*>(event)->getType();
+ return static_cast<int32_t>(eventType);
}
int32_t AInputEvent_getDeviceId(const AInputEvent* event) {
@@ -85,11 +87,8 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) {
const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) {
std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>();
- android::status_t ret = android::android_view_KeyEvent_toNative(env, keyEvent, event.get());
- if (ret == android::OK) {
- return event.release();
- }
- return nullptr;
+ *event = android::android_view_KeyEvent_toNative(env, keyEvent);
+ return event.release();
}
int64_t AKeyEvent_getEventTime(const AInputEvent* key_event) {
@@ -149,7 +148,8 @@ int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointe
}
int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index) {
- return static_cast<const MotionEvent*>(motion_event)->getToolType(pointer_index);
+ const MotionEvent& motion = static_cast<const MotionEvent&>(*motion_event);
+ return static_cast<int32_t>(motion.getToolType(pointer_index));
}
float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index) {
@@ -295,6 +295,12 @@ int32_t AMotionEvent_getClassification(const AInputEvent* motion_event) {
return AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE;
case android::MotionClassification::DEEP_PRESS:
return AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS;
+ case android::MotionClassification::TWO_FINGER_SWIPE:
+ return AMOTION_EVENT_CLASSIFICATION_TWO_FINGER_SWIPE;
+ case android::MotionClassification::MULTI_FINGER_SWIPE:
+ return AMOTION_EVENT_CLASSIFICATION_MULTI_FINGER_SWIPE;
+ case android::MotionClassification::PINCH:
+ return AMOTION_EVENT_CLASSIFICATION_PINCH;
}
}
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index a386923d539a..d74f9b7bb659 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -42,6 +42,7 @@ LIBANDROID {
AConfiguration_fromAssetManager;
AConfiguration_getCountry;
AConfiguration_getDensity;
+ AConfiguration_getGrammaticalGender; # introduced=UpsideDownCake
AConfiguration_getKeyboard;
AConfiguration_getKeysHidden;
AConfiguration_getLanguage;
@@ -66,6 +67,7 @@ LIBANDROID {
AConfiguration_new;
AConfiguration_setCountry;
AConfiguration_setDensity;
+ AConfiguration_setGrammaticalGender; # introduced=UpsideDownCake
AConfiguration_setKeyboard;
AConfiguration_setKeysHidden;
AConfiguration_setLanguage;
@@ -238,6 +240,7 @@ LIBANDROID {
ASurfaceControl_createFromWindow; # introduced=29
ASurfaceControl_acquire; # introduced=31
ASurfaceControl_release; # introduced=29
+ ASurfaceControl_fromJava; # introduced=34
ASurfaceTexture_acquireANativeWindow; # introduced=28
ASurfaceTexture_attachToGLContext; # introduced=28
ASurfaceTexture_detachFromGLContext; # introduced=28
@@ -255,6 +258,7 @@ LIBANDROID {
ASurfaceTransaction_apply; # introduced=29
ASurfaceTransaction_create; # introduced=29
ASurfaceTransaction_delete; # introduced=29
+ ASurfaceTransaction_fromJava; # introduced=34
ASurfaceTransaction_reparent; # introduced=29
ASurfaceTransaction_setBuffer; # introduced=29
ASurfaceTransaction_setBufferAlpha; # introduced=29
@@ -266,10 +270,12 @@ LIBANDROID {
ASurfaceTransaction_setEnableBackPressure; # introduced=31
ASurfaceTransaction_setFrameRate; # introduced=30
ASurfaceTransaction_setFrameRateWithChangeStrategy; # introduced=31
+ ASurfaceTransaction_clearFrameRate; # introduced=34
ASurfaceTransaction_setFrameTimeline; # introduced=Tiramisu
ASurfaceTransaction_setGeometry; # introduced=29
ASurfaceTransaction_setHdrMetadata_cta861_3; # introduced=29
ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29
+ ASurfaceTransaction_setExtendedRangeBrightness; # introduced=UpsideDownCake
ASurfaceTransaction_setOnComplete; # introduced=29
ASurfaceTransaction_setOnCommit; # introduced=31
ASurfaceTransaction_setPosition; # introduced=31
@@ -327,6 +333,7 @@ LIBANDROID {
APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu
APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu
APerformanceHint_closeSession; # introduced=Tiramisu
+ APerformanceHint_setThreads; # introduced=UpsideDownCake
local:
*;
};
@@ -334,9 +341,12 @@ LIBANDROID {
LIBANDROID_PLATFORM {
global:
APerformanceHint_setIHintManagerForTesting;
+ APerformanceHint_sendHint;
+ APerformanceHint_getThreadIds;
extern "C++" {
ASurfaceControl_registerSurfaceStatsListener*;
ASurfaceControl_unregisterSurfaceStatsListener*;
+ ASurfaceControl_getChoreographer*;
ASurfaceControlStats_getAcquireTime*;
ASurfaceControlStats_getFrameNumber*;
};
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index d627984c7fff..b3628fa3e5ce 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "perf_hint"
+#include <aidl/android/hardware/power/SessionHint.h>
#include <android/os/IHintManager.h>
#include <android/os/IHintSession.h>
#include <android/performance_hint.h>
@@ -25,14 +26,21 @@
#include <performance_hint_private.h>
#include <utils/SystemClock.h>
+#include <chrono>
#include <utility>
#include <vector>
using namespace android;
using namespace android::os;
+using namespace std::chrono_literals;
+
+using AidlSessionHint = aidl::android::hardware::power::SessionHint;
+
struct APerformanceHintSession;
+constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
+
struct APerformanceHintManager {
public:
static APerformanceHintManager* getInstance();
@@ -54,24 +62,32 @@ private:
struct APerformanceHintSession {
public:
- APerformanceHintSession(sp<IHintSession> session, int64_t preferredRateNanos,
- int64_t targetDurationNanos);
+ APerformanceHintSession(sp<IHintManager> hintManager, sp<IHintSession> session,
+ int64_t preferredRateNanos, int64_t targetDurationNanos);
APerformanceHintSession() = delete;
~APerformanceHintSession();
int updateTargetWorkDuration(int64_t targetDurationNanos);
int reportActualWorkDuration(int64_t actualDurationNanos);
+ int sendHint(SessionHint hint);
+ int setThreads(const int32_t* threadIds, size_t size);
+ int getThreadIds(int32_t* const threadIds, size_t* size);
private:
friend struct APerformanceHintManager;
+ sp<IHintManager> mHintManager;
sp<IHintSession> mHintSession;
// HAL preferred update rate
const int64_t mPreferredRateNanos;
// Target duration for choosing update rate
int64_t mTargetDurationNanos;
- // Last update timestamp
- int64_t mLastUpdateTimestamp;
+ // First target hit timestamp
+ int64_t mFirstTargetMetTimestamp;
+ // Last target hit timestamp
+ int64_t mLastTargetMetTimestamp;
+ // Last hint reported from sendHint indexed by hint value
+ std::vector<int64_t> mLastHintSentTimestamp;
// Cached samples
std::vector<int64_t> mActualDurationsNanos;
std::vector<int64_t> mTimestampsNanos;
@@ -127,7 +143,7 @@ APerformanceHintSession* APerformanceHintManager::createSession(
if (!ret.isOk() || !session) {
return nullptr;
}
- return new APerformanceHintSession(std::move(session), mPreferredRateNanos,
+ return new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
initialTargetWorkDurationNanos);
}
@@ -137,13 +153,21 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const {
// ===================================== APerformanceHintSession implementation
-APerformanceHintSession::APerformanceHintSession(sp<IHintSession> session,
+APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager,
+ sp<IHintSession> session,
int64_t preferredRateNanos,
int64_t targetDurationNanos)
- : mHintSession(std::move(session)),
+ : mHintManager(hintManager),
+ mHintSession(std::move(session)),
mPreferredRateNanos(preferredRateNanos),
mTargetDurationNanos(targetDurationNanos),
- mLastUpdateTimestamp(elapsedRealtimeNano()) {}
+ mFirstTargetMetTimestamp(0),
+ mLastTargetMetTimestamp(0) {
+ const std::vector<AidlSessionHint> sessionHintRange{ndk::enum_range<AidlSessionHint>().begin(),
+ ndk::enum_range<AidlSessionHint>().end()};
+
+ mLastHintSentTimestamp = std::vector<int64_t>(sessionHintRange.size(), 0);
+}
APerformanceHintSession::~APerformanceHintSession() {
binder::Status ret = mHintSession->close();
@@ -159,7 +183,7 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano
}
binder::Status ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
if (!ret.isOk()) {
- ALOGE("%s: HintSessionn updateTargetWorkDuration failed: %s", __FUNCTION__,
+ ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
ret.exceptionMessage().c_str());
return EPIPE;
}
@@ -170,7 +194,8 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano
*/
mActualDurationsNanos.clear();
mTimestampsNanos.clear();
- mLastUpdateTimestamp = elapsedRealtimeNano();
+ mFirstTargetMetTimestamp = 0;
+ mLastTargetMetTimestamp = 0;
return 0;
}
@@ -183,25 +208,101 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano
mActualDurationsNanos.push_back(actualDurationNanos);
mTimestampsNanos.push_back(now);
- /**
- * Cache the hint if the hint is not overtime and the mLastUpdateTimestamp is
- * still in the mPreferredRateNanos duration.
- */
- if (actualDurationNanos < mTargetDurationNanos &&
- now - mLastUpdateTimestamp <= mPreferredRateNanos) {
- return 0;
+ if (actualDurationNanos >= mTargetDurationNanos) {
+ // Reset timestamps if we are equal or over the target.
+ mFirstTargetMetTimestamp = 0;
+ } else {
+ // Set mFirstTargetMetTimestamp for first time meeting target.
+ if (!mFirstTargetMetTimestamp || !mLastTargetMetTimestamp ||
+ (now - mLastTargetMetTimestamp > 2 * mPreferredRateNanos)) {
+ mFirstTargetMetTimestamp = now;
+ }
+ /**
+ * Rate limit the change if the update is over mPreferredRateNanos since first
+ * meeting target and less than mPreferredRateNanos since last meeting target.
+ */
+ if (now - mFirstTargetMetTimestamp > mPreferredRateNanos &&
+ now - mLastTargetMetTimestamp <= mPreferredRateNanos) {
+ return 0;
+ }
+ mLastTargetMetTimestamp = now;
}
binder::Status ret =
mHintSession->reportActualWorkDuration(mActualDurationsNanos, mTimestampsNanos);
- mActualDurationsNanos.clear();
- mTimestampsNanos.clear();
if (!ret.isOk()) {
ALOGE("%s: HintSession reportActualWorkDuration failed: %s", __FUNCTION__,
ret.exceptionMessage().c_str());
+ mFirstTargetMetTimestamp = 0;
+ mLastTargetMetTimestamp = 0;
+ return EPIPE;
+ }
+ mActualDurationsNanos.clear();
+ mTimestampsNanos.clear();
+
+ return 0;
+}
+
+int APerformanceHintSession::sendHint(SessionHint hint) {
+ if (hint < 0 || hint >= static_cast<int32_t>(mLastHintSentTimestamp.size())) {
+ ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
+ return EINVAL;
+ }
+ int64_t now = elapsedRealtimeNano();
+
+ // Limit sendHint to a pre-detemined rate for safety
+ if (now < (mLastHintSentTimestamp[hint] + SEND_HINT_TIMEOUT)) {
+ return 0;
+ }
+
+ binder::Status ret = mHintSession->sendHint(hint);
+
+ if (!ret.isOk()) {
+ ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ return EPIPE;
+ }
+ mLastHintSentTimestamp[hint] = now;
+ return 0;
+}
+
+int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) {
+ if (size == 0) {
+ ALOGE("%s: the list of thread ids must not be empty.", __FUNCTION__);
+ return EINVAL;
+ }
+ std::vector<int32_t> tids(threadIds, threadIds + size);
+ binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids);
+ if (!ret.isOk()) {
+ ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY ||
+ ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) {
+ return EINVAL;
+ }
return EPIPE;
}
- mLastUpdateTimestamp = now;
+ return 0;
+}
+
+int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) {
+ std::vector<int32_t> tids;
+ binder::Status ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids);
+ if (!ret.isOk()) {
+ ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ return EPIPE;
+ }
+
+ // When threadIds is nullptr, this is the first call to determine the size
+ // of the thread ids list.
+ if (threadIds == nullptr) {
+ *size = tids.size();
+ return 0;
+ }
+
+ // Second call to return the actual list of thread ids.
+ *size = tids.size();
+ for (size_t i = 0; i < *size; ++i) {
+ threadIds[i] = tids[i];
+ }
return 0;
}
@@ -234,6 +335,27 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) {
delete session;
}
+int APerformanceHint_sendHint(void* session, SessionHint hint) {
+ return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint);
+}
+
+int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds,
+ size_t size) {
+ if (session == nullptr) {
+ return EINVAL;
+ }
+ return session->setThreads(threadIds, size);
+}
+
+int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds,
+ size_t* const size) {
+ if (aPerformanceHintSession == nullptr) {
+ return EINVAL;
+ }
+ return static_cast<APerformanceHintSession*>(aPerformanceHintSession)
+ ->getThreadIds(threadIds, size);
+}
+
void APerformanceHint_setIHintManagerForTesting(void* iManager) {
delete gHintManagerForTesting;
gHintManagerForTesting = nullptr;
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 795af8a58351..4b63fbf14d4c 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -17,6 +17,8 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/native_window.h>
#include <android/surface_control.h>
+#include <android/surface_control_jni.h>
+#include <android_runtime/android_view_SurfaceControl.h>
#include <configstore/Utils.h>
#include <gui/HdrMetadata.h>
#include <gui/ISurfaceComposer.h>
@@ -28,6 +30,8 @@
#include <ui/DynamicDisplayInfo.h>
#include <utils/Timers.h>
+#include <utility>
+
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
using namespace android;
@@ -80,7 +84,7 @@ ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* window, const c
Surface* surface = static_cast<Surface*>(window);
sp<IBinder> parentHandle = surface->getSurfaceControlHandle();
- uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
+ int32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
sp<SurfaceControl> surfaceControl;
if (parentHandle) {
surfaceControl =
@@ -88,11 +92,8 @@ ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* window, const c
// Format is only relevant for buffer queue layers.
PIXEL_FORMAT_UNKNOWN /* format */, flags, parentHandle);
} else {
- surfaceControl =
- client->createWithSurfaceParent(String8(debug_name), 0 /* width */, 0 /* height */,
- // Format is only relevant for buffer queue layers.
- PIXEL_FORMAT_UNKNOWN /* format */, flags,
- static_cast<Surface*>(window));
+ // deprecated, this should no longer be used
+ surfaceControl = nullptr;
}
if (!surfaceControl) {
@@ -137,6 +138,18 @@ void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) {
SurfaceControl_release(surfaceControl);
}
+ASurfaceControl* ASurfaceControl_fromJava(JNIEnv* env, jobject surfaceControlObj) {
+ LOG_ALWAYS_FATAL_IF(!env, "nullptr passed to ASurfaceControl_fromJava as env argument");
+ LOG_ALWAYS_FATAL_IF(!surfaceControlObj,
+ "nullptr passed to ASurfaceControl_fromJava as surfaceControlObj argument");
+ SurfaceControl* surfaceControl =
+ android_view_SurfaceControl_getNativeSurfaceControl(env, surfaceControlObj);
+ LOG_ALWAYS_FATAL_IF(!surfaceControl,
+ "surfaceControlObj passed to ASurfaceControl_fromJava is not valid");
+ SurfaceControl_acquire(surfaceControl);
+ return reinterpret_cast<ASurfaceControl*>(surfaceControl);
+}
+
struct ASurfaceControlStats {
std::variant<int64_t, sp<Fence>> acquireTimeOrFence;
sp<Fence> previousReleaseFence;
@@ -167,6 +180,18 @@ void ASurfaceControl_unregisterSurfaceStatsListener(void* context,
reinterpret_cast<void*>(func));
}
+AChoreographer* ASurfaceControl_getChoreographer(ASurfaceControl* aSurfaceControl) {
+ LOG_ALWAYS_FATAL_IF(aSurfaceControl == nullptr, "aSurfaceControl should not be nullptr");
+ SurfaceControl* surfaceControl =
+ ASurfaceControl_to_SurfaceControl(reinterpret_cast<ASurfaceControl*>(aSurfaceControl));
+ if (!surfaceControl->isValid()) {
+ ALOGE("Attempted to get choreographer from invalid surface control");
+ return nullptr;
+ }
+ SurfaceControl_acquire(surfaceControl);
+ return reinterpret_cast<AChoreographer*>(surfaceControl->getChoreographer().get());
+}
+
int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats) {
if (const auto* fence = std::get_if<sp<Fence>>(&stats->acquireTimeOrFence)) {
// We got a fence instead of the acquire time due to latch unsignaled.
@@ -193,6 +218,18 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) {
delete transaction;
}
+ASurfaceTransaction* ASurfaceTransaction_fromJava(JNIEnv* env, jobject transactionObj) {
+ LOG_ALWAYS_FATAL_IF(!env, "nullptr passed to ASurfaceTransaction_fromJava as env argument");
+ LOG_ALWAYS_FATAL_IF(!transactionObj,
+ "nullptr passed to ASurfaceTransaction_fromJava as transactionObj "
+ "argument");
+ Transaction* transaction =
+ android_view_SurfaceTransaction_getNativeSurfaceTransaction(env, transactionObj);
+ LOG_ALWAYS_FATAL_IF(!transaction,
+ "surfaceControlObj passed to ASurfaceTransaction_fromJava is not valid");
+ return reinterpret_cast<ASurfaceTransaction*>(transaction);
+}
+
void ASurfaceTransaction_apply(ASurfaceTransaction* aSurfaceTransaction) {
CHECK_NOT_NULL(aSurfaceTransaction);
@@ -584,6 +621,31 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* aSurfaceTr
transaction->setHdrMetadata(surfaceControl, hdrMetadata);
}
+void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl,
+ float currentBufferRatio, float desiredRatio) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(aSurfaceControl);
+
+ if (!isfinite(currentBufferRatio) || currentBufferRatio < 1.0f) {
+ LOG_ALWAYS_FATAL("setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= "
+ "1.0f",
+ currentBufferRatio);
+ return;
+ }
+
+ if (!isfinite(desiredRatio) || desiredRatio < 1.0f) {
+ LOG_ALWAYS_FATAL("setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f",
+ desiredRatio);
+ return;
+ }
+
+ sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ transaction->setExtendedRangeBrightness(surfaceControl, currentBufferRatio, desiredRatio);
+}
+
void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
float r, float g, float b, float alpha,
@@ -622,6 +684,16 @@ void ASurfaceTransaction_setFrameRateWithChangeStrategy(ASurfaceTransaction* aSu
transaction->setFrameRate(surfaceControl, frameRate, compatibility, changeFrameRateStrategy);
}
+void ASurfaceTransaction_clearFrameRate(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(aSurfaceControl);
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+ sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+ transaction->setFrameRate(surfaceControl, 0, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+}
+
void ASurfaceTransaction_setEnableBackPressure(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
bool enableBackpressure) {
@@ -669,6 +741,8 @@ void ASurfaceTransaction_setFrameTimeline(ASurfaceTransaction* aSurfaceTransacti
AVsyncId vsyncId) {
CHECK_NOT_NULL(aSurfaceTransaction);
const auto startTime = AChoreographer_getStartTimeNanosForVsyncId(vsyncId);
- ASurfaceTransaction_to_Transaction(aSurfaceTransaction)
- ->setFrameTimelineInfo({.vsyncId = vsyncId, .startTimeNanos = startTime});
+ FrameTimelineInfo ftInfo;
+ ftInfo.vsyncId = vsyncId;
+ ftInfo.startTimeNanos = startTime;
+ ASurfaceTransaction_to_Transaction(aSurfaceTransaction)->setFrameTimelineInfo(ftInfo);
}
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index 8e90a6572478..fe3132e3d2a3 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -242,31 +242,23 @@ ASystemFontIterator* ASystemFontIterator_open() {
std::unique_ptr<ASystemFontIterator> ite(new ASystemFontIterator());
std::unordered_set<AFont, FontHasher> fonts;
- minikin::SystemFonts::getFontMap(
- [&fonts](const std::vector<std::shared_ptr<minikin::FontCollection>>& collections) {
- for (const auto& fc : collections) {
- for (const auto& family : fc->getFamilies()) {
- for (uint32_t i = 0; i < family->getNumFonts(); ++i) {
- const minikin::Font* font = family->getFont(i);
-
- std::optional<std::string> locale;
- uint32_t localeId = font->getLocaleListId();
- if (localeId != minikin::kEmptyLocaleListId) {
- locale.emplace(minikin::getLocaleString(localeId));
- }
- std::vector<std::pair<uint32_t, float>> axes;
- for (const auto& [tag, value] : font->typeface()->GetAxes()) {
- axes.push_back(std::make_pair(tag, value));
- }
-
- fonts.insert(
- {font->typeface()->GetFontPath(), std::move(locale),
- font->style().weight(),
- font->style().slant() == minikin::FontStyle::Slant::ITALIC,
- static_cast<uint32_t>(font->typeface()->GetFontIndex()),
- axes});
- }
+ minikin::SystemFonts::getFontSet(
+ [&fonts](const std::vector<std::shared_ptr<minikin::Font>>& fontSet) {
+ for (const auto& font : fontSet) {
+ std::optional<std::string> locale;
+ uint32_t localeId = font->getLocaleListId();
+ if (localeId != minikin::kEmptyLocaleListId) {
+ locale.emplace(minikin::getLocaleString(localeId));
}
+ std::vector<std::pair<uint32_t, float>> axes;
+ for (const auto& [tag, value] : font->typeface()->GetAxes()) {
+ axes.push_back(std::make_pair(tag, value));
+ }
+
+ fonts.insert({font->typeface()->GetFontPath(), std::move(locale),
+ font->style().weight(),
+ font->style().slant() == minikin::FontStyle::Slant::ITALIC,
+ static_cast<uint32_t>(font->typeface()->GetFontIndex()), axes});
}
});
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index b17850e5d1e4..791adfd33fcd 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -37,10 +37,15 @@ using namespace testing;
class MockIHintManager : public IHintManager {
public:
MOCK_METHOD(Status, createHintSession,
- (const ::android::sp<::android::IBinder>& token, const ::std::vector<int32_t>& tids,
- int64_t durationNanos, ::android::sp<::android::os::IHintSession>* _aidl_return),
+ (const sp<IBinder>& token, const ::std::vector<int32_t>& tids,
+ int64_t durationNanos, ::android::sp<IHintSession>* _aidl_return),
(override));
MOCK_METHOD(Status, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+ MOCK_METHOD(Status, setHintSessionThreads,
+ (const sp<IHintSession>& hintSession, const ::std::vector<int32_t>& tids),
+ (override));
+ MOCK_METHOD(Status, getHintSessionThreadIds,
+ (const sp<IHintSession>& hintSession, ::std::vector<int32_t>* tids), (override));
MOCK_METHOD(IBinder*, onAsBinder, (), (override));
};
@@ -51,6 +56,7 @@ public:
(const ::std::vector<int64_t>& actualDurationNanos,
const ::std::vector<int64_t>& timeStampNanos),
(override));
+ MOCK_METHOD(Status, sendHint, (int32_t hints), (override));
MOCK_METHOD(Status, close, (), (override));
MOCK_METHOD(IBinder*, onAsBinder, (), (override));
};
@@ -121,6 +127,55 @@ TEST_F(PerformanceHintTest, TestSession) {
result = APerformanceHint_reportActualWorkDuration(session, -1L);
EXPECT_EQ(EINVAL, result);
+ SessionHint hintId = SessionHint::CPU_LOAD_RESET;
+ EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+ result = APerformanceHint_sendHint(session, hintId);
+ EXPECT_EQ(0, result);
+ usleep(110000); // Sleep for longer than the update timeout.
+ EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+ result = APerformanceHint_sendHint(session, hintId);
+ EXPECT_EQ(0, result);
+ // Expect to get rate limited if we try to send faster than the limiter allows
+ EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(0));
+ result = APerformanceHint_sendHint(session, hintId);
+ EXPECT_EQ(0, result);
+
+ result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
+ EXPECT_EQ(EINVAL, result);
+
EXPECT_CALL(*iSession, close()).Times(Exactly(1));
APerformanceHint_closeSession(session);
}
+
+TEST_F(PerformanceHintTest, SetThreads) {
+ APerformanceHintManager* manager = createManager();
+
+ std::vector<int32_t> tids;
+ tids.push_back(1);
+ tids.push_back(2);
+ int64_t targetDuration = 56789L;
+
+ StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
+ sp<IHintSession> session_sp(iSession);
+
+ EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
+
+ APerformanceHintSession* session =
+ APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ ASSERT_TRUE(session);
+
+ std::vector<int32_t> emptyTids;
+ int result = APerformanceHint_setThreads(session, emptyTids.data(), emptyTids.size());
+ EXPECT_EQ(EINVAL, result);
+
+ std::vector<int32_t> newTids;
+ newTids.push_back(1);
+ newTids.push_back(3);
+ EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids)))
+ .Times(Exactly(1))
+ .WillOnce(Return(Status()));
+ result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
+ EXPECT_EQ(0, result);
+}
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 1709dfd973d6..10c570b30d7a 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -93,7 +93,7 @@ cc_defaults {
],
static_libs: ["libarect"],
fuzz_config: {
- cc: ["scroggo@google.com"],
+ cc: ["dichenzhang@google.com","scroggo@google.com"],
asan_options: [
"detect_odr_violation=1",
],
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index bb25274e3136..e18b4a9d2420 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -25,6 +25,16 @@
#include <hwui/ImageDecoder.h>
#include <log/log.h>
#include <SkAndroidCodec.h>
+#include <SkAlphaType.h>
+#include <SkCodec.h>
+#include <SkCodecAnimation.h>
+#include <SkColorSpace.h>
+#include <SkColorType.h>
+#include <SkImageInfo.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkSize.h>
+#include <SkStream.h>
#include <utils/Color.h>
#include <fcntl.h>
diff --git a/native/webview/TEST_MAPPING b/native/webview/TEST_MAPPING
index bd25200ffc38..c1bc6d720ece 100644
--- a/native/webview/TEST_MAPPING
+++ b/native/webview/TEST_MAPPING
@@ -9,6 +9,14 @@
]
},
{
+ "name": "CtsSdkSandboxWebkitTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
"name": "CtsHostsideWebViewTests",
"options": [
{