From 1175dc00a8888c90a920aacbfdaeeceb385e9823 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Mon, 28 Feb 2022 12:41:27 -0500 Subject: Fix transitive dependencies on SkImageEncoder In https://skia-review.googlesource.com/c/skia/+/512416, we would like to decouple SkImage and SkImageEncoder. This CL was created by searching for use of these objects: - SkEncodedImageFormat - SkStream - SkData - SkBitmap - SkPixmap and making sure those files followed the Include What You Use (IWYU) guidelines. Signed-off-by: Kevin Lubick Change-Id: I8edbcd1c9a526b8084d7e2c023895d1ad2f8c9b1 --- native/graphics/jni/imagedecoder.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'native') diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index bb25274e3136..cd6ed2391608 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -25,6 +25,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include -- cgit v1.2.3-59-g8ed1b From 4fed9b4544a6f8e1819dfde45bc6d8eeeb89aa2e Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Thu, 3 Mar 2022 15:10:33 -0800 Subject: Sync with FrameTimelineInfo aidl migration libgui FrameTimelineInfo has been converted to aidl parcelable. Bug: 222537482 Test: atest libgui_test libsurfaceflinger_unittest SurfaceFlinger_test Change-Id: I6bf8433d7786485faef61633917659cca5d7f512 --- core/jni/android_view_SurfaceControl.cpp | 6 ++++-- native/android/surface_control.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'native') diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 518fc09dee5a..72a1e04e5e5f 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -1950,8 +1950,10 @@ static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transac jlong frameTimelineVsyncId) { auto transaction = reinterpret_cast(transactionObj); - transaction->setFrameTimelineInfo( - {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID}); + FrameTimelineInfo ftInfo; + ftInfo.vsyncId = frameTimelineVsyncId; + ftInfo.inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID; + transaction->setFrameTimelineInfo(ftInfo); } static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj, diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 1ebdc273931b..98edcc30f985 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -669,6 +669,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); } -- cgit v1.2.3-59-g8ed1b From 36b55bc2acc8a7aa9a8ba41a9c7a21aa0626b0f7 Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Tue, 8 Mar 2022 14:50:45 -0800 Subject: Sync with ISurfaceComposerClient changes ISurfaceComposerClient in libgui is migrated to AIDL interface. Bug: 172002646 Test: atest libgui_test Change-Id: I5301a710a84bcf90ca4a789e184748e889115045 --- libs/input/SpriteController.cpp | 3 +-- native/android/surface_control.cpp | 9 +++------ 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'native') diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index 2b809eab4ae4..a5ca49847bb6 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -249,8 +249,7 @@ void SpriteController::doUpdateSprites() { // Pass cursor metadata in the sprite surface so that when Android is running as a // client OS (e.g. ARC++) the host OS can get the requested cursor metadata and // update mouse cursor in the host OS. - t.setMetadata( - update.state.surfaceControl, METADATA_MOUSE_CURSOR, p); + t.setMetadata(update.state.surfaceControl, gui::METADATA_MOUSE_CURSOR, p); } int32_t surfaceLayer = mOverlayLayer + update.state.layer; diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 98edcc30f985..c2afc609e947 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -80,7 +80,7 @@ ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* window, const c Surface* surface = static_cast(window); sp parentHandle = surface->getSurfaceControlHandle(); - uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState; + int32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState; sp surfaceControl; if (parentHandle) { surfaceControl = @@ -88,11 +88,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(window)); + // deprecated, this should no longer be used + surfaceControl = nullptr; } if (!surfaceControl) { -- cgit v1.2.3-59-g8ed1b From 146c6a93d722ba9e8e259650646394f159f5e352 Mon Sep 17 00:00:00 2001 From: Kohsuke Yatoh Date: Sat, 16 Jul 2022 00:15:41 +0000 Subject: Replace getFamilies() with getFamilyAt(). Following minikin signature change. Bug: 174672300 Test: m libhwui Test: m libandroid Change-Id: I25c5d27c406f49b5ee91a7f4390484296d4a6c7f --- libs/hwui/jni/Typeface.cpp | 14 +++++++------- native/android/system_fonts.cpp | 7 ++++--- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'native') diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp index e79b395412b0..30d6d0009d3b 100644 --- a/libs/hwui/jni/Typeface.cpp +++ b/libs/hwui/jni/Typeface.cpp @@ -111,15 +111,15 @@ static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArr std::vector> familyVec; Typeface* typeface = (fallbackPtr == 0) ? nullptr : toTypeface(fallbackPtr); if (typeface != nullptr) { - const std::vector>& fallbackFamilies = - toTypeface(fallbackPtr)->fFontCollection->getFamilies(); - familyVec.reserve(families.size() + fallbackFamilies.size()); + const std::shared_ptr& fallbackCollection = + toTypeface(fallbackPtr)->fFontCollection; + familyVec.reserve(families.size() + fallbackCollection->getFamilyCount()); for (size_t i = 0; i < families.size(); i++) { FontFamilyWrapper* family = reinterpret_cast(families[i]); familyVec.emplace_back(family->family); } - for (size_t i = 0; i < fallbackFamilies.size(); i++) { - familyVec.emplace_back(fallbackFamilies[i]); + for (size_t i = 0; i < fallbackCollection->getFamilyCount(); i++) { + familyVec.emplace_back(fallbackCollection->getFamilyAt(i)); } } else { familyVec.reserve(families.size()); @@ -360,13 +360,13 @@ static void Typeface_forceSetStaticFinalField(JNIEnv *env, jclass cls, jstring f // Critical Native static jint Typeface_getFamilySize(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) { - return toTypeface(faceHandle)->fFontCollection->getFamilies().size(); + return toTypeface(faceHandle)->fFontCollection->getFamilyCount(); } // Critical Native static jlong Typeface_getFamily(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle, jint index) { std::shared_ptr family = - toTypeface(faceHandle)->fFontCollection->getFamilies()[index]; + toTypeface(faceHandle)->fFontCollection->getFamilyAt(index); return reinterpret_cast(new FontFamilyWrapper(std::move(family))); } diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp index 9fe792958cef..4df745ff6a20 100644 --- a/native/android/system_fonts.cpp +++ b/native/android/system_fonts.cpp @@ -248,9 +248,10 @@ ASystemFontIterator* ASystemFontIterator_open() { minikin::SystemFonts::getFontMap( [&fonts](const std::vector>& 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); + for (uint32_t i = 0; i < fc->getFamilyCount(); ++i) { + const auto& family = fc->getFamilyAt(i); + for (uint32_t j = 0; j < family->getNumFonts(); ++j) { + const minikin::Font* font = family->getFont(j); std::optional locale; uint32_t localeId = font->getLocaleListId(); -- cgit v1.2.3-59-g8ed1b From 1e62e215d426408b9b7e978d2185dff9854c3d46 Mon Sep 17 00:00:00 2001 From: Kohsuke Yatoh Date: Thu, 18 Aug 2022 00:16:44 +0000 Subject: Consolidate getFamilyAt() calls to minikin. - Typeface: Use FontCollection::createCollectionWithFamilies() instead of creating fallback list inside hwui. - system_fonts: Use SystemFonts::getFontSet() intead of getFontMap(). Bug: 174672300 Test: atest CtsGraphicsTestCases:android.graphics.cts.TypefaceTest Test: atest CtsGraphicsTestCases:android.graphics.fonts.NativeSystemFontTest Change-Id: I940f8de441b7bd102eca2d08bc5dd4d0fc4a2685 --- libs/hwui/hwui/Typeface.cpp | 9 ++++- libs/hwui/hwui/Typeface.h | 3 +- libs/hwui/jni/Typeface.cpp | 25 +++---------- libs/hwui/tests/unit/TypefaceTests.cpp | 67 ++++++++++++++++++++++------------ native/android/system_fonts.cpp | 41 ++++++++------------- 5 files changed, 74 insertions(+), 71 deletions(-) (limited to 'native') diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index 9a4bda2ee1df..3c67edc9a428 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -125,9 +125,14 @@ Typeface* Typeface::createWithDifferentBaseWeight(Typeface* src, int weight) { } Typeface* Typeface::createFromFamilies(std::vector>&& families, - int weight, int italic) { + int weight, int italic, const Typeface* fallback) { Typeface* result = new Typeface; - result->fFontCollection = minikin::FontCollection::create(families); + if (fallback == nullptr) { + result->fFontCollection = minikin::FontCollection::create(std::move(families)); + } else { + result->fFontCollection = + fallback->fFontCollection->createCollectionWithFamilies(std::move(families)); + } if (weight == RESOLVE_BY_FONT_TABLE || italic == RESOLVE_BY_FONT_TABLE) { int weightFromFont; diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h index 0c3ef01ab26b..565136e53676 100644 --- a/libs/hwui/hwui/Typeface.h +++ b/libs/hwui/hwui/Typeface.h @@ -78,7 +78,8 @@ public: Typeface* src, const std::vector& variations); static Typeface* createFromFamilies( - std::vector>&& families, int weight, int italic); + std::vector>&& families, int weight, int italic, + const Typeface* fallback); static void setDefault(const Typeface* face); diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp index f5ed5689e4e8..209b35c5537c 100644 --- a/libs/hwui/jni/Typeface.cpp +++ b/libs/hwui/jni/Typeface.cpp @@ -109,27 +109,14 @@ static jint Typeface_getWeight(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray, jlong fallbackPtr, int weight, int italic) { ScopedLongArrayRO families(env, familyArray); - std::vector> familyVec; Typeface* typeface = (fallbackPtr == 0) ? nullptr : toTypeface(fallbackPtr); - if (typeface != nullptr) { - const std::shared_ptr& fallbackCollection = - toTypeface(fallbackPtr)->fFontCollection; - familyVec.reserve(families.size() + fallbackCollection->getFamilyCount()); - for (size_t i = 0; i < families.size(); i++) { - FontFamilyWrapper* family = reinterpret_cast(families[i]); - familyVec.emplace_back(family->family); - } - for (size_t i = 0; i < fallbackCollection->getFamilyCount(); i++) { - familyVec.emplace_back(fallbackCollection->getFamilyAt(i)); - } - } else { - familyVec.reserve(families.size()); - for (size_t i = 0; i < families.size(); i++) { - FontFamilyWrapper* family = reinterpret_cast(families[i]); - familyVec.emplace_back(family->family); - } + std::vector> familyVec; + familyVec.reserve(families.size()); + for (size_t i = 0; i < families.size(); i++) { + FontFamilyWrapper* family = reinterpret_cast(families[i]); + familyVec.emplace_back(family->family); } - return toJLong(Typeface::createFromFamilies(std::move(familyVec), weight, italic)); + return toJLong(Typeface::createFromFamilies(std::move(familyVec), weight, italic, typeface)); } // CriticalNative diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp index 25cc8ca0dafb..499afa039d1f 100644 --- a/libs/hwui/tests/unit/TypefaceTests.cpp +++ b/libs/hwui/tests/unit/TypefaceTests.cpp @@ -73,7 +73,8 @@ std::vector> makeSingleFamlyVector(const ch TEST(TypefaceTest, resolveDefault_and_setDefaultTest) { std::unique_ptr regular(Typeface::createFromFamilies( - makeSingleFamlyVector(kRobotoVariable), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + makeSingleFamlyVector(kRobotoVariable), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE, + nullptr /* fallback */)); EXPECT_EQ(regular.get(), Typeface::resolveDefault(regular.get())); // Keep the original to restore it later. @@ -351,24 +352,24 @@ TEST(TypefaceTest, createAbsolute) { TEST(TypefaceTest, createFromFamilies_Single) { // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(false).build(); - std::unique_ptr regular( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 400, false)); + std::unique_ptr regular(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 400, false, nullptr /* fallback */)); EXPECT_EQ(400, regular->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); EXPECT_EQ(Typeface::kNormal, regular->fAPIStyle); // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(700).setItalic(false).build(); - std::unique_ptr bold( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 700, false)); + std::unique_ptr bold(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 700, false, nullptr /* fallback */)); EXPECT_EQ(700, bold->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, bold->fStyle.slant()); EXPECT_EQ(Typeface::kBold, bold->fAPIStyle); // In Java, new // Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(true).build(); - std::unique_ptr italic( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 400, true)); + std::unique_ptr italic(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 400, true, nullptr /* fallback */)); EXPECT_EQ(400, italic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, italic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -376,8 +377,8 @@ TEST(TypefaceTest, createFromFamilies_Single) { // In Java, // new // Typeface.Builder("Roboto-Regular.ttf").setWeight(700).setItalic(true).build(); - std::unique_ptr boldItalic( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 700, true)); + std::unique_ptr boldItalic(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 700, true, nullptr /* fallback */)); EXPECT_EQ(700, boldItalic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, boldItalic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -385,8 +386,8 @@ TEST(TypefaceTest, createFromFamilies_Single) { // In Java, // new // Typeface.Builder("Roboto-Regular.ttf").setWeight(1100).setItalic(false).build(); - std::unique_ptr over1000( - Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoVariable), 1100, false)); + std::unique_ptr over1000(Typeface::createFromFamilies( + makeSingleFamlyVector(kRobotoVariable), 1100, false, nullptr /* fallback */)); EXPECT_EQ(1000, over1000->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, over1000->fStyle.slant()); EXPECT_EQ(Typeface::kBold, over1000->fAPIStyle); @@ -394,30 +395,33 @@ TEST(TypefaceTest, createFromFamilies_Single) { TEST(TypefaceTest, createFromFamilies_Single_resolveByTable) { // In Java, new Typeface.Builder("Family-Regular.ttf").build(); - std::unique_ptr regular(Typeface::createFromFamilies( - makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr regular( + Typeface::createFromFamilies(makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, regular->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); EXPECT_EQ(Typeface::kNormal, regular->fAPIStyle); // In Java, new Typeface.Builder("Family-Bold.ttf").build(); - std::unique_ptr bold(Typeface::createFromFamilies( - makeSingleFamlyVector(kBoldFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr bold( + Typeface::createFromFamilies(makeSingleFamlyVector(kBoldFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(700, bold->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, bold->fStyle.slant()); EXPECT_EQ(Typeface::kBold, bold->fAPIStyle); // In Java, new Typeface.Builder("Family-Italic.ttf").build(); - std::unique_ptr italic(Typeface::createFromFamilies( - makeSingleFamlyVector(kItalicFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr italic( + Typeface::createFromFamilies(makeSingleFamlyVector(kItalicFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, italic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, italic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); // In Java, new Typeface.Builder("Family-BoldItalic.ttf").build(); - std::unique_ptr boldItalic( - Typeface::createFromFamilies(makeSingleFamlyVector(kBoldItalicFont), - RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr boldItalic(Typeface::createFromFamilies( + makeSingleFamlyVector(kBoldItalicFont), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE, + nullptr /* fallback */)); EXPECT_EQ(700, boldItalic->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::ITALIC, boldItalic->fStyle.slant()); EXPECT_EQ(Typeface::kItalic, italic->fAPIStyle); @@ -427,8 +431,9 @@ TEST(TypefaceTest, createFromFamilies_Family) { std::vector> families = { buildFamily(kRegularFont), buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; - std::unique_ptr typeface(Typeface::createFromFamilies( - std::move(families), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr typeface( + Typeface::createFromFamilies(std::move(families), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(400, typeface->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, typeface->fStyle.slant()); } @@ -436,10 +441,24 @@ TEST(TypefaceTest, createFromFamilies_Family) { TEST(TypefaceTest, createFromFamilies_Family_withoutRegular) { std::vector> families = { buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; - std::unique_ptr typeface(Typeface::createFromFamilies( - std::move(families), RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)); + std::unique_ptr typeface( + Typeface::createFromFamilies(std::move(families), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); EXPECT_EQ(700, typeface->fStyle.weight()); EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, typeface->fStyle.slant()); } +TEST(TypefaceTest, createFromFamilies_Family_withFallback) { + std::vector> fallbackFamilies = { + buildFamily(kBoldFont), buildFamily(kItalicFont), buildFamily(kBoldItalicFont)}; + std::unique_ptr fallback( + Typeface::createFromFamilies(std::move(fallbackFamilies), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, nullptr /* fallback */)); + std::unique_ptr regular( + Typeface::createFromFamilies(makeSingleFamlyVector(kRegularFont), RESOLVE_BY_FONT_TABLE, + RESOLVE_BY_FONT_TABLE, fallback.get())); + EXPECT_EQ(400, regular->fStyle.weight()); + EXPECT_EQ(minikin::FontStyle::Slant::UPRIGHT, regular->fStyle.slant()); +} + } // namespace diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp index 4df745ff6a20..30d0c35bcbb0 100644 --- a/native/android/system_fonts.cpp +++ b/native/android/system_fonts.cpp @@ -245,32 +245,23 @@ ASystemFontIterator* ASystemFontIterator_open() { std::unique_ptr ite(new ASystemFontIterator()); std::unordered_set fonts; - minikin::SystemFonts::getFontMap( - [&fonts](const std::vector>& collections) { - for (const auto& fc : collections) { - for (uint32_t i = 0; i < fc->getFamilyCount(); ++i) { - const auto& family = fc->getFamilyAt(i); - for (uint32_t j = 0; j < family->getNumFonts(); ++j) { - const minikin::Font* font = family->getFont(j); - - std::optional locale; - uint32_t localeId = font->getLocaleListId(); - if (localeId != minikin::kEmptyLocaleListId) { - locale.emplace(minikin::getLocaleString(localeId)); - } - std::vector> 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(font->typeface()->GetFontIndex()), - axes}); - } + minikin::SystemFonts::getFontSet( + [&fonts](const std::vector>& fontSet) { + for (const auto& font : fontSet) { + std::optional locale; + uint32_t localeId = font->getLocaleListId(); + if (localeId != minikin::kEmptyLocaleListId) { + locale.emplace(minikin::getLocaleString(localeId)); } + std::vector> 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(font->typeface()->GetFontIndex()), axes}); } }); -- cgit v1.2.3-59-g8ed1b From 4bfeeb4ec5cdb5bc5057f3d53d8f3418dd797ba1 Mon Sep 17 00:00:00 2001 From: Kriti Dang Date: Thu, 11 Aug 2022 15:15:36 +0200 Subject: Add Surface.clearFrameRate API This API is same as using setFrameRate with 0 as frame-rate value. But this causes confusion, as the remaining two arguments are ignored, when frame-rate is 0. Bug: 241096917 Test: android.graphics.cts.SetFrameRateTest#testClearFrameRate Change-Id: I1324c64ac75dacb78a733df2b91d7a5b46fc7455 --- core/api/current.txt | 2 ++ core/java/android/view/Surface.java | 30 +++++++++++++++++++++++++++++- core/java/android/view/SurfaceControl.java | 26 ++++++++++++++++++++++++++ native/android/libandroid.map.txt | 1 + native/android/surface_control.cpp | 10 ++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index 317f8eb5c6b5..fa30d0229e1a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -49421,6 +49421,7 @@ package android.view { public class Surface implements android.os.Parcelable { ctor public Surface(@NonNull android.view.SurfaceControl); ctor public Surface(android.graphics.SurfaceTexture); + method public void clearFrameRate(); method public int describeContents(); method public boolean isValid(); method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; @@ -49478,6 +49479,7 @@ package android.view { ctor public SurfaceControl.Transaction(); method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.SurfaceControl.TransactionCommittedListener); method public void apply(); + method @NonNull public android.view.SurfaceControl.Transaction clearFrameRate(@NonNull android.view.SurfaceControl); method public void close(); method public int describeContents(); method @NonNull public android.view.SurfaceControl.Transaction merge(@NonNull android.view.SurfaceControl.Transaction); diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 6b21bedcd853..2208f89a04c2 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -985,6 +985,8 @@ public class Surface implements Parcelable { * * @throws IllegalArgumentException If frameRate, compatibility or * changeFrameRateStrategy are invalid. + * + * @see #clearFrameRate() */ public void setFrameRate(@FloatRange(from = 0.0) float frameRate, @FrameRateCompatibility int compatibility, @@ -996,7 +998,33 @@ public class Surface implements Parcelable { if (error == -EINVAL) { throw new IllegalArgumentException("Invalid argument to Surface.setFrameRate()"); } else if (error != 0) { - throw new RuntimeException("Failed to set frame rate on Surface"); + throw new RuntimeException("Failed to set frame rate on Surface. Native error: " + + error); + } + } + } + + /** + * Clears the frame rate which was set for this surface. + * + *

This is equivalent to calling {@link #setFrameRate(float, int, int)} using {@code 0} for + * {@code frameRate}. + *

Note that this only has an effect for surfaces presented on the display. If this + * surface is consumed by something other than the system compositor, e.g. a media + * codec, this call has no effect.

+ * + * @see #setFrameRate(float, int, int) + */ + public void clearFrameRate() { + synchronized (mLock) { + checkNotReleasedLocked(); + // The values FRAME_RATE_COMPATIBILITY_DEFAULT and CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS + // are ignored because the value of frameRate is 0 + int error = nativeSetFrameRate(mNativeObject, 0, + FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); + if (error != 0) { + throw new RuntimeException("Failed to clear the frame rate on Surface. Native error" + + ": " + error); } } } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index e0f02d6e567a..385cc1705321 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -3612,6 +3612,8 @@ public final class SurfaceControl implements Parcelable { * black screen for a second or two. This parameter is * ignored when frameRate is 0. * @return This transaction object. + * + * @see #clearFrameRate(SurfaceControl) */ @NonNull public Transaction setFrameRate(@NonNull SurfaceControl sc, @@ -3624,6 +3626,30 @@ public final class SurfaceControl implements Parcelable { return this; } + /** + * Clears the frame rate which was set for the surface {@link SurfaceControl}. + * + *

This is equivalent to calling {@link #setFrameRate(SurfaceControl, float, int, int)} + * using {@code 0} for {@code frameRate}. + *

+ * Note that this only has an effect for surfaces presented on the display. If this + * surface is consumed by something other than the system compositor, e.g. a media + * codec, this call has no effect. + * + * @param sc The SurfaceControl to clear the frame rate of. + * @return This transaction object. + * + * @see #setFrameRate(SurfaceControl, float, int) + */ + @NonNull + public Transaction clearFrameRate(@NonNull SurfaceControl sc) { + checkPreconditions(sc); + nativeSetFrameRate(mNativeObject, sc.mNativeObject, 0.0f, + Surface.FRAME_RATE_COMPATIBILITY_DEFAULT, + Surface.CHANGE_FRAME_RATE_ALWAYS); + return this; + } + /** * Sets the default frame rate compatibility for the surface {@link SurfaceControl} * diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 4aa5bbf19682..1f96617a1ede 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -266,6 +266,7 @@ 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 diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index c2afc609e947..42f4406ce5e8 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -619,6 +619,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 = 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) { -- cgit v1.2.3-59-g8ed1b From 789103b97a56f39926bf62fde2ff8ccabbda156d Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Thu, 15 Sep 2022 16:24:31 -0400 Subject: NDK methods to get SurfaceControl/Transction from java Test: ASurfaceControlTest#testSurfaceControl_fromSurfaceControl and ASurfaceControlTest#testSurfaceTransaction_fromTransaction Change-Id: Ic15bfaae22b50f70c1c82c8945c09b749654a00f --- core/java/android/view/SurfaceControl.java | 1 + core/jni/android_view_SurfaceControl.cpp | 51 +++++++++++++++++++--- .../android_runtime/android_view_SurfaceControl.h | 38 ++++++++++++++++ native/android/libandroid.map.txt | 2 + native/android/surface_control.cpp | 14 ++++++ 5 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 core/jni/include/android_runtime/android_view_SurfaceControl.h (limited to 'native') diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index aef38eb2e2d2..a0a1cb14f4da 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -447,6 +447,7 @@ public final class SurfaceControl implements Parcelable { private String mName; /** + * Note: do not rename, this field is used by native code. * @hide */ public long mNativeObject; diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index e64b2615e1e2..2d68359eb9a6 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -263,8 +264,14 @@ static struct { static struct { jclass clazz; + jfieldID mNativeObject; +} gTransactionClassInfo; + +static struct { + jclass clazz; + jfieldID mNativeObject; jmethodID invokeReleaseCallback; -} gInvokeReleaseCallback; +} gSurfaceControlClassInfo; class JNamedColorSpace { public: @@ -720,10 +727,11 @@ static ReleaseBufferCallback genReleaseCallback(JNIEnv* env, jobject releaseCall if (fenceCopy) { fenceCopy->incStrong(0); } - globalCallbackRef->env()->CallStaticVoidMethod(gInvokeReleaseCallback.clazz, - gInvokeReleaseCallback.invokeReleaseCallback, - globalCallbackRef->object(), - reinterpret_cast(fenceCopy)); + globalCallbackRef->env() + ->CallStaticVoidMethod(gSurfaceControlClassInfo.clazz, + gSurfaceControlClassInfo.invokeReleaseCallback, + globalCallbackRef->object(), + reinterpret_cast(fenceCopy)); }; } @@ -2129,6 +2137,28 @@ static jobject nativeGetDefaultApplyToken(JNIEnv* env, jclass clazz) { // ---------------------------------------------------------------------------- +SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv* env, + jobject surfaceControlObj) { + if (!!surfaceControlObj && + env->IsInstanceOf(surfaceControlObj, gSurfaceControlClassInfo.clazz)) { + return reinterpret_cast( + env->GetLongField(surfaceControlObj, gSurfaceControlClassInfo.mNativeObject)); + } else { + return nullptr; + } +} + +SurfaceComposerClient::Transaction* android_view_SurfaceTransaction_getNativeSurfaceTransaction( + JNIEnv* env, jobject surfaceTransactionObj) { + if (!!surfaceTransactionObj && + env->IsInstanceOf(surfaceTransactionObj, gTransactionClassInfo.clazz)) { + return reinterpret_cast( + env->GetLongField(surfaceTransactionObj, gTransactionClassInfo.mNativeObject)); + } else { + return nullptr; + } +} + static const JNINativeMethod sSurfaceControlMethods[] = { // clang-format off {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", @@ -2594,11 +2624,18 @@ int register_android_view_SurfaceControl(JNIEnv* env) GetFieldIDOrDie(env, displayDecorationSupportClazz, "alphaInterpretation", "I"); jclass surfaceControlClazz = FindClassOrDie(env, "android/view/SurfaceControl"); - gInvokeReleaseCallback.clazz = MakeGlobalRefOrDie(env, surfaceControlClazz); - gInvokeReleaseCallback.invokeReleaseCallback = + gSurfaceControlClassInfo.clazz = MakeGlobalRefOrDie(env, surfaceControlClazz); + gSurfaceControlClassInfo.mNativeObject = + GetFieldIDOrDie(env, gSurfaceControlClassInfo.clazz, "mNativeObject", "J"); + gSurfaceControlClassInfo.invokeReleaseCallback = GetStaticMethodIDOrDie(env, surfaceControlClazz, "invokeReleaseCallback", "(Ljava/util/function/Consumer;J)V"); + jclass surfaceTransactionClazz = FindClassOrDie(env, "android/view/SurfaceControl$Transaction"); + gTransactionClassInfo.clazz = MakeGlobalRefOrDie(env, surfaceTransactionClazz); + gTransactionClassInfo.mNativeObject = + GetFieldIDOrDie(env, gTransactionClassInfo.clazz, "mNativeObject", "J"); + return err; } diff --git a/core/jni/include/android_runtime/android_view_SurfaceControl.h b/core/jni/include/android_runtime/android_view_SurfaceControl.h new file mode 100644 index 000000000000..10a754903208 --- /dev/null +++ b/core/jni/include/android_runtime/android_view_SurfaceControl.h @@ -0,0 +1,38 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_VIEW_SURFACECONTROL_H +#define _ANDROID_VIEW_SURFACECONTROL_H + +#include +#include + +#include "jni.h" + +namespace android { + +/* Gets the underlying native SurfaceControl for a java SurfaceControl. */ +extern SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl( + JNIEnv* env, jobject surfaceControlObj); + +/* Gets the underlying native SurfaceControl for a java SurfaceControl. */ +extern SurfaceComposerClient::Transaction* +android_view_SurfaceTransaction_getNativeSurfaceTransaction(JNIEnv* env, + jobject surfaceTransactionObj); + +} // namespace android + +#endif // _ANDROID_VIEW_SURFACECONTROL_H diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 1f96617a1ede..cb0f22f974ad 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -238,6 +238,7 @@ LIBANDROID { ASurfaceControl_createFromWindow; # introduced=29 ASurfaceControl_acquire; # introduced=31 ASurfaceControl_release; # introduced=29 + ASurfaceControl_fromSurfaceControl; # introduced=34 ASurfaceTexture_acquireANativeWindow; # introduced=28 ASurfaceTexture_attachToGLContext; # introduced=28 ASurfaceTexture_detachFromGLContext; # introduced=28 @@ -255,6 +256,7 @@ LIBANDROID { ASurfaceTransaction_apply; # introduced=29 ASurfaceTransaction_create; # introduced=29 ASurfaceTransaction_delete; # introduced=29 + ASurfaceTransaction_fromTransaction; # introduced=34 ASurfaceTransaction_reparent; # introduced=29 ASurfaceTransaction_setBuffer; # introduced=29 ASurfaceTransaction_setBufferAlpha; # introduced=29 diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 42f4406ce5e8..9e4d72671502 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -28,6 +30,8 @@ #include #include +#include + using namespace android::hardware::configstore; using namespace android::hardware::configstore::V1_0; using namespace android; @@ -134,6 +138,11 @@ void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) { SurfaceControl_release(surfaceControl); } +ASurfaceControl* ASurfaceControl_fromSurfaceControl(JNIEnv* env, jobject surfaceControlObj) { + return reinterpret_cast( + android_view_SurfaceControl_getNativeSurfaceControl(env, surfaceControlObj)); +} + struct ASurfaceControlStats { std::variant> acquireTimeOrFence; sp previousReleaseFence; @@ -190,6 +199,11 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) { delete transaction; } +ASurfaceTransaction* ASurfaceTransaction_fromTransaction(JNIEnv* env, jobject transactionObj) { + return reinterpret_cast( + android_view_SurfaceTransaction_getNativeSurfaceTransaction(env, transactionObj)); +} + void ASurfaceTransaction_apply(ASurfaceTransaction* aSurfaceTransaction) { CHECK_NOT_NULL(aSurfaceTransaction); -- cgit v1.2.3-59-g8ed1b From 7013c869e6f78d03ad626b5d29315dda9ee84fb9 Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Thu, 15 Sep 2022 13:59:09 +0000 Subject: Add CLASSIFICATION_TWO_FINGER_SCROLL for touchpad scrolling This will be used to denote the single-finger touches that TouchInputMapper creates to simulate scrolling when the user makes two-finger swipes on the touchpad. Bug: 246758376 Test: check new value is sent to a test app when scrolling on a touchpad Change-Id: Id93cba764522e36d850f7013ab8a117f64716fac --- core/api/current.txt | 1 + core/java/android/view/MotionEvent.java | 16 ++++++++++++++-- native/android/input.cpp | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index 4d25ad7d8b37..482d4894a520 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -49222,6 +49222,7 @@ package android.view { field public static final int CLASSIFICATION_AMBIGUOUS_GESTURE = 1; // 0x1 field public static final int CLASSIFICATION_DEEP_PRESS = 2; // 0x2 field public static final int CLASSIFICATION_NONE = 0; // 0x0 + field public static final int CLASSIFICATION_TWO_FINGER_SWIPE = 3; // 0x3 field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int EDGE_BOTTOM = 2; // 0x2 field public static final int EDGE_LEFT = 4; // 0x4 diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index ea0012543ba9..5ec796245774 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1457,10 +1457,20 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int CLASSIFICATION_DEEP_PRESS = 2; + /** + * Classification constant: touchpad scroll. + * + * The current event stream represents the user scrolling with two fingers on a touchpad. + * + * @see #getClassification + */ + public static final int CLASSIFICATION_TWO_FINGER_SWIPE = 3; + /** @hide */ @Retention(SOURCE) @IntDef(prefix = { "CLASSIFICATION" }, value = { - CLASSIFICATION_NONE, CLASSIFICATION_AMBIGUOUS_GESTURE, CLASSIFICATION_DEEP_PRESS}) + CLASSIFICATION_NONE, CLASSIFICATION_AMBIGUOUS_GESTURE, CLASSIFICATION_DEEP_PRESS, + CLASSIFICATION_TWO_FINGER_SWIPE}) public @interface Classification {}; /** @@ -3862,9 +3872,11 @@ public final class MotionEvent extends InputEvent implements Parcelable { return "AMBIGUOUS_GESTURE"; case CLASSIFICATION_DEEP_PRESS: return "DEEP_PRESS"; + case CLASSIFICATION_TWO_FINGER_SWIPE: + return "TWO_FINGER_SWIPE"; } - return "NONE"; + return "UNKNOWN"; } /** diff --git a/native/android/input.cpp b/native/android/input.cpp index a231d8f153e7..812db0f1c507 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -295,6 +295,8 @@ 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; } } -- cgit v1.2.3-59-g8ed1b From ee431fc08bb25c18e858c2988596af28aefa5f58 Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Mon, 26 Sep 2022 14:31:02 +0000 Subject: Add input owners of native/android/input.cpp Test: none Change-Id: Ieee0ab493130eba7d825d463cfbdae4369db165c --- native/android/OWNERS | 3 +++ 1 file changed, 3 insertions(+) (limited to 'native') diff --git a/native/android/OWNERS b/native/android/OWNERS index cfe973400c98..d41652f2ad17 100644 --- a/native/android/OWNERS +++ b/native/android/OWNERS @@ -23,3 +23,6 @@ per-file hardware_buffer_jni.cpp = file:/graphics/java/android/graphics/OWNERS 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 -- cgit v1.2.3-59-g8ed1b From dd89c3b56e496ec23329891670dec8d5f6499d64 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Tue, 11 Oct 2022 20:26:31 -0400 Subject: SurfaceControl ndk-jni API review ASurfaceControl_fromSurfaceControl should acquire a reference before returning. Abort if the arguments are invalid, make the return code nonnull. Test: ASurfaceControlTest#testSurfaceControl_fromSurfaceControl and ASurfaceControlTest#testSurfaceTransaction_fromTransaction Bug: 253053203 Change-Id: If48ff4a534c5765c4831e518e44f77d0429e8981 --- native/android/surface_control.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'native') diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 21d4d8023e54..891379977a6c 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -139,8 +139,18 @@ void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) { } ASurfaceControl* ASurfaceControl_fromSurfaceControl(JNIEnv* env, jobject surfaceControlObj) { - return reinterpret_cast( - android_view_SurfaceControl_getNativeSurfaceControl(env, surfaceControlObj)); + LOG_ALWAYS_FATAL_IF(!env, + "nullptr passed to ASurfaceControl_fromSurfaceControl as env argument"); + LOG_ALWAYS_FATAL_IF(!surfaceControlObj, + "nullptr passed to ASurfaceControl_fromSurfaceControl as surfaceControlObj " + "argument"); + SurfaceControl* surfaceControl = + android_view_SurfaceControl_getNativeSurfaceControl(env, surfaceControlObj); + LOG_ALWAYS_FATAL_IF(!surfaceControl, + "surfaceControlObj passed to ASurfaceControl_fromSurfaceControl is not " + "valid"); + SurfaceControl_acquire(surfaceControl); + return reinterpret_cast(surfaceControl); } struct ASurfaceControlStats { @@ -200,8 +210,17 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) { } ASurfaceTransaction* ASurfaceTransaction_fromTransaction(JNIEnv* env, jobject transactionObj) { - return reinterpret_cast( - android_view_SurfaceTransaction_getNativeSurfaceTransaction(env, transactionObj)); + LOG_ALWAYS_FATAL_IF(!env, + "nullptr passed to ASurfaceTransaction_fromTransaction as env argument"); + LOG_ALWAYS_FATAL_IF(!transactionObj, + "nullptr passed to ASurfaceTransaction_fromTransaction as transactionObj " + "argument"); + Transaction* transaction = + android_view_SurfaceTransaction_getNativeSurfaceTransaction(env, transactionObj); + LOG_ALWAYS_FATAL_IF(!transaction, + "surfaceControlObj passed to ASurfaceTransaction_fromTransaction is not " + "valid"); + return reinterpret_cast(transaction); } void ASurfaceTransaction_apply(ASurfaceTransaction* aSurfaceTransaction) { -- cgit v1.2.3-59-g8ed1b From f38eee4014a7173f35b93ed0d5eb357f76c662d1 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Fri, 4 Nov 2022 12:18:34 -0400 Subject: Add Dichen to cc's for imagedecoder_fuzzer Dichen is taking over my image decoding responsibilities, so add him to cc. Leave myself in cc so I can provide context when needed. Bug: 257475598 Test: N/A Change-Id: I2adf43d61d214b3f7352d528ba1af32c0ce4bf32 --- native/graphics/jni/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'native') 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", ], -- cgit v1.2.3-59-g8ed1b From 354cc0a1403ec47a48d26732444a044d5035c76e Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Wed, 28 Sep 2022 20:54:46 +0000 Subject: Add support for ADPF HintSession sendHint to JNI * Add sendHint API to HintManagerService and PerformanceHintManager * Plumb relevant calls through the existing implementation * Extend existing tests to cover new API calls * Update the relevant build files to use power API v4 Bug: b/243973548 Test: atest PerformanceHintNativeTestCases Test: atest FrameworksCoreTests:android.os.PerformanceHintManagerTest Test: atest HintManagerServiceTest Change-Id: Ice7ed8f32e877bd845afad77fcc6ae16f1a1b78c --- core/api/current.txt | 5 ++ core/java/android/os/IHintSession.aidl | 1 + core/java/android/os/PerformanceHintManager.java | 55 ++++++++++++++++++++++ core/jni/android_os_PerformanceHintManager.cpp | 13 +++++ .../src/android/os/PerformanceHintManagerTest.java | 17 +++++++ native/android/libandroid.map.txt | 1 + native/android/performance_hint.cpp | 22 ++++++++- .../performance_hint/PerformanceHintNativeTest.cpp | 10 ++++ services/core/Android.bp | 2 +- .../server/power/hint/HintManagerService.java | 20 ++++++++ services/core/jni/Android.bp | 2 +- .../com_android_server_hint_HintManagerService.cpp | 11 +++++ .../server/power/hint/HintManagerServiceTest.java | 27 +++++++++++ 13 files changed, 183 insertions(+), 3 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index c8241066b258..e28006a000a4 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32165,7 +32165,12 @@ package android.os { public static class PerformanceHintManager.Session implements java.io.Closeable { method public void close(); method public void reportActualWorkDuration(long); + method public void sendHint(int); method public void updateTargetWorkDuration(long); + field public static final int CPU_LOAD_DOWN = 1; // 0x1 + field public static final int CPU_LOAD_RESET = 2; // 0x2 + field public static final int CPU_LOAD_RESUME = 3; // 0x3 + field public static final int CPU_LOAD_UP = 0; // 0x0 } public final class PersistableBundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable { diff --git a/core/java/android/os/IHintSession.aidl b/core/java/android/os/IHintSession.aidl index 09bc4cc4eb7e..0d1dde105c09 100644 --- a/core/java/android/os/IHintSession.aidl +++ b/core/java/android/os/IHintSession.aidl @@ -22,4 +22,5 @@ oneway interface IHintSession { void updateTargetWorkDuration(long targetDurationNanos); void reportActualWorkDuration(in long[] actualDurationNanos, in long[] timeStampNanos); void close(); + void sendHint(int hint); } diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java index a75b5ef6d65e..86135bcb0abf 100644 --- a/core/java/android/os/PerformanceHintManager.java +++ b/core/java/android/os/PerformanceHintManager.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; @@ -24,6 +25,10 @@ import android.content.Context; import com.android.internal.util.Preconditions; import java.io.Closeable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.ref.Reference; + /** The PerformanceHintManager allows apps to send performance hint to system. */ @SystemService(Context.PERFORMANCE_HINT_SERVICE) @@ -104,6 +109,40 @@ public final class PerformanceHintManager { mNativeSessionPtr = nativeSessionPtr; } + /** + * This hint indicates a sudden increase in CPU workload intensity. It means + * that this hint session needs extra CPU resources immediately to meet the + * target duration for the current work cycle. + */ + public static final int CPU_LOAD_UP = 0; + /** + * This hint indicates a decrease in CPU workload intensity. It means that + * this hint session can reduce CPU resources and still meet the target duration. + */ + public static final int CPU_LOAD_DOWN = 1; + /* + * This hint indicates an upcoming CPU workload that is completely changed and + * unknown. It means that the hint session should reset CPU resources to a known + * baseline to prepare for an arbitrary load, and must wake up if inactive. + */ + public static final int CPU_LOAD_RESET = 2; + /* + * This hint indicates that the most recent CPU workload is resuming after a + * period of inactivity. It means that the hint session should allocate similar + * CPU resources to what was used previously, and must wake up if inactive. + */ + public static final int CPU_LOAD_RESUME = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CPU_LOAD_"}, value = { + CPU_LOAD_UP, + CPU_LOAD_DOWN, + CPU_LOAD_RESET, + CPU_LOAD_RESUME + }) + public @interface Hint {} + /** @hide */ @Override protected void finalize() throws Throwable { @@ -152,6 +191,21 @@ public final class PerformanceHintManager { mNativeSessionPtr = 0; } } + + /** + * Sends performance hints to inform the hint session of changes in the workload. + * + * @param hint The hint to send to the session. + */ + public void sendHint(@Hint int hint) { + Preconditions.checkArgumentNonNegative(hint, "the hint ID should be at least" + + " zero."); + try { + nativeSendHint(mNativeSessionPtr, hint); + } finally { + Reference.reachabilityFence(this); + } + } } private static native long nativeAcquireManager(); @@ -163,4 +217,5 @@ public final class PerformanceHintManager { private static native void nativeReportActualWorkDuration(long nativeSessionPtr, long actualDurationNanos); private static native void nativeCloseSession(long nativeSessionPtr); + private static native void nativeSendHint(long nativeSessionPtr, int hint); } diff --git a/core/jni/android_os_PerformanceHintManager.cpp b/core/jni/android_os_PerformanceHintManager.cpp index d05a24fe7c6e..ac1401dbb16d 100644 --- a/core/jni/android_os_PerformanceHintManager.cpp +++ b/core/jni/android_os_PerformanceHintManager.cpp @@ -40,6 +40,7 @@ typedef int64_t (*APH_getPreferredUpdateRateNanos)(APerformanceHintManager* mana typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); +typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t); bool gAPerformanceHintBindingInitialized = false; APH_getManager gAPH_getManagerFn = nullptr; @@ -48,6 +49,7 @@ APH_getPreferredUpdateRateNanos gAPH_getPreferredUpdateRateNanosFn = nullptr; APH_updateTargetWorkDuration gAPH_updateTargetWorkDurationFn = nullptr; APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr; APH_closeSession gAPH_closeSessionFn = nullptr; +APH_sendHint gAPH_sendHintFn = nullptr; void ensureAPerformanceHintBindingInitialized() { if (gAPerformanceHintBindingInitialized) return; @@ -88,6 +90,11 @@ void ensureAPerformanceHintBindingInitialized() { LOG_ALWAYS_FATAL_IF(gAPH_closeSessionFn == nullptr, "Failed to find required symbol APerformanceHint_closeSession!"); + gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint"); + LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr, + "Failed to find required symbol " + "APerformanceHint_sendHint!"); + gAPerformanceHintBindingInitialized = true; } @@ -138,6 +145,11 @@ static void nativeCloseSession(JNIEnv* env, jclass clazz, jlong nativeSessionPtr gAPH_closeSessionFn(reinterpret_cast(nativeSessionPtr)); } +static void nativeSendHint(JNIEnv* env, jclass clazz, jlong nativeSessionPtr, jint hint) { + ensureAPerformanceHintBindingInitialized(); + gAPH_sendHintFn(reinterpret_cast(nativeSessionPtr), hint); +} + static const JNINativeMethod gPerformanceHintMethods[] = { {"nativeAcquireManager", "()J", (void*)nativeAcquireManager}, {"nativeGetPreferredUpdateRateNanos", "(J)J", (void*)nativeGetPreferredUpdateRateNanos}, @@ -145,6 +157,7 @@ static const JNINativeMethod gPerformanceHintMethods[] = { {"nativeUpdateTargetWorkDuration", "(JJ)V", (void*)nativeUpdateTargetWorkDuration}, {"nativeReportActualWorkDuration", "(JJ)V", (void*)nativeReportActualWorkDuration}, {"nativeCloseSession", "(J)V", (void*)nativeCloseSession}, + {"nativeSendHint", "(JI)V", (void*)nativeSendHint}, }; int register_android_os_PerformanceHintManager(JNIEnv* env) { diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java index 69eb13f7854a..d1d14f6fbcb4 100644 --- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java @@ -113,6 +113,23 @@ public class PerformanceHintManagerTest { }); } + @Test + public void testSendHint() { + Session s = createSession(); + assumeNotNull(s); + s.sendHint(Session.CPU_LOAD_UP); + s.sendHint(Session.CPU_LOAD_RESET); + } + + @Test + public void testSendHintWithNegativeHint() { + Session s = createSession(); + assumeNotNull(s); + assertThrows(IllegalArgumentException.class, () -> { + s.sendHint(-1); + }); + } + @Test public void testCloseHintSession() { Session s = createSession(); diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index cb0f22f974ad..584d0ba2ea8c 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -330,6 +330,7 @@ LIBANDROID { APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu APerformanceHint_closeSession; # introduced=Tiramisu + APerformanceHint_sendHint; # introduced=UpsideDownCake local: *; }; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index d627984c7fff..7863a7dba1a7 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -61,6 +61,7 @@ public: int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); + int sendHint(int32_t hint); private: friend struct APerformanceHintManager; @@ -159,7 +160,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; } @@ -205,6 +206,21 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano return 0; } +int APerformanceHintSession::sendHint(int32_t hint) { + if (hint < 0) { + ALOGE("%s: session hint value must be greater than zero", __FUNCTION__); + return EINVAL; + } + + binder::Status ret = mHintSession->sendHint(hint); + + if (!ret.isOk()) { + ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); + return EPIPE; + } + return 0; +} + // ===================================== C API APerformanceHintManager* APerformanceHint_getManager() { return APerformanceHintManager::getInstance(); @@ -230,6 +246,10 @@ int APerformanceHint_reportActualWorkDuration(APerformanceHintSession* session, return session->reportActualWorkDuration(actualDurationNanos); } +int APerformanceHint_sendHint(APerformanceHintSession* session, int32_t hint) { + return session->sendHint(hint); +} + void APerformanceHint_closeSession(APerformanceHintSession* session) { delete session; } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index b17850e5d1e4..1881e60b0f16 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -51,6 +51,7 @@ public: (const ::std::vector& actualDurationNanos, const ::std::vector& timeStampNanos), (override)); + MOCK_METHOD(Status, sendHint, (int32_t hints), (override)); MOCK_METHOD(Status, close, (), (override)); MOCK_METHOD(IBinder*, onAsBinder, (), (override)); }; @@ -121,6 +122,15 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_reportActualWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); + // Send both valid and invalid session hints + int hintId = 2; + EXPECT_CALL(*iSession, sendHint(Eq(2))).Times(Exactly(1)); + result = APerformanceHint_sendHint(session, hintId); + EXPECT_EQ(0, result); + + result = APerformanceHint_sendHint(session, -1); + EXPECT_EQ(EINVAL, result); + EXPECT_CALL(*iSession, close()).Times(Exactly(1)); APerformanceHint_closeSession(session); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 553146d0448d..84f2b63f9775 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -168,7 +168,7 @@ java_library_static { "android.hardware.rebootescrow-V1-java", "android.hardware.soundtrigger-V2.3-java", "android.hardware.power.stats-V1-java", - "android.hardware.power-V3-java", + "android.hardware.power-V4-java", "android.hidl.manager-V1.2-java", "capture_state_listener-aidl-java", "icu4j_calendar_astronomer", diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index dfa12814a138..0d13831abe52 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -24,6 +24,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.IHintManager; import android.os.IHintSession; +import android.os.PerformanceHintManager; import android.os.Process; import android.os.RemoteException; import android.util.ArrayMap; @@ -147,6 +148,8 @@ public final class HintManagerService extends SystemService { private static native void nativeReportActualWorkDuration( long halPtr, long[] actualDurationNanos, long[] timeStampNanos); + private static native void nativeSendHint(long halPtr, int hint); + private static native long nativeGetHintSessionPreferredRate(); /** Wrapper for HintManager.nativeInit */ @@ -186,6 +189,11 @@ public final class HintManagerService extends SystemService { timeStampNanos); } + /** Wrapper for HintManager.sendHint */ + public void halSendHint(long halPtr, int hint) { + nativeSendHint(halPtr, hint); + } + /** Wrapper for HintManager.nativeGetHintSessionPreferredRate */ public long halGetHintSessionPreferredRate() { return nativeGetHintSessionPreferredRate(); @@ -475,6 +483,18 @@ public final class HintManagerService extends SystemService { } } + @Override + public void sendHint(@PerformanceHintManager.Session.Hint int hint) { + synchronized (mLock) { + if (mHalSessionPtr == 0 || !updateHintAllowed()) { + return; + } + Preconditions.checkArgument(hint >= 0, "the hint ID the hint value should be" + + " greater than zero."); + mNativeWrapper.halSendHint(mHalSessionPtr, hint); + } + } + private void onProcStateChanged() { updateHintAllowed(); } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 3c788197b191..57b977cc865a 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -170,7 +170,7 @@ cc_defaults { "android.hardware.power@1.1", "android.hardware.power@1.2", "android.hardware.power@1.3", - "android.hardware.power-V3-cpp", + "android.hardware.power-V4-cpp", "android.hardware.power.stats@1.0", "android.hardware.power.stats-V1-ndk", "android.hardware.thermal@1.0", diff --git a/services/core/jni/com_android_server_hint_HintManagerService.cpp b/services/core/jni/com_android_server_hint_HintManagerService.cpp index 000cb839002b..d975760cbfc2 100644 --- a/services/core/jni/com_android_server_hint_HintManagerService.cpp +++ b/services/core/jni/com_android_server_hint_HintManagerService.cpp @@ -34,6 +34,7 @@ #include "jni.h" using android::hardware::power::IPowerHintSession; +using android::hardware::power::SessionHint; using android::hardware::power::WorkDuration; using android::base::StringPrintf; @@ -81,6 +82,11 @@ static void reportActualWorkDuration(int64_t session_ptr, appSession->reportActualWorkDuration(actualDurations); } +static void sendHint(int64_t session_ptr, SessionHint hint) { + sp appSession = reinterpret_cast(session_ptr); + appSession->sendHint(hint); +} + static int64_t getHintSessionPreferredRate() { int64_t rate = -1; auto result = gPowerHalController.getHintSessionPreferredRate(); @@ -139,6 +145,10 @@ static void nativeReportActualWorkDuration(JNIEnv* env, jclass /* clazz */, jlon reportActualWorkDuration(session_ptr, actualList); } +static void nativeSendHint(JNIEnv* env, jclass /* clazz */, jlong session_ptr, jint hint) { + sendHint(session_ptr, static_cast(hint)); +} + static jlong nativeGetHintSessionPreferredRate(JNIEnv* /* env */, jclass /* clazz */) { return static_cast(getHintSessionPreferredRate()); } @@ -153,6 +163,7 @@ static const JNINativeMethod sHintManagerServiceMethods[] = { {"nativeCloseHintSession", "(J)V", (void*)nativeCloseHintSession}, {"nativeUpdateTargetWorkDuration", "(JJ)V", (void*)nativeUpdateTargetWorkDuration}, {"nativeReportActualWorkDuration", "(J[J[J)V", (void*)nativeReportActualWorkDuration}, + {"nativeSendHint", "(JI)V", (void*)nativeSendHint}, {"nativeGetHintSessionPreferredRate", "()J", (void*)nativeGetHintSessionPreferredRate}, }; diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java index 397770bec822..dcbdcdc98017 100644 --- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java @@ -42,6 +42,7 @@ import android.content.Context; import android.os.Binder; import android.os.IBinder; import android.os.IHintSession; +import android.os.PerformanceHintManager; import android.os.Process; import com.android.server.FgThread; @@ -249,6 +250,32 @@ public class HintManagerServiceTest { verify(mNativeWrapperMock, never()).halReportActualWorkDuration(anyLong(), any(), any()); } + @Test + public void testSendHint() throws Exception { + HintManagerService service = createService(); + IBinder token = new Binder(); + + AppHintSession a = (AppHintSession) service.getBinderServiceInstance() + .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION); + + a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET); + verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(), + eq(PerformanceHintManager.Session.CPU_LOAD_RESET)); + + assertThrows(IllegalArgumentException.class, () -> { + a.sendHint(-1); + }); + + reset(mNativeWrapperMock); + // Set session to background, then the duration would not be updated. + service.mUidObserver.onUidStateChanged( + a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); + FgThread.getHandler().runWithScissors(() -> { }, 500); + assertFalse(a.updateHintAllowed()); + a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET); + verify(mNativeWrapperMock, never()).halSendHint(anyLong(), anyInt()); + } + @Test public void testDoHintInBackground() throws Exception { HintManagerService service = createService(); -- cgit v1.2.3-59-g8ed1b From 23af702a13a10b4558419e70c539c66ffd00d356 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Fri, 11 Nov 2022 15:00:19 -0500 Subject: Rename SC ndk jni API Rename to ASurfaceControl_fromJava / ASurfaceTransaction_fromJava. Test: Compiles Bug: 258245761 Change-Id: Ic9cedd83bad3facb46947ecdac6324f4318d8db6 --- native/android/libandroid.map.txt | 4 ++-- native/android/surface_control.cpp | 21 ++++++++------------- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'native') diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index cb0f22f974ad..0b70b9bde376 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -238,7 +238,7 @@ LIBANDROID { ASurfaceControl_createFromWindow; # introduced=29 ASurfaceControl_acquire; # introduced=31 ASurfaceControl_release; # introduced=29 - ASurfaceControl_fromSurfaceControl; # introduced=34 + ASurfaceControl_fromJava; # introduced=34 ASurfaceTexture_acquireANativeWindow; # introduced=28 ASurfaceTexture_attachToGLContext; # introduced=28 ASurfaceTexture_detachFromGLContext; # introduced=28 @@ -256,7 +256,7 @@ LIBANDROID { ASurfaceTransaction_apply; # introduced=29 ASurfaceTransaction_create; # introduced=29 ASurfaceTransaction_delete; # introduced=29 - ASurfaceTransaction_fromTransaction; # introduced=34 + ASurfaceTransaction_fromJava; # introduced=34 ASurfaceTransaction_reparent; # introduced=29 ASurfaceTransaction_setBuffer; # introduced=29 ASurfaceTransaction_setBufferAlpha; # introduced=29 diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 891379977a6c..ea20c6c9e0b1 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -138,17 +138,14 @@ void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) { SurfaceControl_release(surfaceControl); } -ASurfaceControl* ASurfaceControl_fromSurfaceControl(JNIEnv* env, jobject surfaceControlObj) { - LOG_ALWAYS_FATAL_IF(!env, - "nullptr passed to ASurfaceControl_fromSurfaceControl as env argument"); +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_fromSurfaceControl as surfaceControlObj " - "argument"); + "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_fromSurfaceControl is not " - "valid"); + "surfaceControlObj passed to ASurfaceControl_fromJava is not valid"); SurfaceControl_acquire(surfaceControl); return reinterpret_cast(surfaceControl); } @@ -209,17 +206,15 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) { delete transaction; } -ASurfaceTransaction* ASurfaceTransaction_fromTransaction(JNIEnv* env, jobject transactionObj) { - LOG_ALWAYS_FATAL_IF(!env, - "nullptr passed to ASurfaceTransaction_fromTransaction as env argument"); +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_fromTransaction as 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_fromTransaction is not " - "valid"); + "surfaceControlObj passed to ASurfaceTransaction_fromJava is not valid"); return reinterpret_cast(transaction); } -- cgit v1.2.3-59-g8ed1b From 00feb50078fc971412667c0598f91144dd0aa645 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 18 Oct 2022 10:56:59 -0700 Subject: PerformanceHint: optimize rate limit Skip rate limit when first hit target. Also for 1st frame boost Bug: 254293108 Test: Build Signed-off-by: Wei Wang Change-Id: I0268de156ba2c34723c1593c76a64331016cc87c --- native/android/performance_hint.cpp | 45 +++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'native') diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 7863a7dba1a7..40eb507a5213 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -71,8 +71,10 @@ private: 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; // Cached samples std::vector mActualDurationsNanos; std::vector mTimestampsNanos; @@ -144,7 +146,8 @@ APerformanceHintSession::APerformanceHintSession(sp session, : mHintSession(std::move(session)), mPreferredRateNanos(preferredRateNanos), mTargetDurationNanos(targetDurationNanos), - mLastUpdateTimestamp(elapsedRealtimeNano()) {} + mFirstTargetMetTimestamp(0), + mLastTargetMetTimestamp(0) {} APerformanceHintSession::~APerformanceHintSession() { binder::Status ret = mHintSession->close(); @@ -171,7 +174,8 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano */ mActualDurationsNanos.clear(); mTimestampsNanos.clear(); - mLastUpdateTimestamp = elapsedRealtimeNano(); + mFirstTargetMetTimestamp = 0; + mLastTargetMetTimestamp = 0; return 0; } @@ -184,25 +188,38 @@ 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; } - mLastUpdateTimestamp = now; + mActualDurationsNanos.clear(); + mTimestampsNanos.clear(); + return 0; } -- cgit v1.2.3-59-g8ed1b From 56093a77a950660d0c281ecc7c5de57af88ae397 Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Mon, 7 Nov 2022 21:50:50 +0000 Subject: Add rate limiter to sendHint API call Adds a rate limiter to the HintSession.sendHint API for safety, and update tests to reflect this. Bug: b/243973548 Test: atest PerformanceHintNativeTestCases Test: atest FrameworksCoreTests:android.os.PerformanceHintManagerTest Change-Id: Ic68683bacf7df3e11efc3d59689b5470c3fa4274 --- .../src/android/os/PerformanceHintManagerTest.java | 3 ++- native/android/Android.bp | 1 + native/android/performance_hint.cpp | 28 +++++++++++++++++++--- .../performance_hint/PerformanceHintNativeTest.cpp | 11 +++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) (limited to 'native') diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java index d1d14f6fbcb4..44923b60fbb5 100644 --- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java @@ -117,7 +117,8 @@ public class PerformanceHintManagerTest { public void testSendHint() { Session s = createSession(); assumeNotNull(s); - s.sendHint(Session.CPU_LOAD_UP); + s.sendHint(Session.CPU_LOAD_RESET); + // ensure we can also send within the rate limit without exception s.sendHint(Session.CPU_LOAD_RESET); } 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/performance_hint.cpp b/native/android/performance_hint.cpp index 40eb507a5213..9e97bd33ce9c 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "perf_hint" +#include #include #include #include @@ -25,14 +26,21 @@ #include #include +#include #include #include 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(); @@ -75,6 +83,8 @@ private: int64_t mFirstTargetMetTimestamp; // Last target hit timestamp int64_t mLastTargetMetTimestamp; + // Last hint reported from sendHint indexed by hint value + std::vector mLastHintSentTimestamp; // Cached samples std::vector mActualDurationsNanos; std::vector mTimestampsNanos; @@ -147,7 +157,12 @@ APerformanceHintSession::APerformanceHintSession(sp session, mPreferredRateNanos(preferredRateNanos), mTargetDurationNanos(targetDurationNanos), mFirstTargetMetTimestamp(0), - mLastTargetMetTimestamp(0) {} + mLastTargetMetTimestamp(0) { + const std::vector sessionHintRange{ndk::enum_range().begin(), + ndk::enum_range().end()}; + + mLastHintSentTimestamp = std::vector(sessionHintRange.size(), 0); +} APerformanceHintSession::~APerformanceHintSession() { binder::Status ret = mHintSession->close(); @@ -224,10 +239,16 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano } int APerformanceHintSession::sendHint(int32_t hint) { - if (hint < 0) { - ALOGE("%s: session hint value must be greater than zero", __FUNCTION__); + if (hint < 0 || hint >= static_cast(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); @@ -235,6 +256,7 @@ int APerformanceHintSession::sendHint(int32_t hint) { ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); return EPIPE; } + mLastHintSentTimestamp[hint] = now; return 0; } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 1881e60b0f16..0c2d3b6cd201 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -122,9 +122,16 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_reportActualWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); - // Send both valid and invalid session hints int hintId = 2; - EXPECT_CALL(*iSession, sendHint(Eq(2))).Times(Exactly(1)); + 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); -- cgit v1.2.3-59-g8ed1b From 61726a38043baea5627019d947cd83029c11e616 Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Tue, 6 Dec 2022 23:44:45 +0000 Subject: Make sendHint private in platform * Convert PerformanceHintManager sendHint to a private API * Have HWUI depend on private implementation Bug: b/261640114 Test: atest PerformanceHintNativeTestCases Test: atest FrameworksCoreTests:android.os.PerformanceHintManagerTest Change-Id: Ic65eef1fbd1c26040e86ddf3cf7c59581fee4374 --- core/api/current.txt | 5 ----- core/api/test-current.txt | 8 ++++++++ core/java/android/os/PerformanceHintManager.java | 20 ++++++++++++++++++-- libs/hwui/renderthread/HintSessionWrapper.cpp | 1 + native/android/libandroid.map.txt | 2 +- native/android/performance_hint.cpp | 8 ++++---- 6 files changed, 32 insertions(+), 12 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index f26f8399a6d7..2e5c86649820 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32329,12 +32329,7 @@ package android.os { public static class PerformanceHintManager.Session implements java.io.Closeable { method public void close(); method public void reportActualWorkDuration(long); - method public void sendHint(int); method public void updateTargetWorkDuration(long); - field public static final int CPU_LOAD_DOWN = 1; // 0x1 - field public static final int CPU_LOAD_RESET = 2; // 0x2 - field public static final int CPU_LOAD_RESUME = 3; // 0x3 - field public static final int CPU_LOAD_UP = 0; // 0x0 } public final class PersistableBundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 002032ae10c3..1f294e027f92 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1835,6 +1835,14 @@ package android.os { method public static java.io.File getFile(java.io.FileDescriptor) throws java.io.IOException; } + public static class PerformanceHintManager.Session implements java.io.Closeable { + method public void sendHint(int); + field public static final int CPU_LOAD_DOWN = 1; // 0x1 + field public static final int CPU_LOAD_RESET = 2; // 0x2 + field public static final int CPU_LOAD_RESUME = 3; // 0x3 + field public static final int CPU_LOAD_UP = 0; // 0x0 + } + public final class PowerManager { method public boolean areAutoPowerSaveModesEnabled(); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void forceLowPowerStandbyActive(boolean); diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java index 86135bcb0abf..85d6d83ef9e9 100644 --- a/core/java/android/os/PerformanceHintManager.java +++ b/core/java/android/os/PerformanceHintManager.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; +import android.annotation.TestApi; import android.content.Context; import com.android.internal.util.Preconditions; @@ -113,24 +114,36 @@ public final class PerformanceHintManager { * This hint indicates a sudden increase in CPU workload intensity. It means * that this hint session needs extra CPU resources immediately to meet the * target duration for the current work cycle. + * + * @hide */ + @TestApi public static final int CPU_LOAD_UP = 0; /** * This hint indicates a decrease in CPU workload intensity. It means that * this hint session can reduce CPU resources and still meet the target duration. + * + * @hide */ + @TestApi public static final int CPU_LOAD_DOWN = 1; - /* + /** * This hint indicates an upcoming CPU workload that is completely changed and * unknown. It means that the hint session should reset CPU resources to a known * baseline to prepare for an arbitrary load, and must wake up if inactive. + * + * @hide */ + @TestApi public static final int CPU_LOAD_RESET = 2; - /* + /** * This hint indicates that the most recent CPU workload is resuming after a * period of inactivity. It means that the hint session should allocate similar * CPU resources to what was used previously, and must wake up if inactive. + * + * @hide */ + @TestApi public static final int CPU_LOAD_RESUME = 3; /** @hide */ @@ -196,7 +209,10 @@ public final class PerformanceHintManager { * Sends performance hints to inform the hint session of changes in the workload. * * @param hint The hint to send to the session. + * + * @hide */ + @TestApi public void sendHint(@Hint int hint) { Preconditions.checkArgumentNonNegative(hint, "the hint ID should be at least" + " zero."); diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp index edacef04b50a..94c9d94a7c26 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.cpp +++ b/libs/hwui/renderthread/HintSessionWrapper.cpp @@ -17,6 +17,7 @@ #include "HintSessionWrapper.h" #include +#include #include #include diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 9b0f0203f42b..4e6a0c540f49 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -330,7 +330,6 @@ LIBANDROID { APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu APerformanceHint_closeSession; # introduced=Tiramisu - APerformanceHint_sendHint; # introduced=UpsideDownCake local: *; }; @@ -338,6 +337,7 @@ LIBANDROID { LIBANDROID_PLATFORM { global: APerformanceHint_setIHintManagerForTesting; + APerformanceHint_sendHint; extern "C++" { ASurfaceControl_registerSurfaceStatsListener*; ASurfaceControl_unregisterSurfaceStatsListener*; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 40eb507a5213..95b7513caa30 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -263,14 +263,14 @@ int APerformanceHint_reportActualWorkDuration(APerformanceHintSession* session, return session->reportActualWorkDuration(actualDurationNanos); } -int APerformanceHint_sendHint(APerformanceHintSession* session, int32_t hint) { - return session->sendHint(hint); -} - void APerformanceHint_closeSession(APerformanceHintSession* session) { delete session; } +int APerformanceHint_sendHint(void* session, int32_t hint) { + return reinterpret_cast(session)->sendHint(hint); +} + void APerformanceHint_setIHintManagerForTesting(void* iManager) { delete gHintManagerForTesting; gHintManagerForTesting = nullptr; -- cgit v1.2.3-59-g8ed1b From 095de769a6a821dffb5b6a5f59b4600671fe7c3f Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Fri, 11 Nov 2022 18:28:12 +0000 Subject: Implement setThreads APIs for PerformanceHintManager.Session. Previously the list of threads of a Session was only determined when the Session was created. This means newly forked threads from existing threads of the Session will not get the benefit and the clients have to create new Session for that. This patch adds a new method to allow clients to update the threads of the Session. Bug:b/244216750 Test: atest PerformanceHintManagerTest Test: atest PerformanceHintNativeTest Test: atest HintManagerServiceTest Change-Id: Iae8cbb4ce86a44a7cd9d6e68673c48800bed3a4e --- core/api/current.txt | 1 + core/api/test-current.txt | 1 + core/java/android/os/IHintManager.aidl | 7 ++- core/java/android/os/PerformanceHintManager.java | 34 ++++++++++ core/jni/android_os_PerformanceHintManager.cpp | 58 +++++++++++++++++ .../src/android/os/PerformanceHintManagerTest.java | 9 +++ native/android/libandroid.map.txt | 2 + native/android/performance_hint.cpp | 73 ++++++++++++++++++++-- .../performance_hint/PerformanceHintNativeTest.cpp | 42 ++++++++++++- .../server/power/hint/HintManagerService.java | 59 ++++++++++++++++- .../com_android_server_hint_HintManagerService.cpp | 16 +++++ .../server/power/hint/HintManagerServiceTest.java | 29 +++++++++ 12 files changed, 321 insertions(+), 10 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index 8b3a234e6acc..9a969933794d 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32484,6 +32484,7 @@ package android.os { public static class PerformanceHintManager.Session implements java.io.Closeable { method public void close(); method public void reportActualWorkDuration(long); + method public void setThreads(@NonNull int[]); method public void updateTargetWorkDuration(long); } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 64e2760110e0..191354dd8762 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1861,6 +1861,7 @@ package android.os { } public static class PerformanceHintManager.Session implements java.io.Closeable { + method @Nullable public int[] getThreadIds(); method public void sendHint(int); field public static final int CPU_LOAD_DOWN = 1; // 0x1 field public static final int CPU_LOAD_RESET = 2; // 0x2 diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl index 661b95affaf3..d97ea541f73d 100644 --- a/core/java/android/os/IHintManager.aidl +++ b/core/java/android/os/IHintManager.aidl @@ -24,10 +24,13 @@ interface IHintManager { /** * Creates a {@link Session} for the given set of threads and associates to a binder token. */ - IHintSession createHintSession(in IBinder token, in int[] tids, long durationNanos); + IHintSession createHintSession(in IBinder token, in int[] tids, long durationNanos); /** * Get preferred rate limit in nano second. */ - long getHintSessionPreferredRate(); + long getHintSessionPreferredRate(); + + void setHintSessionThreads(in IHintSession hintSession, in int[] tids); + int[] getHintSessionThreadIds(in IHintSession hintSession); } diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java index 85d6d83ef9e9..f79d6e6da1f8 100644 --- a/core/java/android/os/PerformanceHintManager.java +++ b/core/java/android/os/PerformanceHintManager.java @@ -222,16 +222,50 @@ public final class PerformanceHintManager { Reference.reachabilityFence(this); } } + + /** + * Set a list of threads to the performance hint session. This operation will replace + * the current list of threads with the given list of threads. + * Note that this is not an oneway method. + * + * @param tids The list of threads to be associated with this session. They must be + * part of this app's thread group. + * + * @throws IllegalStateException if the hint session is not in the foreground. + * @throws IllegalArgumentException if the thread id list is empty. + * @throws SecurityException if any thread id doesn't belong to the application. + */ + public void setThreads(@NonNull int[] tids) { + if (mNativeSessionPtr == 0) { + return; + } + if (tids.length == 0) { + throw new IllegalArgumentException("Thread id list can't be empty."); + } + nativeSetThreads(mNativeSessionPtr, tids); + } + + /** + * Returns the list of thread ids. + * + * @hide + */ + @TestApi + public @Nullable int[] getThreadIds() { + return nativeGetThreadIds(mNativeSessionPtr); + } } private static native long nativeAcquireManager(); private static native long nativeGetPreferredUpdateRateNanos(long nativeManagerPtr); private static native long nativeCreateSession(long nativeManagerPtr, int[] tids, long initialTargetWorkDurationNanos); + private static native int[] nativeGetThreadIds(long nativeSessionPtr); private static native void nativeUpdateTargetWorkDuration(long nativeSessionPtr, long targetDurationNanos); private static native void nativeReportActualWorkDuration(long nativeSessionPtr, long actualDurationNanos); private static native void nativeCloseSession(long nativeSessionPtr); private static native void nativeSendHint(long nativeSessionPtr, int hint); + private static native void nativeSetThreads(long nativeSessionPtr, int[] tids); } diff --git a/core/jni/android_os_PerformanceHintManager.cpp b/core/jni/android_os_PerformanceHintManager.cpp index ac1401dbb16d..0223b9669013 100644 --- a/core/jni/android_os_PerformanceHintManager.cpp +++ b/core/jni/android_os_PerformanceHintManager.cpp @@ -41,6 +41,8 @@ typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t); +typedef void (*APH_setThreads)(APerformanceHintSession*, const int32_t*, size_t); +typedef void (*APH_getThreadIds)(APerformanceHintSession*, int32_t* const, size_t* const); bool gAPerformanceHintBindingInitialized = false; APH_getManager gAPH_getManagerFn = nullptr; @@ -50,6 +52,8 @@ APH_updateTargetWorkDuration gAPH_updateTargetWorkDurationFn = nullptr; APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr; APH_closeSession gAPH_closeSessionFn = nullptr; APH_sendHint gAPH_sendHintFn = nullptr; +APH_setThreads gAPH_setThreadsFn = nullptr; +APH_getThreadIds gAPH_getThreadIdsFn = nullptr; void ensureAPerformanceHintBindingInitialized() { if (gAPerformanceHintBindingInitialized) return; @@ -95,6 +99,14 @@ void ensureAPerformanceHintBindingInitialized() { "Failed to find required symbol " "APerformanceHint_sendHint!"); + gAPH_setThreadsFn = (APH_setThreads)dlsym(handle_, "APerformanceHint_setThreads"); + LOG_ALWAYS_FATAL_IF(gAPH_setThreadsFn == nullptr, + "Failed to find required symbol APerformanceHint_setThreads!"); + + gAPH_getThreadIdsFn = (APH_getThreadIds)dlsym(handle_, "APerformanceHint_getThreadIds"); + LOG_ALWAYS_FATAL_IF(gAPH_getThreadIdsFn == nullptr, + "Failed to find required symbol APerformanceHint_getThreadIds!"); + gAPerformanceHintBindingInitialized = true; } @@ -150,6 +162,50 @@ static void nativeSendHint(JNIEnv* env, jclass clazz, jlong nativeSessionPtr, ji gAPH_sendHintFn(reinterpret_cast(nativeSessionPtr), hint); } +static void nativeSetThreads(JNIEnv* env, jclass clazz, jlong nativeSessionPtr, jintArray tids) { + ensureAPerformanceHintBindingInitialized(); + + if (tids == nullptr) { + return; + } + ScopedIntArrayRO tidsArray(env, tids); + std::vector tidsVector; + tidsVector.reserve(tidsArray.size()); + for (size_t i = 0; i < tidsArray.size(); ++i) { + tidsVector.push_back(static_cast(tidsArray[i])); + } + gAPH_setThreadsFn(reinterpret_cast(nativeSessionPtr), + tidsVector.data(), tidsVector.size()); +} + +// This call should only be used for validation in tests only. This call will initiate two IPC +// calls, the first one is used to determined the size of the thread ids list, the second one +// is used to return the actual list. +static jintArray nativeGetThreadIds(JNIEnv* env, jclass clazz, jlong nativeSessionPtr) { + ensureAPerformanceHintBindingInitialized(); + size_t size = 0; + gAPH_getThreadIdsFn(reinterpret_cast(nativeSessionPtr), nullptr, + &size); + if (size == 0) { + jintArray jintArr = env->NewIntArray(0); + return jintArr; + } + std::vector tidsVector(size); + gAPH_getThreadIdsFn(reinterpret_cast(nativeSessionPtr), + tidsVector.data(), &size); + jintArray jintArr = env->NewIntArray(size); + if (jintArr == nullptr) { + jniThrowException(env, "java/lang/OutOfMemoryError", nullptr); + return nullptr; + } + jint* threadIds = env->GetIntArrayElements(jintArr, 0); + for (int i = 0; i < size; ++i) { + threadIds[i] = tidsVector[i]; + } + env->ReleaseIntArrayElements(jintArr, threadIds, 0); + return jintArr; +} + static const JNINativeMethod gPerformanceHintMethods[] = { {"nativeAcquireManager", "()J", (void*)nativeAcquireManager}, {"nativeGetPreferredUpdateRateNanos", "(J)J", (void*)nativeGetPreferredUpdateRateNanos}, @@ -158,6 +214,8 @@ static const JNINativeMethod gPerformanceHintMethods[] = { {"nativeReportActualWorkDuration", "(JJ)V", (void*)nativeReportActualWorkDuration}, {"nativeCloseSession", "(J)V", (void*)nativeCloseSession}, {"nativeSendHint", "(JI)V", (void*)nativeSendHint}, + {"nativeSetThreads", "(J[I)V", (void*)nativeSetThreads}, + {"nativeGetThreadIds", "(J)[I", (void*)nativeGetThreadIds}, }; int register_android_os_PerformanceHintManager(JNIEnv* env) { diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java index 44923b60fbb5..7eefbbca2d01 100644 --- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java @@ -137,4 +137,13 @@ public class PerformanceHintManagerTest { assumeNotNull(s); s.close(); } + + @Test + public void testSetThreadsWithIllegalArgument() { + Session session = createSession(); + assumeNotNull(session); + assertThrows(IllegalArgumentException.class, () -> { + session.setThreads(new int[] { }); + }); + } } diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 4e6a0c540f49..e89c8c9aa583 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -330,6 +330,7 @@ LIBANDROID { APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu APerformanceHint_closeSession; # introduced=Tiramisu + APerformanceHint_setThreads; # introduced=UpsideDownCake local: *; }; @@ -338,6 +339,7 @@ LIBANDROID_PLATFORM { global: APerformanceHint_setIHintManagerForTesting; APerformanceHint_sendHint; + APerformanceHint_getThreadIds; extern "C++" { ASurfaceControl_registerSurfaceStatsListener*; ASurfaceControl_unregisterSurfaceStatsListener*; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 43b3d2e94aac..dfbd7b55a1f0 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -62,18 +62,21 @@ private: struct APerformanceHintSession { public: - APerformanceHintSession(sp session, int64_t preferredRateNanos, - int64_t targetDurationNanos); + APerformanceHintSession(sp hintManager, sp session, + int64_t preferredRateNanos, int64_t targetDurationNanos); APerformanceHintSession() = delete; ~APerformanceHintSession(); int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); int sendHint(int32_t hint); + int setThreads(const int32_t* threadIds, size_t size); + int getThreadIds(int32_t* const threadIds, size_t* size); private: friend struct APerformanceHintManager; + sp mHintManager; sp mHintSession; // HAL preferred update rate const int64_t mPreferredRateNanos; @@ -140,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); } @@ -150,10 +153,12 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const { // ===================================== APerformanceHintSession implementation -APerformanceHintSession::APerformanceHintSession(sp session, +APerformanceHintSession::APerformanceHintSession(sp hintManager, + sp session, int64_t preferredRateNanos, int64_t targetDurationNanos) - : mHintSession(std::move(session)), + : mHintManager(hintManager), + mHintSession(std::move(session)), mPreferredRateNanos(preferredRateNanos), mTargetDurationNanos(targetDurationNanos), mFirstTargetMetTimestamp(0), @@ -260,6 +265,47 @@ int APerformanceHintSession::sendHint(int32_t hint) { 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 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; + } + return 0; +} + +int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) { + std::vector 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; +} + // ===================================== C API APerformanceHintManager* APerformanceHint_getManager() { return APerformanceHintManager::getInstance(); @@ -293,6 +339,23 @@ int APerformanceHint_sendHint(void* session, int32_t hint) { return reinterpret_cast(session)->sendHint(hint); } +int APerformanceHint_setThreads(APerformanceHintSession* session, const int32_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) + ->getThreadIds(threadIds, size); +} + void APerformanceHint_setIHintManagerForTesting(void* iManager) { delete gHintManagerForTesting; gHintManagerForTesting = nullptr; diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 0c2d3b6cd201..321a7dddb144 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& tids, - int64_t durationNanos, ::android::sp<::android::os::IHintSession>* _aidl_return), + (const sp& token, const ::std::vector& tids, + int64_t durationNanos, ::android::sp* _aidl_return), (override)); MOCK_METHOD(Status, getHintSessionPreferredRate, (int64_t * _aidl_return), (override)); + MOCK_METHOD(Status, setHintSessionThreads, + (const sp& hintSession, const ::std::vector& tids), + (override)); + MOCK_METHOD(Status, getHintSessionThreadIds, + (const sp& hintSession, ::std::vector* tids), (override)); MOCK_METHOD(IBinder*, onAsBinder, (), (override)); }; @@ -141,3 +146,36 @@ TEST_F(PerformanceHintTest, TestSession) { EXPECT_CALL(*iSession, close()).Times(Exactly(1)); APerformanceHint_closeSession(session); } + +TEST_F(PerformanceHintTest, SetThreads) { + APerformanceHintManager* manager = createManager(); + + std::vector tids; + tids.push_back(1); + tids.push_back(2); + int64_t targetDuration = 56789L; + + StrictMock* iSession = new StrictMock(); + sp 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 emptyTids; + int result = APerformanceHint_setThreads(session, emptyTids.data(), emptyTids.size()); + EXPECT_EQ(EINVAL, result); + + std::vector 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/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index 952fcdce7e50..a9a1d5e9102c 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -189,6 +189,8 @@ public final class HintManagerService extends SystemService { private static native void nativeSendHint(long halPtr, int hint); + private static native void nativeSetThreads(long halPtr, int[] tids); + private static native long nativeGetHintSessionPreferredRate(); /** Wrapper for HintManager.nativeInit */ @@ -237,6 +239,11 @@ public final class HintManagerService extends SystemService { public long halGetHintSessionPreferredRate() { return nativeGetHintSessionPreferredRate(); } + + /** Wrapper for HintManager.nativeSetThreads */ + public void halSetThreads(long halPtr, int[] tids) { + nativeSetThreads(halPtr, tids); + } } @VisibleForTesting @@ -399,6 +406,18 @@ public final class HintManagerService extends SystemService { return mHintSessionPreferredRate; } + @Override + public void setHintSessionThreads(@NonNull IHintSession hintSession, @NonNull int[] tids) { + AppHintSession appHintSession = (AppHintSession) hintSession; + appHintSession.setThreads(tids); + } + + @Override + public int[] getHintSessionThreadIds(@NonNull IHintSession hintSession) { + AppHintSession appHintSession = (AppHintSession) hintSession; + return appHintSession.getThreadIds(); + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { @@ -434,11 +453,12 @@ public final class HintManagerService extends SystemService { final class AppHintSession extends IHintSession.Stub implements IBinder.DeathRecipient { protected final int mUid; protected final int mPid; - protected final int[] mThreadIds; + protected int[] mThreadIds; protected final IBinder mToken; protected long mHalSessionPtr; protected long mTargetDurationNanos; protected boolean mUpdateAllowed; + protected int[] mNewThreadIds; protected AppHintSession( int uid, int pid, int[] threadIds, IBinder token, @@ -541,6 +561,38 @@ public final class HintManagerService extends SystemService { } } + public void setThreads(@NonNull int[] tids) { + synchronized (mLock) { + if (mHalSessionPtr == 0) { + return; + } + if (tids.length == 0) { + throw new IllegalArgumentException("Thread id list can't be empty."); + } + final int callingUid = Binder.getCallingUid(); + final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid()); + final long identity = Binder.clearCallingIdentity(); + try { + if (!checkTidValid(callingUid, callingTgid, tids)) { + throw new SecurityException("Some tid doesn't belong to the application."); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + if (!updateHintAllowed()) { + Slogf.v(TAG, "update hint not allowed, storing tids."); + mNewThreadIds = tids; + return; + } + mNativeWrapper.halSetThreads(mHalSessionPtr, tids); + mThreadIds = tids; + } + } + + public int[] getThreadIds() { + return mThreadIds; + } + private void onProcStateChanged() { updateHintAllowed(); } @@ -556,6 +608,11 @@ public final class HintManagerService extends SystemService { synchronized (mLock) { if (mHalSessionPtr == 0) return; mNativeWrapper.halResumeHintSession(mHalSessionPtr); + if (mNewThreadIds != null) { + mNativeWrapper.halSetThreads(mHalSessionPtr, mNewThreadIds); + mThreadIds = mNewThreadIds; + mNewThreadIds = null; + } } } diff --git a/services/core/jni/com_android_server_hint_HintManagerService.cpp b/services/core/jni/com_android_server_hint_HintManagerService.cpp index d975760cbfc2..e322fa23e5b4 100644 --- a/services/core/jni/com_android_server_hint_HintManagerService.cpp +++ b/services/core/jni/com_android_server_hint_HintManagerService.cpp @@ -87,6 +87,11 @@ static void sendHint(int64_t session_ptr, SessionHint hint) { appSession->sendHint(hint); } +static void setThreads(int64_t session_ptr, const std::vector& threadIds) { + sp appSession = reinterpret_cast(session_ptr); + appSession->setThreads(threadIds); +} + static int64_t getHintSessionPreferredRate() { int64_t rate = -1; auto result = gPowerHalController.getHintSessionPreferredRate(); @@ -149,6 +154,16 @@ static void nativeSendHint(JNIEnv* env, jclass /* clazz */, jlong session_ptr, j sendHint(session_ptr, static_cast(hint)); } +static void nativeSetThreads(JNIEnv* env, jclass /* clazz */, jlong session_ptr, jintArray tids) { + ScopedIntArrayRO arrayThreadIds(env, tids); + + std::vector threadIds(arrayThreadIds.size()); + for (size_t i = 0; i < arrayThreadIds.size(); i++) { + threadIds[i] = arrayThreadIds[i]; + } + setThreads(session_ptr, threadIds); +} + static jlong nativeGetHintSessionPreferredRate(JNIEnv* /* env */, jclass /* clazz */) { return static_cast(getHintSessionPreferredRate()); } @@ -164,6 +179,7 @@ static const JNINativeMethod sHintManagerServiceMethods[] = { {"nativeUpdateTargetWorkDuration", "(JJ)V", (void*)nativeUpdateTargetWorkDuration}, {"nativeReportActualWorkDuration", "(J[J[J)V", (void*)nativeReportActualWorkDuration}, {"nativeSendHint", "(JI)V", (void*)nativeSendHint}, + {"nativeSetThreads", "(J[I)V", (void*)nativeSetThreads}, {"nativeGetHintSessionPreferredRate", "()J", (void*)nativeGetHintSessionPreferredRate}, }; diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java index dcbdcdc98017..136507d429fc 100644 --- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java @@ -19,6 +19,7 @@ package com.android.server.power.hint; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -310,4 +311,32 @@ public class HintManagerServiceTest { a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0); assertTrue(a.updateHintAllowed()); } + + @Test + public void testSetThreads() throws Exception { + HintManagerService service = createService(); + IBinder token = new Binder(); + + AppHintSession a = (AppHintSession) service.getBinderServiceInstance() + .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION); + + a.updateTargetWorkDuration(100L); + + assertThrows(IllegalArgumentException.class, () -> { + a.setThreads(new int[]{}); + }); + + a.setThreads(SESSION_TIDS_B); + verify(mNativeWrapperMock, times(1)).halSetThreads(anyLong(), eq(SESSION_TIDS_B)); + assertArrayEquals(SESSION_TIDS_B, a.getThreadIds()); + + reset(mNativeWrapperMock); + // Set session to background, then the duration would not be updated. + service.mUidObserver.onUidStateChanged( + a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); + FgThread.getHandler().runWithScissors(() -> { }, 500); + assertFalse(a.updateHintAllowed()); + a.setThreads(SESSION_TIDS_A); + verify(mNativeWrapperMock, never()).halSetThreads(anyLong(), any()); + } } -- cgit v1.2.3-59-g8ed1b From e2da4084a12368d022a217490af146bb9e3f5388 Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Fri, 2 Dec 2022 17:24:34 +0000 Subject: Add MULTI_FINGER_SWIPE motion classification Bug: 251196347 Test: check events received by a custom tester app, and touches shown by pointer location overlay Change-Id: Ice71843404400e73f8170ae108e2e2c89cc1d9bd --- core/java/android/view/MotionEvent.java | 17 +++++++++++++++-- native/android/input.cpp | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'native') diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 4fbb249c507f..1ff7ae662da0 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1491,11 +1491,23 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int CLASSIFICATION_TWO_FINGER_SWIPE = 3; + /** + * Classification constant: multi-finger swipe. + * + * The current event stream represents the user swiping with three or more fingers on a + * touchpad. Unlike two-finger swipes, these are only to be handled by the system UI, which is + * why they have a separate constant from two-finger swipes. + * + * @see #getClassification + * @hide + */ + public static final int CLASSIFICATION_MULTI_FINGER_SWIPE = 4; + /** @hide */ @Retention(SOURCE) @IntDef(prefix = { "CLASSIFICATION" }, value = { CLASSIFICATION_NONE, CLASSIFICATION_AMBIGUOUS_GESTURE, CLASSIFICATION_DEEP_PRESS, - CLASSIFICATION_TWO_FINGER_SWIPE}) + CLASSIFICATION_TWO_FINGER_SWIPE, CLASSIFICATION_MULTI_FINGER_SWIPE}) public @interface Classification {}; /** @@ -3941,7 +3953,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { return "DEEP_PRESS"; case CLASSIFICATION_TWO_FINGER_SWIPE: return "TWO_FINGER_SWIPE"; - + case CLASSIFICATION_MULTI_FINGER_SWIPE: + return "MULTI_FINGER_SWIPE"; } return "UNKNOWN"; } diff --git a/native/android/input.cpp b/native/android/input.cpp index 812db0f1c507..5e5ebed78e61 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -297,6 +297,8 @@ int32_t AMotionEvent_getClassification(const AInputEvent* motion_event) { 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; } } -- cgit v1.2.3-59-g8ed1b From 7ef81116f49d0835175de0c277c1c4a72b7e74fb Mon Sep 17 00:00:00 2001 From: Harry Cutts Date: Tue, 20 Dec 2022 11:04:20 +0000 Subject: Add pinch classification and scale factor axis Bug: 251196347 Test: check events received by a custom tester app, and touches shown by pointer location overlay Test: atest inputflinger_tests Change-Id: I0cb7ade63139ab35025ff1e12609e2b411b1f5f8 --- core/api/current.txt | 2 ++ core/java/android/view/MotionEvent.java | 31 ++++++++++++++++++++++++++++++- native/android/input.cpp | 2 ++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index 3d8491854c33..d0e5ca628e98 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -50482,6 +50482,7 @@ package android.view { field public static final int AXIS_GENERIC_7 = 38; // 0x26 field public static final int AXIS_GENERIC_8 = 39; // 0x27 field public static final int AXIS_GENERIC_9 = 40; // 0x28 + field public static final int AXIS_GESTURE_PINCH_SCALE_FACTOR = 52; // 0x34 field public static final int AXIS_GESTURE_SCROLL_X_DISTANCE = 50; // 0x32 field public static final int AXIS_GESTURE_SCROLL_Y_DISTANCE = 51; // 0x33 field public static final int AXIS_GESTURE_X_OFFSET = 48; // 0x30 @@ -50522,6 +50523,7 @@ package android.view { field public static final int CLASSIFICATION_AMBIGUOUS_GESTURE = 1; // 0x1 field public static final int CLASSIFICATION_DEEP_PRESS = 2; // 0x2 field public static final int CLASSIFICATION_NONE = 0; // 0x0 + field public static final int CLASSIFICATION_PINCH = 5; // 0x5 field public static final int CLASSIFICATION_TWO_FINGER_SWIPE = 3; // 0x3 field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int EDGE_BOTTOM = 2; // 0x2 diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index a36fd8d99e3c..2235663f7706 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1283,6 +1283,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { * swipe gesture starts at X = 500 then moves to X = 400, this axis would have a value of * -0.1. * + * These values are relative to the state from the last event, not accumulated, so developers + * should make sure to process this axis value for all batched historical events. */ public static final int AXIS_GESTURE_X_OFFSET = 48; @@ -1300,6 +1302,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { *

  • For a touch pad, reports the distance that should be scrolled in the X axis as a result * of the user's two-finger scroll gesture, in display pixels. * + * These values are relative to the state from the last event, not accumulated, so developers + * should make sure to process this axis value for all batched historical events. */ public static final int AXIS_GESTURE_SCROLL_X_DISTANCE = 50; @@ -1310,6 +1314,19 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int AXIS_GESTURE_SCROLL_Y_DISTANCE = 51; + /** + * Axis constant: pinch scale factor of a motion event. + *

    + *

      + *
    • For a touch pad, reports the change in distance between the fingers when the user is + * making a pinch gesture, as a proportion of the previous distance. For example, if the fingers + * were 50 units apart and are now 52 units apart, the scale factor would be 1.04. + *
    + * These values are relative to the state from the last event, not accumulated, so developers + * should make sure to process this axis value for all batched historical events. + */ + public static final int AXIS_GESTURE_PINCH_SCALE_FACTOR = 52; + // NOTE: If you add a new axis here you must also add it to: // frameworks/native/include/android/input.h // frameworks/native/libs/input/InputEventLabels.cpp @@ -1369,6 +1386,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { names.append(AXIS_GESTURE_Y_OFFSET, "AXIS_GESTURE_Y_OFFSET"); names.append(AXIS_GESTURE_SCROLL_X_DISTANCE, "AXIS_GESTURE_SCROLL_X_DISTANCE"); names.append(AXIS_GESTURE_SCROLL_Y_DISTANCE, "AXIS_GESTURE_SCROLL_Y_DISTANCE"); + names.append(AXIS_GESTURE_PINCH_SCALE_FACTOR, "AXIS_GESTURE_PINCH_SCALE_FACTOR"); } /** @@ -1522,11 +1540,22 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int CLASSIFICATION_MULTI_FINGER_SWIPE = 4; + /** + * Classification constant: touchpad pinch. + * + * The current event stream represents the user pinching with two fingers on a touchpad. The + * gesture is centered around the current cursor position. + * + * @see #getClassification + */ + public static final int CLASSIFICATION_PINCH = 5; + /** @hide */ @Retention(SOURCE) @IntDef(prefix = { "CLASSIFICATION" }, value = { CLASSIFICATION_NONE, CLASSIFICATION_AMBIGUOUS_GESTURE, CLASSIFICATION_DEEP_PRESS, - CLASSIFICATION_TWO_FINGER_SWIPE, CLASSIFICATION_MULTI_FINGER_SWIPE}) + CLASSIFICATION_TWO_FINGER_SWIPE, CLASSIFICATION_MULTI_FINGER_SWIPE, + CLASSIFICATION_PINCH}) public @interface Classification {}; /** diff --git a/native/android/input.cpp b/native/android/input.cpp index 5e5ebed78e61..f1c30889c4db 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -299,6 +299,8 @@ int32_t AMotionEvent_getClassification(const AInputEvent* motion_event) { 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; } } -- cgit v1.2.3-59-g8ed1b From 7c6023ec98dec332118b2eb412322905efb19e22 Mon Sep 17 00:00:00 2001 From: Mateusz Zbikowski Date: Thu, 5 Jan 2023 12:30:05 +0000 Subject: Add CtsSdkSandboxWebkitTestCases to WebView TEST_MAPPING. Bug: 262697818 Test: atest --test-mapping frameworks/base/core/java/android/webkit Change-Id: Id9d28a5156439985d63676f4e863bfa85868d4f9 --- core/java/android/webkit/TEST_MAPPING | 8 ++++++++ native/webview/TEST_MAPPING | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'native') diff --git a/core/java/android/webkit/TEST_MAPPING b/core/java/android/webkit/TEST_MAPPING index bd25200ffc38..c1bc6d720ece 100644 --- a/core/java/android/webkit/TEST_MAPPING +++ b/core/java/android/webkit/TEST_MAPPING @@ -8,6 +8,14 @@ } ] }, + { + "name": "CtsSdkSandboxWebkitTestCases", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, { "name": "CtsHostsideWebViewTests", "options": [ 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 @@ -8,6 +8,14 @@ } ] }, + { + "name": "CtsSdkSandboxWebkitTestCases", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] + }, { "name": "CtsHostsideWebViewTests", "options": [ -- cgit v1.2.3-59-g8ed1b From 02d8919614b7920aa2c5c3820be77bba8c54846f Mon Sep 17 00:00:00 2001 From: Yurii Zubrytskyi Date: Wed, 4 Jan 2023 08:44:34 -0800 Subject: [res] Add the grammatical gender qualifier Bug: 237579711 Test: UTs + build + boot Change-Id: Id0919799a8a364f109ff351974f02e4f151f23cd --- core/api/current.txt | 6 +- core/java/android/content/pm/ActivityInfo.java | 5 +- core/java/android/content/pm/PackageParser.java | 6 +- core/java/android/content/res/AssetManager.java | 7 ++- core/java/android/content/res/Configuration.java | 67 ++++++++++++++++------ core/java/android/content/res/ResourcesImpl.java | 3 +- core/jni/android_util_AssetManager.cpp | 5 +- core/proto/android/content/configuration.proto | 1 + libs/androidfw/ConfigDescription.cpp | 45 ++++++++++++--- libs/androidfw/ResourceTypes.cpp | 35 ++++++++++- .../include/androidfw/ConfigDescription.h | 6 ++ libs/androidfw/include/androidfw/ResourceTypes.h | 34 ++++++++--- libs/androidfw/tests/ConfigDescription_test.cpp | 18 ++++++ libs/androidfw/tests/Config_test.cpp | 14 +++++ native/android/configuration.cpp | 8 +++ native/android/libandroid.map.txt | 2 + .../server/pm/split/DefaultSplitAssetLoader.java | 2 +- .../pm/split/SplitAssetDependencyLoader.java | 2 +- tools/aapt2/Configuration.proto | 10 ++++ tools/aapt2/format/proto/ProtoDeserialize.cpp | 1 + tools/aapt2/format/proto/ProtoSerialize.cpp | 4 ++ tools/aapt2/format/proto/ProtoSerialize_test.cpp | 8 ++- tools/aapt2/test/Builders.h | 6 +- 23 files changed, 242 insertions(+), 53 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index 24b985d88e4b..ece3f8eff33f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -12984,9 +12984,9 @@ package android.content.res { field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int DENSITY_DPI_UNDEFINED = 0; // 0x0 field public static final int FONT_WEIGHT_ADJUSTMENT_UNDEFINED = 2147483647; // 0x7fffffff - field public static final int GRAMMATICAL_GENDER_FEMININE = 3; // 0x3 - field public static final int GRAMMATICAL_GENDER_MASCULINE = 4; // 0x4 - field public static final int GRAMMATICAL_GENDER_NEUTRAL = 2; // 0x2 + field public static final int GRAMMATICAL_GENDER_FEMININE = 2; // 0x2 + field public static final int GRAMMATICAL_GENDER_MASCULINE = 3; // 0x3 + field public static final int GRAMMATICAL_GENDER_NEUTRAL = 1; // 0x1 field public static final int GRAMMATICAL_GENDER_NOT_SPECIFIED = 0; // 0x0 field public static final int HARDKEYBOARDHIDDEN_NO = 1; // 0x1 field public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0; // 0x0 diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index a9f55bc1ea4c..adcd1861886a 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -998,6 +998,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { Configuration.NATIVE_CONFIG_DENSITY, // DENSITY Configuration.NATIVE_CONFIG_LAYOUTDIR, // LAYOUT DIRECTION Configuration.NATIVE_CONFIG_COLOR_MODE, // COLOR_MODE + Configuration.NATIVE_CONFIG_GRAMMATICAL_GENDER, }; /** @@ -1267,8 +1268,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN}, * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, * {@link #CONFIG_ORIENTATION}, {@link #CONFIG_SCREEN_LAYOUT}, - * {@link #CONFIG_DENSITY}, {@link #CONFIG_LAYOUT_DIRECTION} and - * {@link #CONFIG_COLOR_MODE}. + * {@link #CONFIG_DENSITY}, {@link #CONFIG_LAYOUT_DIRECTION}, + * {@link #CONFIG_COLOR_MODE}, and {link #CONFIG_GRAMMATICAL_GENDER}. * Set from the {@link android.R.attr#configChanges} attribute. */ public int configChanges; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index c15b3e0b80c3..048289f56a0c 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1456,7 +1456,7 @@ public class PackageParser { private static AssetManager newConfiguredAssetManager() { AssetManager assetManager = new AssetManager(); - assetManager.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assetManager.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); return assetManager; } @@ -9011,7 +9011,7 @@ public class PackageParser { } AssetManager assets = new AssetManager(); - assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); assets.setApkAssets(apkAssets, false /*invalidateCaches*/); @@ -9086,7 +9086,7 @@ public class PackageParser { private static AssetManager createAssetManagerWithAssets(ApkAssets[] apkAssets) { final AssetManager assets = new AssetManager(); - assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); assets.setApkAssets(apkAssets, false /*invalidateCaches*/); return assets; diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index c8bbb0c1994d..dfc7b4649770 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1461,13 +1461,14 @@ public final class AssetManager implements AutoCloseable { public void setConfiguration(int mcc, int mnc, @Nullable String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, - int screenHeightDp, int screenLayout, int uiMode, int colorMode, int majorVersion) { + int screenHeightDp, int screenLayout, int uiMode, int colorMode, int grammaticalGender, + int majorVersion) { synchronized (this) { ensureValidLocked(); nativeSetConfiguration(mObject, mcc, mnc, locale, orientation, touchscreen, density, keyboard, keyboardHidden, navigation, screenWidth, screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp, screenLayout, uiMode, - colorMode, majorVersion); + colorMode, grammaticalGender, majorVersion); } } @@ -1557,7 +1558,7 @@ public final class AssetManager implements AutoCloseable { @Nullable String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, - int uiMode, int colorMode, int majorVersion); + int uiMode, int colorMode, int grammaticalGender, int majorVersion); private static native @NonNull SparseArray nativeGetAssignedPackageIdentifiers( long ptr, boolean includeOverlays, boolean includeLoaders); diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 96aa6249245c..0def59f36d80 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -20,6 +20,7 @@ import static android.content.ConfigurationProto.COLOR_MODE; import static android.content.ConfigurationProto.DENSITY_DPI; import static android.content.ConfigurationProto.FONT_SCALE; import static android.content.ConfigurationProto.FONT_WEIGHT_ADJUSTMENT; +import static android.content.ConfigurationProto.GRAMMATICAL_GENDER; import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN; import static android.content.ConfigurationProto.KEYBOARD; import static android.content.ConfigurationProto.KEYBOARD_HIDDEN; @@ -167,19 +168,19 @@ public final class Configuration implements Parcelable, ComparableConstruct an invalid Configuration. This state is only suitable for constructing a @@ -1112,6 +1112,14 @@ public final class Configuration implements Parcelable, Comparable(screen_layout); configuration.uiMode = static_cast(ui_mode); configuration.colorMode = static_cast(color_mode); + configuration.grammaticalInflection = static_cast(grammatical_gender); configuration.sdkVersion = static_cast(major_version); if (locale != nullptr) { @@ -1448,7 +1449,7 @@ static const JNINativeMethod gAssetManagerMethods[] = { {"nativeCreate", "()J", (void*)NativeCreate}, {"nativeDestroy", "(J)V", (void*)NativeDestroy}, {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;Z)V", (void*)NativeSetApkAssets}, - {"nativeSetConfiguration", "(JIILjava/lang/String;IIIIIIIIIIIIIII)V", + {"nativeSetConfiguration", "(JIILjava/lang/String;IIIIIIIIIIIIIIII)V", (void*)NativeSetConfiguration}, {"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;", (void*)NativeGetAssignedPackageIdentifiers}, diff --git a/core/proto/android/content/configuration.proto b/core/proto/android/content/configuration.proto index b1ffe3881caa..0e2234f2fdcc 100644 --- a/core/proto/android/content/configuration.proto +++ b/core/proto/android/content/configuration.proto @@ -50,6 +50,7 @@ message ConfigurationProto { optional .android.app.WindowConfigurationProto window_configuration = 19; optional string locale_list = 20; optional uint32 font_weight_adjustment = 21; + optional uint32 grammatical_gender = 22; } /** diff --git a/libs/androidfw/ConfigDescription.cpp b/libs/androidfw/ConfigDescription.cpp index 93a7d173cb97..cf2fd6f59b87 100644 --- a/libs/androidfw/ConfigDescription.cpp +++ b/libs/androidfw/ConfigDescription.cpp @@ -21,6 +21,7 @@ #include "androidfw/Util.h" #include +#include #include namespace android { @@ -38,11 +39,11 @@ static bool parseMcc(const char* name, ResTable_config* out) { return true; } const char* c = name; - if (tolower(*c) != 'm') return false; + if (*c != 'm') return false; c++; - if (tolower(*c) != 'c') return false; + if (*c != 'c') return false; c++; - if (tolower(*c) != 'c') return false; + if (*c != 'c') return false; c++; const char* val = c; @@ -68,11 +69,11 @@ static bool parseMnc(const char* name, ResTable_config* out) { return true; } const char* c = name; - if (tolower(*c) != 'm') return false; + if (*c != 'm') return false; c++; - if (tolower(*c) != 'n') return false; + if (*c != 'n') return false; c++; - if (tolower(*c) != 'c') return false; + if (*c != 'c') return false; c++; const char* val = c; @@ -93,6 +94,23 @@ static bool parseMnc(const char* name, ResTable_config* out) { return true; } +static bool parseGrammaticalInflection(const std::string& name, ResTable_config* out) { + using namespace std::literals; + if (name == "feminine"sv) { + if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_FEMININE; + return true; + } + if (name == "masculine"sv) { + if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_MASCULINE; + return true; + } + if (name == "neuter"sv) { + if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_NEUTER; + return true; + } + return false; +} + static bool parseLayoutDirection(const char* name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0) { if (out) @@ -678,6 +696,13 @@ bool ConfigDescription::Parse(StringPiece str, ConfigDescription* out) { } } + if (parseGrammaticalInflection(*part_iter, &config)) { + ++part_iter; + if (part_iter == parts_end) { + goto success; + } + } + if (parseLayoutDirection(part_iter->c_str(), &config)) { ++part_iter; if (part_iter == parts_end) { @@ -832,11 +857,13 @@ success: void ConfigDescription::ApplyVersionForCompatibility( ConfigDescription* config) { uint16_t min_sdk = 0; - if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) + if (config->grammaticalInflection != 0) { + min_sdk = SDK_U; + } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) == ResTable_config::UI_MODE_TYPE_VR_HEADSET || config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT || config->colorMode & ResTable_config::MASK_HDR) { - min_sdk = SDK_O; + min_sdk = SDK_O; } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) { min_sdk = SDK_MARSHMALLOW; } else if (config->density == ResTable_config::DENSITY_ANY) { @@ -913,6 +940,7 @@ bool ConfigDescription::HasHigherPrecedenceThan( if (country[0] || o.country[0]) return (!o.country[0]); // Script and variant require either a language or country, both of which // have higher precedence. + if (grammaticalInflection || o.grammaticalInflection) return !o.grammaticalInflection; if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) { return !(o.screenLayout & MASK_LAYOUTDIR); } @@ -971,6 +999,7 @@ bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const { // The values here can be found in ResTable_config#match. Density and range // values can't lead to conflicts, and are ignored. return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) || + !pred(grammaticalInflection, o.grammaticalInflection) || !pred(screenLayout & MASK_LAYOUTDIR, o.screenLayout & MASK_LAYOUTDIR) || !pred(screenLayout & MASK_SCREENLONG, diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 1fed2067d16e..29d33da6b2f7 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -2105,6 +2105,9 @@ int ResTable_config::compare(const ResTable_config& o) const { return 1; } + if (grammaticalInflection != o.grammaticalInflection) { + return grammaticalInflection < o.grammaticalInflection ? -1 : 1; + } if (screenType != o.screenType) { return (screenType > o.screenType) ? 1 : -1; } @@ -2153,7 +2156,9 @@ int ResTable_config::compareLogical(const ResTable_config& o) const { if (diff > 0) { return 1; } - + if (grammaticalInflection != o.grammaticalInflection) { + return grammaticalInflection < o.grammaticalInflection ? -1 : 1; + } if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) { return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1; } @@ -2223,6 +2228,7 @@ int ResTable_config::diff(const ResTable_config& o) const { if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE; if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; + if (grammaticalInflection != o.grammaticalInflection) diffs |= CONFIG_GRAMMATICAL_GENDER; const int diff = compareLocales(*this, o); if (diff) diffs |= CONFIG_LOCALE; @@ -2289,6 +2295,13 @@ bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const { } } + if (grammaticalInflection || o.grammaticalInflection) { + if (grammaticalInflection != o.grammaticalInflection) { + if (!grammaticalInflection) return false; + if (!o.grammaticalInflection) return true; + } + } + if (screenLayout || o.screenLayout) { if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) { if (!(screenLayout & MASK_LAYOUTDIR)) return false; @@ -2555,6 +2568,13 @@ bool ResTable_config::isBetterThan(const ResTable_config& o, return true; } + if (grammaticalInflection || o.grammaticalInflection) { + if (grammaticalInflection != o.grammaticalInflection + && requested->grammaticalInflection) { + return !!grammaticalInflection; + } + } + if (screenLayout || o.screenLayout) { if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0 && (requested->screenLayout & MASK_LAYOUTDIR)) { @@ -2854,6 +2874,10 @@ bool ResTable_config::match(const ResTable_config& settings) const { } } + if (grammaticalInflection && grammaticalInflection != settings.grammaticalInflection) { + return false; + } + if (screenConfig != 0) { const int layoutDir = screenLayout&MASK_LAYOUTDIR; const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR; @@ -3267,6 +3291,15 @@ String8 ResTable_config::toString() const { appendDirLocale(res); + if ((grammaticalInflection & GRAMMATICAL_INFLECTION_GENDER_MASK) != 0) { + if (res.size() > 0) res.append("-"); + switch (grammaticalInflection & GRAMMATICAL_INFLECTION_GENDER_MASK) { + case GRAMMATICAL_GENDER_NEUTER: res.append("neuter"); break; + case GRAMMATICAL_GENDER_FEMININE: res.append("feminine"); break; + case GRAMMATICAL_GENDER_MASCULINE: res.append("masculine"); break; + } + } + if ((screenLayout&MASK_LAYOUTDIR) != 0) { if (res.size() > 0) res.append("-"); switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) { diff --git a/libs/androidfw/include/androidfw/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h index 71087cdfb6fa..7fbd7c08ea69 100644 --- a/libs/androidfw/include/androidfw/ConfigDescription.h +++ b/libs/androidfw/include/androidfw/ConfigDescription.h @@ -53,6 +53,12 @@ enum : ApiVersion { SDK_O = 26, SDK_O_MR1 = 27, SDK_P = 28, + SDK_Q = 29, + SDK_R = 30, + SDK_S = 31, + SDK_S_V2 = 32, + SDK_TIRAMISU = 33, + SDK_U = 34, }; /* diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 52321dad8a5a..631bda4f886c 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1071,15 +1071,32 @@ struct ResTable_config NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN, NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN, }; - - union { - struct { - uint8_t keyboard; - uint8_t navigation; - uint8_t inputFlags; - uint8_t inputPad0; + + enum { + GRAMMATICAL_GENDER_ANY = ACONFIGURATION_GRAMMATICAL_GENDER_ANY, + GRAMMATICAL_GENDER_NEUTER = ACONFIGURATION_GRAMMATICAL_GENDER_NEUTER, + GRAMMATICAL_GENDER_FEMININE = ACONFIGURATION_GRAMMATICAL_GENDER_FEMININE, + GRAMMATICAL_GENDER_MASCULINE = ACONFIGURATION_GRAMMATICAL_GENDER_MASCULINE, + GRAMMATICAL_INFLECTION_GENDER_MASK = 0b11, + }; + + struct { + union { + struct { + uint8_t keyboard; + uint8_t navigation; + uint8_t inputFlags; + uint8_t inputFieldPad0; + }; + struct { + uint32_t input : 24; + uint32_t inputFullPad0 : 8; + }; + struct { + uint8_t grammaticalInflectionPad0[3]; + uint8_t grammaticalInflection; + }; }; - uint32_t input; }; enum { @@ -1263,6 +1280,7 @@ struct ResTable_config CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR, CONFIG_SCREEN_ROUND = ACONFIGURATION_SCREEN_ROUND, CONFIG_COLOR_MODE = ACONFIGURATION_COLOR_MODE, + CONFIG_GRAMMATICAL_GENDER = ACONFIGURATION_GRAMMATICAL_GENDER, }; // Compare two configuration, returning CONFIG_* flags set for each value diff --git a/libs/androidfw/tests/ConfigDescription_test.cpp b/libs/androidfw/tests/ConfigDescription_test.cpp index 8fed0a4d22fc..f5c01e5d9b68 100644 --- a/libs/androidfw/tests/ConfigDescription_test.cpp +++ b/libs/androidfw/tests/ConfigDescription_test.cpp @@ -154,4 +154,22 @@ TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) { EXPECT_FALSE(ParseConfigOrDie("600x400").ConflictsWith(ParseConfigOrDie("300x200"))); } +TEST(ConfigDescriptionTest, TestGrammaticalGenderQualifier) { + ConfigDescription config; + EXPECT_TRUE(TestParse("feminine", &config)); + EXPECT_EQ(android::ResTable_config::GRAMMATICAL_GENDER_FEMININE, config.grammaticalInflection); + EXPECT_EQ(SDK_U, config.sdkVersion); + EXPECT_EQ(std::string("feminine-v34"), config.toString().string()); + + EXPECT_TRUE(TestParse("masculine", &config)); + EXPECT_EQ(android::ResTable_config::GRAMMATICAL_GENDER_MASCULINE, config.grammaticalInflection); + EXPECT_EQ(SDK_U, config.sdkVersion); + EXPECT_EQ(std::string("masculine-v34"), config.toString().string()); + + EXPECT_TRUE(TestParse("neuter", &config)); + EXPECT_EQ(android::ResTable_config::GRAMMATICAL_GENDER_NEUTER, config.grammaticalInflection); + EXPECT_EQ(SDK_U, config.sdkVersion); + EXPECT_EQ(std::string("neuter-v34"), config.toString().string()); +} + } // namespace android diff --git a/libs/androidfw/tests/Config_test.cpp b/libs/androidfw/tests/Config_test.cpp index 698c36f09301..5477621ce9fd 100644 --- a/libs/androidfw/tests/Config_test.cpp +++ b/libs/androidfw/tests/Config_test.cpp @@ -205,4 +205,18 @@ TEST(ConfigTest, ScreenIsHdr) { EXPECT_EQ(defaultConfig.diff(hdrConfig), ResTable_config::CONFIG_COLOR_MODE); } +TEST(ConfigTest, GrammaticalGender) { + ResTable_config defaultConfig = {}; + ResTable_config masculine = {}; + masculine.grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_MASCULINE; + + EXPECT_EQ(defaultConfig.diff(masculine), ResTable_config::CONFIG_GRAMMATICAL_GENDER); + + ResTable_config feminine = {}; + feminine.grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_FEMININE; + + EXPECT_EQ(defaultConfig.diff(feminine), ResTable_config::CONFIG_GRAMMATICAL_GENDER); + EXPECT_EQ(masculine.diff(feminine), ResTable_config::CONFIG_GRAMMATICAL_GENDER); +} + } // namespace android. 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<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/libandroid.map.txt b/native/android/libandroid.map.txt index e89c8c9aa583..e4b9b5dc6157 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; diff --git a/services/core/java/com/android/server/pm/split/DefaultSplitAssetLoader.java b/services/core/java/com/android/server/pm/split/DefaultSplitAssetLoader.java index 2bd7cf848196..a2177e87bcdb 100644 --- a/services/core/java/com/android/server/pm/split/DefaultSplitAssetLoader.java +++ b/services/core/java/com/android/server/pm/split/DefaultSplitAssetLoader.java @@ -82,7 +82,7 @@ public class DefaultSplitAssetLoader implements SplitAssetLoader { } AssetManager assets = new AssetManager(); - assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); assets.setApkAssets(apkAssets, false /*invalidateCaches*/); diff --git a/services/core/java/com/android/server/pm/split/SplitAssetDependencyLoader.java b/services/core/java/com/android/server/pm/split/SplitAssetDependencyLoader.java index ae42e0980fb7..1a8c199608df 100644 --- a/services/core/java/com/android/server/pm/split/SplitAssetDependencyLoader.java +++ b/services/core/java/com/android/server/pm/split/SplitAssetDependencyLoader.java @@ -80,7 +80,7 @@ public class SplitAssetDependencyLoader extends SplitDependencyLoaderscreenWidth = static_cast(pb_config.screen_width()); out_config->screenHeight = static_cast(pb_config.screen_height()); out_config->sdkVersion = static_cast(pb_config.sdk_version()); + out_config->grammaticalInflection = pb_config.grammatical_gender(); return true; } diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp index 0e40124aa79e..0903205b5eb2 100644 --- a/tools/aapt2/format/proto/ProtoSerialize.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize.cpp @@ -275,6 +275,10 @@ void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_ } out_pb_config->set_sdk_version(config.sdkVersion); + + // The constant values are the same across the structs. + out_pb_config->set_grammatical_gender( + static_cast(config.grammaticalInflection)); } static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item, diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp index ecfdba83a2e8..afb83562b129 100644 --- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp @@ -581,9 +581,13 @@ TEST(ProtoSerializeTest, SerializeDeserializeConfiguration) { ExpectConfigSerializes("v8"); + ExpectConfigSerializes("en-feminine"); + ExpectConfigSerializes("en-neuter-v34"); + ExpectConfigSerializes("feminine-v34"); + ExpectConfigSerializes( - "mcc123-mnc456-b+en+GB-ldltr-sw300dp-w300dp-h400dp-large-long-round-widecg-highdr-land-car-" - "night-xhdpi-stylus-keysexposed-qwerty-navhidden-dpad-300x200-v23"); + "mcc123-mnc456-b+en+GB-masculine-ldltr-sw300dp-w300dp-h400dp-large-long-round-widecg-highdr-" + "land-car-night-xhdpi-stylus-keysexposed-qwerty-navhidden-dpad-300x200-v23"); } TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) { diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h index f03d6fcd03f1..098535d8526f 100644 --- a/tools/aapt2/test/Builders.h +++ b/tools/aapt2/test/Builders.h @@ -251,7 +251,11 @@ class ConfigDescriptionBuilder { return *this; } ConfigDescriptionBuilder& setInputPad0(uint8_t inputPad0) { - config_.inputPad0 = inputPad0; + config_.inputFieldPad0 = inputPad0; + return *this; + } + ConfigDescriptionBuilder& setGrammaticalInflection(uint8_t value) { + config_.grammaticalInflection = value; return *this; } ConfigDescriptionBuilder& setScreenWidth(uint16_t screenWidth) { -- cgit v1.2.3-59-g8ed1b From 7ed6de3e90e509ac8822f357822ea3934eeb3fd4 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Thu, 26 Jan 2023 00:52:54 +0000 Subject: Use pid_t instead of not int32_t. Bug: b/266595015 Test: atest PerformanceHintManagerTest Change-Id: I51e0c2190117f9b439088e5a094dc3c74f5deeab --- core/jni/android_os_PerformanceHintManager.cpp | 2 +- native/android/performance_hint.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'native') diff --git a/core/jni/android_os_PerformanceHintManager.cpp b/core/jni/android_os_PerformanceHintManager.cpp index 0223b9669013..d8a2497439c2 100644 --- a/core/jni/android_os_PerformanceHintManager.cpp +++ b/core/jni/android_os_PerformanceHintManager.cpp @@ -41,7 +41,7 @@ typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t); -typedef void (*APH_setThreads)(APerformanceHintSession*, const int32_t*, size_t); +typedef void (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t); typedef void (*APH_getThreadIds)(APerformanceHintSession*, int32_t* const, size_t* const); bool gAPerformanceHintBindingInitialized = false; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index dfbd7b55a1f0..27666caafac4 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -339,7 +339,7 @@ int APerformanceHint_sendHint(void* session, int32_t hint) { return reinterpret_cast(session)->sendHint(hint); } -int APerformanceHint_setThreads(APerformanceHintSession* session, const int32_t* threadIds, +int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds, size_t size) { if (session == nullptr) { return EINVAL; -- cgit v1.2.3-59-g8ed1b From 9c64b1bcf61c2bd732a5c0c99c32fcdb2372aafe Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Tue, 31 Jan 2023 21:22:15 +0000 Subject: Use "SessionHint" enum in ndk API Change NDK to use "SessionHint" enum consistently across definitions. Bug: 266596626 Test: manual Change-Id: I87b157f54d68115c0f972f6fb33153375858fe2e --- native/android/performance_hint.cpp | 6 +++--- native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'native') diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 27666caafac4..b3628fa3e5ce 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -69,7 +69,7 @@ public: int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); - int sendHint(int32_t hint); + int sendHint(SessionHint hint); int setThreads(const int32_t* threadIds, size_t size); int getThreadIds(int32_t* const threadIds, size_t* size); @@ -243,7 +243,7 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano return 0; } -int APerformanceHintSession::sendHint(int32_t hint) { +int APerformanceHintSession::sendHint(SessionHint hint) { if (hint < 0 || hint >= static_cast(mLastHintSentTimestamp.size())) { ALOGE("%s: invalid session hint %d", __FUNCTION__, hint); return EINVAL; @@ -335,7 +335,7 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) { delete session; } -int APerformanceHint_sendHint(void* session, int32_t hint) { +int APerformanceHint_sendHint(void* session, SessionHint hint) { return reinterpret_cast(session)->sendHint(hint); } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 321a7dddb144..791adfd33fcd 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -127,7 +127,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_reportActualWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); - int hintId = 2; + SessionHint hintId = SessionHint::CPU_LOAD_RESET; EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1)); result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); @@ -140,7 +140,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); - result = APerformanceHint_sendHint(session, -1); + result = APerformanceHint_sendHint(session, static_cast(-1)); EXPECT_EQ(EINVAL, result); EXPECT_CALL(*iSession, close()).Times(Exactly(1)); -- cgit v1.2.3-59-g8ed1b From 93d2d0b43ec3e07cfe6b8c32a900f8d433b5f6d5 Mon Sep 17 00:00:00 2001 From: Rachel Lee Date: Fri, 6 Jan 2023 14:06:29 -0800 Subject: NDK attached Choreographer from SurfaceControl. The API to get a native attached choreographer from ASurfaceControl. Bug: 255838011 Test: atest ChoreographerTests Test: atest ChoreographerNativeTest Change-Id: I7ed0ebea9f735e102f2285edb3a1cc35b338c3c9 --- native/android/libandroid.map.txt | 1 + native/android/surface_control.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'native') diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 987b23fdd1fd..f258c27aa070 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -345,6 +345,7 @@ LIBANDROID_PLATFORM { extern "C++" { ASurfaceControl_registerSurfaceStatsListener*; ASurfaceControl_unregisterSurfaceStatsListener*; + ASurfaceControl_getChoreographer*; ASurfaceControlStats_getAcquireTime*; ASurfaceControlStats_getFrameNumber*; }; diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index ea20c6c9e0b1..b7f359602a5d 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -180,6 +180,18 @@ void ASurfaceControl_unregisterSurfaceStatsListener(void* context, reinterpret_cast(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)); + if (!surfaceControl->isValid()) { + ALOGE("Attempted to get choreographer from invalid surface control"); + return nullptr; + } + SurfaceControl_acquire(surfaceControl); + return reinterpret_cast(surfaceControl->getChoreographer().get()); +} + int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats) { if (const auto* fence = std::get_if>(&stats->acquireTimeOrFence)) { // We got a fence instead of the acquire time due to latch unsignaled. -- cgit v1.2.3-59-g8ed1b From 712f58a6f6a628c009e0cf548b33c9e11d9415de Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Tue, 7 Feb 2023 02:10:58 +0000 Subject: Revert "Use "SessionHint" enum in ndk API" Revert submission 21161765-sessionhint_api Reason for revert: this broke the main-finalization-1 build... somehow. see b/268111957 Reverted changes: /q/submissionid:21161765-sessionhint_api Change-Id: I23ca8da4957aa030d7788d22fc946259e34ee3cf --- native/android/performance_hint.cpp | 6 +++--- native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'native') diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index b3628fa3e5ce..27666caafac4 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -69,7 +69,7 @@ public: int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); - int sendHint(SessionHint hint); + int sendHint(int32_t hint); int setThreads(const int32_t* threadIds, size_t size); int getThreadIds(int32_t* const threadIds, size_t* size); @@ -243,7 +243,7 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano return 0; } -int APerformanceHintSession::sendHint(SessionHint hint) { +int APerformanceHintSession::sendHint(int32_t hint) { if (hint < 0 || hint >= static_cast(mLastHintSentTimestamp.size())) { ALOGE("%s: invalid session hint %d", __FUNCTION__, hint); return EINVAL; @@ -335,7 +335,7 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) { delete session; } -int APerformanceHint_sendHint(void* session, SessionHint hint) { +int APerformanceHint_sendHint(void* session, int32_t hint) { return reinterpret_cast(session)->sendHint(hint); } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 791adfd33fcd..321a7dddb144 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -127,7 +127,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_reportActualWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); - SessionHint hintId = SessionHint::CPU_LOAD_RESET; + int hintId = 2; EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1)); result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); @@ -140,7 +140,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); - result = APerformanceHint_sendHint(session, static_cast(-1)); + result = APerformanceHint_sendHint(session, -1); EXPECT_EQ(EINVAL, result); EXPECT_CALL(*iSession, close()).Times(Exactly(1)); -- cgit v1.2.3-59-g8ed1b From 08409e237bc61f1235ba5847ffdf6413f773836d Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 14 Feb 2023 14:29:25 +0000 Subject: Fix Skia includes around codecs In https://skia-review.googlesource.com/c/skia/+/642658 we are cleaning up Skia includes. These changes are necessary to address issues from that CL or are pre-emptive for future include refactoring. Change-Id: I8af0c7979d62f779df74065d5dd548bbc2ce31b5 --- libs/hwui/hwui/ImageDecoder.cpp | 12 ++++++++++++ libs/hwui/jni/ImageDecoder.cpp | 5 +++++ native/graphics/jni/imagedecoder.cpp | 4 ++++ 3 files changed, 21 insertions(+) (limited to 'native') diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp index 5bf53d0c1790..8266beb4ee8c 100644 --- a/libs/hwui/hwui/ImageDecoder.cpp +++ b/libs/hwui/hwui/ImageDecoder.cpp @@ -17,13 +17,25 @@ #include "ImageDecoder.h" #include +#include #include #include #include #include +#include +#include +#include +#include #include +#include #include +#include #include +#include +#include +#include +#include +#include #include #include #include diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp index add62b1f0d6d..fda7080f2864 100644 --- a/libs/hwui/jni/ImageDecoder.cpp +++ b/libs/hwui/jni/ImageDecoder.cpp @@ -18,11 +18,16 @@ #include #include +#include #include #include +#include +#include #include +#include #include #include +#include #include #include #include diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index cd6ed2391608..e18b4a9d2420 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -25,10 +25,14 @@ #include #include #include +#include #include +#include #include +#include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From a40ad03c58141d919e5dfbb2ba65d6ca8e86460d Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 13 Feb 2023 10:20:24 -0500 Subject: Add extended range brightness APIs SurfaceControl & Display APIs to enable arbitrary RANGE_EXTENDED HDR handling Bug: 241001465 Test: make && silkfx demo Change-Id: I1002910bc020f7177e82b3d77559103c1c2732cc --- core/api/current.txt | 5 +++++ core/java/android/view/Display.java | 11 +---------- core/java/android/view/SurfaceControl.java | 15 ++++++++++++--- native/android/libandroid.map.txt | 1 + native/android/surface_control.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 13 deletions(-) (limited to 'native') diff --git a/core/api/current.txt b/core/api/current.txt index de540bf93e4b..026eb3c69ab7 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -49805,6 +49805,7 @@ package android.view { method public int getDisplayId(); method public int getFlags(); method public android.view.Display.HdrCapabilities getHdrCapabilities(); + method public float getHdrSdrRatio(); method @Deprecated public int getHeight(); method @Deprecated public void getMetrics(android.util.DisplayMetrics); method public android.view.Display.Mode getMode(); @@ -49826,9 +49827,12 @@ package android.view { method @Deprecated public float[] getSupportedRefreshRates(); method @Deprecated public int getWidth(); method public boolean isHdr(); + method public boolean isHdrSdrRatioAvailable(); method public boolean isMinimalPostProcessingSupported(); method public boolean isValid(); method public boolean isWideColorGamut(); + method public void registerHdrSdrRatioChangedListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); + method public void unregisterHdrSdrRatioChangedListener(@NonNull java.util.function.Consumer); field public static final int DEFAULT_DISPLAY = 0; // 0x0 field public static final int FLAG_PRESENTATION = 8; // 0x8 field public static final int FLAG_PRIVATE = 4; // 0x4 @@ -51357,6 +51361,7 @@ package android.view { method @NonNull public android.view.SurfaceControl.Transaction setCrop(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect); method @NonNull public android.view.SurfaceControl.Transaction setDamageRegion(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Region); method @NonNull public android.view.SurfaceControl.Transaction setDataSpace(@NonNull android.view.SurfaceControl, int); + method @NonNull public android.view.SurfaceControl.Transaction setExtendedRangeBrightness(@NonNull android.view.SurfaceControl, float, float); method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int); method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int, int); method @Deprecated @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 1563fc0d5075..20be9d65ab8e 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -1298,8 +1298,6 @@ public final class Display { /** * @return Whether the display supports reporting an hdr/sdr ratio. If this is false, * {@link #getHdrSdrRatio()} will always be 1.0f - * @hide - * TODO: make public */ public boolean isHdrSdrRatioAvailable() { synchronized (mLock) { @@ -1312,9 +1310,6 @@ public final class Display { * @return The current hdr/sdr ratio expressed as the ratio of targetHdrPeakBrightnessInNits / * targetSdrWhitePointInNits. If {@link #isHdrSdrRatioAvailable()} is false, this * always returns 1.0f. - * - * @hide - * TODO: make public */ public float getHdrSdrRatio() { synchronized (mLock) { @@ -1344,8 +1339,6 @@ public final class Display { * @param executor The executor to invoke the listener on * @param listener The listener to invoke when the HDR/SDR ratio changes * @throws IllegalStateException if {@link #isHdrSdrRatioAvailable()} is false - * @hide - * TODO: Make public */ public void registerHdrSdrRatioChangedListener(@NonNull Executor executor, @NonNull Consumer listener) { @@ -1375,10 +1368,8 @@ public final class Display { * hdr/sdr ratio listener to remove. * * @see #registerHdrSdrRatioChangedListener(Executor, Consumer) - * @hide - * TODO: Make public */ - public void unregisterHdrSdrRatioChangedListener(Consumer listener) { + public void unregisterHdrSdrRatioChangedListener(@NonNull Consumer listener) { HdrSdrRatioListenerWrapper toRemove = null; synchronized (mLock) { int index = findHdrSdrRatioListenerLocked(listener); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 866301399fd6..458e8c1343d5 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -3789,7 +3789,7 @@ public final class SurfaceControl implements Parcelable { * whose dataspace has RANGE_EXTENDED. * * @param sc The layer whose extended range brightness is being specified - * @param currentBufferRatio The current sdr/hdr ratio of the current buffer. For example + * @param currentBufferRatio The current hdr/sdr ratio of the current buffer. For example * if the buffer was rendered with a target SDR whitepoint of * 100 nits and a max display brightness of 200 nits, this should * be set to 2.0f. @@ -3801,7 +3801,9 @@ public final class SurfaceControl implements Parcelable { * communicate extended content brightness information via * metadata such as CTA861_3 or SMPTE2086. * - * @param desiredRatio The desired sdr/hdr ratio. This can be used to communicate the max + * Must be finite && >= 1.0f + * + * @param desiredRatio The desired hdr/sdr ratio. This can be used to communicate the max * desired brightness range. This is similar to the "max luminance" * value in other HDR metadata formats, but represented as a ratio of * the target SDR whitepoint to the max display brightness. The system @@ -3813,12 +3815,19 @@ public final class SurfaceControl implements Parcelable { * voluntarily reducing the requested range can help improve battery * life as well as can improve quality by ensuring greater bit depth * is allocated to the luminance range in use. + * + * Must be finite && >= 1.0f * @return this - * @hide **/ public @NonNull Transaction setExtendedRangeBrightness(@NonNull SurfaceControl sc, float currentBufferRatio, float desiredRatio) { checkPreconditions(sc); + if (!Float.isFinite(currentBufferRatio) || currentBufferRatio < 1.0f) { + throw new IllegalArgumentException("currentBufferRatio must be finite && >= 1.0f"); + } + if (!Float.isFinite(desiredRatio) || desiredRatio < 1.0f) { + throw new IllegalArgumentException("desiredRatio must be finite && >= 1.0f"); + } nativeSetExtendedRangeBrightness(mNativeObject, sc.mNativeObject, currentBufferRatio, desiredRatio); return this; diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 987b23fdd1fd..28fd040f6c64 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -275,6 +275,7 @@ LIBANDROID { 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 diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index ea20c6c9e0b1..58de02c79e35 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -609,6 +609,30 @@ 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) { + ALOGE("Ignore setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= 1.0f", + currentBufferRatio); + return; + } + + if (!isfinite(desiredRatio) || desiredRatio < 1.0f) { + ALOGE("Ignore setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f", + desiredRatio); + return; + } + + sp 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, -- cgit v1.2.3-59-g8ed1b From 003609870464c4b92d75f2f9fb5b03717cd03b76 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 3 Mar 2023 23:31:17 +0000 Subject: Revert^2 "Use "SessionHint" enum in ndk API" Bug: 266596626 712f58a6f6a628c009e0cf548b33c9e11d9415de Change-Id: Ibdafeb884bb51c6ba1708aa41887dbc38f4561b7 --- native/android/performance_hint.cpp | 6 +++--- native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'native') diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 27666caafac4..b3628fa3e5ce 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -69,7 +69,7 @@ public: int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); - int sendHint(int32_t hint); + int sendHint(SessionHint hint); int setThreads(const int32_t* threadIds, size_t size); int getThreadIds(int32_t* const threadIds, size_t* size); @@ -243,7 +243,7 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano return 0; } -int APerformanceHintSession::sendHint(int32_t hint) { +int APerformanceHintSession::sendHint(SessionHint hint) { if (hint < 0 || hint >= static_cast(mLastHintSentTimestamp.size())) { ALOGE("%s: invalid session hint %d", __FUNCTION__, hint); return EINVAL; @@ -335,7 +335,7 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) { delete session; } -int APerformanceHint_sendHint(void* session, int32_t hint) { +int APerformanceHint_sendHint(void* session, SessionHint hint) { return reinterpret_cast(session)->sendHint(hint); } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 321a7dddb144..791adfd33fcd 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -127,7 +127,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_reportActualWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); - int hintId = 2; + SessionHint hintId = SessionHint::CPU_LOAD_RESET; EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1)); result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); @@ -140,7 +140,7 @@ TEST_F(PerformanceHintTest, TestSession) { result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); - result = APerformanceHint_sendHint(session, -1); + result = APerformanceHint_sendHint(session, static_cast(-1)); EXPECT_EQ(EINVAL, result); EXPECT_CALL(*iSession, close()).Times(Exactly(1)); -- cgit v1.2.3-59-g8ed1b From 732442f47186060fd862c731bbdfeb791fb96204 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 16 Mar 2023 14:28:50 -0400 Subject: setExtendedBrightness ALOGE -> FATAL Bug: 272103317 Test: make Change-Id: I155d818a3e473525c7cccd372978ae44912ffe58 --- native/android/surface_control.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'native') diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 904fa7484027..4b63fbf14d4c 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -628,14 +628,15 @@ void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* aSurfac CHECK_NOT_NULL(aSurfaceControl); if (!isfinite(currentBufferRatio) || currentBufferRatio < 1.0f) { - ALOGE("Ignore setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= 1.0f", - currentBufferRatio); + LOG_ALWAYS_FATAL("setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= " + "1.0f", + currentBufferRatio); return; } if (!isfinite(desiredRatio) || desiredRatio < 1.0f) { - ALOGE("Ignore setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f", - desiredRatio); + LOG_ALWAYS_FATAL("setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f", + desiredRatio); return; } -- cgit v1.2.3-59-g8ed1b From d1be50bcbece8fb938efacc78815cff28230a7a3 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Tue, 1 Nov 2022 14:40:03 -0700 Subject: Use enum class for tool type Update jni code to use enum class Bug: 198472780 Test: compile (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d873b263ee5937ba93a2252424148c0552312332) Merged-In: Ia129a28593c4f7a5ae0326a1aabdd5e6d0b67b82 Change-Id: Ia129a28593c4f7a5ae0326a1aabdd5e6d0b67b82 --- core/jni/android_view_MotionEvent.cpp | 7 ++++--- native/android/input.cpp | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'native') diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 49f47c56e6a6..2e9f1790a4a5 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -316,8 +316,9 @@ static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj, outPointerProperties->clear(); outPointerProperties->id = env->GetIntField(pointerPropertiesObj, gPointerPropertiesClassInfo.id); - outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj, + const int32_t toolType = env->GetIntField(pointerPropertiesObj, gPointerPropertiesClassInfo.toolType); + outPointerProperties->toolType = static_cast(toolType); } static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties, @@ -325,7 +326,7 @@ static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* po env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id, pointerProperties->id); env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType, - pointerProperties->toolType); + static_cast(pointerProperties->toolType)); } @@ -535,7 +536,7 @@ static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz if (!validatePointerIndex(env, pointerIndex, *event)) { return -1; } - return event->getToolType(pointerIndex); + return static_cast(event->getToolType(pointerIndex)); } static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz, diff --git a/native/android/input.cpp b/native/android/input.cpp index f1c30889c4db..432e21cb5c08 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -149,7 +149,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(motion_event)->getToolType(pointer_index); + const MotionEvent& motion = static_cast(*motion_event); + return static_cast(motion.getToolType(pointer_index)); } float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index) { -- cgit v1.2.3-59-g8ed1b From 10acd4aac7068bbbaf2074a918307adc951fcda4 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Wed, 12 Apr 2023 11:01:15 -0700 Subject: Update input event type to enum class The native definitions for event type were changed to enum class. Update the usages here. Bug: 274073185 Test: m checkinput Change-Id: If80dc6fc568da2d195606b5fbece7b7b5975e061 --- core/jni/android_view_InputEventReceiver.cpp | 128 +++++++++++---------- core/jni/android_view_InputQueue.cpp | 2 +- native/android/input.cpp | 4 +- ...om_android_server_input_InputManagerService.cpp | 22 ++-- 4 files changed, 81 insertions(+), 75 deletions(-) (limited to 'native') diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 98814bf602fc..6fcff990974a 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -368,73 +368,77 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, jobject inputEventObj; switch (inputEvent->getType()) { - case AINPUT_EVENT_TYPE_KEY: - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received key event.", getInputChannelName().c_str()); - } - inputEventObj = android_view_KeyEvent_fromNative(env, - static_cast(inputEvent)); - break; - - case AINPUT_EVENT_TYPE_MOTION: { - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received motion event.", getInputChannelName().c_str()); - } - const MotionEvent& motionEvent = static_cast(*inputEvent); - if ((motionEvent.getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) { - *outConsumedBatch = true; + case InputEventType::KEY: + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received key event.", getInputChannelName().c_str()); + } + inputEventObj = + android_view_KeyEvent_fromNative(env, + static_cast(inputEvent)); + break; + + case InputEventType::MOTION: { + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received motion event.", + getInputChannelName().c_str()); + } + const MotionEvent& motionEvent = static_cast(*inputEvent); + if ((motionEvent.getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) { + *outConsumedBatch = true; + } + inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent); + break; } - inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent); - break; - } - case AINPUT_EVENT_TYPE_FOCUS: { - FocusEvent* focusEvent = static_cast(inputEvent); - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received focus event: hasFocus=%s.", - getInputChannelName().c_str(), toString(focusEvent->getHasFocus())); + case InputEventType::FOCUS: { + FocusEvent* focusEvent = static_cast(inputEvent); + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received focus event: hasFocus=%s.", + getInputChannelName().c_str(), toString(focusEvent->getHasFocus())); + } + env->CallVoidMethod(receiverObj.get(), + gInputEventReceiverClassInfo.onFocusEvent, + jboolean(focusEvent->getHasFocus())); + finishInputEvent(seq, true /* handled */); + continue; } - env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onFocusEvent, - jboolean(focusEvent->getHasFocus())); - finishInputEvent(seq, true /* handled */); - continue; - } - case AINPUT_EVENT_TYPE_CAPTURE: { - const CaptureEvent* captureEvent = static_cast(inputEvent); - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received capture event: pointerCaptureEnabled=%s", - getInputChannelName().c_str(), - toString(captureEvent->getPointerCaptureEnabled())); + case InputEventType::CAPTURE: { + const CaptureEvent* captureEvent = static_cast(inputEvent); + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received capture event: pointerCaptureEnabled=%s", + getInputChannelName().c_str(), + toString(captureEvent->getPointerCaptureEnabled())); + } + env->CallVoidMethod(receiverObj.get(), + gInputEventReceiverClassInfo.onPointerCaptureEvent, + jboolean(captureEvent->getPointerCaptureEnabled())); + finishInputEvent(seq, true /* handled */); + continue; } - env->CallVoidMethod(receiverObj.get(), - gInputEventReceiverClassInfo.onPointerCaptureEvent, - jboolean(captureEvent->getPointerCaptureEnabled())); - finishInputEvent(seq, true /* handled */); - continue; - } - case AINPUT_EVENT_TYPE_DRAG: { - const DragEvent* dragEvent = static_cast(inputEvent); - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received drag event: isExiting=%s", - getInputChannelName().c_str(), toString(dragEvent->isExiting())); + case InputEventType::DRAG: { + const DragEvent* dragEvent = static_cast(inputEvent); + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received drag event: isExiting=%s", + getInputChannelName().c_str(), toString(dragEvent->isExiting())); + } + env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onDragEvent, + jboolean(dragEvent->isExiting()), dragEvent->getX(), + dragEvent->getY()); + finishInputEvent(seq, true /* handled */); + continue; } - env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onDragEvent, - jboolean(dragEvent->isExiting()), dragEvent->getX(), - dragEvent->getY()); - finishInputEvent(seq, true /* handled */); - continue; - } - case AINPUT_EVENT_TYPE_TOUCH_MODE: { - const TouchModeEvent* touchModeEvent = static_cast(inputEvent); - if (kDebugDispatchCycle) { - ALOGD("channel '%s' ~ Received touch mode event: isInTouchMode=%s", - getInputChannelName().c_str(), toString(touchModeEvent->isInTouchMode())); + case InputEventType::TOUCH_MODE: { + const TouchModeEvent* touchModeEvent = static_cast(inputEvent); + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received touch mode event: isInTouchMode=%s", + getInputChannelName().c_str(), + toString(touchModeEvent->isInTouchMode())); + } + env->CallVoidMethod(receiverObj.get(), + gInputEventReceiverClassInfo.onTouchModeChanged, + jboolean(touchModeEvent->isInTouchMode())); + finishInputEvent(seq, true /* handled */); + continue; } - env->CallVoidMethod(receiverObj.get(), - gInputEventReceiverClassInfo.onTouchModeChanged, - jboolean(touchModeEvent->isInTouchMode())); - finishInputEvent(seq, true /* handled */); - continue; - } default: assert(false); // InputConsumer should prevent this from ever happening diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp index 2f9df1fbe9d0..2c4966eaf408 100644 --- a/core/jni/android_view_InputQueue.cpp +++ b/core/jni/android_view_InputQueue.cpp @@ -114,7 +114,7 @@ status_t InputQueue::getEvent(InputEvent** outEvent) { } bool InputQueue::preDispatchEvent(InputEvent* e) { - if (e->getType() == AINPUT_EVENT_TYPE_KEY) { + if (e->getType() == InputEventType::KEY) { KeyEvent* keyEvent = static_cast(e); if (keyEvent->getFlags() & AKEY_EVENT_FLAG_PREDISPATCH) { finishEvent(e, false); diff --git a/native/android/input.cpp b/native/android/input.cpp index 432e21cb5c08..1bff97dfdada 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -33,6 +33,7 @@ #include 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(event)->getType(); + const InputEventType eventType = static_cast(event)->getType(); + return static_cast(eventType); } int32_t AInputEvent_getDeviceId(const AInputEvent* event) { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index d64b5a17b33d..b01d08c38531 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1311,17 +1311,17 @@ bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t JNIEnv* env = jniEnv(); switch (inputEvent->getType()) { - case AINPUT_EVENT_TYPE_KEY: - inputEventObj = android_view_KeyEvent_fromNative(env, - static_cast(inputEvent)); - break; - case AINPUT_EVENT_TYPE_MOTION: - inputEventObj = - android_view_MotionEvent_obtainAsCopy(env, - static_cast(*inputEvent)); - break; - default: - return true; // dispatch the event normally + case InputEventType::KEY: + inputEventObj = + android_view_KeyEvent_fromNative(env, static_cast(inputEvent)); + break; + case InputEventType::MOTION: + inputEventObj = android_view_MotionEvent_obtainAsCopy(env, + static_cast( + *inputEvent)); + break; + default: + return true; // dispatch the event normally } if (!inputEventObj) { -- cgit v1.2.3-59-g8ed1b From 690c1ed1163333ec2fdf7bf01e57b141efddf65c Mon Sep 17 00:00:00 2001 From: Austin Borger Date: Thu, 30 Mar 2023 17:52:34 -0700 Subject: UidObserver / Camera: Track the OOM adj of a uid via UidObserver. Previously, onUidProcAdjChanged merely signaled that the OOM adj of a uid changed, but did not provide the actual OOM adj score. Having this information allows the camera service to cut out redundant calls to onCameraAccessPrioritiesChanged and avoid overwhelming apps. The number of calls to onCameraAccessPrioritiesChanged is reduced by only signaling when it's likely the uid owning a camera would lose access to it if another uid tried to open that camera. This is opposed to the status quo, which signals every time a watched uid changes its OOM adj, which is highly inefficient. Bug: 274486653 Test: -- on physical device: -- testCamera2AccessCallbackInSplitMode x10 -- ActivityManagerServiceTest -- ActivityManagerProcessStateTest -- ActivityManagerFgsBgStartTest -- UidObserverControllerTest -- Alternate focus in split screen between Camera2 + GCA x20 Change-Id: I994bf56d8e1687460149626a3a658851ca9513c4 --- core/java/android/app/IUidObserver.aidl | 3 ++- core/java/android/app/UidObserver.java | 2 +- native/android/activity_manager.cpp | 4 ++-- .../android/server/am/ActivityManagerService.java | 4 +++- .../java/com/android/server/am/ProcessRecord.java | 5 +++++ .../com/android/server/am/UidObserverController.java | 7 +++++-- .../core/java/com/android/server/am/UidRecord.java | 20 +++++++++++++++++++- .../android/server/am/UidObserverControllerTest.java | 11 +++++++---- 8 files changed, 44 insertions(+), 12 deletions(-) (limited to 'native') diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl index 0c920f1359f3..60c2eeddac63 100644 --- a/core/java/android/app/IUidObserver.aidl +++ b/core/java/android/app/IUidObserver.aidl @@ -58,8 +58,9 @@ oneway interface IUidObserver { * Report a proc oom adj change associated with a uid. * * @param uid The uid for which the state change is being reported. + * @param adj The minimum OOM adj among all processes with this uid. */ - void onUidProcAdjChanged(int uid); + void onUidProcAdjChanged(int uid, int adj); // =============== End of transactions used on native side as well ============================ diff --git a/core/java/android/app/UidObserver.java b/core/java/android/app/UidObserver.java index 9e928073ac5c..519662448e91 100644 --- a/core/java/android/app/UidObserver.java +++ b/core/java/android/app/UidObserver.java @@ -41,7 +41,7 @@ public class UidObserver extends IUidObserver.Stub { } @Override - public void onUidProcAdjChanged(int uid) { + public void onUidProcAdjChanged(int uid, int adj) { } @Override 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& 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/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1a5d4253b5ba..a992765c0411 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16060,6 +16060,8 @@ public class ActivityManagerService extends IActivityManager.Stub final int procState = uidRec != null ? uidRec.getSetProcState() : PROCESS_STATE_NONEXISTENT; + final int procAdj = uidRec != null + ? uidRec.getMinProcAdj() : ProcessList.INVALID_ADJ; final long procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0; final int capability = uidRec != null ? uidRec.getSetCapability() : 0; final boolean ephemeral = uidRec != null ? uidRec.isEphemeral() : isEphemeralLocked(uid); @@ -16075,7 +16077,7 @@ public class ActivityManagerService extends IActivityManager.Stub } final int enqueuedChange = mUidObserverController.enqueueUidChange( uidRec == null ? null : uidRec.pendingChange, - uid, change, procState, procStateSeq, capability, ephemeral); + uid, change, procState, procAdj, procStateSeq, capability, ephemeral); if (uidRec != null) { uidRec.setLastReportedChange(enqueuedChange); } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 438a08c44ef4..0417b8cfa2e2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -644,6 +644,11 @@ class ProcessRecord implements WindowProcessListener { } } + @GuardedBy({"mService", "mProcLock"}) + int getSetAdj() { + return mState.getSetAdj(); + } + @GuardedBy(anyOf = {"mService", "mProcLock"}) IApplicationThread getThread() { return mThread; diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java index 51cb9878c0b3..790cc7b87f80 100644 --- a/services/core/java/com/android/server/am/UidObserverController.java +++ b/services/core/java/com/android/server/am/UidObserverController.java @@ -96,7 +96,7 @@ public class UidObserverController { } int enqueueUidChange(@Nullable ChangeRecord currentRecord, int uid, int change, int procState, - long procStateSeq, int capability, boolean ephemeral) { + int procAdj, long procStateSeq, int capability, boolean ephemeral) { synchronized (mLock) { if (mPendingUidChanges.size() == 0) { if (DEBUG_UID_OBSERVERS) { @@ -117,6 +117,7 @@ public class UidObserverController { changeRecord.uid = uid; changeRecord.change = change; changeRecord.procState = procState; + changeRecord.procAdj = procAdj; changeRecord.procStateSeq = procStateSeq; changeRecord.capability = capability; changeRecord.ephemeral = ephemeral; @@ -344,7 +345,7 @@ public class UidObserverController { } if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) != 0 && (change & UidRecord.CHANGE_PROCADJ) != 0) { - observer.onUidProcAdjChanged(item.uid); + observer.onUidProcAdjChanged(item.uid, item.procAdj); } } final int duration = (int) (SystemClock.uptimeMillis() - start); @@ -426,6 +427,7 @@ public class UidObserverController { public int uid; public int change; public int procState; + public int procAdj; public int capability; public boolean ephemeral; public long procStateSeq; @@ -435,6 +437,7 @@ public class UidObserverController { changeRecord.uid = uid; changeRecord.change = change; changeRecord.procState = procState; + changeRecord.procAdj = procAdj; changeRecord.capability = capability; changeRecord.ephemeral = ephemeral; changeRecord.procStateSeq = procStateSeq; diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java index e39ac2b08479..993088ef106e 100644 --- a/services/core/java/com/android/server/am/UidRecord.java +++ b/services/core/java/com/android/server/am/UidRecord.java @@ -50,6 +50,12 @@ public final class UidRecord { @CompositeRWLock({"mService", "mProcLock"}) private boolean mProcAdjChanged; + @CompositeRWLock({"mService", "mProcLock"}) + private int mCurAdj; + + @CompositeRWLock({"mService", "mProcLock"}) + private int mSetAdj; + @CompositeRWLock({"mService", "mProcLock"}) private int mCurCapability; @@ -201,11 +207,23 @@ public final class UidRecord { mProcAdjChanged = false; } - @GuardedBy({"mService", "mProcLock"}) + @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean getProcAdjChanged() { return mProcAdjChanged; } + @GuardedBy(anyOf = {"mService", "mProcLock"}) + int getMinProcAdj() { + int minAdj = ProcessList.UNKNOWN_ADJ; + for (int i = mProcRecords.size() - 1; i >= 0; i--) { + int adj = mProcRecords.valueAt(i).getSetAdj(); + if (adj < minAdj) { + minAdj = adj; + } + } + return minAdj; + } + @GuardedBy(anyOf = {"mService", "mProcLock"}) int getCurCapability() { return mCurCapability; diff --git a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java index f788c92b24b2..46974cf72381 100644 --- a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java @@ -28,6 +28,8 @@ import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; +import static com.android.server.am.ProcessList.UNKNOWN_ADJ; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; @@ -81,7 +83,7 @@ public class UidObserverControllerTest { public void testEnqueueUidChange() { int change = mUidObserverController.enqueueUidChange(null, TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, - PROCESS_CAPABILITY_ALL, 0, false); + UNKNOWN_ADJ, PROCESS_CAPABILITY_ALL, 0, false); assertEquals("expected=ACTIVE,actual=" + changeToStr(change), UidRecord.CHANGE_ACTIVE, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, @@ -91,8 +93,8 @@ public class UidObserverControllerTest { final ChangeRecord record2 = new ChangeRecord(); change = mUidObserverController.enqueueUidChange(record2, TEST_UID2, - UidRecord.CHANGE_CACHED, PROCESS_STATE_CACHED_RECENT, PROCESS_CAPABILITY_NONE, - 99, true); + UidRecord.CHANGE_CACHED, PROCESS_STATE_CACHED_RECENT, UNKNOWN_ADJ, + PROCESS_CAPABILITY_NONE, 99, true); assertEquals("expected=ACTIVE,actual=" + changeToStr(change), UidRecord.CHANGE_CACHED, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE, PROCESS_STATE_FOREGROUND_SERVICE, @@ -101,7 +103,8 @@ public class UidObserverControllerTest { PROCESS_CAPABILITY_NONE, 99, true, record2); change = mUidObserverController.enqueueUidChange(record1, TEST_UID1, - UidRecord.CHANGE_UNCACHED, PROCESS_STATE_TOP, PROCESS_CAPABILITY_ALL, 0, false); + UidRecord.CHANGE_UNCACHED, PROCESS_STATE_TOP, UNKNOWN_ADJ, + PROCESS_CAPABILITY_ALL, 0, false); assertEquals("expected=ACTIVE|UNCACHED,actual=" + changeToStr(change), UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_UNCACHED, change); assertPendingChange(TEST_UID1, UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_UNCACHED, -- cgit v1.2.3-59-g8ed1b From f5c06a171c6eb51c6c914540b36a8211036fe735 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Mon, 24 Apr 2023 16:12:38 +0000 Subject: Clean up KeyEvent JNI APIs Directly return a KeyEvent from KeyEvent_toNative, and change the KeyEvent parameter from a pointer to a reference in KeyEvent_fromNative. Bug: 279927189 Bug: 245989146 Test: Presubmit Change-Id: I9c98700ea4645c6c4cb975fabfa25d1ff959bfc3 --- core/jni/android_view_InputEventReceiver.cpp | 2 +- core/jni/android_view_InputEventSender.cpp | 3 +-- core/jni/android_view_InputQueue.cpp | 7 +----- core/jni/android_view_KeyCharacterMap.cpp | 2 +- core/jni/android_view_KeyEvent.cpp | 26 ++++++++++---------- core/jni/android_view_KeyEvent.h | 5 ++-- native/android/input.cpp | 7 ++---- ...om_android_server_input_InputManagerService.cpp | 28 ++++++---------------- 8 files changed, 28 insertions(+), 52 deletions(-) (limited to 'native') diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 6fcff990974a..0f41229dd0c1 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -374,7 +374,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, } inputEventObj = android_view_KeyEvent_fromNative(env, - static_cast(inputEvent)); + static_cast(*inputEvent)); break; case InputEventType::MOTION: { diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index ad54004ec81c..15270efbde57 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -353,8 +353,7 @@ static jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jlong senderPtr, jint seq, jobject eventObj) { sp sender = reinterpret_cast(senderPtr); - KeyEvent event; - android_view_KeyEvent_toNative(env, eventObj, &event); + const KeyEvent event = android_view_KeyEvent_toNative(env, eventObj); status_t status = sender->sendKeyEvent(seq, &event); return !status; } diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp index 2c4966eaf408..21db37e1ef7c 100644 --- a/core/jni/android_view_InputQueue.cpp +++ b/core/jni/android_view_InputQueue.cpp @@ -221,12 +221,7 @@ static jlong nativeSendKeyEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject e jboolean predispatch) { InputQueue* queue = reinterpret_cast(ptr); KeyEvent* event = queue->createKeyEvent(); - status_t status = android_view_KeyEvent_toNative(env, eventObj, event); - if (status) { - queue->recycleInputEvent(event); - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return -1; - } + *event = android_view_KeyEvent_toNative(env, eventObj); if (predispatch) { event->setFlags(event->getFlags() | AKEY_EVENT_FLAG_PREDISPATCH); diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp index 469e577829d8..8fa03cfc5b6f 100644 --- a/core/jni/android_view_KeyCharacterMap.cpp +++ b/core/jni/android_view_KeyCharacterMap.cpp @@ -217,7 +217,7 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr, result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL); if (result) { for (size_t i = 0; i < events.size(); i++) { - jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i)); + jobject keyEventObj = android_view_KeyEvent_fromNative(env, events.itemAt(i)); if (!keyEventObj) break; // threw OOM exception env->SetObjectArrayElement(result, jsize(i), keyEventObj); env->DeleteLocalRef(keyEventObj); diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp index d5568df14aad..a9c991919361 100644 --- a/core/jni/android_view_KeyEvent.cpp +++ b/core/jni/android_view_KeyEvent.cpp @@ -94,16 +94,16 @@ static struct { // ---------------------------------------------------------------------------- -jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { - ScopedLocalRef hmac = toJbyteArray(env, event->getHmac()); +jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event) { + ScopedLocalRef hmac = toJbyteArray(env, event.getHmac()); jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, gKeyEventClassInfo.obtain, - event->getId(), event->getDownTime(), event->getEventTime(), - event->getAction(), event->getKeyCode(), - event->getRepeatCount(), event->getMetaState(), - event->getDeviceId(), event->getScanCode(), - event->getFlags(), event->getSource(), - event->getDisplayId(), hmac.get(), nullptr); + event.getId(), event.getDownTime(), event.getEventTime(), + event.getAction(), event.getKeyCode(), + event.getRepeatCount(), event.getMetaState(), + event.getDeviceId(), event.getScanCode(), event.getFlags(), + event.getSource(), event.getDisplayId(), hmac.get(), + nullptr); if (env->ExceptionCheck()) { ALOGE("An exception occurred while obtaining a key event."); LOGE_EX(env); @@ -113,8 +113,7 @@ jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { return eventObj; } -status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, - KeyEvent* event) { +KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj) { jint id = env->GetIntField(eventObj, gKeyEventClassInfo.mId); jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); @@ -133,9 +132,10 @@ status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); - event->initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode, - metaState, repeatCount, downTime, eventTime); - return OK; + KeyEvent event; + event.initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode, + metaState, repeatCount, downTime, eventTime); + return event; } status_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { diff --git a/core/jni/android_view_KeyEvent.h b/core/jni/android_view_KeyEvent.h index dab6bb75c91e..bc4876a7a835 100644 --- a/core/jni/android_view_KeyEvent.h +++ b/core/jni/android_view_KeyEvent.h @@ -27,12 +27,11 @@ class KeyEvent; /* Obtains an instance of a DVM KeyEvent object as a copy of a native KeyEvent instance. * Returns NULL on error. */ -extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event); +extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event); /* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance. * Returns non-zero on error. */ -extern status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, - KeyEvent* event); +extern KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj); /* Recycles a DVM KeyEvent object. * Key events should only be recycled if they are owned by the system since user diff --git a/native/android/input.cpp b/native/android/input.cpp index 1bff97dfdada..64e8efeaa4e8 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -87,11 +87,8 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) { const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) { std::unique_ptr event = std::make_unique(); - 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) { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 7ff3ecbd6d51..f0d718a30535 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1304,7 +1304,7 @@ bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t case InputEventType::KEY: inputEventObj.reset( android_view_KeyEvent_fromNative(env, - static_cast(&inputEvent))); + static_cast(inputEvent))); break; case InputEventType::MOTION: inputEventObj.reset( @@ -1352,7 +1352,7 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent, const nsecs_t when = keyEvent.getEventTime(); JNIEnv* env = jniEnv(); - ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent)); + ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); if (!keyEventObj.get()) { ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing."); return; @@ -1431,7 +1431,7 @@ nsecs_t NativeInputManager::interceptKeyBeforeDispatching(const sp& tok // Token may be null ScopedLocalRef tokenObj(env, javaObjectForIBinder(env, token)); - ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent)); + ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); if (!keyEventObj.get()) { ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching."); return 0; @@ -1462,7 +1462,7 @@ std::optional NativeInputManager::dispatchUnhandledKey(const sp tokenObj(env, javaObjectForIBinder(env, token)); - ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, &keyEvent)); + ScopedLocalRef keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); if (!keyEventObj.get()) { ALOGE("Failed to obtain key event object for dispatchUnhandledKey."); return {}; @@ -1481,9 +1481,7 @@ std::optional NativeInputManager::dispatchUnhandledKey(const sp(syncMode); if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { - KeyEvent keyEvent; - status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent); - if (status) { - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return static_cast(InputEventInjectionResult::FAILED); - } - + const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj); const InputEventInjectionResult result = im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode, std::chrono::milliseconds( @@ -1913,13 +1905,7 @@ static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobjec NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { - KeyEvent keyEvent; - status_t status = android_view_KeyEvent_toNative(env, inputEventObj, &keyEvent); - if (status) { - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return nullptr; - } - + const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj); std::unique_ptr verifiedEvent = im->getInputManager()->getDispatcher().verifyInputEvent(keyEvent); if (verifiedEvent == nullptr) { -- cgit v1.2.3-59-g8ed1b