diff options
21 files changed, 425 insertions, 63 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index a10baa6b80..e7b0d5d122 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -273,7 +273,7 @@ status_t InstalldNativeService::start() { ps->startThreadPool(); ps->giveThreadPoolName(); sAppDataIsolationEnabled = android::base::GetBoolProperty( - kAppDataIsolationEnabledProperty, false); + kAppDataIsolationEnabledProperty, true); return android::OK; } diff --git a/include/android/bitmap.h b/include/android/bitmap.h index 01cf2f88ea..41718b2904 100644 --- a/include/android/bitmap.h +++ b/include/android/bitmap.h @@ -100,6 +100,19 @@ typedef struct { int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, AndroidBitmapInfo* info); +#if __ANDROID_API__ >= 30 + +/** + * Given a java bitmap object, return its ADataSpace. + * + * Note that ADataSpace only exposes a few values. This may return + * ADATASPACE_UNKNOWN, even for Named ColorSpaces, if they have no + * corresponding ADataSpace. + */ +int32_t AndroidBitmap_getDataSpace(JNIEnv* env, jobject jbitmap) __INTRODUCED_IN(30); + +#endif // __ANDROID_API__ >= 30 + /** * Given a java bitmap object, attempt to lock the pixel address. * Locking will ensure that the memory for the pixels will not move diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp index a8f7d92b41..b1943a4afd 100644 --- a/libs/cputimeinstate/Android.bp +++ b/libs/cputimeinstate/Android.bp @@ -14,6 +14,7 @@ cc_library { "-Wall", "-Wextra", ], + export_include_dirs: ["."], } cc_test { diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp index 4ee9f55227..ee44cf524b 100644 --- a/libs/cputimeinstate/cputimeinstate.cpp +++ b/libs/cputimeinstate/cputimeinstate.cpp @@ -85,6 +85,16 @@ static int comparePolicyFiles(const struct dirent **d1, const struct dirent **d2 return policyN1 - policyN2; } +static int bpf_obj_get_wronly(const char *pathname) { + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.pathname = ptr_to_u64((void *)pathname); + attr.file_flags = BPF_F_WRONLY; + + return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr)); +} + static bool initGlobals() { std::lock_guard<std::mutex> guard(gInitializedMutex); if (gInitialized) return true; @@ -153,17 +163,17 @@ static bool attachTracepointProgram(const std::string &eventType, const std::str bool startTrackingUidTimes() { if (!initGlobals()) return false; - unique_fd fd(bpf_obj_get(BPF_FS_PATH "map_time_in_state_cpu_policy_map")); - if (fd < 0) return false; + unique_fd cpuPolicyFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_cpu_policy_map")); + if (cpuPolicyFd < 0) return false; for (uint32_t i = 0; i < gPolicyCpus.size(); ++i) { for (auto &cpu : gPolicyCpus[i]) { - if (writeToMapEntry(fd, &cpu, &i, BPF_ANY)) return false; + if (writeToMapEntry(cpuPolicyFd, &cpu, &i, BPF_ANY)) return false; } } - unique_fd fd2(bpf_obj_get(BPF_FS_PATH "map_time_in_state_freq_to_idx_map")); - if (fd2 < 0) return false; + unique_fd freqToIdxFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_freq_to_idx_map")); + if (freqToIdxFd < 0) return false; freq_idx_key_t key; for (uint32_t i = 0; i < gNPolicies; ++i) { key.policy = i; @@ -173,14 +183,41 @@ bool startTrackingUidTimes() { // The uid_times map still uses 0-based indexes, and the sched_switch program handles // conversion between them, so this does not affect our map reading code. uint32_t idx = j + 1; - if (writeToMapEntry(fd2, &key, &idx, BPF_ANY)) return false; + if (writeToMapEntry(freqToIdxFd, &key, &idx, BPF_ANY)) return false; } } + unique_fd cpuLastUpdateFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_cpu_last_update_map")); + if (cpuLastUpdateFd < 0) return false; + std::vector<uint64_t> zeros(get_nprocs_conf(), 0); + uint32_t zero = 0; + if (writeToMapEntry(cpuLastUpdateFd, &zero, zeros.data(), BPF_ANY)) return false; + + unique_fd nrActiveFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_nr_active_map")); + if (nrActiveFd < 0) return false; + if (writeToMapEntry(nrActiveFd, &zero, &zero, BPF_ANY)) return false; + + unique_fd policyNrActiveFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_policy_nr_active_map")); + if (policyNrActiveFd < 0) return false; + for (uint32_t i = 0; i < gNPolicies; ++i) { + if (writeToMapEntry(policyNrActiveFd, &i, &zero, BPF_ANY)) return false; + } + + unique_fd policyFreqIdxFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_policy_freq_idx_map")); + if (policyFreqIdxFd < 0) return false; + for (uint32_t i = 0; i < gNPolicies; ++i) { + if (writeToMapEntry(policyFreqIdxFd, &i, &zero, BPF_ANY)) return false; + } + return attachTracepointProgram("sched", "sched_switch") && attachTracepointProgram("power", "cpu_frequency"); } +std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs() { + if (!gInitialized && !initGlobals()) return {}; + return gPolicyFreqs; +} + // Retrieve the times in ns that uid spent running at each CPU frequency. // Return contains no value on error, otherwise it contains a vector of vectors using the format: // [[t0_0, t0_1, ...], diff --git a/libs/cputimeinstate/cputimeinstate.h b/libs/cputimeinstate/cputimeinstate.h index f620715dab..49469d8e04 100644 --- a/libs/cputimeinstate/cputimeinstate.h +++ b/libs/cputimeinstate/cputimeinstate.h @@ -26,6 +26,7 @@ bool startTrackingUidTimes(); std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t uid); std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsCpuFreqTimes(); +std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs(); struct concurrent_time_t { std::vector<uint64_t> active; diff --git a/libs/cputimeinstate/testtimeinstate.cpp b/libs/cputimeinstate/testtimeinstate.cpp index c0cd3e07ff..23d87fd646 100644 --- a/libs/cputimeinstate/testtimeinstate.cpp +++ b/libs/cputimeinstate/testtimeinstate.cpp @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2018 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. + */ + #include <bpf_timeinstate.h> @@ -351,5 +367,16 @@ TEST(TimeInStateTest, RemoveUid) { ASSERT_EQ(allConcurrentTimes->find(uid), allConcurrentTimes->end()); } +TEST(TimeInStateTest, GetCpuFreqs) { + auto freqs = getCpuFreqs(); + ASSERT_TRUE(freqs.has_value()); + + auto times = getUidCpuFreqTimes(0); + ASSERT_TRUE(times.has_value()); + + ASSERT_EQ(freqs->size(), times->size()); + for (size_t i = 0; i < freqs->size(); ++i) EXPECT_EQ((*freqs)[i].size(), (*times)[i].size()); +} + } // namespace bpf } // namespace android diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 8d36ba7b70..04749e6d13 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -112,22 +112,31 @@ public: if (consumed != OK) { return nullptr; } - mInputConsumer->sendFinishedSignal(seqId, true); + status_t status = mInputConsumer->sendFinishedSignal(seqId, true); + EXPECT_EQ(OK, status) << "Could not send finished signal"; return ev; } + void assertFocusChange(bool hasFocus) { + InputEvent *ev = consumeEvent(); + ASSERT_NE(ev, nullptr); + ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType()); + FocusEvent *focusEvent = static_cast<FocusEvent *>(ev); + EXPECT_EQ(hasFocus, focusEvent->getHasFocus()); + } + void expectTap(int x, int y) { InputEvent* ev = consumeEvent(); - EXPECT_TRUE(ev != nullptr); - EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION); + ASSERT_NE(ev, nullptr); + ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType()); MotionEvent* mev = static_cast<MotionEvent*>(ev); EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction()); EXPECT_EQ(x, mev->getX(0)); EXPECT_EQ(y, mev->getY(0)); ev = consumeEvent(); - EXPECT_TRUE(ev != nullptr); - EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION); + ASSERT_NE(ev, nullptr); + ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType()); mev = static_cast<MotionEvent*>(ev); EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction()); } @@ -212,7 +221,7 @@ public: ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); const auto display = mComposerClient->getInternalDisplayToken(); - ASSERT_FALSE(display == nullptr); + ASSERT_NE(display, nullptr); DisplayInfo info; ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info)); @@ -259,18 +268,28 @@ void injectTap(int x, int y) { TEST_F(InputSurfacesTest, can_receive_input) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); surface->showAt(100, 100); + surface->assertFocusChange(true); injectTap(101, 101); - EXPECT_TRUE(surface->consumeEvent() != nullptr); + EXPECT_NE(surface->consumeEvent(), nullptr); } +/** + * Set up two surfaces side-by-side. Tap each surface. + * Next, swap the positions of the two surfaces. Inject tap into the two + * original locations. Ensure that the tap is received by the surfaces in the + * reverse order. + */ TEST_F(InputSurfacesTest, input_respects_positioning) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); surface->showAt(100, 100); + surface->assertFocusChange(true); std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100); surface2->showAt(200, 200); + surface->assertFocusChange(false); + surface2->assertFocusChange(true); injectTap(201, 201); surface2->expectTap(1, 1); @@ -297,11 +316,16 @@ TEST_F(InputSurfacesTest, input_respects_layering) { std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100); surface->showAt(10, 10); + surface->assertFocusChange(true); surface2->showAt(10, 10); + surface->assertFocusChange(false); + surface2->assertFocusChange(true); surface->doTransaction([](auto &t, auto &sc) { t.setLayer(sc, LAYER_BASE + 1); }); + surface2->assertFocusChange(false); + surface->assertFocusChange(true); injectTap(11, 11); surface->expectTap(1, 1); @@ -309,6 +333,8 @@ TEST_F(InputSurfacesTest, input_respects_layering) { surface2->doTransaction([](auto &t, auto &sc) { t.setLayer(sc, LAYER_BASE + 1); }); + surface2->assertFocusChange(true); + surface->assertFocusChange(false); injectTap(11, 11); surface2->expectTap(1, 1); @@ -316,6 +342,8 @@ TEST_F(InputSurfacesTest, input_respects_layering) { surface2->doTransaction([](auto &t, auto &sc) { t.hide(sc); }); + surface2->assertFocusChange(false); + surface->assertFocusChange(true); injectTap(11, 11); surface->expectTap(1, 1); @@ -328,9 +356,12 @@ TEST_F(InputSurfacesTest, input_respects_surface_insets) { std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100); std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(100, 100); + bgSurface->assertFocusChange(true); fgSurface->mInputInfo.surfaceInset = 5; fgSurface->showAt(100, 100); + fgSurface->assertFocusChange(true); + bgSurface->assertFocusChange(false); injectTap(106, 106); fgSurface->expectTap(1, 1); @@ -344,9 +375,12 @@ TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) { std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100); std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100); parentSurface->showAt(100, 100); + parentSurface->assertFocusChange(true); childSurface->mInputInfo.surfaceInset = 10; childSurface->showAt(100, 100); + childSurface->assertFocusChange(true); + parentSurface->assertFocusChange(false); childSurface->doTransaction([&](auto &t, auto &sc) { t.setPosition(sc, -5, -5); @@ -365,9 +399,12 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) { std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100); std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(100, 100); + bgSurface->assertFocusChange(true); fgSurface->mInputInfo.surfaceInset = 5; fgSurface->showAt(100, 100); + bgSurface->assertFocusChange(false); + fgSurface->assertFocusChange(true); fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); }); @@ -384,6 +421,7 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { // In case we pass the very big inset without any checking. fgSurface->mInputInfo.surfaceInset = INT32_MAX; fgSurface->showAt(100, 100); + fgSurface->assertFocusChange(true); fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); @@ -400,6 +438,7 @@ TEST_F(InputSurfacesTest, input_ignores_transparent_region) { t.setTransparentRegionHint(sc, transparentRegion); }); surface->showAt(100, 100); + surface->assertFocusChange(true); injectTap(101, 101); surface->expectTap(1, 1); } @@ -414,7 +453,10 @@ TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) { InputSurface::makeBufferInputSurface(mComposerClient, 100, 100); bgSurface->showAt(10, 10); + bgSurface->assertFocusChange(true); bufferSurface->showAt(10, 10); + bgSurface->assertFocusChange(false); + bufferSurface->assertFocusChange(true); injectTap(11, 11); bufferSurface->expectTap(1, 1); @@ -431,7 +473,10 @@ TEST_F(InputSurfacesTest, input_ignores_buffer_layer_alpha) { postBuffer(bufferSurface->mSurfaceControl); bgSurface->showAt(10, 10); + bgSurface->assertFocusChange(true); bufferSurface->showAt(10, 10); + bufferSurface->assertFocusChange(true); + bgSurface->assertFocusChange(false); injectTap(11, 11); bufferSurface->expectTap(1, 1); @@ -447,7 +492,10 @@ TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(10, 10); + bgSurface->assertFocusChange(true); fgSurface->showAt(10, 10); + bgSurface->assertFocusChange(false); + fgSurface->assertFocusChange(true); injectTap(11, 11); fgSurface->expectTap(1, 1); @@ -464,12 +512,17 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) { InputSurface::makeContainerInputSurface(mComposerClient, 100, 100); bgSurface->showAt(10, 10); + bgSurface->assertFocusChange(true); containerSurface->showAt(10, 10); + bgSurface->assertFocusChange(false); + containerSurface->assertFocusChange(true); injectTap(11, 11); containerSurface->expectTap(1, 1); containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); }); + containerSurface->assertFocusChange(false); + bgSurface->assertFocusChange(true); injectTap(11, 11); bgSurface->expectTap(1, 1); @@ -478,6 +531,7 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) { TEST_F(InputSurfacesTest, input_respects_outscreen) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); surface->showAt(-1, -1); + surface->assertFocusChange(true); injectTap(0, 0); surface->expectTap(1, 1); diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp index e925f5b6ba..b7236547de 100644 --- a/services/inputflinger/dispatcher/Entry.cpp +++ b/services/inputflinger/dispatcher/Entry.cpp @@ -111,6 +111,21 @@ void DeviceResetEntry::appendDescription(std::string& msg) const { msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags); } +// --- FocusEntry --- + +// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries +FocusEntry::FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken, + bool hasFocus) + : EventEntry(sequenceNum, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER), + connectionToken(connectionToken), + hasFocus(hasFocus) {} + +FocusEntry::~FocusEntry() {} + +void FocusEntry::appendDescription(std::string& msg) const { + msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false"); +} + // --- KeyEntry --- KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source, diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h index 9dcaadc6ee..e8c37f0e6e 100644 --- a/services/inputflinger/dispatcher/Entry.h +++ b/services/inputflinger/dispatcher/Entry.h @@ -33,7 +33,13 @@ namespace android::inputdispatcher { constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0; struct EventEntry { - enum class Type { CONFIGURATION_CHANGED, DEVICE_RESET, KEY, MOTION }; + enum class Type { + CONFIGURATION_CHANGED, + DEVICE_RESET, + FOCUS, + KEY, + MOTION, + }; static const char* typeToString(Type type) { switch (type) { @@ -41,6 +47,8 @@ struct EventEntry { return "CONFIGURATION_CHANGED"; case Type::DEVICE_RESET: return "DEVICE_RESET"; + case Type::FOCUS: + return "FOCUS"; case Type::KEY: return "KEY"; case Type::MOTION: @@ -102,6 +110,17 @@ protected: virtual ~DeviceResetEntry(); }; +struct FocusEntry : EventEntry { + sp<IBinder> connectionToken; + bool hasFocus; + + FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus); + virtual void appendDescription(std::string& msg) const; + +protected: + virtual ~FocusEntry(); +}; + struct KeyEntry : EventEntry { int32_t deviceId; uint32_t source; diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 6157d997fd..77bf1e9d63 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -530,6 +530,14 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { break; } + case EventEntry::Type::FOCUS: { + FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent); + dispatchFocusLocked(currentTime, typedEntry); + done = true; + dropReason = DropReason::NOT_DROPPED; // focus events are never dropped + break; + } + case EventEntry::Type::KEY: { KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent); if (isAppSwitchDue) { @@ -634,7 +642,8 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { break; } case EventEntry::Type::CONFIGURATION_CHANGED: - case EventEntry::Type::DEVICE_RESET: { + case EventEntry::Type::DEVICE_RESET: + case EventEntry::Type::FOCUS: { // nothing to do break; } @@ -773,6 +782,7 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason } break; } + case EventEntry::Type::FOCUS: case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type)); @@ -933,6 +943,25 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceReset return true; } +void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) { + FocusEntry* focusEntry = + new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus); + enqueueInboundEventLocked(focusEntry); +} + +void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) { + sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken); + if (channel == nullptr) { + return; // Window has gone away + } + InputTarget target; + target.inputChannel = channel; + target.flags = InputTarget::FLAG_DISPATCH_AS_IS; + entry->dispatchInProgress = true; + + dispatchEventLocked(currentTime, entry, {target}); +} + bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) { // Preprocessing. @@ -1315,6 +1344,7 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) { displayId = motionEntry.displayId; break; } + case EventEntry::Type::FOCUS: case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type)); @@ -2062,6 +2092,10 @@ std::string InputDispatcher::getApplicationWindowLabel( } void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { + if (eventEntry.type == EventEntry::Type::FOCUS) { + // Focus events are passed to apps, but do not represent user activity. + return; + } int32_t displayId = getTargetDisplayId(eventEntry); sp<InputWindowHandle> focusedWindowHandle = getValueByKey(mFocusedWindowHandlesByDisplay, displayId); @@ -2096,6 +2130,7 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { eventType = USER_ACTIVITY_EVENT_BUTTON; break; } + case EventEntry::Type::FOCUS: case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("%s events are not user activity", @@ -2292,6 +2327,9 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio break; } + case EventEntry::Type::FOCUS: { + break; + } case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("%s events should not go to apps", @@ -2427,6 +2465,14 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, reportTouchEventForStatistics(*motionEntry); break; } + case EventEntry::Type::FOCUS: { + FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry); + status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq, + focusEntry->hasFocus, + mInTouchMode); + break; + } + case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events", @@ -2666,6 +2712,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( *cancelationEventEntry)); break; } + case EventEntry::Type::FOCUS: { + LOG_ALWAYS_FATAL("Canceling focus events is not supported"); + break; + } case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: { LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue", @@ -3456,6 +3506,7 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, "focus left window"); synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options); + enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/); } mFocusedWindowHandlesByDisplay.erase(displayId); } @@ -3465,6 +3516,7 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& newFocusedWindowHandle->getName().c_str(), displayId); } mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle; + enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/); } if (mFocusedDisplayId == displayId) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 50b52502a0..a4ba0dec6a 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -157,6 +157,9 @@ private: // Cleans up input state when dropping an inbound event. void dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) REQUIRES(mLock); + // Enqueues a focus event. + void enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) REQUIRES(mLock); + // Adds an event to a queue of recent events for debugging purposes. void addRecentEventLocked(EventEntry* entry) REQUIRES(mLock); @@ -299,6 +302,7 @@ private: nsecs_t* nextWakeupTime) REQUIRES(mLock); bool dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock); + void dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) REQUIRES(mLock); void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry, const std::vector<InputTarget>& inputTargets) REQUIRES(mLock); diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index bd8d2a4d39..98ebf50819 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -482,12 +482,31 @@ public: EXPECT_EQ(expectedFlags, motionEvent.getFlags()); break; } + case AINPUT_EVENT_TYPE_FOCUS: { + FAIL() << "Use 'consumeFocusEvent' for FOCUS events"; + } default: { FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType; } } } + void consumeFocusEvent(bool hasFocus, bool inTouchMode) { + InputEvent* event = consume(); + ASSERT_NE(nullptr, event) << mName.c_str() + << ": consumer should have returned non-NULL event."; + ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType()) + << "Got " << inputEventTypeToString(event->getType()) + << " event instead of FOCUS event"; + + ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId()) + << mName.c_str() << ": event displayId should always be NONE."; + + FocusEvent* focusEvent = static_cast<FocusEvent*>(event); + EXPECT_EQ(hasFocus, focusEvent->getHasFocus()); + EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode()); + } + void assertNoEvents() { InputEvent* event = consume(); ASSERT_EQ(nullptr, event) @@ -508,7 +527,6 @@ class FakeWindowHandle : public InputWindowHandle { public: static const int32_t WIDTH = 600; static const int32_t HEIGHT = 800; - const std::string mName; FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle, const sp<InputDispatcher>& dispatcher, const std::string name, @@ -551,7 +569,7 @@ public: virtual bool updateInfo() { return true; } - void setFocus() { mInfo.hasFocus = true; } + void setFocus(bool hasFocus) { mInfo.hasFocus = hasFocus; } void setFrame(const Rect& frame) { mInfo.frameLeft = frame.left; @@ -586,6 +604,12 @@ public: expectedFlags); } + void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) { + ASSERT_NE(mInputReceiver, nullptr) + << "Cannot consume events from a window with no receiver"; + mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode); + } + void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId, int32_t expectedFlags) { ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver"; @@ -608,7 +632,10 @@ public: sp<IBinder> getToken() { return mInfo.token; } + const std::string& getName() { return mName; } + private: + const std::string mName; std::unique_ptr<FakeInputReceiver> mInputReceiver; }; @@ -759,10 +786,11 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) { // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); - // Expect one focus window exist in display. - windowSecond->setFocus(); - + // Display should have only one focused window + windowSecond->setFocus(true); mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT); + + windowSecond->consumeFocusEvent(true); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; @@ -782,10 +810,11 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) { mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first) - windowTop->setFocus(); - windowSecond->setFocus(); + windowTop->setFocus(true); + windowSecond->setFocus(true); mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT); + windowTop->consumeFocusEvent(true); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED"; @@ -805,11 +834,12 @@ TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) { // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); - windowTop->setFocus(); - windowSecond->setFocus(); + windowTop->setFocus(true); + windowSecond->setFocus(true); // Release channel for window is no longer valid. windowTop->releaseChannel(); mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT); + windowSecond->consumeFocusEvent(true); // Test inject a key down, should dispatch to a valid window. ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) @@ -849,9 +879,10 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) { sp<FakeApplicationHandle> application = new FakeApplicationHandle(); sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); - window->setFocus(); + window->setFocus(true); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(true); NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); mDispatcher->notifyKey(&keyArgs); @@ -890,6 +921,59 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { 0 /*expectedFlags*/); } +TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) { + sp<FakeApplicationHandle> application = new FakeApplicationHandle(); + sp<FakeWindowHandle> window = + new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); + + window->setFocus(true); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + + window->consumeFocusEvent(true); + + NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); + mDispatcher->notifyKey(&keyArgs); + + // Window should receive key down event. + window->consumeKeyDown(ADISPLAY_ID_DEFAULT); +} + +TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) { + sp<FakeApplicationHandle> application = new FakeApplicationHandle(); + sp<FakeWindowHandle> window = + new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); + + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + + NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); + mDispatcher->notifyKey(&keyArgs); + mDispatcher->waitForIdle(); + + window->assertNoEvents(); +} + +// If a window is touchable, but does not have focus, it should receive motion events, but not keys +TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) { + sp<FakeApplicationHandle> application = new FakeApplicationHandle(); + sp<FakeWindowHandle> window = + new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); + + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + + // Send key + NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT); + mDispatcher->notifyKey(&keyArgs); + // Send motion + NotifyMotionArgs motionArgs = + generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT); + mDispatcher->notifyMotion(&motionArgs); + + // Window should receive only the motion event + window->consumeMotionDown(ADISPLAY_ID_DEFAULT); + window->assertNoEvents(); // Key event or focus event will not be received +} + class FakeMonitorReceiver { public: FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name, @@ -946,9 +1030,10 @@ TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) { new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); - window->setFocus(); + window->setFocus(true); mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(true); FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, true /*isGestureMonitor*/); @@ -1010,6 +1095,49 @@ TEST_F(InputDispatcherTest, TestMoveEvent) { 0 /*expectedFlags*/); } +/** + * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to + * the device default right away. In the test scenario, we check both the default value, + * and the action of enabling / disabling. + */ +TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { + sp<FakeApplicationHandle> application = new FakeApplicationHandle(); + sp<FakeWindowHandle> window = + new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT); + + // Set focused application. + mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); + window->setFocus(true); + + SCOPED_TRACE("Check default value of touch mode"); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/); + + SCOPED_TRACE("Remove the window to trigger focus loss"); + window->setFocus(false); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/); + + SCOPED_TRACE("Disable touch mode"); + mDispatcher->setInTouchMode(false); + window->setFocus(true); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/); + + SCOPED_TRACE("Remove the window to trigger focus loss"); + window->setFocus(false); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/); + + SCOPED_TRACE("Enable touch mode again"); + mDispatcher->setInTouchMode(true); + window->setFocus(true); + mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT); + window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/); + + window->assertNoEvents(); +} + /* Test InputDispatcher for MultiDisplay */ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest { public: @@ -1023,8 +1151,9 @@ public: // Set focus window for primary display, but focused display would be second one. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1); - windowInPrimary->setFocus(); + windowInPrimary->setFocus(true); mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT); + windowInPrimary->consumeFocusEvent(true); application2 = new FakeApplicationHandle(); windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2", @@ -1034,8 +1163,9 @@ public: mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID); // Set focus window for second display. mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2); - windowInSecondary->setFocus(); + windowInSecondary->setFocus(true); mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID); + windowInSecondary->consumeFocusEvent(true); } virtual void TearDown() override { @@ -1094,6 +1224,7 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher)) << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT"; windowInPrimary->assertNoEvents(); + windowInSecondary->consumeFocusEvent(false); windowInSecondary->assertNoEvents(); } @@ -1244,10 +1375,11 @@ class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest { // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); - mFocusedWindow->setFocus(); + mFocusedWindow->setFocus(true); // Expect one focus window exist in display. mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT); + mFocusedWindow->consumeFocusEvent(true); } virtual void TearDown() override { @@ -1350,7 +1482,7 @@ protected: void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction, const std::vector<PointF>& points) { - std::string name = window->mName; + const std::string name = window->getName(); InputEvent* event = window->consume(); ASSERT_NE(nullptr, event) << name.c_str() diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index d476f7b40c..4c5e5da36a 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -51,7 +51,7 @@ cc_defaults { "libprocessgroup", "libprotobuf-cpp-lite", "libsync", - "libtimestats_proto", + "libtimestats", "libui", "libinput", "libutils", @@ -70,7 +70,6 @@ cc_defaults { "libperfetto_client_experimental", "librenderengine", "libserviceutils", - "libtimestats", "libtrace_proto", "libvr_manager", "libvrflinger", @@ -84,7 +83,6 @@ cc_defaults { "libcompositionengine", "librenderengine", "libserviceutils", - "libtimestats", ], export_shared_lib_headers: [ "android.hardware.graphics.allocator@2.0", @@ -96,6 +94,7 @@ cc_defaults { "android.hardware.graphics.composer@2.4", "android.hardware.power@1.3", "libhidlbase", + "libtimestats", ], // TODO (marissaw): this library is not used by surfaceflinger. This is here so // the library compiled in a way that is accessible to system partition when running @@ -231,7 +230,6 @@ cc_defaults { "liblog", "libprocessgroup", "libsync", - "libtimestats_proto", "libutils", ], static_libs: [ diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp index 78f8104915..18477bbe4c 100644 --- a/services/surfaceflinger/CompositionEngine/Android.bp +++ b/services/surfaceflinger/CompositionEngine/Android.bp @@ -22,14 +22,13 @@ cc_defaults { "libnativewindow", "libprotobuf-cpp-lite", "libsync", - "libtimestats_proto", + "libtimestats", "libui", "libutils", ], static_libs: [ "libmath", "librenderengine", - "libtimestats", "libtrace_proto", ], header_libs: [ diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 37714f55c1..2593681b6b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1893,7 +1893,7 @@ void Layer::setInputInfo(const InputWindowInfo& info) { setTransactionFlags(eTransactionNeeded); } -void Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) const { +LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) const { LayerProto* layerProto = layersProto.add_layers(); writeToProtoDrawingState(layerProto, traceFlags); writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags); @@ -1901,6 +1901,8 @@ void Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) const { for (const sp<Layer>& layer : mDrawingChildren) { layer->writeToProto(layersProto, traceFlags); } + + return layerProto; } void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags) const { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 76edfa5fcb..174ac8da1e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -454,8 +454,8 @@ public: bool isRemovedFromCurrentState() const; - void writeToProto(LayersProto& layersProto, - uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const; + LayerProto* writeToProto(LayersProto& layersProto, + uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const; // Write states that are modified by the main thread. This includes drawing // state as well as buffer data. This should be called in the main or tracing diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 65d02adeef..b7a2c760e6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4277,13 +4277,8 @@ void SurfaceFlinger::dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t rootProto->add_children(offscreenLayer->sequence); // Add layer - LayerProto* layerProto = layersProto.add_layers(); - offscreenLayer->writeToProtoDrawingState(layerProto, traceFlags); - offscreenLayer->writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, - traceFlags); + LayerProto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags); layerProto->set_parent(offscreenRootLayerId); - - offscreenLayer->writeToProto(layersProto, traceFlags); } } diff --git a/services/surfaceflinger/TimeStats/Android.bp b/services/surfaceflinger/TimeStats/Android.bp index 2080a3847e..20c22184d2 100644 --- a/services/surfaceflinger/TimeStats/Android.bp +++ b/services/surfaceflinger/TimeStats/Android.bp @@ -1,12 +1,27 @@ -cc_library_static { +cc_library_shared { name: "libtimestats", - defaults: ["surfaceflinger_defaults"], srcs: [ - "TimeStats.cpp", + "TimeStats.cpp", ], - export_include_dirs: ["."], shared_libs: [ - "libtimestats_proto", - "libui", + "libbase", + "libcutils", + "liblog", + "libprotobuf-cpp-lite", + "libtimestats_proto", + "libui", + "libutils", + ], + export_include_dirs: ["."], + export_shared_lib_headers: [ + "libtimestats_proto", + ], + cppflags: [ + "-Wall", + "-Werror", + "-Wformat", + "-Wthread-safety", + "-Wunused", + "-Wunreachable-code", ], } diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 0403237371..1c8199ac6d 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -55,7 +55,6 @@ cc_test { "liblog", "libnativewindow", "libprotobuf-cpp-full", - "libtimestats_proto", "libui", "libutils", ], @@ -68,7 +67,7 @@ cc_defaults { name: "ipc_defaults", cflags: [ "-Wall", - "-Werror", + "-Werror", ], } @@ -82,11 +81,11 @@ cc_test { ], cppflags: [ "-Wall", - "-Werror", - "-Wformat", - "-Wthread-safety", - "-Wunused", - "-Wunreachable-code", + "-Werror", + "-Wformat", + "-Wthread-safety", + "-Wunused", + "-Wunreachable-code", ], shared_libs: [ "libandroid", @@ -98,7 +97,6 @@ cc_test { "liblayers_proto", "liblog", "libprotobuf-cpp-full", - "libtimestats_proto", "libui", "libutils", ], diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp index 31837a9ec3..ff403f683e 100644 --- a/services/surfaceflinger/tests/fakehwc/Android.bp +++ b/services/surfaceflinger/tests/fakehwc/Android.bp @@ -29,7 +29,7 @@ cc_test { "liblog", "libnativewindow", "libsync", - "libtimestats_proto", + "libtimestats", "libui", "libutils", ], @@ -38,7 +38,6 @@ cc_test { "libgmock", "libperfetto_client_experimental", "librenderengine", - "libtimestats", "libtrace_proto", ], header_libs: [ diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 68adbfc254..e4ef19ea7a 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -79,11 +79,12 @@ cc_test { "libgui_mocks", "libperfetto_client_experimental", "librenderengine_mocks", - "libtimestats", "perfetto_trace_protos", ], shared_libs: [ "libsurfaceflinger", + "libtimestats", + "libtimestats_proto", ], header_libs: [ "libsurfaceflinger_headers", |