diff options
author | 2023-08-25 12:59:08 -0700 | |
---|---|---|
committer | 2023-08-25 12:59:08 -0700 | |
commit | 7d3ffbae618e9e728644a96647ed709bf39ae759 (patch) | |
tree | ab369a30c6a0e17a69c8f80c6353be4de3692e10 /native | |
parent | a8a87bbca9162af7add830139198c4ee899fa123 (diff) | |
parent | 8a809c6e46007521f75ac035ad4b1dcc1d00d9cf (diff) |
Merge Android U (ab/10368041)
Bug: 291102124
Merged-In: I3c9e9d15786fbead1b874636b46844f6c24bccc2
Change-Id: Id6cf6cc13baef4e67486c6271a1510146204affa
Diffstat (limited to 'native')
-rw-r--r-- | native/android/Android.bp | 1 | ||||
-rw-r--r-- | native/android/OWNERS | 3 | ||||
-rw-r--r-- | native/android/activity_manager.cpp | 4 | ||||
-rw-r--r-- | native/android/configuration.cpp | 8 | ||||
-rw-r--r-- | native/android/input.cpp | 20 | ||||
-rw-r--r-- | native/android/libandroid.map.txt | 10 | ||||
-rw-r--r-- | native/android/performance_hint.cpp | 162 | ||||
-rw-r--r-- | native/android/surface_control.cpp | 90 | ||||
-rw-r--r-- | native/android/system_fonts.cpp | 40 | ||||
-rw-r--r-- | native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 59 | ||||
-rw-r--r-- | native/graphics/jni/Android.bp | 2 | ||||
-rw-r--r-- | native/graphics/jni/imagedecoder.cpp | 10 | ||||
-rw-r--r-- | native/webview/TEST_MAPPING | 8 |
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": [ { |