diff options
29 files changed, 268 insertions, 114 deletions
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp index a447cda492..822ab7fbb7 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -437,6 +437,9 @@ private: maybe_open_reference_profile(parameters_.pkgName, parameters_.apk_path, parameters_.profile_name, profile_guided, is_public, parameters_.uid, is_secondary_dex); + // `maybe_open_reference_profile` installs a hook that clears the profile on + // destruction. Disable it. + reference_profile.DisableCleanup(); struct stat sbuf; if (reference_profile.fd() == -1 || (fstat(reference_profile.fd(), &sbuf) != -1 && sbuf.st_size == 0)) { diff --git a/include/android/bitmap.h b/include/android/bitmap.h index 35f87f96ae..87a14c021d 100644 --- a/include/android/bitmap.h +++ b/include/android/bitmap.h @@ -196,7 +196,7 @@ enum AndroidBitmapCompressFormat { * * @param userContext Pointer to user-defined data passed to * {@link AndroidBitmap_compress}. - * @param data Compressed data of |size| bytes to write. + * @param data Compressed data of `size` bytes to write. * @param size Length in bytes of data to write. * @return Whether the operation succeeded. */ @@ -205,7 +205,7 @@ typedef bool (*AndroidBitmap_CompressWriteFunc)(void* userContext, size_t size) __INTRODUCED_IN(30); /** - * Compress |pixels| as described by |info|. + * Compress `pixels` as described by `info`. * * Available since API level 30. * diff --git a/include/android/sharedmem.h b/include/android/sharedmem.h index e0a8045d41..645fa8a5e7 100644 --- a/include/android/sharedmem.h +++ b/include/android/sharedmem.h @@ -53,7 +53,7 @@ extern "C" { /** * Create a shared memory region. * - * Create shared memory region and returns an file descriptor. The resulting file descriptor can be + * Create shared memory region and returns a file descriptor. The resulting file descriptor can be * mmap'ed to process memory space with PROT_READ | PROT_WRITE | PROT_EXEC. Access to shared memory * region can be restricted with {@link ASharedMemory_setProt}. * @@ -65,7 +65,7 @@ extern "C" { * cmsg(3) man pages for more information. * * If you intend to share this file descriptor with a child process after - * calling exec(3), note that you will need to use fcntl(2) with FD_SETFD + * calling exec(3), note that you will need to use fcntl(2) with F_SETFD * to clear the FD_CLOEXEC flag for this to work on all versions of Android. * * Available since API level 26. diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index 25b8e975b3..3724fa100a 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -433,20 +433,21 @@ TEST(NdkBinder, GetLazyService) { EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get())); } -TEST(NdkBinder, IsUpdatable) { - bool isUpdatable = AServiceManager_isUpdatableViaApex("android.hardware.light.ILights/default"); - EXPECT_EQ(isUpdatable, false); -} - -TEST(NdkBinder, GetUpdatableViaApex) { - std::optional<std::string> updatableViaApex; - AServiceManager_getUpdatableApexName( - "android.hardware.light.ILights/default", &updatableViaApex, - [](const char* apexName, void* context) { - *static_cast<std::optional<std::string>*>(context) = apexName; - }); - EXPECT_EQ(updatableViaApex, std::nullopt) << *updatableViaApex; -} +// TEST(NdkBinder, IsUpdatable) { +// bool isUpdatable = +// AServiceManager_isUpdatableViaApex("android.hardware.light.ILights/default"); +// EXPECT_EQ(isUpdatable, true); +// } +// +// TEST(NdkBinder, GetUpdatableViaApex) { +// std::optional<std::string> updatableViaApex; +// AServiceManager_getUpdatableApexName( +// "android.hardware.light.ILights/default", &updatableViaApex, +// [](const char* apexName, void* context) { +// *static_cast<std::optional<std::string>*>(context) = apexName; +// }); +// EXPECT_NE(updatableViaApex, std::nullopt) << *updatableViaApex; +// } // This is too slow TEST(NdkBinder, CheckLazyServiceShutDown) { diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 1f1439608b..16000139f7 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -476,8 +476,6 @@ status_t InputChannel::sendMessage(const InputMessage* msg) { } status_t InputChannel::receiveMessage(InputMessage* msg) { - ATRACE_NAME_IF(ATRACE_ENABLED(), - StringPrintf("receiveMessage(inputChannel=%s)", mName.c_str())); ssize_t nRead; do { nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT); diff --git a/libs/input/tests/InputDevice_test.cpp b/libs/input/tests/InputDevice_test.cpp index ee961f0ffc..a0ec6adc65 100644 --- a/libs/input/tests/InputDevice_test.cpp +++ b/libs/input/tests/InputDevice_test.cpp @@ -20,6 +20,7 @@ #include <input/InputDevice.h> #include <input/KeyLayoutMap.h> #include <input/Keyboard.h> +#include <linux/uinput.h> #include "android-base/file.h" namespace android { @@ -97,7 +98,7 @@ TEST_F(InputDeviceKeyMapTest, keyCharacterMapWithOverlayParcelingTest) { ASSERT_EQ(*map, *mKeyMap.keyCharacterMap); } -TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) { +TEST_F(InputDeviceKeyMapTest, keyCharacterMapApplyMultipleOverlaysTest) { std::string frenchOverlayPath = base::GetExecutableDirectory() + "/data/french.kcm"; std::string englishOverlayPath = base::GetExecutableDirectory() + "/data/english_us.kcm"; std::string germanOverlayPath = base::GetExecutableDirectory() + "/data/german.kcm"; @@ -133,14 +134,33 @@ TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) { ASSERT_EQ(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap); } -TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadAxisLabel) { +TEST_F(InputDeviceKeyMapTest, keyCharacterMapApplyOverlayTest) { + std::string frenchOverlayPath = base::GetExecutableDirectory() + "/data/french.kcm"; + base::Result<std::shared_ptr<KeyCharacterMap>> frenchOverlay = + KeyCharacterMap::load(frenchOverlayPath, KeyCharacterMap::Format::OVERLAY); + ASSERT_TRUE(frenchOverlay.ok()) << "Cannot load KeyCharacterMap at " << frenchOverlayPath; + + // Apply the French overlay + mKeyMap.keyCharacterMap->combine(*frenchOverlay->get()); + + // Check if mapping for key_Q is correct + int32_t outKeyCode; + status_t mapKeyResult = mKeyMap.keyCharacterMap->mapKey(KEY_Q, /*usageCode=*/0, &outKeyCode); + ASSERT_EQ(mapKeyResult, OK) << "No mapping for KEY_Q for " << frenchOverlayPath; + ASSERT_EQ(outKeyCode, AKEYCODE_A); + + mapKeyResult = mKeyMap.keyCharacterMap->mapKey(KEY_E, /*usageCode=*/0, &outKeyCode); + ASSERT_NE(mapKeyResult, OK) << "Mapping exists for KEY_E for " << frenchOverlayPath; +} + +TEST_F(InputDeviceKeyMapTest, keyCharacterMapBadAxisLabel) { std::string klPath = base::GetExecutableDirectory() + "/data/bad_axis_label.kl"; base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath); ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath; } -TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadLedLabel) { +TEST_F(InputDeviceKeyMapTest, keyCharacterMapBadLedLabel) { std::string klPath = base::GetExecutableDirectory() + "/data/bad_led_label.kl"; base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath); diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index e253ad596e..cc1d12bc5c 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -24,6 +24,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <GrContextOptions.h> +#include <GrTypes.h> #include <android-base/stringprintf.h> #include <gl/GrGLInterface.h> #include <gui/TraceUtils.h> @@ -338,7 +339,8 @@ base::unique_fd SkiaGLRenderEngine::flushAndSubmit(GrDirectContext* grContext) { } else { ATRACE_BEGIN("Submit(sync=false)"); } - bool success = grContext->submit(requireSync); + bool success = grContext->submit(requireSync ? GrSyncCpu::kYes : + GrSyncCpu::kNo); ATRACE_END(); if (!success) { ALOGE("Failed to flush RenderEngine commands"); diff --git a/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h b/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h index 30149c11f0..b86ce5f450 100644 --- a/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h +++ b/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h @@ -136,7 +136,7 @@ private: size_t mHeight; // Position of EXIF package, default value is -1 which means no EXIF package appears. - size_t mExifPos; + ssize_t mExifPos = -1; }; } /* namespace android::ultrahdr */ diff --git a/libs/ultrahdr/jpegr.cpp b/libs/ultrahdr/jpegr.cpp index 74760d9b32..3d70fcea71 100644 --- a/libs/ultrahdr/jpegr.cpp +++ b/libs/ultrahdr/jpegr.cpp @@ -85,13 +85,11 @@ static void copyJpegWithoutExif(jr_compressed_ptr pDest, jr_compressed_ptr pSource, size_t exif_pos, size_t exif_size) { - memcpy(pDest, pSource, sizeof(jpegr_compressed_struct)); - const size_t exif_offset = 4; //exif_pos has 4 bytes offset to the FF sign pDest->length = pSource->length - exif_size - exif_offset; pDest->data = new uint8_t[pDest->length]; - std::unique_ptr<uint8_t[]> dest_data; - dest_data.reset(reinterpret_cast<uint8_t*>(pDest->data)); + pDest->maxLength = pDest->length; + pDest->colorGamut = pSource->colorGamut; memcpy(pDest->data, pSource->data, exif_pos - exif_offset); memcpy((uint8_t*)pDest->data + exif_pos - exif_offset, (uint8_t*)pSource->data + exif_pos + exif_size, @@ -1262,13 +1260,13 @@ status_t JpegR::appendGainMap(jr_compressed_ptr primary_jpg_image_ptr, if (!decoder.extractEXIF(primary_jpg_image_ptr->data, primary_jpg_image_ptr->length)) { return ERROR_JPEGR_DECODE_ERROR; } - jpegr_exif_struct exif_from_jpg; - exif_from_jpg.data = nullptr; - exif_from_jpg.length = 0; - jpegr_compressed_struct new_jpg_image; - new_jpg_image.data = nullptr; - new_jpg_image.length = 0; - if (decoder.getEXIFPos() != 0) { + jpegr_exif_struct exif_from_jpg = {.data = nullptr, .length = 0}; + jpegr_compressed_struct new_jpg_image = {.data = nullptr, + .length = 0, + .maxLength = 0, + .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED}; + std::unique_ptr<uint8_t[]> dest_data; + if (decoder.getEXIFPos() >= 0) { if (pExif != nullptr) { ALOGE("received EXIF from outside while the primary image already contains EXIF"); return ERROR_JPEGR_INVALID_INPUT_TYPE; @@ -1277,6 +1275,7 @@ status_t JpegR::appendGainMap(jr_compressed_ptr primary_jpg_image_ptr, primary_jpg_image_ptr, decoder.getEXIFPos(), decoder.getEXIFSize()); + dest_data.reset(reinterpret_cast<uint8_t*>(new_jpg_image.data)); exif_from_jpg.data = decoder.getEXIFPtr(); exif_from_jpg.length = decoder.getEXIFSize(); pExif = &exif_from_jpg; diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp index 052efb6bbb..e5b1e44b44 100644 --- a/services/gpuservice/Android.bp +++ b/services/gpuservice/Android.bp @@ -21,7 +21,13 @@ cc_defaults { cc_defaults { name: "libgpuservice_defaults", - defaults: ["gpuservice_defaults"], + defaults: [ + "gpuservice_defaults", + "libvkjson_deps", + "libgfxstats_deps", + "libgpumem_deps", + "libgpumemtracer_deps", + ], cflags: [ "-DLOG_TAG=\"GpuService\"", ], @@ -29,17 +35,17 @@ cc_defaults { "libbase", "libbinder", "libcutils", - "libgfxstats", - "libgpumem", "libgpuwork", - "libgpumemtracer", "libgraphicsenv", "liblog", "libutils", - "libvkjson", ], static_libs: [ + "libgfxstats", + "libgpumem", + "libgpumemtracer", "libserviceutils", + "libvkjson", ], export_static_lib_headers: [ "libserviceutils", @@ -68,7 +74,7 @@ filegroup { ], } -cc_library_shared { +cc_library_static { name: "libgpuservice", defaults: ["libgpuservice_production_defaults"], export_include_dirs: ["include"], @@ -96,14 +102,17 @@ filegroup { cc_binary { name: "gpuservice", - defaults: ["libgpuservice_binary"], + defaults: [ + "libgpuservice_binary", + "libgpuservice_production_defaults", + ], init_rc: ["gpuservice.rc"], required: [ "bpfloader", "gpuMem.o", ], srcs: [":gpuservice_binary_sources"], - shared_libs: [ + static_libs: [ "libgpuservice", ], } diff --git a/services/gpuservice/gpumem/Android.bp b/services/gpuservice/gpumem/Android.bp index d0ea856fb5..66a30597a7 100644 --- a/services/gpuservice/gpumem/Android.bp +++ b/services/gpuservice/gpumem/Android.bp @@ -21,12 +21,8 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_shared { - name: "libgpumem", - srcs: [ - "GpuMem.cpp", - ], - header_libs: ["bpf_headers"], +cc_defaults { + name: "libgpumem_deps", shared_libs: [ "libbase", "libbpf_bcc", @@ -34,6 +30,17 @@ cc_library_shared { "liblog", "libutils", ], +} + +cc_library_static { + name: "libgpumem", + defaults: [ + "libgpumem_deps", + ], + srcs: [ + "GpuMem.cpp", + ], + header_libs: ["bpf_headers"], export_include_dirs: ["include"], export_header_lib_headers: ["bpf_headers"], export_shared_lib_headers: ["libbase"], diff --git a/services/gpuservice/gpustats/Android.bp b/services/gpuservice/gpustats/Android.bp index 54291ad6c6..0e64716e6d 100644 --- a/services/gpuservice/gpustats/Android.bp +++ b/services/gpuservice/gpustats/Android.bp @@ -7,11 +7,8 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_shared { - name: "libgfxstats", - srcs: [ - "GpuStats.cpp", - ], +cc_defaults { + name: "libgfxstats_deps", shared_libs: [ "libcutils", "libgraphicsenv", @@ -22,6 +19,16 @@ cc_library_shared { "libstatssocket", "libutils", ], +} + +cc_library_static { + name: "libgfxstats", + defaults: [ + "libgfxstats_deps", + ], + srcs: [ + "GpuStats.cpp", + ], export_include_dirs: ["include"], export_shared_lib_headers: [ "libstatspull", diff --git a/services/gpuservice/tests/fuzzers/Android.bp b/services/gpuservice/tests/fuzzers/Android.bp index 6bcc5e8601..d4d48c48ea 100644 --- a/services/gpuservice/tests/fuzzers/Android.bp +++ b/services/gpuservice/tests/fuzzers/Android.bp @@ -5,10 +5,12 @@ package { cc_fuzz { name: "gpu_service_fuzzer", defaults: [ + "libgpuservice_defaults", "service_fuzzer_defaults", "fuzzer_disable_leaks", ], static_libs: [ + "libgpuservice", "liblog", ], fuzz_config: { @@ -20,7 +22,4 @@ cc_fuzz { }, include_dirs: ["frameworks/native/services/gpuservice/"], srcs: ["GpuServiceFuzzer.cpp"], - shared_libs: [ - "libgpuservice", - ], } diff --git a/services/gpuservice/tests/unittests/Android.bp b/services/gpuservice/tests/unittests/Android.bp index c870b17b79..8056a2c601 100644 --- a/services/gpuservice/tests/unittests/Android.bp +++ b/services/gpuservice/tests/unittests/Android.bp @@ -24,6 +24,9 @@ package { cc_test { name: "gpuservice_unittest", test_suites: ["device-tests"], + defaults: [ + "libgpuservice_defaults", + ], srcs: [ "GpuMemTest.cpp", "GpuMemTracerTest.cpp", @@ -36,9 +39,6 @@ cc_test { "libbinder", "libbpf_bcc", "libcutils", - "libgfxstats", - "libgpumem", - "libgpumemtracer", "libgraphicsenv", "liblog", "libprotobuf-cpp-lite", @@ -46,10 +46,10 @@ cc_test { "libstatslog", "libstatspull", "libutils", - "libgpuservice", ], static_libs: [ "libgmock", + "libgpuservice", "libperfetto_client_experimental", "perfetto_trace_protos", ], diff --git a/services/gpuservice/tracing/Android.bp b/services/gpuservice/tracing/Android.bp index a1bc1edad8..d636b7d195 100644 --- a/services/gpuservice/tracing/Android.bp +++ b/services/gpuservice/tracing/Android.bp @@ -21,20 +21,28 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_shared { - name: "libgpumemtracer", - srcs: [ - "GpuMemTracer.cpp", - ], +cc_defaults { + name: "libgpumemtracer_deps", shared_libs: [ - "libgpumem", "libbase", "liblog", "libutils", ], static_libs: [ + "libgpumem", "libperfetto_client_experimental", ], +} + +cc_library_static { + name: "libgpumemtracer", + defaults: [ + "libgpumemtracer_deps", + "libgpumem_deps", + ], + srcs: [ + "GpuMemTracer.cpp", + ], export_include_dirs: ["include"], export_static_lib_headers: [ "libperfetto_client_experimental", diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp index cb369a836e..fa8f5485c0 100644 --- a/services/inputflinger/dispatcher/Entry.cpp +++ b/services/inputflinger/dispatcher/Entry.cpp @@ -269,6 +269,11 @@ std::string MotionEntry::getDescription() const { return msg; } +std::ostream& operator<<(std::ostream& out, const MotionEntry& motionEntry) { + out << motionEntry.getDescription(); + return out; +} + // --- SensorEntry --- SensorEntry::SensorEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h index 8dc2a2a221..dd4aab85f5 100644 --- a/services/inputflinger/dispatcher/Entry.h +++ b/services/inputflinger/dispatcher/Entry.h @@ -24,6 +24,7 @@ #include <stdint.h> #include <utils/Timers.h> #include <functional> +#include <ostream> #include <string> namespace android::inputdispatcher { @@ -189,6 +190,8 @@ struct MotionEntry : EventEntry { ~MotionEntry() override; }; +std::ostream& operator<<(std::ostream& out, const MotionEntry& motionEntry); + struct SensorEntry : EventEntry { int32_t deviceId; uint32_t source; diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index d98641ec1d..0a1e8896b0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -668,7 +668,15 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState, } else { // This pointer was already sent to the window. Use ACTION_HOVER_MOVE. if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) { - LOG(FATAL) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription(); + android::base::LogSeverity severity = android::base::LogSeverity::FATAL; + if (entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) { + // The Accessibility injected touch exploration event stream + // has known inconsistencies, so log ERROR instead of + // crashing the device with FATAL. + // TODO(b/299977100): Move a11y severity back to FATAL. + severity = android::base::LogSeverity::ERROR; + } + LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription(); } touchedWindow.targetFlags = InputTarget::Flags::DISPATCH_AS_IS; } diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index 4221e42ae5..9dcf615479 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -288,4 +288,9 @@ std::string TouchState::dump() const { return out; } +std::ostream& operator<<(std::ostream& out, const TouchState& state) { + out << state.dump(); + return out; +} + } // namespace android::inputdispatcher diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h index 39e63e5894..f01693662c 100644 --- a/services/inputflinger/dispatcher/TouchState.h +++ b/services/inputflinger/dispatcher/TouchState.h @@ -17,6 +17,7 @@ #pragma once #include <bitset> +#include <ostream> #include <set> #include "TouchedWindow.h" @@ -79,5 +80,7 @@ struct TouchState { std::string dump() const; }; +std::ostream& operator<<(std::ostream& out, const TouchState& state); + } // namespace inputdispatcher } // namespace android diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp index 9807a6da9b..ff4b425da3 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.cpp +++ b/services/inputflinger/dispatcher/TouchedWindow.cpp @@ -256,5 +256,10 @@ std::string TouchedWindow::dump() const { return out; } +std::ostream& operator<<(std::ostream& out, const TouchedWindow& window) { + out << window.dump(); + return out; +} + } // namespace inputdispatcher } // namespace android diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h index 0a38f9f5cd..3f760c0fac 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.h +++ b/services/inputflinger/dispatcher/TouchedWindow.h @@ -20,6 +20,7 @@ #include <input/Input.h> #include <utils/BitSet.h> #include <bitset> +#include <ostream> #include <set> #include "InputTarget.h" @@ -92,5 +93,7 @@ private: static std::string deviceStateToString(const TouchedWindow::DeviceState& state); }; +std::ostream& operator<<(std::ostream& out, const TouchedWindow& window); + } // namespace inputdispatcher } // namespace android diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index b565454805..90bd7c9c74 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -130,7 +130,10 @@ TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext, TouchInputMapper::~TouchInputMapper() {} uint32_t TouchInputMapper::getSources() const { - return mSource; + // The SOURCE_BLUETOOTH_STYLUS is added to events dynamically if the current stream is modified + // by the external stylus state. That's why we don't add it directly to mSource during + // configuration. + return mSource | (hasExternalStylus() ? AINPUT_SOURCE_BLUETOOTH_STYLUS : 0); } void TouchInputMapper::populateDeviceInfo(InputDeviceInfo& info) { @@ -932,9 +935,6 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } - if (hasExternalStylus()) { - mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS; - } } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) { mSource = AINPUT_SOURCE_TOUCH_NAVIGATION; mDeviceMode = DeviceMode::NAVIGATION; @@ -1664,6 +1664,10 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re mSource, mViewport.displayId, policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState); + if (mCurrentCookedState.cookedPointerData.pointerCount == 0) { + mCurrentStreamModifiedByExternalStylus = false; + } + // Clear some transient state. mCurrentRawState.rawVScroll = 0; mCurrentRawState.rawHScroll = 0; @@ -1715,6 +1719,10 @@ void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) { mExternalStylusButtonsApplied |= pressedButtons; mExternalStylusButtonsApplied &= ~releasedButtons; + + if (mExternalStylusButtonsApplied != 0 || releasedButtons != 0) { + mCurrentStreamModifiedByExternalStylus = true; + } } } @@ -1725,6 +1733,8 @@ void TouchInputMapper::applyExternalStylusTouchState(nsecs_t when) { return; } + mCurrentStreamModifiedByExternalStylus = true; + float pressure = lastPointerData.isTouching(*mFusedStylusPointerId) ? lastPointerData.pointerCoordsForId(*mFusedStylusPointerId) .getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) @@ -3821,6 +3831,9 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion( ALOG_ASSERT(false); } } + if (mCurrentStreamModifiedByExternalStylus) { + source |= AINPUT_SOURCE_BLUETOOTH_STYLUS; + } const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE); const bool showDirectStylusPointer = mConfig.stylusPointerIconEnabled && diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index c5dfb00adb..bd9371d263 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -357,6 +357,8 @@ protected: bool mExternalStylusDataPending; // A subset of the buttons in mCurrentRawState that came from an external stylus. int32_t mExternalStylusButtonsApplied{0}; + // True if the current cooked pointer data was modified due to the state of an external stylus. + bool mCurrentStreamModifiedByExternalStylus{false}; // True if we sent a HOVER_ENTER event. bool mSentHoverEnter{false}; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index dc281a3d5f..dd003a6921 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -3349,6 +3349,31 @@ TEST_F(InputDispatcherTest, HoverExitIsSentToRemovedWindow) { } /** + * Test that invalid HOVER events sent by accessibility do not cause a fatal crash. + */ +TEST_F(InputDispatcherTest, InvalidA11yHoverStreamDoesNotCrash) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window = + sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); + window->setFrame(Rect(0, 0, 1200, 800)); + + mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); + + mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); + + MotionEventBuilder hoverEnterBuilder = + MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400)) + .addFlag(AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, hoverEnterBuilder.build())); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, hoverEnterBuilder.build())); + window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)); + window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)); +} + +/** * If mouse is hovering when the touch goes down, the hovering should be stopped via HOVER_EXIT. */ TEST_F(InputDispatcherTest, TouchDownAfterMouseHover) { diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index bce0937890..6539593217 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -91,6 +91,9 @@ static constexpr int32_t ACTION_POINTER_1_DOWN = static constexpr int32_t ACTION_POINTER_1_UP = AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); +static constexpr uint32_t STYLUS_FUSION_SOURCE = + AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS; + // Minimum timestamp separation between subsequent input events from a Bluetooth device. static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4); // Maximum smoothing time delta so that we don't generate events too far into the future. @@ -2308,6 +2311,22 @@ TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) { // ongoing stylus gesture that is being emitted by the touchscreen. using ExternalStylusIntegrationTest = BaseTouchIntegrationTest; +TEST_F(ExternalStylusIntegrationTest, ExternalStylusConnectionChangesTouchscreenSource) { + // Create an external stylus capable of reporting pressure data that + // should be fused with a touch pointer. + std::unique_ptr<UinputExternalStylusWithPressure> stylus = + createUinputDevice<UinputExternalStylusWithPressure>(); + ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); + ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled()); + const auto stylusInfo = findDeviceByName(stylus->getName()); + ASSERT_TRUE(stylusInfo); + + // Connecting an external stylus changes the source of the touchscreen. + const auto deviceInfo = findDeviceByName(mDevice->getName()); + ASSERT_TRUE(deviceInfo); + ASSERT_TRUE(isFromSource(deviceInfo->getSources(), STYLUS_FUSION_SOURCE)); +} + TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) { const Point centerPoint = mDevice->getCenterPoint(); @@ -2337,17 +2356,17 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) { mDevice->sendDown(centerPoint); mDevice->sendSync(); ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled( - AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), - WithToolType(ToolType::STYLUS), WithButtonState(0), - WithDeviceId(touchscreenId), WithPressure(100.f / RAW_PRESSURE_MAX)))); + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithToolType(ToolType::STYLUS), + WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId), + WithPressure(100.f / RAW_PRESSURE_MAX)))); // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE // event with the updated pressure. stylus->setPressure(200); ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled( - AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), - WithToolType(ToolType::STYLUS), WithButtonState(0), - WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX)))); + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithToolType(ToolType::STYLUS), + WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId), + WithPressure(200.f / RAW_PRESSURE_MAX)))); // The external stylus did not generate any events. ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled()); @@ -2392,8 +2411,8 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) { // it shows up as a finger pointer. ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), - WithToolType(ToolType::FINGER), WithDeviceId(touchscreenId), - WithPressure(1.f)))); + WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS), + WithToolType(ToolType::FINGER), WithDeviceId(touchscreenId), WithPressure(1.f)))); // Change the pressure on the external stylus. Since the pressure was not present at the start // of the gesture, it is ignored for now. @@ -2405,6 +2424,7 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) { mDevice->sendSync(); ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), + WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS), WithToolType(ToolType::FINGER)))); // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus. @@ -2413,9 +2433,9 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) { mDevice->sendDown(centerPoint); mDevice->sendSync(); ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled( - AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), - WithToolType(ToolType::STYLUS), WithButtonState(0), - WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX)))); + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithSource(STYLUS_FUSION_SOURCE), + WithToolType(ToolType::STYLUS), WithButtonState(0), WithDeviceId(touchscreenId), + WithPressure(200.f / RAW_PRESSURE_MAX)))); // The external stylus did not generate any events. ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled()); @@ -2447,14 +2467,15 @@ TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) { std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT)); mDevice->sendSync(); ASSERT_NO_FATAL_FAILURE( - mTestListener - ->assertNotifyMotionWasCalled(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), - WithToolType( - ToolType::FINGER), - WithButtonState(0), - WithDeviceId(touchscreenId), - WithPressure(1.f)), - waitUntil)); + mTestListener->assertNotifyMotionWasCalled(AllOf(WithMotionAction( + AMOTION_EVENT_ACTION_DOWN), + WithToolType(ToolType::FINGER), + WithSource(AINPUT_SOURCE_TOUCHSCREEN | + AINPUT_SOURCE_STYLUS), + WithButtonState(0), + WithDeviceId(touchscreenId), + WithPressure(1.f)), + waitUntil)); // The external stylus did not generate any events. ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled()); @@ -7567,12 +7588,10 @@ public: protected: StylusState mStylusState{}; - static constexpr uint32_t EXPECTED_SOURCE = - AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS; void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) { auto toolTypeSource = - AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS)); + AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)); // The first pointer is withheld. processDown(mapper, 100, 200); @@ -7606,7 +7625,7 @@ protected: processUp(mapper); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( - AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE), + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)))); mStylusState.pressure = 0.f; @@ -7616,8 +7635,10 @@ protected: } void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) { + // When stylus fusion is not successful, events should be reported with the original source. + // In this case, it is from a touchscreen. auto toolTypeSource = - AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::FINGER)); + AllOf(WithSource(AINPUT_SOURCE_TOUCHSCREEN), WithToolType(ToolType::FINGER)); // The first pointer is withheld when an external stylus is connected, // and a timeout is requested. @@ -7657,7 +7678,7 @@ private: TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSource) { SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus(); - ASSERT_EQ(EXPECTED_SOURCE, mapper.getSources()); + ASSERT_EQ(STYLUS_FUSION_SOURCE, mapper.getSources()); } TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) { @@ -7674,8 +7695,7 @@ TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) { // before the touch is reported by the touchscreen. TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) { SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus(); - auto toolTypeSource = - AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS)); + auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)); // The external stylus reports pressure first. It is ignored for now. mStylusState.pressure = 1.f; @@ -7717,8 +7737,7 @@ TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) { TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) { SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus(); - auto toolTypeSource = - AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS)); + auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)); mStylusState.pressure = 0.8f; processExternalStylusState(mapper); @@ -7779,7 +7798,7 @@ TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) { processUp(mapper); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( - AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE), + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)))); ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested()); @@ -7788,7 +7807,7 @@ TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) { TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) { SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus(); - auto source = WithSource(EXPECTED_SOURCE); + auto source = WithSource(STYLUS_FUSION_SOURCE); mStylusState.pressure = 1.f; mStylusState.toolType = ToolType::ERASER; @@ -7841,8 +7860,7 @@ TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) { TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) { SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus(); - auto toolTypeSource = - AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS)); + auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS)); ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper)); diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp index 5a00972dd8..e378946f1b 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp @@ -905,7 +905,8 @@ auto RefreshRateSelector::getFrameRateOverrides(const std::vector<LayerRequireme } for (const auto& layer : layersWithSameUid) { - if (layer->vote == LayerVoteType::NoVote || layer->vote == LayerVoteType::Min) { + if (layer->isNoVote() || layer->frameRateCategory == FrameRateCategory::NoPreference || + layer->vote == LayerVoteType::Min) { continue; } diff --git a/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h index 8e28a75ed4..11723c7509 100644 --- a/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h +++ b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <android-base/properties.h> #include <gtest/gtest.h> #include <gui/SurfaceComposerClient.h> #include <private/android_filesystem_config.h> @@ -21,7 +22,8 @@ #include <future> namespace android { -using Transaction = SurfaceComposerClient::Transaction; + +using base::HwTimeoutMultiplier; using gui::DisplayInfo; using gui::WindowInfo; @@ -36,7 +38,8 @@ public: auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); mClient->addWindowInfosListener(listener); auto future = promise.get_future(); - bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; + bool satisfied = future.wait_for(std::chrono::seconds{5 * HwTimeoutMultiplier()}) == + std::future_status::ready; mClient->removeWindowInfosListener(listener); return satisfied; } diff --git a/vulkan/vkjson/Android.bp b/vulkan/vkjson/Android.bp index b544245a7a..de4271d47d 100644 --- a/vulkan/vkjson/Android.bp +++ b/vulkan/vkjson/Android.bp @@ -7,8 +7,19 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_shared { +cc_defaults { + name: "libvkjson_deps", + shared_libs: [ + "libjsoncpp", + "libvulkan", + ], +} + +cc_library_static { name: "libvkjson", + defaults: [ + "libvkjson_deps", + ], srcs: [ "vkjson.cc", "vkjson_instance.cc", @@ -24,10 +35,6 @@ cc_library_shared { export_include_dirs: [ ".", ], - shared_libs: [ - "libjsoncpp", - "libvulkan", - ], export_shared_lib_headers: [ "libvulkan", ], |