Merge "SF: Bundle ftl::Flags for CompositionCoverage"
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 7617136..7e7bba3 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -215,8 +215,6 @@
cc_defaults {
name: "trusty_mock_defaults",
- vendor_available: true,
- host_supported: true,
header_libs: [
"trusty_mock_headers",
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 458dff3..7006f87 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -371,30 +371,6 @@
}
cc_test {
- name: "binderRpcTest_on_trusty_mock",
- defaults: [
- "trusty_mock_defaults",
- ],
-
- srcs: [
- "binderRpcUniversalTests.cpp",
- "binderRpcTestCommon.cpp",
- "binderRpcTestTrusty.cpp",
- ],
-
- shared_libs: [
- "libbinder_on_trusty_mock",
- "libbase",
- "libutils",
- "libcutils",
- ],
-
- static_libs: [
- "binderRpcTestIface-cpp",
- ],
-}
-
-cc_test {
name: "binderRpcTest",
defaults: [
"binderRpcTest_defaults",
@@ -406,7 +382,6 @@
required: [
"libbinder_on_trusty_mock",
"binderRpcTestService_on_trusty_mock",
- "binderRpcTest_on_trusty_mock",
],
}
diff --git a/libs/binder/tests/binderRpcTestTrusty.cpp b/libs/binder/tests/binderRpcTestTrusty.cpp
deleted file mode 100644
index b3bb5eb..0000000
--- a/libs/binder/tests/binderRpcTestTrusty.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "binderRpcTest"
-
-#include <android-base/stringprintf.h>
-#include <binder/RpcTransportTipcTrusty.h>
-#include <trusty-gtest.h>
-#include <trusty_ipc.h>
-
-#include "binderRpcTestFixture.h"
-
-namespace android {
-
-// Destructors need to be defined, even if pure virtual
-ProcessSession::~ProcessSession() {}
-
-class TrustyProcessSession : public ProcessSession {
-public:
- ~TrustyProcessSession() override {}
-
- void setCustomExitStatusCheck(std::function<void(int wstatus)> /*f*/) override {
- LOG_ALWAYS_FATAL("setCustomExitStatusCheck() not supported");
- }
-
- void terminate() override { LOG_ALWAYS_FATAL("terminate() not supported"); }
-};
-
-std::string BinderRpc::PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
- auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
- auto ret = PrintToString(type) + "_clientV" + std::to_string(clientVersion) + "_serverV" +
- std::to_string(serverVersion);
- if (singleThreaded) {
- ret += "_single_threaded";
- }
- if (noKernel) {
- ret += "_no_kernel";
- }
- return ret;
-}
-
-// This creates a new process serving an interface on a certain number of
-// threads.
-std::unique_ptr<ProcessSession> BinderRpc::createRpcTestSocketServerProcessEtc(
- const BinderRpcOptions& options) {
- LOG_ALWAYS_FATAL_IF(options.numIncomingConnections != 0,
- "Non-zero incoming connections %zu on Trusty",
- options.numIncomingConnections);
-
- uint32_t clientVersion = std::get<2>(GetParam());
- uint32_t serverVersion = std::get<3>(GetParam());
-
- auto ret = std::make_unique<TrustyProcessSession>();
-
- status_t status;
- for (size_t i = 0; i < options.numSessions; i++) {
- auto factory = android::RpcTransportCtxFactoryTipcTrusty::make();
- auto session = android::RpcSession::make(std::move(factory));
-
- EXPECT_TRUE(session->setProtocolVersion(clientVersion));
- session->setMaxOutgoingThreads(options.numOutgoingConnections);
- session->setFileDescriptorTransportMode(options.clientFileDescriptorTransportMode);
-
- status = session->setupPreconnectedClient({}, [&]() {
- auto port = trustyIpcPort(serverVersion);
- int rc = connect(port.c_str(), IPC_CONNECT_WAIT_FOR_PORT);
- LOG_ALWAYS_FATAL_IF(rc < 0, "Failed to connect to service: %d", rc);
- return base::unique_fd(rc);
- });
- if (options.allowConnectFailure && status != OK) {
- ret->sessions.clear();
- break;
- }
- LOG_ALWAYS_FATAL_IF(status != OK, "Failed to connect to service: %s",
- statusToString(status).c_str());
- ret->sessions.push_back({session, session->getRootObject()});
- }
-
- return ret;
-}
-
-INSTANTIATE_TEST_CASE_P(Trusty, BinderRpc,
- ::testing::Combine(::testing::Values(SocketType::TIPC),
- ::testing::Values(RpcSecurity::RAW),
- ::testing::ValuesIn(testVersions()),
- ::testing::ValuesIn(testVersions()),
- ::testing::Values(false), ::testing::Values(true)),
- BinderRpc::PrintParamInfo);
-
-} // namespace android
-
-PORT_GTEST(BinderRpcTest, "com.android.trusty.binderRpcTest");
diff --git a/libs/binder/tests/binderRpcUniversalTests.cpp b/libs/binder/tests/binderRpcUniversalTests.cpp
index 11a22b0..2249e5c 100644
--- a/libs/binder/tests/binderRpcUniversalTests.cpp
+++ b/libs/binder/tests/binderRpcUniversalTests.cpp
@@ -386,11 +386,11 @@
EXPECT_EQ(b, weak.promote());
}
-#define EXPECT_SESSIONS(expected, iface) \
+#define expectSessions(expected, iface) \
do { \
int session; \
EXPECT_OK((iface)->getNumOpenSessions(&session)); \
- EXPECT_EQ(static_cast<int>(expected), session); \
+ EXPECT_EQ(expected, session); \
} while (false)
TEST_P(BinderRpc, SingleSession) {
@@ -402,9 +402,9 @@
EXPECT_OK(session->getName(&out));
EXPECT_EQ("aoeu", out);
- EXPECT_SESSIONS(1, proc.rootIface);
+ expectSessions(1, proc.rootIface);
session = nullptr;
- EXPECT_SESSIONS(0, proc.rootIface);
+ expectSessions(0, proc.rootIface);
}
TEST_P(BinderRpc, ManySessions) {
@@ -413,24 +413,24 @@
std::vector<sp<IBinderRpcSession>> sessions;
for (size_t i = 0; i < 15; i++) {
- EXPECT_SESSIONS(i, proc.rootIface);
+ expectSessions(i, proc.rootIface);
sp<IBinderRpcSession> session;
EXPECT_OK(proc.rootIface->openSession(std::to_string(i), &session));
sessions.push_back(session);
}
- EXPECT_SESSIONS(sessions.size(), proc.rootIface);
+ expectSessions(sessions.size(), proc.rootIface);
for (size_t i = 0; i < sessions.size(); i++) {
std::string out;
EXPECT_OK(sessions.at(i)->getName(&out));
EXPECT_EQ(std::to_string(i), out);
}
- EXPECT_SESSIONS(sessions.size(), proc.rootIface);
+ expectSessions(sessions.size(), proc.rootIface);
while (!sessions.empty()) {
sessions.pop_back();
- EXPECT_SESSIONS(sessions.size(), proc.rootIface);
+ expectSessions(sessions.size(), proc.rootIface);
}
- EXPECT_SESSIONS(0, proc.rootIface);
+ expectSessions(0, proc.rootIface);
}
TEST_P(BinderRpc, OnewayCallDoesNotWait) {
@@ -483,7 +483,7 @@
cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); });
}
- EXPECT_EQ(cb->mValues.size(), 1UL)
+ EXPECT_EQ(cb->mValues.size(), 1)
<< "callIsOneway: " << callIsOneway
<< " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
if (cb->mValues.empty()) continue;
diff --git a/libs/binder/trusty/binderRpcTest/manifest.json b/libs/binder/trusty/binderRpcTest/manifest.json
deleted file mode 100644
index d8b080f..0000000
--- a/libs/binder/trusty/binderRpcTest/manifest.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "uuid": "9dbe9fb8-60fd-4bdd-af86-03e95d7ad78b",
- "app_name": "binderRpcTest",
- "min_heap": 163840,
- "min_stack": 16384
-}
diff --git a/libs/binder/trusty/binderRpcTest/rules.mk b/libs/binder/trusty/binderRpcTest/rules.mk
deleted file mode 100644
index ae39492..0000000
--- a/libs/binder/trusty/binderRpcTest/rules.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 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.
-#
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-LIBBINDER_TESTS_DIR := frameworks/native/libs/binder/tests
-
-MODULE := $(LOCAL_DIR)
-
-MANIFEST := $(LOCAL_DIR)/manifest.json
-
-MODULE_SRCS += \
- $(LIBBINDER_TESTS_DIR)/binderRpcUniversalTests.cpp \
- $(LIBBINDER_TESTS_DIR)/binderRpcTestCommon.cpp \
- $(LIBBINDER_TESTS_DIR)/binderRpcTestTrusty.cpp \
-
-MODULE_LIBRARY_DEPS += \
- $(LOCAL_DIR)/aidl \
- frameworks/native/libs/binder/trusty \
- frameworks/native/libs/binder/trusty/ndk \
- trusty/user/base/lib/googletest \
- trusty/user/base/lib/libstdc++-trusty \
-
-include make/trusted_app.mk
diff --git a/libs/binder/trusty/build-config-usertests b/libs/binder/trusty/build-config-usertests
deleted file mode 100644
index d0a1fbc..0000000
--- a/libs/binder/trusty/build-config-usertests
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 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.
-
-# This file lists userspace tests
-
-[
- porttest("com.android.trusty.binderRpcTest"),
-]
diff --git a/libs/binder/trusty/include_mock/trusty-gtest.h b/libs/binder/trusty/include_mock/trusty-gtest.h
deleted file mode 100644
index 046b403..0000000
--- a/libs/binder/trusty/include_mock/trusty-gtest.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#pragma once
-
-#define PORT_GTEST(suite, port) \
- int main(void) { \
- return 0; \
- }
diff --git a/libs/binder/trusty/include_mock/trusty_ipc.h b/libs/binder/trusty/include_mock/trusty_ipc.h
index db044c2..43ab84a 100644
--- a/libs/binder/trusty/include_mock/trusty_ipc.h
+++ b/libs/binder/trusty/include_mock/trusty_ipc.h
@@ -27,8 +27,6 @@
#define IPC_PORT_ALLOW_TA_CONNECT 0x1
#define IPC_PORT_ALLOW_NS_CONNECT 0x2
-#define IPC_CONNECT_WAIT_FOR_PORT 0x1
-
#define IPC_HANDLE_POLL_HUP 0x1
#define IPC_HANDLE_POLL_MSG 0x2
#define IPC_HANDLE_POLL_SEND_UNBLOCKED 0x4
diff --git a/libs/binder/trusty/usertests-inc.mk b/libs/binder/trusty/usertests-inc.mk
index 1300121..2f5a7f4 100644
--- a/libs/binder/trusty/usertests-inc.mk
+++ b/libs/binder/trusty/usertests-inc.mk
@@ -14,6 +14,4 @@
#
TRUSTY_USER_TESTS += \
- frameworks/native/libs/binder/trusty/binderRpcTest \
frameworks/native/libs/binder/trusty/binderRpcTest/service \
-
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index dc9f02a..5d9ee5f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3165,6 +3165,9 @@
}
dispatchEntry->resolvedFlags = motionEntry.flags;
+ if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
+ }
if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
}
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 563868d..93419a1 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -289,13 +289,16 @@
if (options.pointerIds == std::nullopt) {
const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT
: AMOTION_EVENT_ACTION_CANCEL;
+ int32_t flags = memento.flags;
+ if (action == AMOTION_EVENT_ACTION_CANCEL) {
+ flags |= AMOTION_EVENT_FLAG_CANCELED;
+ }
events.push_back(
std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime,
memento.deviceId, memento.source,
memento.displayId, memento.policyFlags,
- action, 0 /*actionButton*/, memento.flags,
- AMETA_NONE, 0 /*buttonState*/,
- MotionClassification::NONE,
+ action, 0 /*actionButton*/, flags, AMETA_NONE,
+ 0 /*buttonState*/, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE,
memento.xPrecision, memento.yPrecision,
memento.xCursorPosition,
@@ -388,11 +391,15 @@
if (canceledPointerIndices.size() == memento.pointerCount) {
const int32_t action =
memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
+ int32_t flags = memento.flags;
+ if (action == AMOTION_EVENT_ACTION_CANCEL) {
+ flags |= AMOTION_EVENT_FLAG_CANCELED;
+ }
events.push_back(
std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId,
memento.source, memento.displayId,
memento.policyFlags, action, 0 /*actionButton*/,
- memento.flags, AMETA_NONE, 0 /*buttonState*/,
+ flags, AMETA_NONE, 0 /*buttonState*/,
MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
memento.yPrecision, memento.xCursorPosition,
@@ -400,7 +407,7 @@
memento.pointerCount, memento.pointerProperties,
memento.pointerCoords));
} else {
- // If we aren't canceling all pointers, we need to generated ACTION_POINTER_UP with
+ // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
// FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
// previously canceled pointers from PointerProperties and PointerCoords, and update
// pointerCount appropriately. For convenience, sort the canceled pointer indices so that we
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 3abe43a..dfe3d16 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -58,6 +58,7 @@
static constexpr int32_t SECOND_DISPLAY_ID = 1;
static constexpr int32_t ACTION_OUTSIDE = AMOTION_EVENT_ACTION_OUTSIDE;
+static constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL;
static constexpr int32_t POINTER_1_DOWN =
AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
static constexpr int32_t POINTER_2_DOWN =
@@ -139,12 +140,20 @@
return arg.getDownTime() == downTime;
}
+MATCHER_P(WithDisplayId, displayId, "InputEvent with specified displayId") {
+ return arg.getDisplayId() == displayId;
+}
+
MATCHER_P(WithSource, source, "InputEvent with specified source") {
*result_listener << "expected source " << inputEventSourceToString(source) << ", but got "
<< inputEventSourceToString(arg.getSource());
return arg.getSource() == source;
}
+MATCHER_P(WithFlags, flags, "InputEvent with specified flags") {
+ return arg.getFlags() == flags;
+}
+
MATCHER_P2(WithCoords, x, y, "MotionEvent with specified coordinates") {
if (arg.getPointerCount() != 1) {
*result_listener << "Expected 1 pointer, got " << arg.getPointerCount();
@@ -944,6 +953,28 @@
}
}
+ MotionEvent* consumeMotion() {
+ InputEvent* event = consume();
+
+ if (event == nullptr) {
+ ADD_FAILURE() << mName << ": expected a MotionEvent, but didn't get one.";
+ return nullptr;
+ }
+
+ if (event->getType() != AINPUT_EVENT_TYPE_MOTION) {
+ ADD_FAILURE() << mName << " expected a MotionEvent, got "
+ << inputEventTypeToString(event->getType()) << " event";
+ return nullptr;
+ }
+ return static_cast<MotionEvent*>(event);
+ }
+
+ void consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) {
+ MotionEvent* motionEvent = consumeMotion();
+ ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event, but expected " << matcher;
+ ASSERT_THAT(*motionEvent, matcher);
+ }
+
void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
InputEvent* event = consume();
ASSERT_NE(nullptr, event) << mName.c_str()
@@ -1196,14 +1227,14 @@
void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
- expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED)));
}
void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
- expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithDisplayId(expectedDisplayId), WithFlags(expectedFlags)));
}
void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
@@ -2546,8 +2577,8 @@
// on the app side.
NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
mDispatcher->notifyDeviceReset(&args);
- window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
- 0 /*expectedFlags*/);
+ window->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
TEST_F(InputDispatcherTest, InterceptKeyByPolicy) {
@@ -3544,8 +3575,10 @@
}
void consumeMotionCancel(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
- mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
- expectedDisplayId, expectedFlags);
+ mInputReceiver->consumeMotionEvent(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
+ WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED)));
}
void consumeMotionPointerDown(int32_t pointerIdx) {
@@ -5109,8 +5142,8 @@
mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, mWindow);
mWindow->finishEvent(*sequenceNum);
- mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
- ADISPLAY_ID_DEFAULT, 0 /*flags*/);
+ mWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_TRUE(mDispatcher->waitForIdle());
mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid());
}
@@ -5277,8 +5310,8 @@
mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, spy);
spy->finishEvent(*sequenceNum);
- spy->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
- 0 /*flags*/);
+ spy->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT)));
ASSERT_TRUE(mDispatcher->waitForIdle());
mFakePolicy->assertNotifyWindowResponsiveWasCalled(spy->getToken(), mWindow->getPid());
}
@@ -5400,8 +5433,8 @@
mFakePolicy->assertNotifyAnrWasNotCalled();
// When the ANR happened, dispatcher should abort the current event stream via ACTION_CANCEL
mWindow->consumeMotionDown();
- mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
- ADISPLAY_ID_DEFAULT, 0 /*flags*/);
+ mWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT)));
mWindow->assertNoEvents();
mDispatcher->waitForIdle();
mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid());
@@ -7768,7 +7801,7 @@
ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT,
InputEventInjectionSync::WAIT_FOR_RESULT))
- << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::FAILED";
spy->assertNoEvents();
window->assertNoEvents();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 1d27cfc..c5b3e14 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -929,17 +929,38 @@
RefreshRateOrder refreshRateOrder,
std::optional<DisplayModeId> preferredDisplayModeOpt) const
-> FrameRateRanking {
+ using fps_approx_ops::operator<;
const char* const whence = __func__;
+
+ // find the highest frame rate for each display mode
+ ftl::SmallMap<DisplayModeId, Fps, 8> maxRenderRateForMode;
+ const bool ascending = (refreshRateOrder == RefreshRateOrder::Ascending);
+ if (ascending) {
+ // TODO(b/266481656): Once this bug is fixed, we can remove this workaround and actually
+ // use a lower frame rate when we want Ascending frame rates.
+ for (const auto& frameRateMode : mPrimaryFrameRates) {
+ if (anchorGroupOpt && frameRateMode.modePtr->getGroup() != anchorGroupOpt) {
+ continue;
+ }
+
+ const auto [iter, _] = maxRenderRateForMode.try_emplace(frameRateMode.modePtr->getId(),
+ frameRateMode.fps);
+ if (iter->second < frameRateMode.fps) {
+ iter->second = frameRateMode.fps;
+ }
+ }
+ }
+
std::deque<ScoredFrameRate> ranking;
const auto rankFrameRate = [&](const FrameRateMode& frameRateMode) REQUIRES(mLock) {
- using fps_approx_ops::operator<;
const auto& modePtr = frameRateMode.modePtr;
if (anchorGroupOpt && modePtr->getGroup() != anchorGroupOpt) {
return;
}
const bool ascending = (refreshRateOrder == RefreshRateOrder::Ascending);
- if (ascending && frameRateMode.fps < getMinRefreshRateByPolicyLocked()->getFps()) {
+ const auto id = frameRateMode.modePtr->getId();
+ if (ascending && frameRateMode.fps < *maxRenderRateForMode.get(id)) {
// TODO(b/266481656): Once this bug is fixed, we can remove this workaround and actually
// use a lower frame rate when we want Ascending frame rates.
return;
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index 5fddda5..f4d052d 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -1165,7 +1165,7 @@
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
case Config::FrameRateOverride::Enabled:
- return {{30_Hz, kMode30}, {45_Hz, kMode90}, {60_Hz, kMode60}, {90_Hz, kMode90}};
+ return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
@@ -1197,7 +1197,7 @@
case Config::FrameRateOverride::AppOverride:
return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
case Config::FrameRateOverride::Enabled:
- return {{30_Hz, kMode30}, {45_Hz, kMode90}, {60_Hz, kMode60}, {90_Hz, kMode90}};
+ return {{30_Hz, kMode30}, {60_Hz, kMode60}, {90_Hz, kMode90}};
}
}();
ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
@@ -2983,5 +2983,24 @@
EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
+TEST_P(RefreshRateSelectorTest, frameRateIsCappedByPolicy) {
+ if (GetParam() != Config::FrameRateOverride::Enabled) {
+ return;
+ }
+
+ auto selector = createSelector(kModes_60_90, kModeId60);
+
+ constexpr FpsRanges kCappedAt30 = {{60_Hz, 90_Hz}, {30_Hz, 30_Hz}};
+
+ EXPECT_EQ(SetPolicyResult::Changed,
+ selector.setDisplayManagerPolicy(
+ {DisplayModeId(kModeId60), kCappedAt30, kCappedAt30}));
+
+ std::vector<LayerRequirement> layers = {{.weight = 1.f}};
+ layers[0].name = "Test layer";
+ layers[0].vote = LayerVoteType::Min;
+ EXPECT_FRAME_RATE_MODE(kMode60, 30_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
+}
+
} // namespace
} // namespace android::scheduler