Merge "Use WindowInfosListener instead of SF reporting to IF" into sc-v2-dev am: ad802be877 am: 8f2390cc6e
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14885200
Change-Id: Ifab6d36bf411eea082e9b0940d1efac687e9793d
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 5cf7a5f..326da3a 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -68,6 +68,7 @@
"android/gui/FocusRequest.aidl",
"android/gui/InputApplicationInfo.aidl",
"android/gui/IWindowInfosListener.aidl",
+ "android/gui/IWindowInfosReportedListener.aidl",
"android/gui/WindowInfo.aidl",
"WindowInfo.cpp",
],
diff --git a/libs/gui/WindowInfosListenerReporter.cpp b/libs/gui/WindowInfosListenerReporter.cpp
index 834e2b8..c00a438 100644
--- a/libs/gui/WindowInfosListenerReporter.cpp
+++ b/libs/gui/WindowInfosListenerReporter.cpp
@@ -19,6 +19,7 @@
namespace android {
+using gui::IWindowInfosReportedListener;
using gui::WindowInfo;
using gui::WindowInfosListener;
@@ -64,7 +65,8 @@
}
binder::Status WindowInfosListenerReporter::onWindowInfosChanged(
- const std::vector<WindowInfo>& windowInfos) {
+ const std::vector<WindowInfo>& windowInfos,
+ const sp<IWindowInfosReportedListener>& windowInfosReportedListener) {
std::unordered_set<sp<WindowInfosListener>, ISurfaceComposer::SpHash<WindowInfosListener>>
windowInfosListeners;
@@ -79,6 +81,10 @@
listener->onWindowInfosChanged(windowInfos);
}
+ if (windowInfosReportedListener) {
+ windowInfosReportedListener->onWindowInfosReported();
+ }
+
return binder::Status::ok();
}
diff --git a/libs/gui/android/gui/IWindowInfosListener.aidl b/libs/gui/android/gui/IWindowInfosListener.aidl
index 500d928..d4553ca 100644
--- a/libs/gui/android/gui/IWindowInfosListener.aidl
+++ b/libs/gui/android/gui/IWindowInfosListener.aidl
@@ -16,10 +16,11 @@
package android.gui;
+import android.gui.IWindowInfosReportedListener;
import android.gui.WindowInfo;
/** @hide */
oneway interface IWindowInfosListener
{
- void onWindowInfosChanged(in WindowInfo[] windowInfos);
+ void onWindowInfosChanged(in WindowInfo[] windowInfos, in @nullable IWindowInfosReportedListener windowInfosReportedListener);
}
diff --git a/libs/input/android/os/ISetInputWindowsListener.aidl b/libs/gui/android/gui/IWindowInfosReportedListener.aidl
similarity index 85%
rename from libs/input/android/os/ISetInputWindowsListener.aidl
rename to libs/gui/android/gui/IWindowInfosReportedListener.aidl
index bb58fb6..0e4cce6 100644
--- a/libs/input/android/os/ISetInputWindowsListener.aidl
+++ b/libs/gui/android/gui/IWindowInfosReportedListener.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.os;
+package android.gui;
/** @hide */
-oneway interface ISetInputWindowsListener
+oneway interface IWindowInfosReportedListener
{
- void onSetInputWindowsFinished();
+ void onWindowInfosReported();
}
diff --git a/libs/gui/include/gui/WindowInfosListenerReporter.h b/libs/gui/include/gui/WindowInfosListenerReporter.h
index 3e346de..7cb96e0 100644
--- a/libs/gui/include/gui/WindowInfosListenerReporter.h
+++ b/libs/gui/include/gui/WindowInfosListenerReporter.h
@@ -17,6 +17,7 @@
#pragma once
#include <android/gui/BnWindowInfosListener.h>
+#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <gui/ISurfaceComposer.h>
#include <gui/WindowInfosListener.h>
@@ -29,8 +30,8 @@
class WindowInfosListenerReporter : public gui::BnWindowInfosListener {
public:
static sp<WindowInfosListenerReporter> getInstance();
-
- binder::Status onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) override;
+ binder::Status onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos,
+ const sp<gui::IWindowInfosReportedListener>&) override;
status_t addWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener,
const sp<ISurfaceComposer>&);
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 02cf9eb..e73c3b8 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -83,7 +83,6 @@
"android/os/IInputFlinger.aidl",
"android/os/InputEventInjectionResult.aidl",
"android/os/InputEventInjectionSync.aidl",
- "android/os/ISetInputWindowsListener.aidl",
],
export_shared_lib_headers: ["libbinder"],
@@ -119,7 +118,6 @@
"InputTransport.cpp",
"android/os/IInputConstants.aidl",
"android/os/IInputFlinger.aidl",
- "android/os/ISetInputWindowsListener.aidl",
],
static_libs: [
"libhostgraphics",
diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl
index 43b262f..00ebd4d 100644
--- a/libs/input/android/os/IInputFlinger.aidl
+++ b/libs/input/android/os/IInputFlinger.aidl
@@ -19,17 +19,10 @@
import android.InputChannel;
import android.gui.FocusRequest;
import android.gui.WindowInfo;
-import android.os.ISetInputWindowsListener;
/** @hide */
interface IInputFlinger
{
- // SurfaceFlinger is the caller of this method, it uses the listener callback to ensure the
- // ordering when needed.
- // SurfaceFlinger calls this only every VSync, so overflow of binder's oneway buffer
- // shouldn't be a concern.
- oneway void setInputWindows(in WindowInfo[] windowInfoHandles,
- in @nullable ISetInputWindowsListener setInputWindowsListener);
InputChannel createInputChannel(in @utf8InCpp String name);
void removeInputChannel(in IBinder connectionToken);
/**
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 693b1f9..7b3658d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -114,24 +114,6 @@
return mDispatcher;
}
-binder::Status InputManager::setInputWindows(
- const std::vector<WindowInfo>& infos,
- const sp<ISetInputWindowsListener>& setInputWindowsListener) {
- std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
-
- std::vector<sp<WindowInfoHandle>> handles;
- for (const auto& info : infos) {
- handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
- handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
- }
- mDispatcher->setInputWindows(handlesPerDisplay);
-
- if (setInputWindowsListener) {
- setInputWindowsListener->onSetInputWindowsFinished();
- }
- return binder::Status::ok();
-}
-
// Used by tests only.
binder::Status InputManager::createInputChannel(const std::string& name, InputChannel* outChannel) {
IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 035a9a3..4c07c22 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -26,7 +26,6 @@
#include <InputDispatcherInterface.h>
#include <InputDispatcherPolicyInterface.h>
-#include <android/os/ISetInputWindowsListener.h>
#include <input/Input.h>
#include <input/InputTransport.h>
@@ -38,7 +37,6 @@
#include <utils/Vector.h>
using android::os::BnInputFlinger;
-using android::os::ISetInputWindowsListener;
namespace android {
class InputChannel;
@@ -104,10 +102,6 @@
sp<InputDispatcherInterface> getDispatcher() override;
status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status setInputWindows(
- const std::vector<gui::WindowInfo>& handles,
- const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
-
binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
binder::Status setFocusedWindow(const gui::FocusRequest&) override;
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 80db035..a7dccf0 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -21,7 +21,6 @@
#include <android-base/result.h>
#include <android/gui/FocusRequest.h>
#include <android/os/BlockUntrustedTouchesMode.h>
-#include <android/os/ISetInputWindowsListener.h>
#include <android/os/InputEventInjectionResult.h>
#include <android/os/InputEventInjectionSync.h>
#include <gui/InputApplication.h>
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index c05ff39..3cf1b2b 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -23,7 +23,6 @@
#include "InputHost.h"
#include <android/os/BnInputFlinger.h>
-#include <android/os/ISetInputWindowsListener.h>
#include <binder/Binder.h>
#include <cutils/compiler.h>
#include <utils/String16.h>
@@ -31,9 +30,7 @@
#include <utils/StrongPointer.h>
using android::gui::FocusRequest;
-using android::gui::WindowInfo;
using android::os::BnInputFlinger;
-using android::os::ISetInputWindowsListener;
namespace android {
@@ -46,10 +43,6 @@
InputFlinger() ANDROID_API;
status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status setInputWindows(const std::vector<WindowInfo>&,
- const sp<ISetInputWindowsListener>&) override {
- return binder::Status::ok();
- }
binder::Status createInputChannel(const std::string&, InputChannel*) override {
return binder::Status::ok();
}
diff --git a/services/inputflinger/tests/IInputFlingerQuery.aidl b/services/inputflinger/tests/IInputFlingerQuery.aidl
index aff03bf..5aeb21f 100644
--- a/services/inputflinger/tests/IInputFlingerQuery.aidl
+++ b/services/inputflinger/tests/IInputFlingerQuery.aidl
@@ -17,14 +17,11 @@
import android.InputChannel;
import android.gui.FocusRequest;
import android.gui.WindowInfo;
-import android.os.ISetInputWindowsListener;
/** @hide */
interface IInputFlingerQuery
{
/* Test interfaces */
- void getInputWindows(out WindowInfo[] inputHandles);
void getInputChannels(out InputChannel[] channels);
- void getLastFocusRequest(out FocusRequest request);
void resetInputManager();
}
diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp
index d2a98df..454e531 100644
--- a/services/inputflinger/tests/InputFlingerService_test.cpp
+++ b/services/inputflinger/tests/InputFlingerService_test.cpp
@@ -18,9 +18,7 @@
#include <IInputFlingerQuery.h>
#include <android/os/BnInputFlinger.h>
-#include <android/os/BnSetInputWindowsListener.h>
#include <android/os/IInputFlinger.h>
-#include <android/os/ISetInputWindowsListener.h>
#include <binder/Binder.h>
#include <binder/IPCThreadState.h>
@@ -28,7 +26,6 @@
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
-#include <gui/WindowInfo.h>
#include <input/Input.h>
#include <input/InputTransport.h>
@@ -45,57 +42,17 @@
#define TAG "InputFlingerServiceTest"
using android::gui::FocusRequest;
-using android::gui::WindowInfo;
-using android::gui::WindowInfoHandle;
using android::os::BnInputFlinger;
-using android::os::BnSetInputWindowsListener;
using android::os::IInputFlinger;
-using android::os::ISetInputWindowsListener;
using std::chrono_literals::operator""ms;
using std::chrono_literals::operator""s;
namespace android {
-static const sp<IBinder> TestInfoToken = new BBinder();
-static const sp<IBinder> FocusedTestInfoToken = new BBinder();
-static constexpr int32_t TestInfoId = 1;
-static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo";
-static constexpr Flags<WindowInfo::Flag> TestInfoFlags = WindowInfo::Flag::NOT_FOCUSABLE;
-static constexpr WindowInfo::Type TestInfoType = WindowInfo::Type::INPUT_METHOD;
-static constexpr std::chrono::duration TestInfoDispatchingTimeout = 2532ms;
-static constexpr int32_t TestInfoFrameLeft = 93;
-static constexpr int32_t TestInfoFrameTop = 34;
-static constexpr int32_t TestInfoFrameRight = 16;
-static constexpr int32_t TestInfoFrameBottom = 19;
-static constexpr int32_t TestInfoSurfaceInset = 17;
-static constexpr float TestInfoGlobalScaleFactor = 0.3;
-static constexpr float TestInfoWindowXScale = 0.4;
-static constexpr float TestInfoWindowYScale = 0.5;
-static const Rect TestInfoTouchableRegionRect = {100 /* left */, 150 /* top */, 400 /* right */,
- 450 /* bottom */};
-static const Region TestInfoTouchableRegion(TestInfoTouchableRegionRect);
-static constexpr bool TestInfoVisible = false;
-static constexpr bool TestInfoTrustedOverlay = true;
-static constexpr bool TestInfoFocusable = false;
-static constexpr bool TestInfoHasWallpaper = false;
-static constexpr bool TestInfoPaused = false;
-static constexpr int32_t TestInfoOwnerPid = 19;
-static constexpr int32_t TestInfoOwnerUid = 24;
-static constexpr WindowInfo::Feature TestInfoInputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
-static constexpr int32_t TestInfoDisplayId = 34;
-static constexpr int32_t TestInfoPortalToDisplayId = 2;
-static constexpr bool TestInfoReplaceTouchableRegionWithCrop = true;
-static const sp<IBinder> TestInfoTouchableRegionCropHandle = new BBinder();
-
-static const std::string TestAppInfoName = "InputFlingerServiceTestInputApplicationInfo";
-static const sp<IBinder> TestAppInfoToken = new BBinder();
-static constexpr std::chrono::duration TestAppInfoDispatchingTimeout = 12345678ms;
-
static const String16 kTestServiceName = String16("InputFlingerService");
static const String16 kQueryServiceName = String16("InputFlingerQueryService");
-struct SetInputWindowsListener;
// --- InputFlingerServiceTest ---
class InputFlingerServiceTest : public testing::Test {
public:
@@ -104,32 +61,15 @@
protected:
void InitializeInputFlinger();
- void setInputWindowsByInfos(const std::vector<WindowInfo>& infos);
- void setFocusedWindow(const sp<IBinder> token, const sp<IBinder> focusedToken,
- nsecs_t timestampNanos);
-
- void setInputWindowsFinished();
- void verifyInputWindowInfo(const WindowInfo& info) const;
- WindowInfo& getInfo() const { return const_cast<WindowInfo&>(mInfo); }
sp<IInputFlinger> mService;
sp<IInputFlingerQuery> mQuery;
private:
- sp<SetInputWindowsListener> mSetInputWindowsListener;
std::unique_ptr<InputChannel> mServerChannel, mClientChannel;
- WindowInfo mInfo;
std::mutex mLock;
- std::condition_variable mSetInputWindowsFinishedCondition;
};
-struct SetInputWindowsListener : BnSetInputWindowsListener {
- explicit SetInputWindowsListener(std::function<void()> cbFunc) : mCbFunc(cbFunc) {}
-
- binder::Status onSetInputWindowsFinished() override;
-
- std::function<void()> mCbFunc;
-};
class TestInputManager : public BnInputFlinger {
protected:
@@ -138,16 +78,10 @@
public:
TestInputManager(){};
- binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles);
binder::Status getInputChannels(std::vector<::android::InputChannel>* channels);
- binder::Status getLastFocusRequest(FocusRequest*);
status_t dump(int fd, const Vector<String16>& args) override;
- binder::Status setInputWindows(
- const std::vector<WindowInfo>& handles,
- const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
-
binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
binder::Status setFocusedWindow(const FocusRequest&) override;
@@ -156,62 +90,28 @@
private:
mutable Mutex mLock;
- std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> mHandlesPerDisplay;
std::vector<std::shared_ptr<InputChannel>> mInputChannels;
- FocusRequest mFocusRequest;
};
class TestInputQuery : public BnInputFlingerQuery {
public:
TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){};
- binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles) override;
binder::Status getInputChannels(std::vector<::android::InputChannel>* channels) override;
- binder::Status getLastFocusRequest(FocusRequest*) override;
binder::Status resetInputManager() override;
private:
sp<android::TestInputManager> mManager;
};
-binder::Status TestInputQuery::getInputWindows(std::vector<WindowInfo>* inputHandles) {
- return mManager->getInputWindows(inputHandles);
-}
-
binder::Status TestInputQuery::getInputChannels(std::vector<::android::InputChannel>* channels) {
return mManager->getInputChannels(channels);
}
-binder::Status TestInputQuery::getLastFocusRequest(FocusRequest* request) {
- return mManager->getLastFocusRequest(request);
-}
-
binder::Status TestInputQuery::resetInputManager() {
mManager->reset();
return binder::Status::ok();
}
-binder::Status SetInputWindowsListener::onSetInputWindowsFinished() {
- if (mCbFunc != nullptr) {
- mCbFunc();
- }
- return binder::Status::ok();
-}
-
-binder::Status TestInputManager::setInputWindows(
- const std::vector<WindowInfo>& infos,
- const sp<ISetInputWindowsListener>& setInputWindowsListener) {
- AutoMutex _l(mLock);
-
- for (const auto& info : infos) {
- mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
- mHandlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
- }
- if (setInputWindowsListener) {
- setInputWindowsListener->onSetInputWindowsFinished();
- }
- return binder::Status::ok();
-}
-
binder::Status TestInputManager::createInputChannel(const std::string& name,
InputChannel* outChannel) {
AutoMutex _l(mLock);
@@ -249,15 +149,6 @@
return NO_ERROR;
}
-binder::Status TestInputManager::getInputWindows(std::vector<WindowInfo>* inputInfos) {
- for (auto& [displayId, inputHandles] : mHandlesPerDisplay) {
- for (auto& inputHandle : inputHandles) {
- inputInfos->push_back(*inputHandle->getInfo());
- }
- }
- return binder::Status::ok();
-}
-
binder::Status TestInputManager::getInputChannels(std::vector<::android::InputChannel>* channels) {
channels->clear();
for (std::shared_ptr<InputChannel>& channel : mInputChannels) {
@@ -266,64 +157,16 @@
return binder::Status::ok();
}
-binder::Status TestInputManager::getLastFocusRequest(FocusRequest* request) {
- *request = mFocusRequest;
- return binder::Status::ok();
-}
-
binder::Status TestInputManager::setFocusedWindow(const FocusRequest& request) {
- mFocusRequest = request;
return binder::Status::ok();
}
void TestInputManager::reset() {
- mHandlesPerDisplay.clear();
mInputChannels.clear();
- mFocusRequest = FocusRequest();
}
void InputFlingerServiceTest::SetUp() {
- mSetInputWindowsListener = new SetInputWindowsListener([&]() {
- std::unique_lock<std::mutex> lock(mLock);
- mSetInputWindowsFinishedCondition.notify_all();
- });
InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
-
- mInfo.token = TestInfoToken;
- mInfo.id = TestInfoId;
- mInfo.name = TestInfoName;
- mInfo.flags = TestInfoFlags;
- mInfo.type = TestInfoType;
- mInfo.dispatchingTimeout = TestInfoDispatchingTimeout;
- mInfo.frameLeft = TestInfoFrameLeft;
- mInfo.frameTop = TestInfoFrameTop;
- mInfo.frameRight = TestInfoFrameRight;
- mInfo.frameBottom = TestInfoFrameBottom;
- mInfo.surfaceInset = TestInfoSurfaceInset;
- mInfo.globalScaleFactor = TestInfoGlobalScaleFactor;
- mInfo.transform.set({TestInfoWindowXScale, 0, TestInfoFrameLeft, 0, TestInfoWindowYScale,
- TestInfoFrameTop, 0, 0, 1});
- mInfo.touchableRegion = TestInfoTouchableRegion;
- mInfo.visible = TestInfoVisible;
- mInfo.trustedOverlay = TestInfoTrustedOverlay;
- mInfo.focusable = TestInfoFocusable;
-
- mInfo.hasWallpaper = TestInfoHasWallpaper;
- mInfo.paused = TestInfoPaused;
- mInfo.ownerPid = TestInfoOwnerPid;
- mInfo.ownerUid = TestInfoOwnerUid;
- mInfo.inputFeatures = TestInfoInputFeatures;
- mInfo.displayId = TestInfoDisplayId;
- mInfo.portalToDisplayId = TestInfoPortalToDisplayId;
- mInfo.replaceTouchableRegionWithCrop = TestInfoReplaceTouchableRegionWithCrop;
- mInfo.touchableRegionCropHandle = TestInfoTouchableRegionCropHandle;
-
- mInfo.applicationInfo.name = TestAppInfoName;
- mInfo.applicationInfo.token = TestAppInfoToken;
- mInfo.applicationInfo.dispatchingTimeoutMillis =
- std::chrono::duration_cast<std::chrono::milliseconds>(TestAppInfoDispatchingTimeout)
- .count();
-
InitializeInputFlinger();
}
@@ -331,10 +174,6 @@
mQuery->resetInputManager();
}
-void InputFlingerServiceTest::verifyInputWindowInfo(const WindowInfo& info) const {
- EXPECT_EQ(mInfo, info);
-}
-
void InputFlingerServiceTest::InitializeInputFlinger() {
sp<IBinder> input(defaultServiceManager()->waitForService(kTestServiceName));
ASSERT_TRUE(input != nullptr);
@@ -345,40 +184,6 @@
mQuery = interface_cast<IInputFlingerQuery>(input);
}
-void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<WindowInfo>& infos) {
- std::unique_lock<std::mutex> lock(mLock);
- mService->setInputWindows(infos, mSetInputWindowsListener);
- // Verify listener call
- EXPECT_NE(mSetInputWindowsFinishedCondition.wait_for(lock, 1s), std::cv_status::timeout);
-}
-
-void InputFlingerServiceTest::setFocusedWindow(const sp<IBinder> token,
- const sp<IBinder> focusedToken,
- nsecs_t timestampNanos) {
- FocusRequest request;
- request.token = TestInfoToken;
- request.focusedToken = focusedToken;
- request.timestamp = timestampNanos;
- mService->setFocusedWindow(request);
- // call set input windows and wait for the callback to drain the queue.
- setInputWindowsByInfos(std::vector<WindowInfo>());
-}
-
-/**
- * Test InputFlinger service interface SetInputWindows
- */
-TEST_F(InputFlingerServiceTest, InputWindow_SetInputWindows) {
- std::vector<WindowInfo> infos = {getInfo()};
- setInputWindowsByInfos(infos);
-
- // Verify input windows from service
- std::vector<WindowInfo> windowInfos;
- mQuery->getInputWindows(&windowInfos);
- for (const WindowInfo& windowInfo : windowInfos) {
- verifyInputWindowInfo(windowInfo);
- }
-}
-
/**
* Test InputFlinger service interface createInputChannel
*/
@@ -397,7 +202,7 @@
EXPECT_EQ(result & O_NONBLOCK, O_NONBLOCK);
}
-TEST_F(InputFlingerServiceTest, InputWindow_CreateInputChannel) {
+TEST_F(InputFlingerServiceTest, CreateInputChannel) {
InputChannel channel;
ASSERT_TRUE(mService->createInputChannel("testchannels", &channel).isOk());
@@ -411,30 +216,6 @@
EXPECT_EQ(channels.size(), 0UL);
}
-TEST_F(InputFlingerServiceTest, InputWindow_setFocusedWindow) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- setFocusedWindow(TestInfoToken, nullptr /* focusedToken */, now);
-
- FocusRequest request;
- mQuery->getLastFocusRequest(&request);
-
- EXPECT_EQ(request.token, TestInfoToken);
- EXPECT_EQ(request.focusedToken, nullptr);
- EXPECT_EQ(request.timestamp, now);
-}
-
-TEST_F(InputFlingerServiceTest, InputWindow_setFocusedWindowWithFocusedToken) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- setFocusedWindow(TestInfoToken, FocusedTestInfoToken, now);
-
- FocusRequest request;
- mQuery->getLastFocusRequest(&request);
-
- EXPECT_EQ(request.token, TestInfoToken);
- EXPECT_EQ(request.focusedToken, FocusedTestInfoToken);
- EXPECT_EQ(request.timestamp, now);
-}
-
} // namespace android
int main(int argc, char** argv) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 967f028..5991091 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -31,7 +31,6 @@
#include <android/hardware/configstore/1.1/types.h>
#include <android/hardware/power/Boost.h>
#include <android/native_window.h>
-#include <android/os/BnSetInputWindowsListener.h>
#include <android/os/IInputFlinger.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -277,21 +276,6 @@
} // namespace anonymous
-struct SetInputWindowsListener : os::BnSetInputWindowsListener {
- explicit SetInputWindowsListener(std::function<void()> listenerCb) : mListenerCb(listenerCb) {}
-
- binder::Status onSetInputWindowsFinished() override;
-
- std::function<void()> mListenerCb;
-};
-
-binder::Status SetInputWindowsListener::onSetInputWindowsFinished() {
- if (mListenerCb != nullptr) {
- mListenerCb();
- }
- return binder::Status::ok();
-}
-
// ---------------------------------------------------------------------------
const String16 sHardwareTest("android.permission.HARDWARE_TEST");
@@ -358,10 +342,8 @@
mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
mPowerAdvisor(*this),
- mWindowInfosListenerInvoker(new WindowInfosListenerInvoker()) {
+ mWindowInfosListenerInvoker(new WindowInfosListenerInvoker(this)) {
ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
-
- mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });
}
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
@@ -3058,11 +3040,11 @@
if (mVisibleRegionsDirty || mInputInfoChanged) {
mInputInfoChanged = false;
- updateInputWindowInfo();
+ notifyWindowInfos();
} else if (mInputWindowCommands.syncInputWindows) {
// If the caller requested to sync input windows, but there are no
// changes to input windows, notify immediately.
- setInputWindowsFinished();
+ windowInfosReported();
}
for (const auto& focusRequest : mInputWindowCommands.focusRequests) {
@@ -3077,8 +3059,8 @@
return value;
}
-void SurfaceFlinger::updateInputWindowInfo() {
- std::vector<WindowInfo> inputInfos;
+void SurfaceFlinger::notifyWindowInfos() {
+ std::vector<WindowInfo> windowInfos;
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (!layer->needsInputInfo()) return;
@@ -3087,12 +3069,10 @@
: nullptr;
// When calculating the screen bounds we ignore the transparent region since it may
// result in an unwanted offset.
- inputInfos.push_back(layer->fillInputInfo(display));
+ windowInfos.push_back(layer->fillInputInfo(display));
});
-
- mInputFlinger->setInputWindows(inputInfos,
- mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
- : nullptr);
+ mWindowInfosListenerInvoker->windowInfosChanged(windowInfos,
+ mInputWindowCommands.syncInputWindows);
}
void SurfaceFlinger::updateCursorAsync() {
@@ -6410,7 +6390,7 @@
return NO_ERROR;
}
-void SurfaceFlinger::setInputWindowsFinished() {
+void SurfaceFlinger::windowInfosReported() {
Mutex::Autolock _l(mStateLock);
signalSynchronousTransactions(CountDownLatch::eSyncInputWindows);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 00590dd..462f98b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -93,7 +93,6 @@
class TunnelModeEnabledReporter;
class HdrLayerInfoReporter;
class HWComposer;
-struct SetInputWindowsListener;
class IGraphicBufferProducer;
class Layer;
class MessageBase;
@@ -333,7 +332,7 @@
// If set, disables reusing client composition buffers. This can be set by
// debug.sf.disable_client_composition_cache
bool mDisableClientCompositionCache = false;
- void setInputWindowsFinished();
+ void windowInfosReported();
// Disables expensive rendering for all displays
// This is scheduled on the main thread
@@ -819,7 +818,7 @@
void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
void updateInputFlinger();
- void updateInputWindowInfo();
+ void notifyWindowInfos();
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
@@ -1443,8 +1442,6 @@
// Should only be accessed by the main thread.
InputWindowCommands mInputWindowCommands;
- sp<SetInputWindowsListener> mSetInputWindowsListener;
-
Hwc2::impl::PowerAdvisor mPowerAdvisor;
// This should only be accessed on the main thread.
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
index 55136fb..dc2aa58 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
@@ -17,12 +17,32 @@
#include "WindowInfosListenerInvoker.h"
#include <gui/ISurfaceComposer.h>
#include <unordered_set>
+#include "SurfaceFlinger.h"
namespace android {
using gui::IWindowInfosListener;
using gui::WindowInfo;
+struct WindowInfosReportedListener : gui::BnWindowInfosReportedListener {
+ explicit WindowInfosReportedListener(std::function<void()> listenerCb)
+ : mListenerCb(listenerCb) {}
+
+ binder::Status onWindowInfosReported() override {
+ if (mListenerCb != nullptr) {
+ mListenerCb();
+ }
+ return binder::Status::ok();
+ }
+
+ std::function<void()> mListenerCb;
+};
+
+WindowInfosListenerInvoker::WindowInfosListenerInvoker(const sp<SurfaceFlinger>& sf) : mSf(sf) {
+ mWindowInfosReportedListener =
+ new WindowInfosReportedListener([&]() { windowInfosReported(); });
+}
+
void WindowInfosListenerInvoker::addWindowInfosListener(
const sp<IWindowInfosListener>& windowInfosListener) {
sp<IBinder> asBinder = IInterface::asBinder(windowInfosListener);
@@ -46,7 +66,8 @@
mWindowInfosListeners.erase(who);
}
-void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos) {
+void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
+ bool shouldSync) {
std::unordered_set<sp<IWindowInfosListener>, ISurfaceComposer::SpHash<IWindowInfosListener>>
windowInfosListeners;
@@ -57,8 +78,18 @@
}
}
+ mCallbacksPending = windowInfosListeners.size();
+
for (const auto& listener : windowInfosListeners) {
- listener->onWindowInfosChanged(windowInfos);
+ listener->onWindowInfosChanged(windowInfos,
+ shouldSync ? mWindowInfosReportedListener : nullptr);
+ }
+}
+
+void WindowInfosListenerInvoker::windowInfosReported() {
+ mCallbacksPending--;
+ if (mCallbacksPending == 0) {
+ mSf->windowInfosReported();
}
}
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h
index b979de1..5e5796f 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.h
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.h
@@ -16,32 +16,42 @@
#pragma once
+#include <android/gui/BnWindowInfosReportedListener.h>
#include <android/gui/IWindowInfosListener.h>
+#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <utils/Mutex.h>
#include <unordered_map>
namespace android {
+class SurfaceFlinger;
+
class WindowInfosListenerInvoker : public IBinder::DeathRecipient {
public:
+ WindowInfosListenerInvoker(const sp<SurfaceFlinger>& sf);
void addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);
void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);
- void windowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos);
+ void windowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos, bool shouldSync);
protected:
void binderDied(const wp<IBinder>& who) override;
private:
+ void windowInfosReported();
+
struct WpHash {
size_t operator()(const wp<IBinder>& p) const {
return std::hash<IBinder*>()(p.unsafe_get());
}
};
+ const sp<SurfaceFlinger> mSf;
std::mutex mListenersMutex;
std::unordered_map<wp<IBinder>, const sp<gui::IWindowInfosListener>, WpHash>
mWindowInfosListeners GUARDED_BY(mListenersMutex);
+ sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener;
+ std::atomic<size_t> mCallbacksPending{0};
};
} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index b96725f..26c91fa 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -51,6 +51,7 @@
"Stress_test.cpp",
"SurfaceInterceptor_test.cpp",
"VirtualDisplay_test.cpp",
+ "WindowInfosListener_test.cpp",
],
data: ["SurfaceFlinger_test.filter"],
static_libs: [
diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
new file mode 100644
index 0000000..89228d5
--- /dev/null
+++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2021 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 <gtest/gtest.h>
+#include <gui/SurfaceComposerClient.h>
+#include <private/android_filesystem_config.h>
+#include <future>
+#include "utils/TransactionUtils.h"
+
+namespace android {
+using Transaction = SurfaceComposerClient::Transaction;
+using gui::WindowInfo;
+
+class WindowInfosListenerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ seteuid(AID_SYSTEM);
+ mClient = new SurfaceComposerClient;
+ mWindowInfosListener = new SyncWindowInfosListener();
+ mClient->addWindowInfosListener(mWindowInfosListener);
+ }
+
+ void TearDown() override {
+ mClient->removeWindowInfosListener(mWindowInfosListener);
+ seteuid(AID_ROOT);
+ }
+
+ struct SyncWindowInfosListener : public gui::WindowInfosListener {
+ public:
+ void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos) override {
+ windowInfosPromise.set_value(windowInfos);
+ }
+
+ std::vector<WindowInfo> waitForWindowInfos() {
+ std::future<std::vector<WindowInfo>> windowInfosFuture =
+ windowInfosPromise.get_future();
+ std::vector<WindowInfo> windowInfos = windowInfosFuture.get();
+ windowInfosPromise = std::promise<std::vector<WindowInfo>>();
+ return windowInfos;
+ }
+
+ private:
+ std::promise<std::vector<WindowInfo>> windowInfosPromise;
+ };
+
+ sp<SurfaceComposerClient> mClient;
+ sp<SyncWindowInfosListener> mWindowInfosListener;
+};
+
+std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo,
+ std::vector<WindowInfo> windowInfos) {
+ std::optional<WindowInfo> foundWindowInfo = std::nullopt;
+ for (WindowInfo windowInfo : windowInfos) {
+ if (windowInfo.token == targetWindowInfo.token) {
+ foundWindowInfo = std::make_optional<>(windowInfo);
+ break;
+ }
+ }
+
+ return foundWindowInfo;
+}
+
+TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
+ std::string name = "Test Layer";
+ sp<IBinder> token = new BBinder();
+ WindowInfo windowInfo;
+ windowInfo.name = name;
+ windowInfo.token = token;
+ sp<SurfaceControl> surfaceControl =
+ mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState);
+
+ Transaction()
+ .setLayerStack(surfaceControl, 0)
+ .show(surfaceControl)
+ .setLayer(surfaceControl, INT32_MAX - 1)
+ .setInputWindowInfo(surfaceControl, windowInfo)
+ .apply();
+
+ std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
+ std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ ASSERT_NE(std::nullopt, foundWindowInfo);
+
+ Transaction().reparent(surfaceControl, nullptr).apply();
+
+ windowInfos = mWindowInfosListener->waitForWindowInfos();
+ foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ ASSERT_EQ(std::nullopt, foundWindowInfo);
+}
+
+TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
+ std::string name = "Test Layer";
+ sp<IBinder> token = new BBinder();
+ WindowInfo windowInfo;
+ windowInfo.name = name;
+ windowInfo.token = token;
+ sp<SurfaceControl> surfaceControl =
+ mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState);
+
+ Transaction()
+ .setLayerStack(surfaceControl, 0)
+ .show(surfaceControl)
+ .setLayer(surfaceControl, INT32_MAX - 1)
+ .setInputWindowInfo(surfaceControl, windowInfo)
+ .apply();
+
+ std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
+ std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ ASSERT_NE(std::nullopt, foundWindowInfo);
+ ASSERT_TRUE(foundWindowInfo->touchableRegion.isEmpty());
+
+ Rect touchableRegions(0, 0, 50, 50);
+ windowInfo.addTouchableRegion(Rect(0, 0, 50, 50));
+ Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();
+
+ windowInfos = mWindowInfosListener->waitForWindowInfos();
+ foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ ASSERT_NE(std::nullopt, foundWindowInfo);
+ ASSERT_TRUE(foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion));
+}
+
+} // namespace android